0

Initial Setting

You have a JavaScript object for keeping configs, it may be extended by plugins, each plugin has a version and one property on the configs object.

const CONFIGS = {
  plugins: {
    plugins: { version: '0.15' }, // Plugins is a plugin itself.
    proxies: { version: '0.15' }  // Used to configure proxies.
  },
  proxies: {
    HTTPS: ['satan.hell:666']
  }
}

Question

How to express in JSON schema, that each key of CONFIGS.plugins MUST have corresponding property on root of CONFIGS object and vice versa.

My Failed Attempt

ajv is 4.8.2, prints "Valid!" but must be "Invalid"

'use strict';

var Ajv = require('ajv');
var ajv = Ajv({allErrors: true, v5: true});

var schema = {

  definitions: {
    pluginDescription: {
      type: "object",
      properties: {
        version: { type: "string" }
      },
      required: ["version"],
      additionalProperties: false
    }
  },

  type: "object",
  properties: {

    plugins: {
      type: "object",
      properties: {

        plugins: {
          $ref: "#/definitions/pluginDescription"
        }

      },
      required: ["plugins"],
      additionalProperties: {
        $ref: "#/definitions/pluginDescription"
      }
    }

  },
  required: { $data: "0/plugins/#" }, // current obj > plugins > all props?
  additionalProperties: false
};

var validate = ajv.compile(schema);

test({
  plugins: {
    plugins: { version: 'def' },
    proxies: { version: 'abc' }
  }
  // Sic! No `proxies` prop, but must be.
});

function test(data) {
  var valid = validate(data);
  if (valid) console.log('Valid!');
  else console.log('Invalid: ' + ajv.errorsText(validate.errors));
}
ilyaigpetrov
  • 3,657
  • 3
  • 30
  • 46

1 Answers1

1

There are three solutions here:

  1. create another property on the root level, e.g. requiredProperties. Its value should be an array with the list of properties you want to have both on the top level and inside plugins. Then you can use required with $data pointing to this array both on top level and inside plugins. See example here: https://runkit.com/esp/581ce9faca86cc0013c4f43f

  2. use custom keyword(s).

  3. check this requirement in code - there is no way in JSON schema to say keys in one object should be the same as keys in another (apart from above options).

esp
  • 7,314
  • 6
  • 49
  • 79