Blame view

node_modules/ajv/lib/compile/async.js 2.58 KB
aaac7fed   liuqimichale   add
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  '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];
        }
      }
    }
  }