| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 | 'use strict';module.exports = {  setup: setupAsync,  compile: compileAsync};var util = require('./compile/util');var ASYNC = {  '*': checkGenerators,  'co*': checkGenerators,  'es7': checkAsyncFunction};var TRANSPILE = {  'nodent': getNodent,  'regenerator': getRegenerator};var MODES = [  { async: 'co*' },  { async: 'es7', transpile: 'nodent' },  { async: 'co*', transpile: 'regenerator' }];var regenerator, nodent;function setupAsync(opts, required) {  if (required !== false) required = true;  var async = opts.async    , transpile = opts.transpile    , check;  switch (typeof transpile) {    case 'string':      var get = TRANSPILE[transpile];      if (!get) throw new Error('bad transpiler: ' + transpile);      return (opts._transpileFunc = get(opts, required));    case 'undefined':    case 'boolean':      if (typeof async == 'string') {        check = ASYNC[async];        if (!check) throw new Error('bad async mode: ' + async);        return (opts.transpile = check(opts, required));      }      for (var i=0; i<MODES.length; i++) {        var _opts = MODES[i];        if (setupAsync(_opts, false)) {          util.copy(_opts, opts);          return opts.transpile;        }      }      /* istanbul ignore next */      throw new Error('generators, nodent and regenerator are not available');    case 'function':      return (opts._transpileFunc = opts.transpile);    default:      throw new Error('bad transpiler: ' + transpile);  }}function checkGenerators(opts, required) {  /* jshint evil: true */  try {    (new Function('(function*(){})()'))();    return true;  } catch(e) {    /* istanbul ignore next */    if (required) throw new Error('generators not supported');  }}function checkAsyncFunction(opts, required) {  /* jshint evil: true */  try {    (new Function('(async function(){})()'))();    /* istanbul ignore next */    return true;  } catch(e) {    if (required) throw new Error('es7 async functions not supported');  }}function getRegenerator(opts, required) {  try {    if (!regenerator) {      var name = 'regenerator';      regenerator = require(name);      regenerator.runtime();    }    if (!opts.async || opts.async === true)      opts.async = 'es7';    return regeneratorTranspile;  } catch(e) {    /* istanbul ignore next */    if (required) throw new Error('regenerator not available');  }}function regeneratorTranspile(code) {  return regenerator.compile(code).code;}function getNodent(opts, required) {  /* jshint evil: true */  try {    if (!nodent) {      var name = 'nodent';      nodent = require(name)({ log: false, dontInstallRequireHook: true });    }    if (opts.async != 'es7') {      if (opts.async && opts.async !== true) console.warn('nodent transpiles only es7 async functions');      opts.async = 'es7';    }    return nodentTranspile;  } catch(e) {    /* istanbul ignore next */    if (required) throw new Error('nodent not available');  }}function nodentTranspile(code) {  return nodent.compile(code, '', { promises: true, sourcemap: false }).code;}/** * Creates validating function for passed schema with asynchronous loading of missing schemas. * `loadSchema` option should be a function that accepts schema uri and node-style callback. * @this  Ajv * @param {Object}   schema schema object * @param {Function} callback node-style callback, it is always called with 2 parameters: error (or null) and validating function. */function compileAsync(schema, callback) {  /* eslint no-shadow: 0 */  /* jshint validthis: true */  var schemaObj;  var self = this;  try {    schemaObj = this._addSchema(schema);  } catch(e) {    setTimeout(function() { callback(e); });    return;  }  if (schemaObj.validate) {    setTimeout(function() { callback(null, schemaObj.validate); });  } else {    if (typeof this._opts.loadSchema != 'function')      throw new Error('options.loadSchema should be a function');    _compileAsync(schema, callback, true);  }  function _compileAsync(schema, callback, firstCall) {    var validate;    try { validate = self.compile(schema); }    catch(e) {      if (e.missingSchema) loadMissingSchema(e);      else deferCallback(e);      return;    }    deferCallback(null, validate);    function loadMissingSchema(e) {      var ref = e.missingSchema;      if (self._refs[ref] || self._schemas[ref])        return callback(new Error('Schema ' + ref + ' is loaded but ' + e.missingRef + ' cannot be resolved'));      var _callbacks = self._loadingSchemas[ref];      if (_callbacks) {        if (typeof _callbacks == 'function')          self._loadingSchemas[ref] = [_callbacks, schemaLoaded];        else          _callbacks[_callbacks.length] = schemaLoaded;      } else {        self._loadingSchemas[ref] = schemaLoaded;        self._opts.loadSchema(ref, function (err, sch) {          var _callbacks = self._loadingSchemas[ref];          delete self._loadingSchemas[ref];          if (typeof _callbacks == 'function') {            _callbacks(err, sch);          } else {            for (var i=0; i<_callbacks.length; i++)              _callbacks[i](err, sch);          }        });      }      function schemaLoaded(err, sch) {        if (err) return callback(err);        if (!(self._refs[ref] || self._schemas[ref])) {          try {            self.addSchema(sch, ref);          } catch(e) {            callback(e);            return;          }        }        _compileAsync(schema, callback);      }    }    function deferCallback(err, validate) {      if (firstCall) setTimeout(function() { callback(err, validate); });      else return callback(err, validate);    }  }}
 |