json - 如何将 $ref 与 json-schema 和顶级属性一起使用

标签 json jsonschema ajv

friend 们大家好:)我有一个如下所示的 JSON 架构:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Sync Repo Settings Config",
  "description": "Schema for defining the sync repo settings config",
  "additionalProperties": false,
  "type": "object",
  "$ref": "#/definitions/repoConfig",
  "definitions": {
    "repoConfig": {
      "type": "object",
      "properties": {
        "name": {
          "description": "A simple label for describing the ruleset.",
          "type": "string"
        },
        "selector": {
          "description": "For use in the org/.github repository. A GitHub repo search query that identifies the repositories which should be managed by the given rule.",
          "type": "boolean"
        },
        "squashMergeAllowed": {
          "description": "Whether or not squash-merging is enabled on this repository.",
          "type": "boolean"
        },
        "rebaseMergeAllowed": {
          "description": "Whether or not rebase-merging is enabled on this repository.",
          "type": "boolean"
        },
        "mergeCommitAllowed": {
          "description": "Whether or not PRs are merged with a merge commit on this repository.",
          "type": "boolean"
        },
        "deleteBranchOnMerge": {
          "description": "Either true to allow automatically deleting head branches when pull requests are merged, or false to prevent automatic deletion.",
          "type": "boolean"
        },
        "branchProtectionRules": {
          "description": "Branch protection rules",
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "pattern": {
                "description": "Identifies the protection rule pattern.",
                "type": "string"
              },
              "dismissesStaleReviews": {
                "description": "Will new commits pushed to matching branches dismiss pull request review approvals.",
                "type": "boolean"
              },
              "isAdminEnforced": {
                "description": "Can admins overwrite branch protection.",
                "type": "boolean"
              },
              "requiredApprovingReviewCount": {
                "description": "Number of approving reviews required to update matching branches.",
                "type": "number"
              },
              "requiredStatusCheckContexts": {
                "description": "List of required status check contexts that must pass for commits to be accepted to matching branches.",
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "requiresCodeOwnerReviews": {
                "description": "Are reviews from code owners required to update matching branches.",
                "type": "boolean"
              },
              "requiresCommitSignatures": {
                "description": "Are commits required to be signed.",
                "type": "boolean"
              },
              "requiresStatusChecks": {
                "description": "Are status checks required to update matching branches.",
                "type": "boolean"
              },
              "requiresStrictStatusChecks": {
                "description": "Are branches required to be up to date before merging.",
                "type": "boolean"
              },
              "restrictsPushes": {
                "description": "Is pushing to matching branches restricted.",
                "type": "boolean"
              },
              "restrictsReviewDismissals": {
                "description": "Is dismissal of pull request reviews restricted.",
                "type": "boolean"
              }
            }
          }
        },
        "permissionRules": {
          "description": "List of explicit permissions to add (additive only)",
          "type": "array",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "team": {
                "description": "Team slug to provide access.",
                "type": "string"
              },
              "permission": {
                "description": "Permission to provide the team.  Can be one of (pull|push|admin)",
                "type": "string",
                "enum": ["pull", "push", "admin"]
              }
            },
            "required": ["team", "permission"]
          }
        }
      }
    }
  }
}

我正在尝试创建一个可重用的 repoConfig 架构,它也可以在我的 json 文档的根中表示。我很挑剔,并关闭了 additionalProperties 设置,只是为了使 100% 一切都按预期工作。当我尝试验证此文档时:

{
   "rebaseMergeAllowed": false,
   "branchProtectionRules": [
      {
         "requiresCodeOwnerReviews": true,
         "requiredStatusCheckContexts": [
            "check1",
            "check2"
         ]
      }
   ],
   "permissionRules": [
      {
         "team": "team1",
         "permission": "push"
      }
   ]
}

我在验证期间从 ajv npm 模块收到以下错误:

[
  {
    instancePath: '',
    schemaPath: '#/additionalProperties',
    keyword: 'additionalProperties',
    params: { additionalProperty: 'rebaseMergeAllowed' },
    message: 'must NOT have additional properties'
  }
]

如果我获取在共享 repoConfig 对象中定义的 properties 集合,并将它们直接内联到我的架构文档的根中,验证器将按预期工作。

最佳答案

虽然 Ether 的答案是正确的,但你实际上有一个 XY problem在这里。

(我认为 ajv 实际上允许在根级别使用 $refdefinitions。其合法性值得商榷且不清楚。)

您的问题在于您对 additionalProperties 的使用,因为它无法“透视”应用程序,例如 $ref

Validation with "additionalProperties" applies only to the child values of instance names that do not match any names in "properties", and do not match any regular expression in "patternProperties".

https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-validation-01#section-6.5.6

简单来说,propertiespatternProperties 位于同一架构对象中,仅作为 additionalProperties

如果您需要继续使用JSON Schema的draft-07,那么您需要在同一级别重新定义properties(您可以将它们的值设置为true )。

如果您可以迁移到较新版本的 JSON Schema,则可以使用 unevaluatedProperties,简单来说,它可以“透视”应用程序关键字。它有点复杂,但它会按照您的预期运行。

关于json - 如何将 $ref 与 json-schema 和顶级属性一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67248783/

相关文章:

node.js - AJV 架构验证失败

javascript - 以 0. 开头并以 ] 结尾的字符串的正则表达式?

javascript - 有没有一种方法可以用 MongoDB 识别的 JSON 来表示 ISODate 和 ObjectID 字段?

java - 为嵌套 JSON 对象创建 GWT 覆盖

validation - OpenAPI:如何验证示例?

javascript - AJV 自定义关键字验证

jsonschema - JSON Schema - 根据输入属性指定字符串长度

json - 将 JSON 字符串映射到 FLUTTER 中的项目模型

javascript - typescript 编译时错误

JSON 模式对数组中某些对象属性进行条件检查