UNPKG

@apidevtools/json-schema-ref-parser

Version:

Parse, Resolve, and Dereference JSON Schema $ref pointers

160 lines (159 loc) 5.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.InvalidPointerError = exports.TimeoutError = exports.MissingPointerError = exports.UnmatchedResolverError = exports.ResolverError = exports.UnmatchedParserError = exports.ParserError = exports.JSONParserErrorGroup = exports.JSONParserError = void 0; exports.toJSON = toJSON; exports.getDeepKeys = getDeepKeys; exports.isHandledError = isHandledError; exports.normalizeError = normalizeError; const url_js_1 = require("./url.js"); const nonJsonTypes = ["function", "symbol", "undefined"]; const protectedProps = ["constructor", "prototype", "__proto__"]; const objectPrototype = Object.getPrototypeOf({}); /** * Custom JSON serializer for Error objects. * Returns all built-in error properties, as well as extended properties. */ function toJSON() { // HACK: We have to cast the objects to `any` so we can use symbol indexers. // see https://github.com/Microsoft/TypeScript/issues/1863 const pojo = {}; const error = this; for (const key of getDeepKeys(error)) { if (typeof key === "string") { const value = error[key]; const type = typeof value; if (!nonJsonTypes.includes(type)) { pojo[key] = value; } } } return pojo; } /** * Returns own, inherited, enumerable, non-enumerable, string, and symbol keys of `obj`. * Does NOT return members of the base Object prototype, or the specified omitted keys. */ function getDeepKeys(obj, omit = []) { let keys = []; // Crawl the prototype chain, finding all the string and symbol keys while (obj && obj !== objectPrototype) { keys = keys.concat(Object.getOwnPropertyNames(obj), Object.getOwnPropertySymbols(obj)); obj = Object.getPrototypeOf(obj); } // De-duplicate the list of keys const uniqueKeys = new Set(keys); // Remove any omitted keys for (const key of omit.concat(protectedProps)) { uniqueKeys.delete(key); } return uniqueKeys; } class JSONParserError extends Error { constructor(message, source) { super(); this.toJSON = toJSON.bind(this); this.code = "EUNKNOWN"; this.name = "JSONParserError"; this.message = message; this.source = source; this.path = null; } get footprint() { return `${this.path}+${this.source}+${this.code}+${this.message}`; } } exports.JSONParserError = JSONParserError; class JSONParserErrorGroup extends Error { constructor(parser) { super(); this.toJSON = toJSON.bind(this); this.files = parser; this.name = "JSONParserErrorGroup"; this.message = `${this.errors.length} error${this.errors.length > 1 ? "s" : ""} occurred while reading '${(0, url_js_1.toFileSystemPath)(parser.$refs._root$Ref.path)}'`; } static getParserErrors(parser) { const errors = []; for (const $ref of Object.values(parser.$refs._$refs)) { if ($ref.errors) { errors.push(...$ref.errors); } } return errors; } get errors() { return JSONParserErrorGroup.getParserErrors(this.files); } } exports.JSONParserErrorGroup = JSONParserErrorGroup; class ParserError extends JSONParserError { constructor(message, source) { super(`Error parsing ${source}: ${message}`, source); this.code = "EPARSER"; this.name = "ParserError"; } } exports.ParserError = ParserError; class UnmatchedParserError extends JSONParserError { constructor(source) { super(`Could not find parser for "${source}"`, source); this.code = "EUNMATCHEDPARSER"; this.name = "UnmatchedParserError"; } } exports.UnmatchedParserError = UnmatchedParserError; class ResolverError extends JSONParserError { constructor(ex, source) { super(ex.message || `Error reading file "${source}"`, source); this.code = "ERESOLVER"; this.name = "ResolverError"; if ("code" in ex) { this.ioErrorCode = String(ex.code); } } } exports.ResolverError = ResolverError; class UnmatchedResolverError extends JSONParserError { constructor(source) { super(`Could not find resolver for "${source}"`, source); this.code = "EUNMATCHEDRESOLVER"; this.name = "UnmatchedResolverError"; } } exports.UnmatchedResolverError = UnmatchedResolverError; class MissingPointerError extends JSONParserError { constructor(token, path, targetRef, targetFound, parentPath) { super(`Missing $ref pointer "${(0, url_js_1.getHash)(path)}". Token "${token}" does not exist.`, (0, url_js_1.stripHash)(path)); this.code = "EMISSINGPOINTER"; this.name = "MissingPointerError"; this.targetToken = token; this.targetRef = targetRef; this.targetFound = targetFound; this.parentPath = parentPath; } } exports.MissingPointerError = MissingPointerError; class TimeoutError extends JSONParserError { constructor(timeout) { super(`Dereferencing timeout reached: ${timeout}ms`); this.code = "ETIMEOUT"; this.name = "TimeoutError"; } } exports.TimeoutError = TimeoutError; class InvalidPointerError extends JSONParserError { constructor(pointer, path) { super(`Invalid $ref pointer "${pointer}". Pointers must begin with "#/"`, (0, url_js_1.stripHash)(path)); this.code = "EUNMATCHEDRESOLVER"; this.name = "InvalidPointerError"; } } exports.InvalidPointerError = InvalidPointerError; function isHandledError(err) { return err instanceof JSONParserError || err instanceof JSONParserErrorGroup; } function normalizeError(err) { if (err.path === null) { err.path = []; } return err; }