Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Containing $ref in select statement throws error unless fully qualified. #42

Open
sirockin opened this issue Oct 20, 2017 · 9 comments
Open

Comments

@sirockin
Copy link

Example code below throws the following error when it attempts to compile selectSchema2:

/Users/sirockin/source/f2/f2-schema/node_modules/ajv/lib/dotjs/ref.js:61
        throw new it.MissingRefError(it.baseId, $schema, $message);
        ^
Error: can't resolve reference defs.json#/definitions/int from id #

Example code:

var Ajv = require('ajv');

var schema = {
  "$id": "http://example.com/schemas/schema.json",
  "type": "object",
  "properties": {
    "foo": { "$ref": "defs.json#/definitions/int" },
    "bar": { "$ref": "defs.json#/definitions/str" }
  }
};

var selectSchema1={
  "$id": "http://example.com/schemas/select1.json",
  type: "object",
  required: ['kind'],
  properties: {
    kind: { type: 'string' }
  },
  select: { $data: '0/kind' },
  selectCases: {
    foo: {
      required: ['foo'],
      properties: {
        kind: {},
        foo: { type: 'string' }
      },
      additionalProperties: false
    },
    bar: {
      required: ['bar'],
      properties: {
        kind: {},
        bar: { type: 'number' }
      },
      additionalProperties: false
    }
  },
  selectDefault: {
    propertyNames: {
      not: { enum: ['foo', 'bar'] }
    }
  }
};

var selectSchema2={
  "$id": "http://example.com/schemas/select2.json",
  type: "object",
  required: ['kind'],
  properties: {
    kind: { type: 'string' }
  },
  select: { $data: '0/kind' },
  selectCases: {
    foo: {
      required: ['foo'],
      properties: {
        kind: {},
        foo: { "$ref": "defs.json#/definitions/int" }
      },
      additionalProperties: false
    },
    bar: {
      required: ['bar'],
      properties: {
        kind: {},
        bar: { type: 'number' }
      },
      additionalProperties: false
    }
  },
  selectDefault: {
    propertyNames: {
      not: { enum: ['foo', 'bar'] }
    }
  }
};


var defsSchema = {
  "$id": "http://example.com/schemas/defs.json",
  "definitions": {
    "int": { "type": "integer" },
    "str": { "type": "string" }
  }
};

// Validate against simple schema
var ajv = new Ajv({schemas: [schema, defsSchema]});
var validate = ajv.getSchema('http://example.com/schemas/schema.json');

var result = validate({ foo:2});
console.log("Simple schema validation result: " + result);

// Validate against select schema
ajv = new Ajv({schemas: [selectSchema1, defsSchema],$data:true});
require('ajv-keywords')(ajv, 'select');
validate = ajv.getSchema('http://example.com/schemas/select1.json');

var result = validate({ kind: 'foo', foo:"blah" });
console.log("Select schema validation result: " + result);

// Validate against select schema with refs - throws an error
ajv = new Ajv({schemas: [selectSchema2, defsSchema],$data:true});  
require('ajv-keywords')(ajv,'select');
validate = ajv.getSchema('http://example.com/schemas/select2.json'); // Error thrown here
var result = validate({ kind: 'foo', foo: 'any' });
console.log("Select with refs schema validation result: " + result);



@sirockin sirockin changed the title Contianing $ref in select statement throws error Containing $ref in select statement throws error Oct 20, 2017
@sirockin sirockin changed the title Containing $ref in select statement throws error Containing $ref in select statement throws error unless fully qualified. Oct 20, 2017
@sirockin
Copy link
Author

Did some further investigations: The reference will work but needs to be specified with the full ID ie http://example.com/schemas/defs.json#/definitions/int but not defs.json#/definitions/int. This applies even when using a ref declared in the same schema - so you can't for example use #/definitions/int to refer to a locally defined definition.

This is inconsistent with other rules for $ref usage so should at least be documented or preferably fixed.

@epoberezkin
Copy link
Member

That's why it's BETA :)

Select indeed compiles cases as separate schemas without resolving the IDs in them against the current base.

Happy with PR marking it as a limitation in docs and with a fix, but I won't invest more time in this keyword until there are better chances of it being adopted by the spec - please express your support in the relevant issue in JSON Schema GitHub org.

@sirockin
Copy link
Author

sirockin commented Oct 20, 2017 via email

@coco-super
Copy link

0/kind , what`s mean number zero??

@epoberezkin
Copy link
Member

It’s relative JSON pointer spec - “0” means the current level in the data (I.e. 0 levels up). “1” would mean one level up etc.

@coco-super
Copy link

It’s relative JSON pointer spec - “0” means the current level in the data (I.e. 0 levels up). “1” would mean one level up etc.

what is the down one level ?

@coco-super
Copy link

image

@coco-super
Copy link

Why is my selectCase not working, is it wrong for me?????????????
image

@coco-super
Copy link

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

3 participants