| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 | 'use strict';var MissingRefError = require('./error_classes').MissingRef;module.exports = compileAsync;/** * Creates validating function for passed schema with asynchronous loading of missing schemas. * `loadSchema` option should be a function that accepts schema uri and returns promise that resolves with the schema. * @this  Ajv * @param {Object}   schema schema object * @param {Boolean}  meta optional true to compile meta-schema; this parameter can be skipped * @param {Function} callback an optional node-style callback, it is called with 2 parameters: error (or null) and validating function. * @return {Promise} promise that resolves with a validating function. */function compileAsync(schema, meta, callback) {  /* eslint no-shadow: 0 */  /* global Promise */  /* jshint validthis: true */  var self = this;  if (typeof this._opts.loadSchema != 'function')    throw new Error('options.loadSchema should be a function');  if (typeof meta == 'function') {    callback = meta;    meta = undefined;  }  var p = loadMetaSchemaOf(schema).then(function () {    var schemaObj = self._addSchema(schema, undefined, meta);    return schemaObj.validate || _compileAsync(schemaObj);  });  if (callback) {    p.then(      function(v) { callback(null, v); },      callback    );  }  return p;  function loadMetaSchemaOf(sch) {    var $schema = sch.$schema;    return $schema && !self.getSchema($schema)            ? compileAsync.call(self, { $ref: $schema }, true)            : Promise.resolve();  }  function _compileAsync(schemaObj) {    try { return self._compile(schemaObj); }    catch(e) {      if (e instanceof MissingRefError) return loadMissingSchema(e);      throw e;    }    function loadMissingSchema(e) {      var ref = e.missingSchema;      if (added(ref)) throw new Error('Schema ' + ref + ' is loaded but ' + e.missingRef + ' cannot be resolved');      var schemaPromise = self._loadingSchemas[ref];      if (!schemaPromise) {        schemaPromise = self._loadingSchemas[ref] = self._opts.loadSchema(ref);        schemaPromise.then(removePromise, removePromise);      }      return schemaPromise.then(function (sch) {        if (!added(ref)) {          return loadMetaSchemaOf(sch).then(function () {            if (!added(ref)) self.addSchema(sch, ref, undefined, meta);          });        }      }).then(function() {        return _compileAsync(schemaObj);      });      function removePromise() {        delete self._loadingSchemas[ref];      }      function added(ref) {        return self._refs[ref] || self._schemas[ref];      }    }  }}
 |