JSON 架构/AJV 数组项必须在另一个数组中

JSON Schema / AJV array item must be in another array

我正在使用 Node 的 AJV(强制执行 JSON 架构)。

我想验证数组 1 properties.bars。很简单。

然后我想确保 array2 properties.keep 中的一个项目在 array1 properties.bars.

我该怎么做?

我有:

const config = require('../../../config')
const VALID_BARS = Object.keys(config.LHS_RHS_LOOKUP)

const schemaItems = {
  id: 'schemaItems',
  type: 'string',
  anyOf: [
    { enum: VALID_BARS },
    { pattern: '^[^\s]+ [^\s]+$' }
  ]
}

const schemaOptions = {
  type: 'object',
  properties: {
    bars: {
      type: 'array',
      default: [VALID_BARS[0]],
      items: schemaItems,
      minItems: 1,
      uniqueItems: true
    },
    keep: {
      type: 'array',
      default: [],
      items: schemaItems, // << THIS NEEDS TO CHANGE
      minItems: 0,
      uniqueItems: true
    },
    protect: {
      default: true,
      type: 'boolean'
    }
  }
}

module.exports = schemaOptions

你会想要使用 $data pointer to the first array. Right now it's just a proposal。它允许您使用另一个 属性.

data 值将值分配给 keyword

所以在这种情况下,您的第二个数组的项目 属性 将有一个枚举 属性,它将使用第一个数组的 $data 值。

为此,我必须删除原始架构中的 'anyOf',这样第一个数组就不会引用自身。我还通过 $ref 和定义将 schemaItems 组合到主模式中。

这是 a PLNKR 的实际效果。

测试代码类似于:

let schema = {
  definitions: {
    schemaItems: {
      id: 'schemaItems',
      type: 'string',
      pattern: '^[^\s]+ [^\s]+$'
    }
  },
  type: 'object',
  properties: {
    bars: {
      type: 'array',
      items: {
        $ref: "#/definitions/schemaItems"
      },
      minItems: 1,
      uniqueItems: true
    },
    keep: {
      type: 'array',
      items: {
        type: 'string',
        enum: {
          "$data": "/bars"
        }
      },
      minItems: 0,
      uniqueItems: true
    },
    protect: {
      default: true,
      type: 'boolean'
    }
  }
};

有效数据样本为:

let data = {
  bars: [
    "d d",
    "b b"
  ],
  keep: [
    "d d"
  ],
  protect: true
};