[d565449] | 1 | 'use strict';
|
---|
| 2 |
|
---|
| 3 | var compileSchema = require('./compile')
|
---|
| 4 | , resolve = require('./compile/resolve')
|
---|
| 5 | , Cache = require('./cache')
|
---|
| 6 | , SchemaObject = require('./compile/schema_obj')
|
---|
| 7 | , stableStringify = require('fast-json-stable-stringify')
|
---|
| 8 | , formats = require('./compile/formats')
|
---|
| 9 | , rules = require('./compile/rules')
|
---|
| 10 | , $dataMetaSchema = require('./data')
|
---|
| 11 | , util = require('./compile/util');
|
---|
| 12 |
|
---|
| 13 | module.exports = Ajv;
|
---|
| 14 |
|
---|
| 15 | Ajv.prototype.validate = validate;
|
---|
| 16 | Ajv.prototype.compile = compile;
|
---|
| 17 | Ajv.prototype.addSchema = addSchema;
|
---|
| 18 | Ajv.prototype.addMetaSchema = addMetaSchema;
|
---|
| 19 | Ajv.prototype.validateSchema = validateSchema;
|
---|
| 20 | Ajv.prototype.getSchema = getSchema;
|
---|
| 21 | Ajv.prototype.removeSchema = removeSchema;
|
---|
| 22 | Ajv.prototype.addFormat = addFormat;
|
---|
| 23 | Ajv.prototype.errorsText = errorsText;
|
---|
| 24 |
|
---|
| 25 | Ajv.prototype._addSchema = _addSchema;
|
---|
| 26 | Ajv.prototype._compile = _compile;
|
---|
| 27 |
|
---|
| 28 | Ajv.prototype.compileAsync = require('./compile/async');
|
---|
| 29 | var customKeyword = require('./keyword');
|
---|
| 30 | Ajv.prototype.addKeyword = customKeyword.add;
|
---|
| 31 | Ajv.prototype.getKeyword = customKeyword.get;
|
---|
| 32 | Ajv.prototype.removeKeyword = customKeyword.remove;
|
---|
| 33 | Ajv.prototype.validateKeyword = customKeyword.validate;
|
---|
| 34 |
|
---|
| 35 | var errorClasses = require('./compile/error_classes');
|
---|
| 36 | Ajv.ValidationError = errorClasses.Validation;
|
---|
| 37 | Ajv.MissingRefError = errorClasses.MissingRef;
|
---|
| 38 | Ajv.$dataMetaSchema = $dataMetaSchema;
|
---|
| 39 |
|
---|
| 40 | var META_SCHEMA_ID = 'http://json-schema.org/draft-07/schema';
|
---|
| 41 |
|
---|
| 42 | var META_IGNORE_OPTIONS = [ 'removeAdditional', 'useDefaults', 'coerceTypes', 'strictDefaults' ];
|
---|
| 43 | var META_SUPPORT_DATA = ['/properties'];
|
---|
| 44 |
|
---|
| 45 | /**
|
---|
| 46 | * Creates validator instance.
|
---|
| 47 | * Usage: `Ajv(opts)`
|
---|
| 48 | * @param {Object} opts optional options
|
---|
| 49 | * @return {Object} ajv instance
|
---|
| 50 | */
|
---|
| 51 | function Ajv(opts) {
|
---|
| 52 | if (!(this instanceof Ajv)) return new Ajv(opts);
|
---|
| 53 | opts = this._opts = util.copy(opts) || {};
|
---|
| 54 | setLogger(this);
|
---|
| 55 | this._schemas = {};
|
---|
| 56 | this._refs = {};
|
---|
| 57 | this._fragments = {};
|
---|
| 58 | this._formats = formats(opts.format);
|
---|
| 59 |
|
---|
| 60 | this._cache = opts.cache || new Cache;
|
---|
| 61 | this._loadingSchemas = {};
|
---|
| 62 | this._compilations = [];
|
---|
| 63 | this.RULES = rules();
|
---|
| 64 | this._getId = chooseGetId(opts);
|
---|
| 65 |
|
---|
| 66 | opts.loopRequired = opts.loopRequired || Infinity;
|
---|
| 67 | if (opts.errorDataPath == 'property') opts._errorDataPathProperty = true;
|
---|
| 68 | if (opts.serialize === undefined) opts.serialize = stableStringify;
|
---|
| 69 | this._metaOpts = getMetaSchemaOptions(this);
|
---|
| 70 |
|
---|
| 71 | if (opts.formats) addInitialFormats(this);
|
---|
| 72 | if (opts.keywords) addInitialKeywords(this);
|
---|
| 73 | addDefaultMetaSchema(this);
|
---|
| 74 | if (typeof opts.meta == 'object') this.addMetaSchema(opts.meta);
|
---|
| 75 | if (opts.nullable) this.addKeyword('nullable', {metaSchema: {type: 'boolean'}});
|
---|
| 76 | addInitialSchemas(this);
|
---|
| 77 | }
|
---|
| 78 |
|
---|
| 79 |
|
---|
| 80 |
|
---|
| 81 | /**
|
---|
| 82 | * Validate data using schema
|
---|
| 83 | * Schema will be compiled and cached (using serialized JSON as key. [fast-json-stable-stringify](https://github.com/epoberezkin/fast-json-stable-stringify) is used to serialize.
|
---|
| 84 | * @this Ajv
|
---|
| 85 | * @param {String|Object} schemaKeyRef key, ref or schema object
|
---|
| 86 | * @param {Any} data to be validated
|
---|
| 87 | * @return {Boolean} validation result. Errors from the last validation will be available in `ajv.errors` (and also in compiled schema: `schema.errors`).
|
---|
| 88 | */
|
---|
| 89 | function validate(schemaKeyRef, data) {
|
---|
| 90 | var v;
|
---|
| 91 | if (typeof schemaKeyRef == 'string') {
|
---|
| 92 | v = this.getSchema(schemaKeyRef);
|
---|
| 93 | if (!v) throw new Error('no schema with key or ref "' + schemaKeyRef + '"');
|
---|
| 94 | } else {
|
---|
| 95 | var schemaObj = this._addSchema(schemaKeyRef);
|
---|
| 96 | v = schemaObj.validate || this._compile(schemaObj);
|
---|
| 97 | }
|
---|
| 98 |
|
---|
| 99 | var valid = v(data);
|
---|
| 100 | if (v.$async !== true) this.errors = v.errors;
|
---|
| 101 | return valid;
|
---|
| 102 | }
|
---|
| 103 |
|
---|
| 104 |
|
---|
| 105 | /**
|
---|
| 106 | * Create validating function for passed schema.
|
---|
| 107 | * @this Ajv
|
---|
| 108 | * @param {Object} schema schema object
|
---|
| 109 | * @param {Boolean} _meta true if schema is a meta-schema. Used internally to compile meta schemas of custom keywords.
|
---|
| 110 | * @return {Function} validating function
|
---|
| 111 | */
|
---|
| 112 | function compile(schema, _meta) {
|
---|
| 113 | var schemaObj = this._addSchema(schema, undefined, _meta);
|
---|
| 114 | return schemaObj.validate || this._compile(schemaObj);
|
---|
| 115 | }
|
---|
| 116 |
|
---|
| 117 |
|
---|
| 118 | /**
|
---|
| 119 | * Adds schema to the instance.
|
---|
| 120 | * @this Ajv
|
---|
| 121 | * @param {Object|Array} schema schema or array of schemas. If array is passed, `key` and other parameters will be ignored.
|
---|
| 122 | * @param {String} key Optional schema key. Can be passed to `validate` method instead of schema object or id/ref. One schema per instance can have empty `id` and `key`.
|
---|
| 123 | * @param {Boolean} _skipValidation true to skip schema validation. Used internally, option validateSchema should be used instead.
|
---|
| 124 | * @param {Boolean} _meta true if schema is a meta-schema. Used internally, addMetaSchema should be used instead.
|
---|
| 125 | * @return {Ajv} this for method chaining
|
---|
| 126 | */
|
---|
| 127 | function addSchema(schema, key, _skipValidation, _meta) {
|
---|
| 128 | if (Array.isArray(schema)){
|
---|
| 129 | for (var i=0; i<schema.length; i++) this.addSchema(schema[i], undefined, _skipValidation, _meta);
|
---|
| 130 | return this;
|
---|
| 131 | }
|
---|
| 132 | var id = this._getId(schema);
|
---|
| 133 | if (id !== undefined && typeof id != 'string')
|
---|
| 134 | throw new Error('schema id must be string');
|
---|
| 135 | key = resolve.normalizeId(key || id);
|
---|
| 136 | checkUnique(this, key);
|
---|
| 137 | this._schemas[key] = this._addSchema(schema, _skipValidation, _meta, true);
|
---|
| 138 | return this;
|
---|
| 139 | }
|
---|
| 140 |
|
---|
| 141 |
|
---|
| 142 | /**
|
---|
| 143 | * Add schema that will be used to validate other schemas
|
---|
| 144 | * options in META_IGNORE_OPTIONS are alway set to false
|
---|
| 145 | * @this Ajv
|
---|
| 146 | * @param {Object} schema schema object
|
---|
| 147 | * @param {String} key optional schema key
|
---|
| 148 | * @param {Boolean} skipValidation true to skip schema validation, can be used to override validateSchema option for meta-schema
|
---|
| 149 | * @return {Ajv} this for method chaining
|
---|
| 150 | */
|
---|
| 151 | function addMetaSchema(schema, key, skipValidation) {
|
---|
| 152 | this.addSchema(schema, key, skipValidation, true);
|
---|
| 153 | return this;
|
---|
| 154 | }
|
---|
| 155 |
|
---|
| 156 |
|
---|
| 157 | /**
|
---|
| 158 | * Validate schema
|
---|
| 159 | * @this Ajv
|
---|
| 160 | * @param {Object} schema schema to validate
|
---|
| 161 | * @param {Boolean} throwOrLogError pass true to throw (or log) an error if invalid
|
---|
| 162 | * @return {Boolean} true if schema is valid
|
---|
| 163 | */
|
---|
| 164 | function validateSchema(schema, throwOrLogError) {
|
---|
| 165 | var $schema = schema.$schema;
|
---|
| 166 | if ($schema !== undefined && typeof $schema != 'string')
|
---|
| 167 | throw new Error('$schema must be a string');
|
---|
| 168 | $schema = $schema || this._opts.defaultMeta || defaultMeta(this);
|
---|
| 169 | if (!$schema) {
|
---|
| 170 | this.logger.warn('meta-schema not available');
|
---|
| 171 | this.errors = null;
|
---|
| 172 | return true;
|
---|
| 173 | }
|
---|
| 174 | var valid = this.validate($schema, schema);
|
---|
| 175 | if (!valid && throwOrLogError) {
|
---|
| 176 | var message = 'schema is invalid: ' + this.errorsText();
|
---|
| 177 | if (this._opts.validateSchema == 'log') this.logger.error(message);
|
---|
| 178 | else throw new Error(message);
|
---|
| 179 | }
|
---|
| 180 | return valid;
|
---|
| 181 | }
|
---|
| 182 |
|
---|
| 183 |
|
---|
| 184 | function defaultMeta(self) {
|
---|
| 185 | var meta = self._opts.meta;
|
---|
| 186 | self._opts.defaultMeta = typeof meta == 'object'
|
---|
| 187 | ? self._getId(meta) || meta
|
---|
| 188 | : self.getSchema(META_SCHEMA_ID)
|
---|
| 189 | ? META_SCHEMA_ID
|
---|
| 190 | : undefined;
|
---|
| 191 | return self._opts.defaultMeta;
|
---|
| 192 | }
|
---|
| 193 |
|
---|
| 194 |
|
---|
| 195 | /**
|
---|
| 196 | * Get compiled schema from the instance by `key` or `ref`.
|
---|
| 197 | * @this Ajv
|
---|
| 198 | * @param {String} keyRef `key` that was passed to `addSchema` or full schema reference (`schema.id` or resolved id).
|
---|
| 199 | * @return {Function} schema validating function (with property `schema`).
|
---|
| 200 | */
|
---|
| 201 | function getSchema(keyRef) {
|
---|
| 202 | var schemaObj = _getSchemaObj(this, keyRef);
|
---|
| 203 | switch (typeof schemaObj) {
|
---|
| 204 | case 'object': return schemaObj.validate || this._compile(schemaObj);
|
---|
| 205 | case 'string': return this.getSchema(schemaObj);
|
---|
| 206 | case 'undefined': return _getSchemaFragment(this, keyRef);
|
---|
| 207 | }
|
---|
| 208 | }
|
---|
| 209 |
|
---|
| 210 |
|
---|
| 211 | function _getSchemaFragment(self, ref) {
|
---|
| 212 | var res = resolve.schema.call(self, { schema: {} }, ref);
|
---|
| 213 | if (res) {
|
---|
| 214 | var schema = res.schema
|
---|
| 215 | , root = res.root
|
---|
| 216 | , baseId = res.baseId;
|
---|
| 217 | var v = compileSchema.call(self, schema, root, undefined, baseId);
|
---|
| 218 | self._fragments[ref] = new SchemaObject({
|
---|
| 219 | ref: ref,
|
---|
| 220 | fragment: true,
|
---|
| 221 | schema: schema,
|
---|
| 222 | root: root,
|
---|
| 223 | baseId: baseId,
|
---|
| 224 | validate: v
|
---|
| 225 | });
|
---|
| 226 | return v;
|
---|
| 227 | }
|
---|
| 228 | }
|
---|
| 229 |
|
---|
| 230 |
|
---|
| 231 | function _getSchemaObj(self, keyRef) {
|
---|
| 232 | keyRef = resolve.normalizeId(keyRef);
|
---|
| 233 | return self._schemas[keyRef] || self._refs[keyRef] || self._fragments[keyRef];
|
---|
| 234 | }
|
---|
| 235 |
|
---|
| 236 |
|
---|
| 237 | /**
|
---|
| 238 | * Remove cached schema(s).
|
---|
| 239 | * If no parameter is passed all schemas but meta-schemas are removed.
|
---|
| 240 | * If RegExp is passed all schemas with key/id matching pattern but meta-schemas are removed.
|
---|
| 241 | * Even if schema is referenced by other schemas it still can be removed as other schemas have local references.
|
---|
| 242 | * @this Ajv
|
---|
| 243 | * @param {String|Object|RegExp} schemaKeyRef key, ref, pattern to match key/ref or schema object
|
---|
| 244 | * @return {Ajv} this for method chaining
|
---|
| 245 | */
|
---|
| 246 | function removeSchema(schemaKeyRef) {
|
---|
| 247 | if (schemaKeyRef instanceof RegExp) {
|
---|
| 248 | _removeAllSchemas(this, this._schemas, schemaKeyRef);
|
---|
| 249 | _removeAllSchemas(this, this._refs, schemaKeyRef);
|
---|
| 250 | return this;
|
---|
| 251 | }
|
---|
| 252 | switch (typeof schemaKeyRef) {
|
---|
| 253 | case 'undefined':
|
---|
| 254 | _removeAllSchemas(this, this._schemas);
|
---|
| 255 | _removeAllSchemas(this, this._refs);
|
---|
| 256 | this._cache.clear();
|
---|
| 257 | return this;
|
---|
| 258 | case 'string':
|
---|
| 259 | var schemaObj = _getSchemaObj(this, schemaKeyRef);
|
---|
| 260 | if (schemaObj) this._cache.del(schemaObj.cacheKey);
|
---|
| 261 | delete this._schemas[schemaKeyRef];
|
---|
| 262 | delete this._refs[schemaKeyRef];
|
---|
| 263 | return this;
|
---|
| 264 | case 'object':
|
---|
| 265 | var serialize = this._opts.serialize;
|
---|
| 266 | var cacheKey = serialize ? serialize(schemaKeyRef) : schemaKeyRef;
|
---|
| 267 | this._cache.del(cacheKey);
|
---|
| 268 | var id = this._getId(schemaKeyRef);
|
---|
| 269 | if (id) {
|
---|
| 270 | id = resolve.normalizeId(id);
|
---|
| 271 | delete this._schemas[id];
|
---|
| 272 | delete this._refs[id];
|
---|
| 273 | }
|
---|
| 274 | }
|
---|
| 275 | return this;
|
---|
| 276 | }
|
---|
| 277 |
|
---|
| 278 |
|
---|
| 279 | function _removeAllSchemas(self, schemas, regex) {
|
---|
| 280 | for (var keyRef in schemas) {
|
---|
| 281 | var schemaObj = schemas[keyRef];
|
---|
| 282 | if (!schemaObj.meta && (!regex || regex.test(keyRef))) {
|
---|
| 283 | self._cache.del(schemaObj.cacheKey);
|
---|
| 284 | delete schemas[keyRef];
|
---|
| 285 | }
|
---|
| 286 | }
|
---|
| 287 | }
|
---|
| 288 |
|
---|
| 289 |
|
---|
| 290 | /* @this Ajv */
|
---|
| 291 | function _addSchema(schema, skipValidation, meta, shouldAddSchema) {
|
---|
| 292 | if (typeof schema != 'object' && typeof schema != 'boolean')
|
---|
| 293 | throw new Error('schema should be object or boolean');
|
---|
| 294 | var serialize = this._opts.serialize;
|
---|
| 295 | var cacheKey = serialize ? serialize(schema) : schema;
|
---|
| 296 | var cached = this._cache.get(cacheKey);
|
---|
| 297 | if (cached) return cached;
|
---|
| 298 |
|
---|
| 299 | shouldAddSchema = shouldAddSchema || this._opts.addUsedSchema !== false;
|
---|
| 300 |
|
---|
| 301 | var id = resolve.normalizeId(this._getId(schema));
|
---|
| 302 | if (id && shouldAddSchema) checkUnique(this, id);
|
---|
| 303 |
|
---|
| 304 | var willValidate = this._opts.validateSchema !== false && !skipValidation;
|
---|
| 305 | var recursiveMeta;
|
---|
| 306 | if (willValidate && !(recursiveMeta = id && id == resolve.normalizeId(schema.$schema)))
|
---|
| 307 | this.validateSchema(schema, true);
|
---|
| 308 |
|
---|
| 309 | var localRefs = resolve.ids.call(this, schema);
|
---|
| 310 |
|
---|
| 311 | var schemaObj = new SchemaObject({
|
---|
| 312 | id: id,
|
---|
| 313 | schema: schema,
|
---|
| 314 | localRefs: localRefs,
|
---|
| 315 | cacheKey: cacheKey,
|
---|
| 316 | meta: meta
|
---|
| 317 | });
|
---|
| 318 |
|
---|
| 319 | if (id[0] != '#' && shouldAddSchema) this._refs[id] = schemaObj;
|
---|
| 320 | this._cache.put(cacheKey, schemaObj);
|
---|
| 321 |
|
---|
| 322 | if (willValidate && recursiveMeta) this.validateSchema(schema, true);
|
---|
| 323 |
|
---|
| 324 | return schemaObj;
|
---|
| 325 | }
|
---|
| 326 |
|
---|
| 327 |
|
---|
| 328 | /* @this Ajv */
|
---|
| 329 | function _compile(schemaObj, root) {
|
---|
| 330 | if (schemaObj.compiling) {
|
---|
| 331 | schemaObj.validate = callValidate;
|
---|
| 332 | callValidate.schema = schemaObj.schema;
|
---|
| 333 | callValidate.errors = null;
|
---|
| 334 | callValidate.root = root ? root : callValidate;
|
---|
| 335 | if (schemaObj.schema.$async === true)
|
---|
| 336 | callValidate.$async = true;
|
---|
| 337 | return callValidate;
|
---|
| 338 | }
|
---|
| 339 | schemaObj.compiling = true;
|
---|
| 340 |
|
---|
| 341 | var currentOpts;
|
---|
| 342 | if (schemaObj.meta) {
|
---|
| 343 | currentOpts = this._opts;
|
---|
| 344 | this._opts = this._metaOpts;
|
---|
| 345 | }
|
---|
| 346 |
|
---|
| 347 | var v;
|
---|
| 348 | try { v = compileSchema.call(this, schemaObj.schema, root, schemaObj.localRefs); }
|
---|
| 349 | catch(e) {
|
---|
| 350 | delete schemaObj.validate;
|
---|
| 351 | throw e;
|
---|
| 352 | }
|
---|
| 353 | finally {
|
---|
| 354 | schemaObj.compiling = false;
|
---|
| 355 | if (schemaObj.meta) this._opts = currentOpts;
|
---|
| 356 | }
|
---|
| 357 |
|
---|
| 358 | schemaObj.validate = v;
|
---|
| 359 | schemaObj.refs = v.refs;
|
---|
| 360 | schemaObj.refVal = v.refVal;
|
---|
| 361 | schemaObj.root = v.root;
|
---|
| 362 | return v;
|
---|
| 363 |
|
---|
| 364 |
|
---|
| 365 | /* @this {*} - custom context, see passContext option */
|
---|
| 366 | function callValidate() {
|
---|
| 367 | /* jshint validthis: true */
|
---|
| 368 | var _validate = schemaObj.validate;
|
---|
| 369 | var result = _validate.apply(this, arguments);
|
---|
| 370 | callValidate.errors = _validate.errors;
|
---|
| 371 | return result;
|
---|
| 372 | }
|
---|
| 373 | }
|
---|
| 374 |
|
---|
| 375 |
|
---|
| 376 | function chooseGetId(opts) {
|
---|
| 377 | switch (opts.schemaId) {
|
---|
| 378 | case 'auto': return _get$IdOrId;
|
---|
| 379 | case 'id': return _getId;
|
---|
| 380 | default: return _get$Id;
|
---|
| 381 | }
|
---|
| 382 | }
|
---|
| 383 |
|
---|
| 384 | /* @this Ajv */
|
---|
| 385 | function _getId(schema) {
|
---|
| 386 | if (schema.$id) this.logger.warn('schema $id ignored', schema.$id);
|
---|
| 387 | return schema.id;
|
---|
| 388 | }
|
---|
| 389 |
|
---|
| 390 | /* @this Ajv */
|
---|
| 391 | function _get$Id(schema) {
|
---|
| 392 | if (schema.id) this.logger.warn('schema id ignored', schema.id);
|
---|
| 393 | return schema.$id;
|
---|
| 394 | }
|
---|
| 395 |
|
---|
| 396 |
|
---|
| 397 | function _get$IdOrId(schema) {
|
---|
| 398 | if (schema.$id && schema.id && schema.$id != schema.id)
|
---|
| 399 | throw new Error('schema $id is different from id');
|
---|
| 400 | return schema.$id || schema.id;
|
---|
| 401 | }
|
---|
| 402 |
|
---|
| 403 |
|
---|
| 404 | /**
|
---|
| 405 | * Convert array of error message objects to string
|
---|
| 406 | * @this Ajv
|
---|
| 407 | * @param {Array<Object>} errors optional array of validation errors, if not passed errors from the instance are used.
|
---|
| 408 | * @param {Object} options optional options with properties `separator` and `dataVar`.
|
---|
| 409 | * @return {String} human readable string with all errors descriptions
|
---|
| 410 | */
|
---|
| 411 | function errorsText(errors, options) {
|
---|
| 412 | errors = errors || this.errors;
|
---|
| 413 | if (!errors) return 'No errors';
|
---|
| 414 | options = options || {};
|
---|
| 415 | var separator = options.separator === undefined ? ', ' : options.separator;
|
---|
| 416 | var dataVar = options.dataVar === undefined ? 'data' : options.dataVar;
|
---|
| 417 |
|
---|
| 418 | var text = '';
|
---|
| 419 | for (var i=0; i<errors.length; i++) {
|
---|
| 420 | var e = errors[i];
|
---|
| 421 | if (e) text += dataVar + e.dataPath + ' ' + e.message + separator;
|
---|
| 422 | }
|
---|
| 423 | return text.slice(0, -separator.length);
|
---|
| 424 | }
|
---|
| 425 |
|
---|
| 426 |
|
---|
| 427 | /**
|
---|
| 428 | * Add custom format
|
---|
| 429 | * @this Ajv
|
---|
| 430 | * @param {String} name format name
|
---|
| 431 | * @param {String|RegExp|Function} format string is converted to RegExp; function should return boolean (true when valid)
|
---|
| 432 | * @return {Ajv} this for method chaining
|
---|
| 433 | */
|
---|
| 434 | function addFormat(name, format) {
|
---|
| 435 | if (typeof format == 'string') format = new RegExp(format);
|
---|
| 436 | this._formats[name] = format;
|
---|
| 437 | return this;
|
---|
| 438 | }
|
---|
| 439 |
|
---|
| 440 |
|
---|
| 441 | function addDefaultMetaSchema(self) {
|
---|
| 442 | var $dataSchema;
|
---|
| 443 | if (self._opts.$data) {
|
---|
| 444 | $dataSchema = require('./refs/data.json');
|
---|
| 445 | self.addMetaSchema($dataSchema, $dataSchema.$id, true);
|
---|
| 446 | }
|
---|
| 447 | if (self._opts.meta === false) return;
|
---|
| 448 | var metaSchema = require('./refs/json-schema-draft-07.json');
|
---|
| 449 | if (self._opts.$data) metaSchema = $dataMetaSchema(metaSchema, META_SUPPORT_DATA);
|
---|
| 450 | self.addMetaSchema(metaSchema, META_SCHEMA_ID, true);
|
---|
| 451 | self._refs['http://json-schema.org/schema'] = META_SCHEMA_ID;
|
---|
| 452 | }
|
---|
| 453 |
|
---|
| 454 |
|
---|
| 455 | function addInitialSchemas(self) {
|
---|
| 456 | var optsSchemas = self._opts.schemas;
|
---|
| 457 | if (!optsSchemas) return;
|
---|
| 458 | if (Array.isArray(optsSchemas)) self.addSchema(optsSchemas);
|
---|
| 459 | else for (var key in optsSchemas) self.addSchema(optsSchemas[key], key);
|
---|
| 460 | }
|
---|
| 461 |
|
---|
| 462 |
|
---|
| 463 | function addInitialFormats(self) {
|
---|
| 464 | for (var name in self._opts.formats) {
|
---|
| 465 | var format = self._opts.formats[name];
|
---|
| 466 | self.addFormat(name, format);
|
---|
| 467 | }
|
---|
| 468 | }
|
---|
| 469 |
|
---|
| 470 |
|
---|
| 471 | function addInitialKeywords(self) {
|
---|
| 472 | for (var name in self._opts.keywords) {
|
---|
| 473 | var keyword = self._opts.keywords[name];
|
---|
| 474 | self.addKeyword(name, keyword);
|
---|
| 475 | }
|
---|
| 476 | }
|
---|
| 477 |
|
---|
| 478 |
|
---|
| 479 | function checkUnique(self, id) {
|
---|
| 480 | if (self._schemas[id] || self._refs[id])
|
---|
| 481 | throw new Error('schema with key or id "' + id + '" already exists');
|
---|
| 482 | }
|
---|
| 483 |
|
---|
| 484 |
|
---|
| 485 | function getMetaSchemaOptions(self) {
|
---|
| 486 | var metaOpts = util.copy(self._opts);
|
---|
| 487 | for (var i=0; i<META_IGNORE_OPTIONS.length; i++)
|
---|
| 488 | delete metaOpts[META_IGNORE_OPTIONS[i]];
|
---|
| 489 | return metaOpts;
|
---|
| 490 | }
|
---|
| 491 |
|
---|
| 492 |
|
---|
| 493 | function setLogger(self) {
|
---|
| 494 | var logger = self._opts.logger;
|
---|
| 495 | if (logger === false) {
|
---|
| 496 | self.logger = {log: noop, warn: noop, error: noop};
|
---|
| 497 | } else {
|
---|
| 498 | if (logger === undefined) logger = console;
|
---|
| 499 | if (!(typeof logger == 'object' && logger.log && logger.warn && logger.error))
|
---|
| 500 | throw new Error('logger must implement log, warn and error methods');
|
---|
| 501 | self.logger = logger;
|
---|
| 502 | }
|
---|
| 503 | }
|
---|
| 504 |
|
---|
| 505 |
|
---|
| 506 | function noop() {}
|
---|