Giter VIP home page Giter VIP logo

jsonschema's Introduction

Build Status

jsonschema

JSON schema validator, which is designed to be fast and simple to use. JSON Schema versions through draft-07 are fully supported.

Contributing & bugs

Please fork the repository, make the changes in your fork and include tests. Once you're done making changes, send in a pull request.

Bug reports

Please include a test which shows why the code fails.

Usage

Simple

Simple object validation using JSON schemas.

var Validator = require('jsonschema').Validator;
var v = new Validator();
var instance = 4;
var schema = {"type": "number"};
console.log(v.validate(instance, schema));

Even simpler

var validate = require('jsonschema').validate;
console.log(validate(4, {"type": "number"}));

Complex example, with split schemas and references

var Validator = require('jsonschema').Validator;
var v = new Validator();

// Address, to be embedded on Person
var addressSchema = {
  "id": "/SimpleAddress",
  "type": "object",
  "properties": {
    "lines": {
      "type": "array",
      "items": {"type": "string"}
    },
    "zip": {"type": "string"},
    "city": {"type": "string"},
    "country": {"type": "string"}
  },
  "required": ["country"]
};

// Person
var schema = {
  "id": "/SimplePerson",
  "type": "object",
  "properties": {
    "name": {"type": "string"},
    "address": {"$ref": "/SimpleAddress"},
    "votes": {"type": "integer", "minimum": 1}
  }
};

var p = {
  "name": "Barack Obama",
  "address": {
    "lines": [ "1600 Pennsylvania Avenue Northwest" ],
    "zip": "DC 20500",
    "city": "Washington",
    "country": "USA"
  },
  "votes": "lots"
};

v.addSchema(addressSchema, '/SimpleAddress');
console.log(v.validate(p, schema));

Returned ValidatorResult object, will show this example is NOT valid since: "votes": "lots" is not an integer.

Example for Array schema

var arraySchema = {
        "type": "array",
        "items": {
            "properties": {
                "name": { "type": "string" },
                "lastname": { "type": "string" }
            },
            "required": ["name", "lastname"]
        }
    }

For a comprehensive, annotated example illustrating all possible validation options, see examples/all.js

Features

Definitions

All schema definitions are supported, $schema is ignored.

Types

All types are supported

Handling undefined

undefined is not a value known to JSON, and by default, the validator treats it as if it is not invalid. i.e., it will return valid.

var res = validate(undefined, {type: 'string'});
res.valid // true

This behavior may be changed with the "required" option:

var res = validate(undefined, {type: 'string'}, {required: true});
res.valid // false

Formats

Disabling the format keyword.

You may disable format validation by providing disableFormat: true to the validator options.

String Formats

All formats are supported, phone numbers are expected to follow the E.123 standard.

Custom Formats

You may add your own custom format functions. Format functions accept the input being validated and return a boolean value. If the returned value is true, then validation succeeds. If the returned value is false, then validation fails.

  • Formats added to Validator.prototype.customFormats do not affect previously instantiated Validators. This is to prevent validator instances from being altered once created. It is conceivable that multiple validators may be created to handle multiple schemas with different formats in a program.
  • Formats added to validator.customFormats affect only that Validator instance.

Here is an example that uses custom formats:

Validator.prototype.customFormats.myFormat = function(input) {
  return input === 'myFormat';
};

var validator = new Validator();
validator.validate('myFormat', {type: 'string', format: 'myFormat'}).valid; // true
validator.validate('foo', {type: 'string', format: 'myFormat'}).valid; // false

Results

By default, results will be returned in a ValidatorResult object with the following properties:

  • instance: any.
  • schema: Schema.
  • errors: ValidationError[].
  • valid: boolean.

Each item in errors is a ValidationError with the following properties:

  • path: array. An array of property keys or array offsets, indicating where inside objects or arrays the instance was found.
  • property: string. Describes the property path. Starts with instance, and is delimited with a dot (.).
  • message: string. A human-readable message for debugging use. Provided in English and subject to change.
  • schema: object. The schema containing the keyword that failed
  • instance: any. The instance that failed
  • name: string. The keyword within the schema that failed.
  • argument: any. Provides information about the keyword that failed.

The validator can be configured to throw in the event of a validation error:

  • If the throwFirst option is set, the validator will terminate validation at the first encountered error and throw a ValidatorResultError object.

  • If the throwAll option is set, the validator will throw a ValidatorResultError object after the entire instance has been validated.

  • If the throwError option is set, it will throw at the first encountered validation error (like throwFirst), but the ValidationError object itself will be thrown. Note that, despite the name, this does not inherit from Error like ValidatorResultError does.

The ValidatorResultError object has the same properties as ValidatorResult and additionally inherits from Error.

"nestedErrors" option

When oneOf or anyOf validations fail, errors that caused any of the sub-schemas referenced therein to fail are normally suppressed, because it is not necessary to fix all of them. And in the case of oneOf, it would itself be an error to fix all of the listed errors.

This behavior may be configured with options.nestedErrors. If truthy, it will emit all the errors from the subschemas. This option may be useful when troubleshooting validation errors in complex schemas:

