title: Keys in One Object Must be the Same as Keys in Another Object
body: <h1>Initial Setting</h1>
  
  <p>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.</p>
  
  <pre class="lang-js prettyprint-override"><code>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']
    }
  }
  </code></pre>
  
  <h1>Question</h1>
  
  <p>How to express in JSON schema, that each key of <code>CONFIGS.plugins</code> MUST have corresponding property on root of <code>CONFIGS</code> object and vice versa.</p>
  
  <h1>My Failed Attempt</h1>
  
  <p>ajv is 4.8.2, prints <em>"Valid!"</em> but must be <em>"Invalid"</em></p>
  
  <pre class="lang-js prettyprint-override"><code>'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 &gt; plugins &gt; 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));
  }
  </code></pre>