Skip to content
Snippets Groups Projects
json-schema-faker.js 519 KiB
Newer Older
  • Learn to ignore specific revisions
  • Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * json-schema-faker library v0.5.0-rc10
    
     * http://json-schema-faker.js.org
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Copyright (c) 2014-2017 Alvaro Cabrera & Tomasz Ducin
    
     * Released under the MIT license
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Date: 2017-07-08 01:12:12.776Z
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    (function (global, factory) {
    	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    	typeof define === 'function' && define.amd ? define(factory) :
    	(global.JSONSchemaFaker = factory());
    }(this, (function () { 'use strict';
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    
    var jsonSchemaRefParser = createCommonjsModule(function(module, exports) {(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.$RefParser = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof _dereq_=="function"&&_dereq_;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof _dereq_=="function"&&_dereq_;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
    /** !
     * JSON Schema $Ref Parser v3.1.2
     *
     * @link https://github.com/BigstickCarpet/json-schema-ref-parser
     * @license MIT
     */
    'use strict';
    
    var $Ref    = _dereq_('./ref'),
        Pointer = _dereq_('./pointer'),
        debug   = _dereq_('./util/debug'),
        url     = _dereq_('./util/url');
    
    module.exports = bundle;
    
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Bundles all external JSON references into the main JSON schema, thus resulting in a schema that
     * only has *internal* references, not any *external* references.
     * This method mutates the JSON schema object, adding new references and re-mapping existing ones.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {$RefParser} parser
     * @param {$RefParserOptions} options
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function bundle(parser, options) {
      debug('Bundling $ref pointers in %s', parser.$refs._root$Ref.path);
    
      // Build an inventory of all $ref pointers in the JSON Schema
      var inventory = [];
      crawl(parser, 'schema', parser.$refs._root$Ref.path + '#', '#', inventory, parser.$refs, options);
    
      // Remap all $ref pointers
      remap(inventory);
    }
    
    /**
     * Recursively crawls the given value, and inventories all JSON references.
     *
     * @param {object} parent - The object containing the value to crawl. If the value is not an object or array, it will be ignored.
     * @param {string} key - The property key of `parent` to be crawled
     * @param {string} path - The full path of the property being crawled, possibly with a JSON Pointer in the hash
     * @param {string} pathFromRoot - The path of the property being crawled, from the schema root
     * @param {object[]} inventory - An array of already-inventoried $ref pointers
     * @param {$Refs} $refs
     * @param {$RefParserOptions} options
     */
    function crawl(parent, key, path, pathFromRoot, inventory, $refs, options) {
      var obj = key === null ? parent : parent[key];
    
      if (obj && typeof obj === 'object') {
        if ($Ref.is$Ref(obj)) {
          inventory$Ref(parent, key, path, pathFromRoot, inventory, $refs, options);
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
        else {
          var keys = Object.keys(obj);
    
          // Most people will expect references to be bundled into the the "definitions" property,
          // so we always crawl that property first, if it exists.
          var defs = keys.indexOf('definitions');
          if (defs > 0) {
            keys.splice(0, 0, keys.splice(defs, 1)[0]);
          }
    
          keys.forEach(function(key) {
            var keyPath = Pointer.join(path, key);
            var keyPathFromRoot = Pointer.join(pathFromRoot, key);
            var value = obj[key];
    
            if ($Ref.is$Ref(value)) {
              inventory$Ref(obj, key, path, keyPathFromRoot, inventory, $refs, options);
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
            }
            else {
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
              crawl(obj, key, keyPath, keyPathFromRoot, inventory, $refs, options);
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
            }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
          });
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Inventories the given JSON Reference (i.e. records detailed information about it so we can
     * optimize all $refs in the schema), and then crawls the resolved value.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {object} $refParent - The object that contains a JSON Reference as one of its keys
     * @param {string} $refKey - The key in `$refParent` that is a JSON Reference
     * @param {string} path - The full path of the JSON Reference at `$refKey`, possibly with a JSON Pointer in the hash
     * @param {string} pathFromRoot - The path of the JSON Reference at `$refKey`, from the schema root
     * @param {object[]} inventory - An array of already-inventoried $ref pointers
     * @param {$Refs} $refs
     * @param {$RefParserOptions} options
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function inventory$Ref($refParent, $refKey, path, pathFromRoot, inventory, $refs, options) {
      if (inventory.some(function(i) { return i.parent === $refParent && i.key === $refKey; })) {
        // This $Ref has already been inventoried, so we don't need to process it again
        return;
      }
    
      var $ref = $refKey === null ? $refParent : $refParent[$refKey];
      var $refPath = url.resolve(path, $ref.$ref);
      var pointer = $refs._resolve($refPath, options);
      var depth = Pointer.parse(pathFromRoot).length;
      var file = url.stripHash(pointer.path);
      var hash = url.getHash(pointer.path);
      var external = file !== $refs._root$Ref.path;
      var extended = $Ref.isExtended$Ref($ref);
    
      inventory.push({
        $ref: $ref,                   // The JSON Reference (e.g. {$ref: string})
        parent: $refParent,           // The object that contains this $ref pointer
        key: $refKey,                 // The key in `parent` that is the $ref pointer
        pathFromRoot: pathFromRoot,   // The path to the $ref pointer, from the JSON Schema root
        depth: depth,                 // How far from the JSON Schema root is this $ref pointer?
        file: file,                   // The file that the $ref pointer resolves to
        hash: hash,                   // The hash within `file` that the $ref pointer resolves to
        value: pointer.value,         // The resolved value of the $ref pointer
        circular: pointer.circular,   // Is this $ref pointer DIRECTLY circular? (i.e. it references itself)
        extended: extended,           // Does this $ref extend its resolved value? (i.e. it has extra properties, in addition to "$ref")
        external: external            // Does this $ref pointer point to a file other than the main JSON Schema file?
      });
    
      // Recursively crawl the resolved value
      crawl(pointer.value, null, pointer.path, pathFromRoot, inventory, $refs, options);
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Re-maps every $ref pointer, so that they're all relative to the root of the JSON Schema.
     * Each referenced value is dereferenced EXACTLY ONCE.  All subsequent references to the same
     * value are re-mapped to point to the first reference.
     *
     * @example:
     *  {
     *    first: { $ref: somefile.json#/some/part },
     *    second: { $ref: somefile.json#/another/part },
     *    third: { $ref: somefile.json },
     *    fourth: { $ref: somefile.json#/some/part/sub/part }
     *  }
     *
     * In this example, there are four references to the same file, but since the third reference points
     * to the ENTIRE file, that's the only one we need to dereference.  The other three can just be
     * remapped to point inside the third one.
     *
     * On the other hand, if the third reference DIDN'T exist, then the first and second would both need
     * to be dereferenced, since they point to different parts of the file. The fourth reference does NOT
     * need to be dereferenced, because it can be remapped to point inside the first one.
     *
     * @param {object[]} inventory
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function remap(inventory) {
      // Group & sort all the $ref pointers, so they're in the order that we need to dereference/remap them
      inventory.sort(function(a, b) {
        if (a.file !== b.file) {
          return a.file < b.file ? -1 : +1;   // Group all the $refs that point to the same file
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
        else if (a.hash !== b.hash) {
          return a.hash < b.hash ? -1 : +1;   // Group all the $refs that point to the same part of the file
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
        else if (a.circular !== b.circular) {
          return a.circular ? -1 : +1;        // If the $ref points to itself, then sort it higher than other $refs that point to this $ref
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
        else if (a.extended !== b.extended) {
          return a.extended ? +1 : -1;        // If the $ref extends the resolved value, then sort it lower than other $refs that don't extend the value
        }
        else if (a.depth !== b.depth) {
          return a.depth - b.depth;           // Sort $refs by how close they are to the JSON Schema root
        }
        else {
          // If all else is equal, use the $ref that's in the "definitions" property
          return b.pathFromRoot.lastIndexOf('/definitions') - a.pathFromRoot.lastIndexOf('/definitions');
        }
      });
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
      var file, hash, pathFromRoot;
      inventory.forEach(function(i) {
        debug('Re-mapping $ref pointer "%s" at %s', i.$ref.$ref, i.pathFromRoot);
    
        if (!i.external) {
          // This $ref already resolves to the main JSON Schema file
          i.$ref.$ref = i.hash;
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
        else if (i.file === file && i.hash === hash) {
          // This $ref points to the same value as the prevous $ref, so remap it to the same path
          i.$ref.$ref = pathFromRoot;
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
        else if (i.file === file && i.hash.indexOf(hash + '/') === 0) {
          // This $ref points to the a sub-value as the prevous $ref, so remap it beneath that path
          i.$ref.$ref = Pointer.join(pathFromRoot, Pointer.parse(i.hash));
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        }
        else {
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
          // We've moved to a new file or new hash
          file = i.file;
          hash = i.hash;
          pathFromRoot = i.pathFromRoot;
    
          // This is the first $ref to point to this value, so dereference the value.
          // Any other $refs that point to the same value will point to this $ref instead
          i.$ref = i.parent[i.key] = $Ref.dereference(i.$ref, i.value);
    
          if (i.circular) {
            // This $ref points to itself
            i.$ref.$ref = i.pathFromRoot;
          }
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    
        debug('    new value: %s', (i.$ref && i.$ref.$ref) ? i.$ref.$ref : '[object Object]');
      });
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    },{"./pointer":10,"./ref":11,"./util/debug":16,"./util/url":19}],2:[function(_dereq_,module,exports){
    'use strict';
    
    var $Ref    = _dereq_('./ref'),
        Pointer = _dereq_('./pointer'),
        ono     = _dereq_('ono'),
        debug   = _dereq_('./util/debug'),
        url     = _dereq_('./util/url');
    
    module.exports = dereference;
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Crawls the JSON schema, finds all JSON references, and dereferences them.
     * This method mutates the JSON schema object, replacing JSON references with their resolved value.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {$RefParser} parser
     * @param {$RefParserOptions} options
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function dereference(parser, options) {
      debug('Dereferencing $ref pointers in %s', parser.$refs._root$Ref.path);
      var dereferenced = crawl(parser.schema, parser.$refs._root$Ref.path, '#', [], parser.$refs, options);
      parser.$refs.circular = dereferenced.circular;
      parser.schema = dereferenced.value;
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Recursively crawls the given value, and dereferences any JSON references.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {*} obj - The value to crawl. If it's not an object or array, it will be ignored.
     * @param {string} path - The full path of `obj`, possibly with a JSON Pointer in the hash
     * @param {string} pathFromRoot - The path of `obj` from the schema root
     * @param {object[]} parents - An array of the parent objects that have already been dereferenced
     * @param {$Refs} $refs
     * @param {$RefParserOptions} options
     * @returns {{value: object, circular: boolean}}
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function crawl(obj, path, pathFromRoot, parents, $refs, options) {
      var dereferenced;
      var result = {
        value: obj,
        circular: false
      };
    
      if (obj && typeof obj === 'object') {
        parents.push(obj);
    
        if ($Ref.isAllowed$Ref(obj, options)) {
          dereferenced = dereference$Ref(obj, path, pathFromRoot, parents, $refs, options);
          result.circular = dereferenced.circular;
          result.value = dereferenced.value;
        }
        else {
          Object.keys(obj).forEach(function(key) {
            var keyPath = Pointer.join(path, key);
            var keyPathFromRoot = Pointer.join(pathFromRoot, key);
            var value = obj[key];
            var circular = false;
    
            if ($Ref.isAllowed$Ref(value, options)) {
              dereferenced = dereference$Ref(value, keyPath, keyPathFromRoot, parents, $refs, options);
              circular = dereferenced.circular;
              obj[key] = dereferenced.value;
            }
            else {
              if (parents.indexOf(value) === -1) {
                dereferenced = crawl(value, keyPath, keyPathFromRoot, parents, $refs, options);
                circular = dereferenced.circular;
                obj[key] = dereferenced.value;
              }
              else {
                circular = foundCircularReference(keyPath, $refs, options);
              }
            }
    
            // Set the "isCircular" flag if this or any other property is circular
            result.circular = result.circular || circular;
          });
        }
    
        parents.pop();
      }
    
      return result;
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Dereferences the given JSON Reference, and then crawls the resulting value.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {{$ref: string}} $ref - The JSON Reference to resolve
     * @param {string} path - The full path of `$ref`, possibly with a JSON Pointer in the hash
     * @param {string} pathFromRoot - The path of `$ref` from the schema root
     * @param {object[]} parents - An array of the parent objects that have already been dereferenced
     * @param {$Refs} $refs
     * @param {$RefParserOptions} options
     * @returns {{value: object, circular: boolean}}
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function dereference$Ref($ref, path, pathFromRoot, parents, $refs, options) {
      debug('Dereferencing $ref pointer "%s" at %s', $ref.$ref, path);
    
      var $refPath = url.resolve(path, $ref.$ref);
      var pointer = $refs._resolve($refPath, options);
    
      // Check for circular references
      var directCircular = pointer.circular;
      var circular = directCircular || parents.indexOf(pointer.value) !== -1;
      circular && foundCircularReference(path, $refs, options);
    
      // Dereference the JSON reference
      var dereferencedValue = $Ref.dereference($ref, pointer.value);
    
      // Crawl the dereferenced value (unless it's circular)
      if (!circular) {
        // Determine if the dereferenced value is circular
        var dereferenced = crawl(dereferencedValue, pointer.path, pathFromRoot, parents, $refs, options);
        circular = dereferenced.circular;
        dereferencedValue = dereferenced.value;
      }
    
      if (circular && !directCircular && options.dereference.circular === 'ignore') {
        // The user has chosen to "ignore" circular references, so don't change the value
        dereferencedValue = $ref;
      }
    
      if (directCircular) {
        // The pointer is a DIRECT circular reference (i.e. it references itself).
        // So replace the $ref path with the absolute path from the JSON Schema root
        dereferencedValue.$ref = pathFromRoot;
      }
    
      return {
        circular: circular,
        value: dereferencedValue
      };
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Called when a circular reference is found.
     * It sets the {@link $Refs#circular} flag, and throws an error if options.dereference.circular is false.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {string} keyPath - The JSON Reference path of the circular reference
     * @param {$Refs} $refs
     * @param {$RefParserOptions} options
     * @returns {boolean} - always returns true, to indicate that a circular reference was found
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function foundCircularReference(keyPath, $refs, options) {
      $refs.circular = true;
      if (!options.dereference.circular) {
        throw ono.reference('Circular $ref pointer found at %s', keyPath);
      }
      return true;
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    
    },{"./pointer":10,"./ref":11,"./util/debug":16,"./util/url":19,"ono":69}],3:[function(_dereq_,module,exports){
    (function (Buffer){
    'use strict';
    
    var Promise         = _dereq_('./util/promise'),
        Options         = _dereq_('./options'),
        $Refs           = _dereq_('./refs'),
        parse           = _dereq_('./parse'),
        resolveExternal = _dereq_('./resolve-external'),
        bundle          = _dereq_('./bundle'),
        dereference     = _dereq_('./dereference'),
        url             = _dereq_('./util/url'),
        maybe           = _dereq_('call-me-maybe'),
        ono             = _dereq_('ono');
    
    module.exports = $RefParser;
    module.exports.YAML = _dereq_('./util/yaml');
    
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * This class parses a JSON schema, builds a map of its JSON references and their resolved values,
     * and provides methods for traversing, manipulating, and dereferencing those references.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @constructor
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function $RefParser() {
      /**
       * The parsed (and possibly dereferenced) JSON schema object
       *
       * @type {object}
       * @readonly
       */
      this.schema = null;
    
      /**
       * The resolved JSON references
       *
       * @type {$Refs}
       * @readonly
       */
      this.$refs = new $Refs();
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Parses the given JSON schema.
     * This method does not resolve any JSON references.
     * It just reads a single file in JSON or YAML format, and parse it as a JavaScript object.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {string|object} schema - The file path or URL of the JSON schema. Or a JSON schema object.
     * @param {$RefParserOptions} [options] - Options that determine how the schema is parsed
     * @param {function} [callback] - An error-first callback. The second parameter is the parsed JSON schema object.
     * @returns {Promise} - The returned promise resolves with the parsed JSON schema object.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    $RefParser.parse = function(schema, options, callback) {
      var Class = this; // eslint-disable-line consistent-this
      var instance = new Class();
      return instance.parse.apply(instance, arguments);
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Parses the given JSON schema.
     * This method does not resolve any JSON references.
     * It just reads a single file in JSON or YAML format, and parse it as a JavaScript object.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {string|object} schema - The file path or URL of the JSON schema. Or a JSON schema object.
     * @param {$RefParserOptions} [options] - Options that determine how the schema is parsed
     * @param {function} [callback] - An error-first callback. The second parameter is the parsed JSON schema object.
     * @returns {Promise} - The returned promise resolves with the parsed JSON schema object.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    $RefParser.prototype.parse = function(schema, options, callback) {
      var args = normalizeArgs(arguments);
      var promise;
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
      if (!args.path && !args.schema) {
        var err = ono('Expected a file path, URL, or object. Got %s', args.path || args.schema);
        return maybe(args.callback, Promise.reject(err));
      }
    
      // Reset everything
      this.schema = null;
      this.$refs = new $Refs();
    
      // If the path is a filesystem path, then convert it to a URL.
      // NOTE: According to the JSON Reference spec, these should already be URLs,
      // but, in practice, many people use local filesystem paths instead.
      // So we're being generous here and doing the conversion automatically.
      // This is not intended to be a 100% bulletproof solution.
      // If it doesn't work for your use-case, then use a URL instead.
      if (url.isFileSystemPath(args.path)) {
        args.path = url.fromFileSystemPath(args.path);
      }
    
      // Resolve the absolute path of the schema
      args.path = url.resolve(url.cwd(), args.path);
    
      if (args.schema && typeof args.schema === 'object') {
        // A schema object was passed-in.
        // So immediately add a new $Ref with the schema object as its value
        this.$refs._add(args.path, args.schema);
        promise = Promise.resolve(args.schema);
      }
      else {
        // Parse the schema file/url
        promise = parse(args.path, this.$refs, args.options);
      }
    
      var me = this;
      return promise
        .then(function(result) {
          if (!result || typeof result !== 'object' || Buffer.isBuffer(result)) {
            throw ono.syntax('"%s" is not a valid JSON Schema', me.$refs._root$Ref.path || result);
          }
          else {
            me.schema = result;
            return maybe(args.callback, Promise.resolve(me.schema));
          }
        })
        .catch(function(e) {
          return maybe(args.callback, Promise.reject(e));
        });
    };
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Parses the given JSON schema and resolves any JSON references, including references in
     * externally-referenced files.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {string|object} schema - The file path or URL of the JSON schema. Or a JSON schema object.
     * @param {$RefParserOptions} [options] - Options that determine how the schema is parsed and resolved
     * @param {function} [callback]
     * - An error-first callback. The second parameter is a {@link $Refs} object containing the resolved JSON references
     *
     * @returns {Promise}
     * The returned promise resolves with a {@link $Refs} object containing the resolved JSON references
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    $RefParser.resolve = function(schema, options, callback) {
      var Class = this; // eslint-disable-line consistent-this
      var instance = new Class();
      return instance.resolve.apply(instance, arguments);
    };
    
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Parses the given JSON schema and resolves any JSON references, including references in
     * externally-referenced files.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {string|object} schema - The file path or URL of the JSON schema. Or a JSON schema object.
     * @param {$RefParserOptions} [options] - Options that determine how the schema is parsed and resolved
     * @param {function} [callback]
     * - An error-first callback. The second parameter is a {@link $Refs} object containing the resolved JSON references
     *
     * @returns {Promise}
     * The returned promise resolves with a {@link $Refs} object containing the resolved JSON references
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    $RefParser.prototype.resolve = function(schema, options, callback) {
      var me = this;
      var args = normalizeArgs(arguments);
    
      return this.parse(args.path, args.schema, args.options)
        .then(function() {
          return resolveExternal(me, args.options);
        })
        .then(function() {
          return maybe(args.callback, Promise.resolve(me.$refs));
        })
        .catch(function(err) {
          return maybe(args.callback, Promise.reject(err));
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        });
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Parses the given JSON schema, resolves any JSON references, and bundles all external references
     * into the main JSON schema. This produces a JSON schema that only has *internal* references,
     * not any *external* references.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {string|object} schema - The file path or URL of the JSON schema. Or a JSON schema object.
     * @param {$RefParserOptions} [options] - Options that determine how the schema is parsed, resolved, and dereferenced
     * @param {function} [callback] - An error-first callback. The second parameter is the bundled JSON schema object
     * @returns {Promise} - The returned promise resolves with the bundled JSON schema object.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    $RefParser.bundle = function(schema, options, callback) {
      var Class = this; // eslint-disable-line consistent-this
      var instance = new Class();
      return instance.bundle.apply(instance, arguments);
    };
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Parses the given JSON schema, resolves any JSON references, and bundles all external references
     * into the main JSON schema. This produces a JSON schema that only has *internal* references,
     * not any *external* references.
     *
     * @param {string|object} schema - The file path or URL of the JSON schema. Or a JSON schema object.
     * @param {$RefParserOptions} [options] - Options that determine how the schema is parsed, resolved, and dereferenced
     * @param {function} [callback] - An error-first callback. The second parameter is the bundled JSON schema object
     * @returns {Promise} - The returned promise resolves with the bundled JSON schema object.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    $RefParser.prototype.bundle = function(schema, options, callback) {
      var me = this;
      var args = normalizeArgs(arguments);
    
      return this.resolve(args.path, args.schema, args.options)
        .then(function() {
          bundle(me, args.options);
          return maybe(args.callback, Promise.resolve(me.schema));
        })
        .catch(function(err) {
          return maybe(args.callback, Promise.reject(err));
        });
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    };
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Parses the given JSON schema, resolves any JSON references, and dereferences the JSON schema.
     * That is, all JSON references are replaced with their resolved values.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {string|object} schema - The file path or URL of the JSON schema. Or a JSON schema object.
     * @param {$RefParserOptions} [options] - Options that determine how the schema is parsed, resolved, and dereferenced
     * @param {function} [callback] - An error-first callback. The second parameter is the dereferenced JSON schema object
     * @returns {Promise} - The returned promise resolves with the dereferenced JSON schema object.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    $RefParser.dereference = function(schema, options, callback) {
      var Class = this; // eslint-disable-line consistent-this
      var instance = new Class();
      return instance.dereference.apply(instance, arguments);
    };
    
    /**
     * Parses the given JSON schema, resolves any JSON references, and dereferences the JSON schema.
     * That is, all JSON references are replaced with their resolved values.
     *
     * @param {string|object} schema - The file path or URL of the JSON schema. Or a JSON schema object.
     * @param {$RefParserOptions} [options] - Options that determine how the schema is parsed, resolved, and dereferenced
     * @param {function} [callback] - An error-first callback. The second parameter is the dereferenced JSON schema object
     * @returns {Promise} - The returned promise resolves with the dereferenced JSON schema object.
     */
    $RefParser.prototype.dereference = function(schema, options, callback) {
      var me = this;
      var args = normalizeArgs(arguments);
    
      return this.resolve(args.path, args.schema, args.options)
        .then(function() {
          dereference(me, args.options);
          return maybe(args.callback, Promise.resolve(me.schema));
        })
        .catch(function(err) {
          return maybe(args.callback, Promise.reject(err));
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        });
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    };
    
    /**
     * Normalizes the given arguments, accounting for optional args.
     *
     * @param {Arguments} args
     * @returns {object}
     */
    function normalizeArgs(args) {
      var path, schema, options, callback;
      args = Array.prototype.slice.call(args);
    
      if (typeof args[args.length - 1] === 'function') {
        // The last parameter is a callback function
        callback = args.pop();
      }
    
      if (typeof args[0] === 'string') {
        // The first parameter is the path
        path = args[0];
        if (typeof args[2] === 'object') {
          // The second parameter is the schema, and the third parameter is the options
          schema = args[1];
          options = args[2];
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
        else {
          // The second parameter is the options
          schema = undefined;
          options = args[1];
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
      }
      else {
        // The first parameter is the schema
        path = '';
        schema = args[0];
        options = args[1];
      }
    
      if (!(options instanceof Options)) {
        options = new Options(options);
      }
    
      return {
        path: path,
        schema: schema,
        options: options,
        callback: callback
      };
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    }).call(this,{"isBuffer":_dereq_("../node_modules/is-buffer/index.js")})
    
    },{"../node_modules/is-buffer/index.js":36,"./bundle":1,"./dereference":2,"./options":4,"./parse":5,"./refs":12,"./resolve-external":13,"./util/promise":18,"./util/url":19,"./util/yaml":20,"call-me-maybe":27,"ono":69}],4:[function(_dereq_,module,exports){
    /* eslint lines-around-comment: [2, {beforeBlockComment: false}] */
    'use strict';
    
    var jsonParser       = _dereq_('./parsers/json'),
        yamlParser       = _dereq_('./parsers/yaml'),
        textParser       = _dereq_('./parsers/text'),
        binaryParser     = _dereq_('./parsers/binary'),
        fileResolver     = _dereq_('./resolvers/file'),
        httpResolver     = _dereq_('./resolvers/http'),
        zschemaValidator = _dereq_('./validators/z-schema');
    
    module.exports = $RefParserOptions;
    
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Options that determine how JSON schemas are parsed, resolved, dereferenced, and validated.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {object|$RefParserOptions} [options] - Overridden options
     * @constructor
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function $RefParserOptions(options) {
      merge(this, $RefParserOptions.defaults);
      merge(this, options);
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    $RefParserOptions.defaults = {
      /**
       * Determines how different types of files will be parsed.
       *
       * You can add additional parsers of your own, replace an existing one with
       * your own implemenation, or disable any parser by setting it to false.
       */
      parse: {
        json: jsonParser,
        yaml: yamlParser,
        text: textParser,
        binary: binaryParser,
      },
    
      /**
       * Determines how JSON References will be resolved.
       *
       * You can add additional resolvers of your own, replace an existing one with
       * your own implemenation, or disable any resolver by setting it to false.
       */
      resolve: {
        file: fileResolver,
        http: httpResolver,
    
        /**
         * Determines whether external $ref pointers will be resolved.
         * If this option is disabled, then none of above resolvers will be called.
         * Instead, external $ref pointers will simply be ignored.
         *
         * @type {boolean}
         */
        external: true,
      },
    
      /**
       * Determines the types of JSON references that are allowed.
       */
      dereference: {
        /**
         * Dereference circular (recursive) JSON references?
         * If false, then a {@link ReferenceError} will be thrown if a circular reference is found.
         * If "ignore", then circular references will not be dereferenced.
         *
         * @type {boolean|string}
         */
        circular: true
      },
    
      /**
       * Validator plug-ins that can be used to validate the schema.
       */
      validate: {
        zschema: zschemaValidator
      }
    };
    
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Merges the properties of the source object into the target object.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {object} target - The object that we're populating
     * @param {?object} source - The options that are being merged
     * @returns {object}
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function merge(target, source) {
      if (isMergeable(source)) {
        var keys = Object.keys(source);
        for (var i = 0; i < keys.length; i++) {
          var key = keys[i];
          var sourceSetting = source[key];
          var targetSetting = target[key];
    
          if (isMergeable(sourceSetting)) {
            // It's a nested object, so merge it recursively
            target[key] = merge(targetSetting || {}, sourceSetting);
          }
          else if (sourceSetting !== undefined) {
            // It's a scalar value, function, or array. No merging necessary. Just overwrite the target value.
            target[key] = sourceSetting;
          }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
      }
      return target;
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Determines whether the given value can be merged,
     * or if it is a scalar value that should just override the target value.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param   {*}  val
     * @returns {Boolean}
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function isMergeable(val) {
      return val &&
        (typeof val === 'object') &&
        !Array.isArray(val) &&
        !(val instanceof RegExp) &&
        !(val instanceof Date);
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    },{"./parsers/binary":6,"./parsers/json":7,"./parsers/text":8,"./parsers/yaml":9,"./resolvers/file":14,"./resolvers/http":15,"./validators/z-schema":21}],5:[function(_dereq_,module,exports){
    (function (Buffer){
    'use strict';
    
    var ono      = _dereq_('ono'),
        debug    = _dereq_('./util/debug'),
        url      = _dereq_('./util/url'),
        plugins  = _dereq_('./util/plugins'),
        Promise  = _dereq_('./util/promise');
    
    module.exports = parse;
    
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Reads and parses the specified file path or URL.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {string} path - This path MUST already be resolved, since `read` doesn't know the resolution context
     * @param {$Refs} $refs
     * @param {$RefParserOptions} options
     *
     * @returns {Promise}
     * The promise resolves with the parsed file contents, NOT the raw (Buffer) contents.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function parse(path, $refs, options) {
      try {
        // Remove the URL fragment, if any
        path = url.stripHash(path);
    
        // Add a new $Ref for this file, even though we don't have the value yet.
        // This ensures that we don't simultaneously read & parse the same file multiple times
        var $ref = $refs._add(path);
    
        // This "file object" will be passed to all resolvers and parsers.
        var file = {
          url: path,
          extension: url.getExtension(path),
        };
    
        // Read the file and then parse the data
        return readFile(file, options)
          .then(function(resolver) {
            $ref.pathType = resolver.plugin.name;
            file.data = resolver.result;
            return parseFile(file, options);
          })
          .then(function(parser) {
            $ref.value = parser.result;
            return parser.result;
          });
      }
      catch (e) {
        return Promise.reject(e);
      }
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Reads the given file, using the configured resolver plugins
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {object} file           - An object containing information about the referenced file
     * @param {string} file.url       - The full URL of the referenced file
     * @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
     * @param {$RefParserOptions} options
     *
     * @returns {Promise}
     * The promise resolves with the raw file contents and the resolver that was used.
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function readFile(file, options) {
      return new Promise(function(resolve, reject) {
        debug('Reading %s', file.url);
    
        // Find the resolvers that can read this file
        var resolvers = plugins.all(options.resolve);
        resolvers = plugins.filter(resolvers, 'canRead', file);
    
        // Run the resolvers, in order, until one of them succeeds
        plugins.sort(resolvers);
        plugins.run(resolvers, 'read', file)
          .then(resolve, onError);
    
        function onError(err) {
          // Throw the original error, if it's one of our own (user-friendly) errors.
          // Otherwise, throw a generic, friendly error.
          if (err && !(err instanceof SyntaxError)) {
            reject(err);
          }
          else {
            reject(ono.syntax('Unable to resolve $ref pointer "%s"', file.url));
          }
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
      });
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    
    /**
     * Parses the given file's contents, using the configured parser plugins.
     *
     * @param {object} file           - An object containing information about the referenced file
     * @param {string} file.url       - The full URL of the referenced file
     * @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
     * @param {*}      file.data      - The file contents. This will be whatever data type was returned by the resolver
     * @param {$RefParserOptions} options
     *
     * @returns {Promise}
     * The promise resolves with the parsed file contents and the parser that was used.
     */
    function parseFile(file, options) {
      return new Promise(function(resolve, reject) {
        debug('Parsing %s', file.url);
    
        // Find the parsers that can read this file type.
        // If none of the parsers are an exact match for this file, then we'll try ALL of them.
        // This handles situations where the file IS a supported type, just with an unknown extension.
        var allParsers = plugins.all(options.parse);
        var filteredParsers = plugins.filter(allParsers, 'canParse', file);
        var parsers = filteredParsers.length > 0 ? filteredParsers : allParsers;
    
        // Run the parsers, in order, until one of them succeeds
        plugins.sort(parsers);
        plugins.run(parsers, 'parse', file)
          .then(onParsed, onError);
    
        function onParsed(parser) {
          if (!parser.plugin.allowEmpty && isEmpty(parser.result)) {
            reject(ono.syntax('Error parsing "%s" as %s. \nParsed value is empty', file.url, parser.plugin.name));
          }
          else {
            resolve(parser);
          }
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    
        function onError(err) {
          if (err) {
            err = err instanceof Error ? err : new Error(err);
            reject(ono.syntax(err, 'Error parsing %s', file.url));
          }
          else {
            reject(ono.syntax('Unable to parse %s', file.url));
          }
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        }
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
      });
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    /**
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * Determines whether the parsed value is "empty".
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     *
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
     * @param {*} value
     * @returns {boolean}
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
     */
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    function isEmpty(value) {
      return value === undefined ||
        (typeof value === 'object' && Object.keys(value).length === 0) ||
        (typeof value === 'string' && value.trim().length === 0) ||
        (Buffer.isBuffer(value) && value.length === 0);
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
    }
    
    
    Alvaro Cabrera's avatar
    Alvaro Cabrera committed
    }).call(this,{"isBuffer":_dereq_("../node_modules/is-buffer/index.js")})
    
    },{"../node_modules/is-buffer/index.js":36,"./util/debug":16,"./util/plugins":17,"./util/promise":18,"./util/url":19,"ono":69}],6:[function(_dereq_,module,exports){
    (function (Buffer){
    'use strict';
    
    var BINARY_REGEXP = /\.(jpeg|jpg|gif|png|bmp|ico)$/i;
    
    module.exports = {
      /**
       * The order that this parser will run, in relation to other parsers.
       *
       * @type {number}
       */
      order: 400,
    
      /**
       * Whether to allow "empty" files (zero bytes).
       *
       * @type {boolean}
       */
      allowEmpty: true,
    
      /**
       * Determines whether this parser can parse a given file reference.
       * Parsers that return true will be tried, in order, until one successfully parses the file.
       * Parsers that return false will be skipped, UNLESS all parsers returned false, in which case
       * every parser will be tried.
       *
       * @param {object} file           - An object containing information about the referenced file
       * @param {string} file.url       - The full URL of the referenced file
       * @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
       * @param {*}      file.data      - The file contents. This will be whatever data type was returned by the resolver
       * @returns {boolean}
       */
      canParse: function isBinary(file) {
        // Use this parser if the file is a Buffer, and has a known binary extension
        return Buffer.isBuffer(file.data) && BINARY_REGEXP.test(file.url);
      },
    
      /**
       * Parses the given data as a Buffer (byte array).
       *
       * @param {object} file           - An object containing information about the referenced file
       * @param {string} file.url       - The full URL of the referenced file
       * @param {string} file.extension - The lowercased file extension (e.g. ".txt", ".html", etc.)
       * @param {*}      file.data      - The file contents. This will be whatever data type was returned by the resolver
       * @returns {Promise<Buffer>}
       */
      parse: function parseBinary(file) {
        if (Buffer.isBuffer(file.data)) {
          return file.data;
    
    Tomasz Ducin's avatar
    Tomasz Ducin committed
        }