var schema = {
  oneOf: [
    { type: 'string', minLength: 32, maxLength: 32 },
    { type: 'string', maxLength: 16 },
    { type: 'number' },
  ]
};
var validator = new Validator();
var result = validator.validate('This string is 28 chars long', schema, {nestedErrors: true});

// result.toString() reads out:
// 0: instance does not meet minimum length of 32
// 1: instance does not meet maximum length of 16
// 2: instance is not of a type(s) number
// 3: instance is not exactly one from [subschema 0],[subschema 1],[subschema 2]

Localizing Error Messages

To provide localized, human-readable errors, use the name string as a translation key. Feel free to open an issue for support relating to localizing error messages. For example:

var localized = result.errors.map(function(err){
  return localeService.translate(err.name);
});

Custom keywords

Specify your own JSON Schema keywords with the validator.attributes property:

validator.attributes.contains = function validateContains(instance, schema, options, ctx) {
  if(typeof instance !== 'string') return;
  if(typeof schema.contains !== 'string') throw new jsonschema.SchemaError('"contains" expects a string', schema);
  if(instance.indexOf(schema.contains)<0){
    return 'does not contain the string ' + JSON.stringify(schema.contains);
  }
}
var result = validator.validate("I am an instance", { type:"string", contains: "I am" });
// result.valid === true;

The instance passes validation if the function returns nothing. A single validation error is produced if the function returns a string. Any number of errors (maybe none at all) may be returned by passing a ValidatorResult object, which may be used like so:

  var result = new ValidatorResult(instance, schema, options, ctx);
  while(someErrorCondition()){
    result.addError('fails some validation test');
  }
  return result;

Dereferencing schemas

Sometimes you may want to download schemas from remote sources, like a database, or over HTTP. When importing a schema, unknown references are inserted into the validator.unresolvedRefs Array. Asynchronously shift elements off this array and import them:

var Validator = require('jsonschema').Validator;
var v = new Validator();
v.addSchema(initialSchema);
function importNextSchema(){
  var nextSchema = v.unresolvedRefs.shift();
  if(!nextSchema){ done(); return; }
  databaseGet(nextSchema, function(schema){
    v.addSchema(schema);
    importNextSchema();
  });
}
importNextSchema();

Disallowing unknown attributes

Sometimes you may want to disallow unknown attributes passed in the body of the request, in order to disallow those unknown attributes before the validation of the body, you need to set additionalProperties to false.

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "title": "Accounting Resource - Add Item",
  "type": "object",
  "additionalProperties": false,
  "properties": {
      "itemNumber": {
          "type":"string"
      },
      "title": {
          "type":"string"
      },
      "description": {
          "type":"string"
      }
  },
  "required": [
      "itemNumber",
      "title",
      "description"
  ]
}

Default base URI

Schemas should typically have an id with an absolute, full URI. However if the schema you are using contains only relative URI references, the base option will be used to resolve these.

This following example would throw a SchemaError if the base option were unset:

var result = validate(["Name"], {
  id: "/schema.json",
  type: "array",
  items: { $ref: "http://example.com/schema.json#/definitions/item" },
  definitions: {
    item: { type: "string" },
  },
}, { base: 'http://example.com/' });

Rewrite Hook

The rewrite option lets you change the value of an instance after it has successfully been validated. This will mutate the instance passed to the validate function. This can be useful for unmarshalling data and parsing it into native instances, such as changing a string to a Date instance.

The rewrite option accepts a function with the following arguments:

  • instance: any
  • schema: object
  • options: object
  • ctx: object
  • return value: any new value for the instance

The value may be removed by returning undefined. If you don't want to change the value, call return instance.

Here is an example that can convert a property expecting a date into a Date instance:

const schema = {
  properties: {
    date: {id: 'http://example.com/date', type: 'string'},
  },
};

const value = {
  date: '2020-09-30T23:39:27.060Z',
};

function unmarshall(instance, schema){
  if(schema.id === 'http://example.com/date'){
    return new Date(instance);
  }
  return instance;
}

const v = new Validator();
const res = v.validate(value, schema, {rewrite: unmarshall});

assert(res.instance.date instanceof Date);

Pre-Property Validation Hook

If some processing of properties is required prior to validation a function may be passed via the options parameter of the validate function. For example, say you needed to perform type coercion for some properties:

// See examples/coercion.js
function preValidateProperty(object, key, schema, options, ctx) {
  var value = object[key];
  if (typeof value === 'undefined') return;

  // Test if the schema declares a type, but the type keyword fails validation
  if (schema.type && validator.attributes.type.call(validator, value, schema, options, ctx.makeChild(schema, key))) {
    // If the type is "number" but the instance is not a number, cast it
    if(schema.type==='number' && typeof value!=='number'){
      object[key] = parseFloat(value);
      return;
    }
    // If the type is "string" but the instance is not a string, cast it
    if(schema.type==='string' && typeof value!=='string'){
      object[key] = String(value).toString();
      return;
    }
  }
};

