| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- /* eslint-disable no-unused-vars */
- "use strict";
- const $Refs = require("./refs");
- const _parse = require("./parse");
- const normalizeArgs = require("./normalize-args");
- const resolveExternal = require("./resolve-external");
- const _bundle = require("./bundle");
- const _dereference = require("./dereference");
- const url = require("./util/url");
- const { JSONParserError, InvalidPointerError, MissingPointerError, ResolverError, ParserError, UnmatchedParserError, UnmatchedResolverError, isHandledError, JSONParserErrorGroup } = require("./util/errors");
- const maybe = require("call-me-maybe");
- const { ono } = require("@jsdevtools/ono");
- module.exports = $RefParser;
- module.exports.default = $RefParser;
- module.exports.JSONParserError = JSONParserError;
- module.exports.InvalidPointerError = InvalidPointerError;
- module.exports.MissingPointerError = MissingPointerError;
- module.exports.ResolverError = ResolverError;
- module.exports.ParserError = ParserError;
- module.exports.UnmatchedParserError = UnmatchedParserError;
- module.exports.UnmatchedResolverError = UnmatchedResolverError;
- /**
- * 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.
- *
- * @constructor
- */
- 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();
- }
- /**
- * 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.
- *
- * @param {string} [path] - The file path or URL of the JSON schema
- * @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
- * @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.
- */
- $RefParser.parse = function parse (path, schema, options, callback) {
- let Class = this; // eslint-disable-line consistent-this
- let instance = new Class();
- return instance.parse.apply(instance, arguments);
- };
- /**
- * 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.
- *
- * @param {string} [path] - The file path or URL of the JSON schema
- * @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
- * @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.
- */
- $RefParser.prototype.parse = async function parse (path, schema, options, callback) {
- let args = normalizeArgs(arguments);
- let promise;
- if (!args.path && !args.schema) {
- let err = ono(`Expected a file path, URL, or object. Got ${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.
- let pathType = "http";
- if (url.isFileSystemPath(args.path)) {
- args.path = url.fromFileSystemPath(args.path);
- pathType = "file";
- }
- // 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
- let $ref = this.$refs._add(args.path);
- $ref.value = args.schema;
- $ref.pathType = pathType;
- promise = Promise.resolve(args.schema);
- }
- else {
- // Parse the schema file/url
- promise = _parse(args.path, this.$refs, args.options);
- }
- let me = this;
- try {
- let result = await promise;
- if (result !== null && typeof result === "object" && !Buffer.isBuffer(result)) {
- me.schema = result;
- return maybe(args.callback, Promise.resolve(me.schema));
- }
- else if (args.options.continueOnError) {
- me.schema = null; // it's already set to null at line 79, but let's set it again for the sake of readability
- return maybe(args.callback, Promise.resolve(me.schema));
- }
- else {
- throw ono.syntax(`"${me.$refs._root$Ref.path || result}" is not a valid JSON Schema`);
- }
- }
- catch (err) {
- if (!args.options.continueOnError || !isHandledError(err)) {
- return maybe(args.callback, Promise.reject(err));
- }
- if (this.$refs._$refs[url.stripHash(args.path)]) {
- this.$refs._$refs[url.stripHash(args.path)].addError(err);
- }
- return maybe(args.callback, Promise.resolve(null));
- }
- };
- /**
- * Parses the given JSON schema and resolves any JSON references, including references in
- * externally-referenced files.
- *
- * @param {string} [path] - The file path or URL of the JSON schema
- * @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
- * @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
- */
- $RefParser.resolve = function resolve (path, schema, options, callback) {
- let Class = this; // eslint-disable-line consistent-this
- let instance = new Class();
- return instance.resolve.apply(instance, arguments);
- };
- /**
- * Parses the given JSON schema and resolves any JSON references, including references in
- * externally-referenced files.
- *
- * @param {string} [path] - The file path or URL of the JSON schema
- * @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
- * @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
- */
- $RefParser.prototype.resolve = async function resolve (path, schema, options, callback) {
- let me = this;
- let args = normalizeArgs(arguments);
- try {
- await this.parse(args.path, args.schema, args.options);
- await resolveExternal(me, args.options);
- finalize(me);
- return maybe(args.callback, Promise.resolve(me.$refs));
- }
- catch (err) {
- return maybe(args.callback, Promise.reject(err));
- }
- };
- /**
- * 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} [path] - The file path or URL of the JSON schema
- * @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
- * @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.
- */
- $RefParser.bundle = function bundle (path, schema, options, callback) {
- let Class = this; // eslint-disable-line consistent-this
- let instance = new Class();
- return instance.bundle.apply(instance, arguments);
- };
- /**
- * 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} [path] - The file path or URL of the JSON schema
- * @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
- * @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.
- */
- $RefParser.prototype.bundle = async function bundle (path, schema, options, callback) {
- let me = this;
- let args = normalizeArgs(arguments);
- try {
- await this.resolve(args.path, args.schema, args.options);
- _bundle(me, args.options);
- finalize(me);
- return maybe(args.callback, Promise.resolve(me.schema));
- }
- catch (err) {
- return maybe(args.callback, Promise.reject(err));
- }
- };
- /**
- * 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} [path] - The file path or URL of the JSON schema
- * @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
- * @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.dereference = function dereference (path, schema, options, callback) {
- let Class = this; // eslint-disable-line consistent-this
- let 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} [path] - The file path or URL of the JSON schema
- * @param {object} [schema] - A JSON schema object. This object will be used instead of reading from `path`.
- * @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 = async function dereference (path, schema, options, callback) {
- let me = this;
- let args = normalizeArgs(arguments);
- try {
- await this.resolve(args.path, args.schema, args.options);
- _dereference(me, args.options);
- finalize(me);
- return maybe(args.callback, Promise.resolve(me.schema));
- }
- catch (err) {
- return maybe(args.callback, Promise.reject(err));
- }
- };
- function finalize (parser) {
- const errors = JSONParserErrorGroup.getParserErrors(parser);
- if (errors.length > 0) {
- throw new JSONParserErrorGroup(parser);
- }
- }
|