javascript 在json模式中,可以将默认值注解为this.parent.key吗?

wpcxdonn  于 2023-03-16  发布在  Java
关注(0)|答案(1)|浏览(91)

我有一个带有$def:{..,“machine”:{..,“displayName”:{..} }的模式,它将验证类似于“machines”:{“FA 23”:{..},“FA 41”:[..}}的结构。我想注解一下displayName属性的默认值将是机器的键(例如“FA 23”)。如果不通过程序生成模式,这是否完全可行?
这背后的原因是我想避免使用一个单独的结构来保存默认值:相反,我将在验证成功后解析模式,并使用指定的默认值填充缺失的值。我希望解析函数尽可能通用,以允许在不同的项目中重复使用。因此,默认值必须包含确切的值,或者是一种安全的方式来获得它,而不需要特定于模式的逻辑。
我使用的是draft-07,但我还没有提交到一个特定的草稿。我也在node.js@v14-latest environment(node-red)下使用javascript,但如果可能的话,我希望避免使用模块或代码来生成模式。
我使用对象属性列表而不是数组,因为这是我在运行时实际使用的结构,允许我直接将其写入文件,而无需转换步骤。
到目前为止,我的模式的子集如下所示

{
    "$schema":"http://json-schema.org/draft-07/schema#",
    "title":"commonConfigSchema",
    "description":"global common config for this project",
    "$defs":{
        "javascriptFalsy":{
            "enum":[false, 0, null, ""]
        },
        "macKey":{
            "type":"string",
            "enum":["FA419","FA420","FA421","FA422","FA423","MO41","MO42","OMET"]
        },
        "signalKey":{
            "type":"string",
            "enum":["noop","A1","A2","A3","A4","B","C1","C2","D","E"],
            "default":"noop"
        },
        "towerDevice":{
            "type":"string",
            "enum":["redLight","greenLight","horn"]
        },
        "machine":{
            "type":"object",
            "properties":{
                "displayName":{"type":"string", "default":"this.parent.key"},
                "cellHeaderText":{"type":"string", "default":"Linea + this.displayName"},
                "toA3Timeout":{"type":"integer", "minimum":0, "default":20000},
                "toA4Timeout":{"type":"integer", "minimum":0, "default":"120*60*1000"},
                "initCellSignalKey":{"$ref":"#/$defs/signalKey", "default":"noop"},
                "initTowerBits":{
                    "type":"object",
                    "propertyNames":{"$ref":"#/$defs/towerDevice"},
                    "patternProperties":{".":{"enum":[0, 1, true, false], "default":0}}
                }
            },
            "$comment":"exactly all the props are required",
            "additionalProperties":false,
            "required":["displayName", "cellHeaderText", "toA3Timeout", "toA4Timeout", "initCellSignalKey", "initTowerBits"]
        }
    },
    "type":"object",
    "properties":{
        "machines":{
            "$description": "holding machine-specific configs. Made up of macKey:config pairs",
            "type":"object",
            "propertyNames":{"$ref":"#/$defs/macKey"},
            "patternProperties":{".":{"$ref":"#/$defs/machine"} },
            //"required":{"$ref":"#/$defs/macKey/enum"},
            "required":["FA419","FA420","FA421","FA422","FA423","MO41","MO42","OMET"]
            "additionalProperties":false,
        }
    },
    "required":["cellsLayout", "machines"],
    "additionalProperties":false,
}

p.s. as you can see from the commented out "required" i was also struggling with binding that string array to my enum definition, thus avoiding redundancies. But $refs are schemas, not string arrays :/
I found this old answer [link][1] stating that it's not possible, has anything changed?
0md85ypi

0md85ypi1#

你不能通过直接引用示例中的值来设置default。但是,由于所有可能的值都是已知的,所以有一种方法可以通过if/then关键字来实现。这不是一个很好的解决方案,但它是一个解决方案。

"allOf": [
    {
      "if": {
        "properties": {
          "macKey": { "const": "FA419" }
        },
        "required": ["macKey"]
      },
      "then": {
        "properties": {
          "machine": {
            "properties": {
              "displayName": { "default": "FA419" }
            }
          }
        }
      }
    }
  ]

这意味着,如果/macKey是“FA 419”,那么/machine/displayName的默认值是“FA 419”。如果您为每个可能的/macKeyallOf添加这些条件模式之一,您将获得您正在寻找的行为。

相关问题