// And now, to actually perform validation with the coercion hook!
v.validate(instance, schema, { preValidateProperty });

Skip validation of certain keywords

Use the "skipAttributes" option to skip validation of certain keywords. Provide an array of keywords to ignore.

For skipping the "format" keyword, see the disableFormat option.

Fail on unknown keywords

By default, JSON Schema is supposed to ignore unknown schema keywords.

You can change this behavior to require that all keywords used in a schema have a defined behavior, by using setting the "allowUnknownAttributes" option to false.

This example will throw a SchemaError:

var schema = {
  type: "string",
  format: "email",
  example: "foo",
};
var result = validate("Name", schema, { allowUnknownAttributes: false });

Tests

Uses JSON Schema Test Suite as well as our own tests. You'll need to update and init the git submodules:

git submodule update --init
npm test

Contributions

This library would not be possible without the valuable contributions by:

  • Austin Wright

... and many others!

License

jsonschema is licensed under MIT license.

Copyright (C) 2012-2019 Tom de Grunt <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

jsonschema's People

Contributors

awwright avatar benkitzelman avatar coryvirok avatar deyhle avatar echojc avatar franciscop avatar gamedevsam avatar hasansaghir avatar haywood avatar henryrgithub avatar hugowetterberg avatar itz1t4y07 avatar janmentzel avatar jaredh159 avatar jasonpincin avatar joepadmiraal avatar jolcese avatar kbsbng avatar mpareja avatar mugeso avatar nick-ivanov-ibm avatar peterdavehello avatar pmlopes avatar pushplay avatar pyldin601 avatar remcohaszing avatar richardprior avatar sebastiang77 avatar tdegrunt avatar trashstack avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jsonschema's Issues

optional enum

Hi.
I am trying to create a schema for an value type enum which is optional.
Like: "status": {"type": "string", "enum":["on","off"]}
If i omitt the status i still get an error, even when required set to false.

no such schema. valid schema, offline usage?

I'm trying to validate a valid JSON string with a valid JSON schema, but I keep getting the "no such schema" error.

Investigation lead me to believe that since I'm using jsonschema with NodeJS, I can't use an URI in the id var.

So the question is: How can I run jsonschema with NodeJS?

required fails if used in the global space

From JSON-schema.org sample:

{
    "title": "Example Schema",
    "type": "object",
    "properties": {
        "firstName": {
            "type": "string"
        },
        "lastName": {
            "type": "string"
        },
        "age": {
            "description": "Age in years",
            "type": "integer",
            "minimum": 0
        }
    },
    "required": ["firstName", "lastName"]
}

If you use this schema and don't pass in a firstName or lastName it still validates. Looks like the current code base looks for each property to have a required on each.

If this isn't supposed to support the json-schema.org definition then this is something to note some place :)

Validation of external sub-schema

Hi,

Iโ€™m using Frisby to test my REST API. Frisby is using jsonschema to validate the JSONs returned by a URL.

The JSON schema I use to validate my JSON is referencing an external sub-schema via $ref. In that situation, it seems that the jsonschema validation is always failing with a message similar to:

SchemaError: no such schema http://api-portal.anypoint.mulesoft.com/telus/api/kinexchangeapi/schema_domaine.json

I tried a simple script to check if itโ€™s really the problem with the following code using only jsonschema and I get the same error. Is there something I donโ€™t get or is it a real bug ?

var Validator = require('jsonschema').Validator;
var v = new Validator();

 // Liste domaines
 var schema_liste_domaines = {
    "type":"object",
    "$schema": "http://json-schema.org/draft-03/schema",
    "title": "Liste de domaines",
    "required":false,
    "properties": {
      "domaines": {
        "type":"array",
        "required":true,
        "items": {
          "$ref": "http://api-portal.anypoint.mulesoft.com/telus/api/kinexchangeapi/schema_domaine.json"
        }
      }
    }
  };

 var p = {
 "domaines": [
      {
        "id": 1234,
        "nom": "Clinique mรฉdicale Amyot",
        "services" : [
          {
            "id": 14,
            "description" : "Liste des domaines accessibles",
            "hrefs" : [
                {"href" : "/domaines", "methode" : "get"}
            ]
          }
        ]
      }
    ]
  };

 console.log(v.validate(p, schema_liste_domaines));

invalid schema with a property set to "undefined" causes TypeError exception during validation

I got following exception when using jsonschema:

Uncaught exception: TypeError: Cannot read property 'id' of undefined, stack:
    at SchemaContext.makeChild (/root/nef/node_modules/jsonschema/lib/helpers.js:100:43)
    at Validator.validateProperties (/root/nef/node_modules/jsonschema/lib/attribute.js:153:76)
    at Validator.validateSchema (/root/nef/node_modules/jsonschema/lib/validator.js:208:34)
    at Validator.validate (/root/nef/node_modules/jsonschema/lib/validator.js:137:23)
    at Object.module.exports.validate (/root/nef/node_modules/jsonschema/lib/index.js:11:12)
    at Object.validate (/root/nef/lib/nef/schemaUtils.js:223:29)
    at /root/nef/node_modules/async/lib/async.js:229:13

It took me a day until I figured out that the error is caused by invalid JSON schema where definition of one of the properties is set to undefined. I.e.

{
   "type": "object",
   "properties": {
        "a": { "type": string },
        "b": undefined
   }
}

for loop iterating over schema properties in attribute.js:validators.properties() will yield attribute "b" (although it is set to undefined) and undefined value is then passed to ctx.makeChild() where exception is thrown when trying to reference 'id' attribute of undefined.

Two things which need to fixed here:

  • when such schema is validated by JSON schema (http://json-schema.org/draft-03/schema) it should report error, currently it passes the validation.
  • when the schema is used for validation it should either skip undefined property during validation or throw SchemaError.

Custom error messages

Hi,

I want to uses another language when the validator fails, but the message are in hard code, could I validate error messages but these may change in the future.
Maybe returning a code error or being able to extend message strings

Regards

Object validation vs Date/Array and the JSON Schema spec

Currently we validate objects using return (instance && (typeof instance) === 'object'); but this doesn't work for Array and Date validation.

We depend on objects with changed constructor. So the above won't work for us. The spec is specifically vague about this:

5.1. type
...
object Value MUST be an object.

So technically this should be enough: return (instance && (typeof instance) === 'object')

But I see the Date and Array problem. Perhaps we should reverse the testing of the instance?

i.e. we decide the "main" type of the instance through a method similar to testType (in lib/attribute.js) and compare that against what's in the schema. That way if we move the Date and Array tests above the Object test, Date's and Array's won't validate as Objects.

Add method to clean an object

I need a mechanism to clean undeclared properties off of an object. I could use another library or write my own function, but I'd rather have it as part of this library.

var cleaned = require('jsonschema').clean({
  name: 'Prestaul',
  foo: 'bar' // This should be removed
}, {
  type: 'object',
  properties: {
    name: { type:'string' }
  }
});

cleaned; // { name:'Prestaul' }

Even better, I would love to be able to validate and clean an object in a single pass. (syntax is up for debate)

var result = require('jsonschema').validateAndClean({
  name: 'Prestaul',
  foo: 'bar' // This should be removed
}, {
  type: 'object',
  properties: {
    name: { type:'string' }
  }
});

output:

{
  valid: true,
  errors: [], // empty if valid
  instance: {}, // the original object
  cleanInstance: {} // the cleaned object if valid, else null
}

Does this feel like something that belongs here? I'm happy to help contribute, but lack the familiarity with the project to feel comfortable jumping in without first ensuring my approach fits the intended design. Looking for feedback.

Support 'default' and ability to return modified instance in general

In my current master I've implemented some cool stuff:

  1. return (actually, throw) only the first error, which should be faster than parsing for every single error when doing so is unnecessary.
  2. Implement a uniform interface for returning errors
  3. Make use of that options argument and allow people to define a callback that modifies the value of an instance once it validates, but before it gets used in a parent instance. For instance, to implement the default schema attribute. (see https://github.com/Acubed/jsonschema/blob/8233ccbbd7994287be05375e6ed93d9e17f5e68a/lib/validator.js#L71-L74)
  4. Allow users to specify their own schema attributes and types at runtime (see https://github.com/Acubed/jsonschema/blob/20891118822e0deb7f50549d6a24ec2c2981af92/lib/validator.js#L12-L13)

However, this is a breaking API change to some extent, since no longer are errors being returned, but an object containing among other things the list of errors.

I'd like your comments, and if this is alright I'll begin merging in your recent commits. I'd like to make breaking API changes (including remove environment.js), so could I request that you release it as v2.0.0? (Version 2, since it's ambiguous if a bump from 0->1 means a breaking change in semver semantics. Probably not, but I wouldn't want to give humans the impression it's a stabilized version of the 0 branch, it's actually breaking.)

Add URI resolution support

Using plain strings and JSON path fragment resolution isn't enough to fully support $ref. Schema references should be able to resolve relative URIs specified with id and $ref against the parent id or document URI.

Some simple questions need answering, like: Does this require that the entire schema be scanned before it may be used? How can two schemas have the same id? (As specified in the spec, under the "5.27. id" heading -- it probably intends to say that the URL base doesn't change.) Should it keep track of the stack, so that any ancestor schemas can be referred to by their URI (but not sibling schemas)?

backslash escaping in pattern matching

The spec says that the value of pattern must be a string: http://json-schema.org/latest/json-schema-validation.html#anchor33

So the output of validate seems a bit inconsistent:

console.log(validate('-', {type:'string', pattern: '-'}));

{ instance: '-',
  schema: { type: 'string', pattern: '-' },
  propertyPath: 'instance',
  errors: [],
  throwError: undefined }


console.log(validate('-', {type:'string', pattern: '\-'}));

{ instance: '-',
  schema: { type: 'string', pattern: '-' },
  propertyPath: 'instance',
  errors: [],
  throwError: undefined }


console.log(validate('-', {type:'string', pattern: '\\-'}));

{ instance: '-',
  schema: { type: 'string', pattern: '\\-' },
  propertyPath: 'instance',
  errors: [],
  throwError: undefined }

The last one is a correctly escaped javascript string for a backslash, but the regexp pattern output should probably just be a single backslah.
I understand wanting to avoid the ugliness that could occur for wanting to represent a \ requiring a \\ in a string pre-regexp conversion the way Java handles it, but maybe the output should be what the regex will look like.

Json schma fails to validate perfectly good URL

The following is an error report my service generates using the validation result provided by jsonschema but re-organized for better readability. The validation fails on a url that is well formed because the schema validator thinks the URL is not well formed.

{
  "type": "INPUT_VALIDATION_ERROR",
  "details": {
    "valid": false,
    "errors": [
      {
        "property": "instance.featuresProvided[0].onboardingLink",
        "message": "does not conform to the 'url' format",
        "schema": {
          "type": "string",
          "description": "The link for onboarding onto this feature.",
          "format": "url"
        },
        "instance": "http://getStartedWithAce.com/go",
        "stack": "instance.featuresProvided[0].onboardingLink does not conform to the 'url' format"
      }
    ],
    "objectValidated": {
      "name": "ACE",
      "type": "SERVICE",
      "featuresProvided": [
        {
          "name": "RIGHTS_MANAGEMETN",
          "description": "Manage permissions and secured entities",
          "onboardingLink": "http://getStartedWithAce.com/go",
          "subscriptionMetadataSchema": {
            "type": "string"
          }
        }
      ],
      "revision": 0
    },
    "schemaUsed": {
      "id": "Entity",
      "type": "object",
      "properties": {
        "_id": {
          "type": "string",
          "description": "Unique system identifier for the entity.  This will be assigned by the system and need not be provided by the client for new entities."
        },
        "revision": {
          "type": "integer",
          "description": "Assigned by the system to track revisions, and coordinate predictable updates.  This will be assigned (and maintained) by the system and need not be provided by the client for new entities."
        },
        "name": {
          "type": "string",
          "description": "A name that IS unique that may not be so friendly.",
          "required": true
        },
        "type": {
          "type": "string",
          "enum": [
            "GUEST",
            "CAST_MEMBER",
            "APPLICATION",
            "SERVICE",
            "DEVICE"
          ],
          "required": true
        },
        "featuresProvided": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "description": "Unique identifier with respect to the Provider Entity for the feature."
              },
              "description": {
                "type": "string",
                "description": "Describes what the feature is or does."
              },
              "onboardingLink": {
                "type": "string",
                "description": "The link for onboarding onto this feature.",
                "format": "url"
              },
              "subscriptionMetadataSchema": {
                "type": "any"
              }
            }
          }
        }
      },
      "example": {
        "_id": "54ed3472cd3a24dc57679a2e",
        "revision": 0,
        "type": "SERVICE",
        "name": "ACE",
        "contactEmail": "[email protected]",
        "description": "Fine grained dynamic, self service authorization provider.",
        "featuresProvided": [
          {
            "name": "rights-management",
            "description": "Register items to secure and assign permissions to manage those items to users, groups and based on other criteria.",
            "onboardingLink": "https://beta.dws.cloud.corp.dig.com/",
            "subscriptionMetadataSchema": null
          }
        ]
      }
    }
  }
}

validation with "not" in schema fails with TypeError

js = require('jsonschema')
js.validate('asdf', {not: {type: 'string'}})
TypeError: Cannot call method 'toString' of undefined
    at /root/nef-sculejs/node_modules/jsonschema/lib/attribute.js:590:71
    at Array.forEach (native)
    at Validator.validateNot (/root/nef-sculejs/node_modules/jsonschema/lib/attribute.js:588:9)
    at Validator.validateSchema (/root/nef-sculejs/node_modules/jsonschema/lib/validator.js:208:34)
    at Validator.validate (/root/nef-sculejs/node_modules/jsonschema/lib/validator.js:137:23)
    at Object.module.exports.validate (/root/nef-sculejs/node_modules/jsonschema/lib/index.js:11:12)
    at repl:1:5
    at REPLServer.self.eval (repl.js:110:21)
    at Interface.<anonymous> (repl.js:239:12)
    at Interface.EventEmitter.emit (events.js:95:17)

the problem is in validators.not() definition:

--- attribute.js.orig   Tue Feb 25 06:04:23 2014
+++ attribute.js        Tue Feb 25 06:13:44 2014
@@ -584,7 +584,8 @@
 validators.not = validators.disallow = function validateNot (instance, schema, options, ctx) {
   var self = this;
   var result = new ValidatorResult(instance, schema, options, ctx);
-  var types = (schema.disallow instanceof Array) ? schema.disallow : [schema.disallow];
+  var types = schema.disallow || schema.not;
+  types = (types instanceof Array) ? types : [types];
   types.forEach(function (type) {
     if (self.testType(instance, schema, options, ctx, type)) {
       var schemaId = type && type.id && ('<' + type.id + '>') || type.toString();

Method to coerce instance into validation

A useful feature for many applications would be a function that takes a possibly non-validating instance, and "coerces" it into validation. Strings would be parsed into integers, if the property is specified as an integer; values would be placed into arrays, if the property is specified as an array; missing properties would be given their default values; and so on.

There's many possible use cases for this:

In a software that stores instances of schemas, when a user creates a new instance of a schema, I would like them to be presented with a "minimally validating instance" for example purposes.

Similarly, when a user stores a schema, perhaps make trivial corrections instead of sending back a parse error.

When a URL encoded string from HTML forms, or the proposed enctype="application/json" value for HTML forms, is sent, it's received only as strings. JSON Schema could be used to convert the strings back to the native, correct type.

For me, this is also the case with reverse-parsing URI Templates. I can generate URIs of form http://example.com/uid/{uid} where id is an integer, but if I parse a URI like http://example.com/uid/4, the 4 must be converted to an integer before I can query the database. Coercing the object {"uid":"4"} to the schema {"properties":{"uid":{"type":"string"}}} would eliminate the need to do this explicitly.

This seems like an in-scope feature, as it would be most useful as a method on the existing prototype, but super programmer senses tell me this is better done as a separate project/module.

Feedback welcome.

Accepts missing required

Hi.
I have this schema

{
    "properties":{
        "a":{"type":"string"},
        "z":{"type":"string"}
    },
    "additionalProperties":false,
    "required":["a","z"]
 }

and this data

{"a":"hello"}

which should fail due to the required "z" is missing (and I've verified it failing here https://json-schema-validator.herokuapp.com/)

but this code gives me no error

var validate = require('jsonschema').validate;

var schema = {
    "properties":{
        "a":{"type":"string"},
        "z":{"type":"string"}
    },
    "additionalProperties":false,
    "required":["a","z"]
};
var instance = {"a":"hello"};
console.log(validate(instance, schema));

Any ideas on what is the problem?

When running jsonschema against the official JSON-schema test suite it causes side-effects. It alters the data.

When running jsonschema against the official JSON-schema test suite, running the tests:

  • multiple dependencies subschema, valid
  • multiple dependencies subschema, wrong type
  • multiple dependencies subschema, wrong type other
  • multiple dependencies subschema, wrong type both

has side-effects on the data. The data is altered by jsonschema.

https://github.com/Muscula/json-schema-benchmark/blob/master/reports/jsonschema-side-effects.md

Edit: I just added some more detail to the error report, to make it easier for you to see what's going on, and to reproduce the error.

How to deal with field called "refName"

Hey, I'm trying to validate a json object, that contains a field called "refName", the validator is treating it like a "$ref" field and throwing an exception because it can't find the schema.

How should I deal with this and still be able to validate the json correctly?

Usage examples are a bit confusing

Your example shows var v = new Validator(), but it is not clear where this is coming from.

Something like:

var Validator = require('jsonschema').Validator;

would already help.

Tag

Could you create a release of the current version, please?

Custom types

Hey guys,

Awesome library, it's great for enforcing schema structures for JS objects, not just JSON. This isn't an issue but I thought I would add it here in case someone like me comes looking for it.

For those looking to add custom types, it can be done like this:

  var Validator = require('jsonschema').Validator;
  var validator = new Validator();

  // custom function type
    // return true for valid and false for invalid
  validator.types.function = function testFunction(instance) {
    return instance instanceof Function;
  };

  // usage example
  validator.validate(function() {}, { type: 'function' });

Custom properties can also be added for all validator instances if required.

  // add to validator prototype
  Validator.prototype.types.wateva = function(instance) {
    return false; /* always fail */
  };

nested object issue

Hi,
I have a question, the error message I am getting in case of wrong property name or mismatch type value of property is not exactly pin pointing the property it just say something like that:


{
  "instance": {
    "is_and": false,
    "filters": [
      {
        "is_and": false,
        "filters": [
          {
            "is_and": true,
            "filters": [
              {
                "is_and": true,
                "filters": [
                  {
                    "is_and": true,
                    "filters": [
                      {
                        "is_and": true,
                        "filters": [
                          {
                            "text": 99,
                            "is_last": true,
                            "filters": []
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  },
  "schema": {
    "type": "object",
    "required": true,
    "additionalProperties": false,
    "properties": {
      "is_and": {
        "type": "boolean",
        "required": true
      },
      "filters": {
        "type": "array",
        "additionalItems": false,
        "items": {
          "oneOf": [
            {
              "$ref": "#"
            },
            {
              "$ref": "#/definitions/last"
            }
          ]
        }
      }
    },
    "definitions": {
      "last": {
        "type": "object",
        "required": true,
        "additionalProperties": false,
        "properties": {
          "text": {
            "type": "string"
          },
          "is_last": {
            "type": "boolean"
          },
          "filters": {
            "type": "array",
            "additionalItems": false
          }
        }
      }
    }
  },
  "propertyPath": "my_object",
  "errors": [
    {
      "property": "my_object.filters[0]",
      "message": "is not exactly one from [object Object],[object Object]",
      "schema": {
        "oneOf": [
          {
            "$ref": "#"
          },
          {
            "$ref": "#/definitions/last"
          }
        ]
      },
      "instance": {
        "is_and": false,
        "filters": [
          {
            "is_and": true,
            "filters": [
              {
                "is_and": true,
                "filters": [
                  {
                    "is_and": true,
                    "filters": [
                      {
                        "is_and": true,
                        "filters": [
                          {
                            "text": 99,
                            "is_last": true,
                            "filters": []
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      },
      "stack": "my_object.filters[0] is not exactly one from [object Object],[object Object]"
    },
    {
      "property": "my_object.filters[0]",
      "message": "is not exactly one from [object Object],[object Object]",
      "schema": {
        "oneOf": [
          {
            "$ref": "#"
          },
          {
            "$ref": "#/definitions/last"
          }
        ]
      },
      "instance": {
        "is_and": false,
        "filters": [
          {
            "is_and": true,
            "filters": [
              {
                "is_and": true,
                "filters": [
                  {
                    "is_and": true,
                    "filters": [
                      {
                        "is_and": true,
                        "filters": [
                          {
                            "text": 99,
                            "is_last": true,
                            "filters": []
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      },
      "stack": "my_object.filters[0] is not exactly one from [object Object],[object Object]"
    }
  ]
}

the text property in of last object is number instead of string,
normally the validation points to nested arrays with index and property name but not in this case???

ValidationError not instanceof Error

Hi!
Great package. I'm new to node.js and I am using this package all the time now.

So, if you do:

> js = require('jsonschema')
> new js.SchemaError() instanceof  Error
true
> new js.ValidationError() instanceof Error
false

Just wondering if this is by design or in the plans for changing or if I am missing something somewhere (Sorry if this is the case).

subSchemas

Hi,
I was testing how to describe a required JSON property which is a subSchema.
I was expecting something like

var subSchema = {
    "id": "/subSchema",
    "type": "object",
    "properties": {
        "prop1": { "type": "string", "required": true },
        "prop2": { "type": "string", "required": true }
    }
};

var schema = {
    "id": "/schema",
    "type": "object",
    "properties": {
        "prop1": { "$ref": "/subSchema", "required": true },
        "prop2": { "type": "string", "required": true }
    }
};

This way I can reuse the subScheme on another schema where the property is not required, although it seems that jsonschema expects the "required" options on subSchema itself.

var subSchema = {
    "id": "/subSchema",
    "type": "object",
   "required": true,
    "properties": {
        "prop1": { "type": "string", "required": true },
        "prop2": { "type": "string", "required": true }
    }
};

var schema = {
    "id": "/schema",
    "type": "object",
    "properties": {
        "prop1": { "$ref": "/subSchema"},
        "prop2": { "type": "string", "required": true }
    }
};

Can you clarify the required feature?
Thanks,
Paulo A. Silva

Support for extends?

Hi,
I'm currently comparing some JSON Schema validators and would like to know whether you support the extends attribute for schema "inheritance"
Thanks

How to validate against a definition within a schema?

I want to have a single schema file with many definitions.

I then want to validate messages against different definitions within that schema.

Is there a way of doing this with jsonschema?

(Apologies if this is not logically possible - I'm new to JSON Schema.)

delete me pls

Hello, thanks for your great module.

I'd like to submit some PR to improve it:

  1. regex validator (I think should be included by default in the module because with it everything is easier)
  2. strings support for minimum and maximum to make it works even for strings.

What do you think? If you agree I can prepare the PRs.

"required" field of an object definition won't be recognized

Using the following schema, validation will pass, even when firstName and lastName are not present:

{
    "title": "Example Schema",
    "type": "object",
    "properties": {
        "firstName": {
            "type": "string"
        },
        "lastName": {
            "type": "string"
        },
        "age": {
            "type": "number"
        }
    },
    "required": ["firstName", "lastName"]
}

Using required:true attributes within the definitions of firstName or lastName works though.

"instance is not all from [object Object]" isn't descriptive enough

I would think that it makes more sense to list off the errors against a schema referenced in allOf, instead of just opaquely saying "This object didn't validate against something in this huge list".

Instead of seeing:

0: instance is not all from [object Object]

Maybe show the details:

0: instance is not all from [object Object] (1 error)
1: instance.foo is not of type string

Add extends support

#5.26. extends

The value of this property MUST be another schema which will provide
a base schema which the current schema will inherit from. The
inheritance rules are such that any instance that is valid according
to the current schema MUST be valid according to the referenced
schema. This MAY also be an array, in which case, the instance MUST
be valid for all the schemas in the array. A schema that extends
another schema MAY define additional attributes, constrain existing
attributes, or add other constraints.

Conceptually, the behavior of extends can be seen as validating an
instance against all constraints in the extending schema as well as
the extended schema(s). More optimized implementations that merge
schemas are possible, but are not required. An example of using
"extends":

{
  "description":"An adult",
  "properties":{"age":{"minimum": 21}},
  "extends":"person"
}

Repository lacks tags

Releases should be tagged in the Git repository, this helps developers using package management tools, and helps software depending on this repository figure out which future releases are compatible (when employing semver semantics).

I tagged all the releases through 0.2.0 in my repository with the lightweight tags, pointing to the commit where package.json was touched. These may be pulled.

Re: Custom error messages

This library was the best I've ever used, but unfortunately I had to stop using it because it didn't support custom error messages. It would be nice if such a critical feature existed. I'm pretty sure it can help lots of people.

revalidator has this feature but it lacks some awesome draft 4 support that jsonschema has

Thanks!

Allow adding formats and auto replace formated string in target object type

Standard formats are interesting but it could be great to allow developers to add custom formats.
Moreover, as said in #68 task, when I validate a structure, I would like to auto replace properties with "date-time" format by a Date.
#68 issue suggests a solution in which developers declare explicitly on each property whether they want to cast an object to another, I think that all string with date-time format should be replaced by a Date object.

As I'm using Mongodb and I don't want to use Mongoose, I also think that _id fields should be cast to ObjectID object.

I managed to do that by :

  • adding a call to a new function at the end of attribute.js validateProperties function :
replaceFormatBySpecificObject(this, properties, property, instance);
  • declaring this new function replaceFormatBySpecificObject in attribute.js
var replaceFormatBySpecificObject = function(validator, properties, property, instance ) {
    if(validator.replacingValueIfStringIsFormat) {
        var ReplacingType = validator.replacingValueIfStringIsFormat[properties[property].format];
        if(ReplacingType) {
            instance[property] = new ReplacingType(instance[property]);
        }
    }
}
  • add a new function in validator.js in order to add a new format in helpers.FORMAT_REGEXPS
Validator.prototype.addFormat = function(formatName, formatRegexp) {
    helpers.FORMAT_REGEXPS[formatName] = formatRegexp;
}
  • Then in developer's code, we can have something like that :
var Validator = require('jsonschema').Validator;

Validator.prototype.types.objectid = function testObjectID (instance) {
        return instance instanceof ObjectID;
};


Validator.prototype.addFormat("objectid", /^[0-9a-fA-F]{24}$/);

var v = new Validator();
v.replacingValueIfStringIsFormat = {
        "date-time" : Date,
        "date" : Date,
        "objectid" : ObjectID
};
  • And when we want to validate structures
var shema1= {
        "id" : "/Schema1",
        "type" : "object",
        "properties" : {
            "madate" : {
                "type" : ["string", "date"],
                "format" : "date-time"
            }
        },
        "additionalProperties" : false
 };

var shema2= {
        "id" : "/Schema2",
        "type" : "object",
        "properties" : {
            "_id" : {
                "type" : ["string", "objectid"],
                "format" : "objectid"
            }
        },
        "additionalProperties" : false
 };


var struct = {"mydate" : new Date()};
var validation = v.validate(struct, schema1);
if (validation.errors && validation.errors.length !== 0) {
            throw new Error("The request sent to API is not correct", validation.errors);
}
struct = {"mydate" : new Date().toString()};
var validation = v.validate(struct, schema);
if (validation.errors && validation.errors.length !== 0) {
            throw new Error("The request sent to API is not correct", validation.errors);
}
struct = {"_id" : new ObjectID()};
var validation = v.validate(struct, schema);
if (validation.errors && validation.errors.length !== 0) {
            throw new Error("The request sent to API is not correct", validation.errors);
}
struct = {"_id" : new ObjectID().toString()};
var validation = v.validate(struct, schema);
if (validation.errors && validation.errors.length !== 0) {
            throw new Error("The request sent to API is not correct", validation.errors);
}

add support for anyOf, allOf, oneOf, not

Adding support for anyOf, allOf, oneOf, and not would implement much of the soon to be published v4 draft.

I'll get on this myself soon, since iirc the "extends" keyword (really "allOf") has funky behavior that needs to be fixed.

How to enforce additionalProperties to be false for nested schemas?

Hi,

first off thanks for this great library it is really saving a lot of time to me implementing a REST http interface for input validation.

I've searched through the source code and other issues but didn't find an answer to my question: is there a way to enforce the additionalProperties to be false for all nested schemas? By default it accepts additional properties and by setting that property to "false" fixes that. By the way I need a deny-first way so that implementing new schemas will reject additional properties (that in my case is a must-to since we're accepting the json object from external sources).

It would be nice if there's a way to enforce that on the validator itself or simply on the root element making it inherited by child schemas (I don't know what the spec says about that and so if it would be compliant).

Thanks,
-- Lex

addSchema should scan a schema for sub-schemas and incomplete references

The addSchema function, for adding schemas to the local environment, should recursively pre-parse a schema for sub-schemas with an "id" and add those to the environment, too.

Have some way of listing the referenced schemas that do not end up being defined, so that the application may dereference it and manually define it itself, if it so chooses. Perhaps set the definition of these schemas to null in the schema map.

Add a method to stringify all the validation errors together

A ValidatorResult instance contains an errors property with a list of validation failures. Returning a list of all the errors to a client can be awkward to piece together and is often repetitive, so add a errorsToString or similar method to provide a human-readable summary of validation errors, ideally suitable for returning in a 400 Client Error response.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.