Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@json-schema-tools/dereferencer

Package Overview
Dependencies
Maintainers
1
Versions
48
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@json-schema-tools/dereferencer - npm Package Compare versions

Comparing version 1.1.0 to 1.2.0

build/dereferencer.d.ts

134

build/index.d.ts

@@ -1,122 +0,12 @@

import { JSONSchema, JSONSchemaObject } from "@json-schema-tools/meta-schema";
export interface RefCache {
[k: string]: JSONSchema;
}
/**
* Options that can be passed to the derefencer constructor.
*/
export interface DereferencerOptions {
/**
* If true, resolved non-local references will also be dereferenced using the same options.
*/
recursive?: boolean;
}
export declare const defaultDereferencerOptions: DereferencerOptions;
/**
* Error thrown by the constructor when given a ref that isn't a string
*
*
* @example
* ```typescript
*
* import Dereferencer, { NonStringRefError } from "@json-schema-tools/dereferencer";
*
* try { const dereffer = new Dereferencer({}); }
* catch(e) {
* if (e instanceof NonStringRefError) { ... }
* }
* ```
*
*/
export declare class NonStringRefError extends Error {
constructor(schema: JSONSchema);
}
/**
* Error thrown when the fetched reference is not properly formatted JSON or is encoded
* incorrectly
*
* @example
* ```typescript
*
* import Dereferencer, { NonJsonRefError } from "@json-schema-tools/dereferencer";
* const dereffer = new Dereferencer({});
* try { await dereffer.resolve(); }
* catch(e) {
* if (e instanceof NonJsonRefError) { ... }
* }
* ```
*
*/
export declare class NonJsonRefError extends Error {
constructor(schema: JSONSchemaObject, nonJson: string);
}
/**
* Error thrown when a JSON pointer is provided but is not parseable as per the RFC6901
*
* @example
* ```typescript
*
* import Dereferencer, { InvalidJsonPointerRefError } from "@json-schema-tools/dereferencer";
* const dereffer = new Dereferencer({});
* try { await dereffer.resolve(); }
* catch(e) {
* if (e instanceof InvalidJsonPointerRefError) { ... }
* }
* ```
*
*/
export declare class InvalidJsonPointerRefError extends Error {
constructor(schema: JSONSchemaObject);
}
/**
* Error thrown when given an invalid file system path as a reference.
*
* @example
* ```typescript
*
* import Dereferencer, { InvalidFileSystemPathError } from "@json-schema-tools/dereferencer";
* const dereffer = new Dereferencer({});
* try { await dereffer.resolve(); }
* catch(e) {
* if (e instanceof InvalidFileSystemPathError) { ... }
* }
* ```
*
*/
export declare class InvalidFileSystemPathError extends Error {
constructor(ref: string);
}
/**
* Error thrown when given an invalid file system path as a reference.
*
*/
export declare class InvalidRemoteURLError extends Error {
constructor(ref: string);
}
/**
* When instantiated, represents a fully configured dereferencer. When constructed, references are pulled out.
* No references are fetched until .resolve is called.
*/
export declare class Dereferencer {
private options;
refs: string[];
private refCache;
private schema;
constructor(schema: JSONSchema, options?: DereferencerOptions);
/**
* Fetches the schemas for all the refs in the configured input schema(s)
*
* @returns a promise that will resolve a fully dereferenced schema, where all the
* promises for each ref has been resolved as well.
*
*
*/
resolve(): Promise<JSONSchema>;
fetchRef(ref: string): Promise<JSONSchema>;
/**
* First-pass traversal to collect all the refs that we can find. This allows us to
* optimize the async work required as well.
*/
collectRefs(): string[];
}
export default Dereferencer;
declare const _default: {
new (schema: import("@json-schema-tools/meta-schema").JSONSchema, options?: import("./dereferencer").DereferencerOptions): {
refs: string[];
refCache: import("./dereferencer").RefCache;
schema: import("@json-schema-tools/meta-schema").JSONSchema;
options: import("./dereferencer").DereferencerOptions;
resolve(): Promise<import("@json-schema-tools/meta-schema").JSONSchema>;
fetchRef(ref: string): Promise<import("@json-schema-tools/meta-schema").JSONSchema>;
collectRefs(): string[];
};
};
export default _default;
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {

@@ -34,38 +21,2 @@ if (k2 === undefined) k2 = k;

};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -75,339 +26,5 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

Object.defineProperty(exports, "__esModule", { value: true });
exports.Dereferencer = exports.InvalidRemoteURLError = exports.InvalidFileSystemPathError = exports.InvalidJsonPointerRefError = exports.NonJsonRefError = exports.NonStringRefError = exports.defaultDereferencerOptions = void 0;
var traverse_1 = __importDefault(require("@json-schema-tools/traverse"));
var dereferencer_1 = __importDefault(require("./dereferencer"));
var isomorphic_fetch_1 = __importDefault(require("isomorphic-fetch"));
var fs = __importStar(require("fs"));
var node_fetch_1 = __importDefault(require("node-fetch"));
var json_pointer_1 = __importDefault(require("@json-schema-spec/json-pointer"));
var path = __importStar(require("path"));
var fileExistsAndReadable = function (f) {
return new Promise(function (resolve) {
return fs.access(f, fs.constants.F_OK | fs.constants.R_OK, function (e) {
if (e) {
return resolve(false);
}
return resolve(true);
});
});
};
var readFile = function (f) {
return new Promise(function (resolve, reject) {
return fs.readFile(f, "utf8", function (err, data) {
if (err) {
return reject(err);
}
return resolve(data);
});
});
};
exports.defaultDereferencerOptions = {
recursive: true,
};
/**
* Error thrown by the constructor when given a ref that isn't a string
*
*
* @example
* ```typescript
*
* import Dereferencer, { NonStringRefError } from "@json-schema-tools/dereferencer";
*
* try { const dereffer = new Dereferencer({}); }
* catch(e) {
* if (e instanceof NonStringRefError) { ... }
* }
* ```
*
*/
var NonStringRefError = /** @class */ (function (_super) {
__extends(NonStringRefError, _super);
function NonStringRefError(schema) {
var _this = this;
var schemaString = "";
try {
schemaString = JSON.stringify(schema);
}
catch (e) {
schemaString = [
"Keys: " + Object.keys(schema),
"Respective Values: " + Object.values(schema),
].join("\n");
}
_this = _super.call(this, [
"NonStringRefError",
"Found an improperly formatted $ref in schema. $ref must be a string",
"schema in question: " + schemaString,
].join("\n")) || this;
return _this;
}
return NonStringRefError;
}(Error));
exports.NonStringRefError = NonStringRefError;
/**
* Error thrown when the fetched reference is not properly formatted JSON or is encoded
* incorrectly
*
* @example
* ```typescript
*
* import Dereferencer, { NonJsonRefError } from "@json-schema-tools/dereferencer";
* const dereffer = new Dereferencer({});
* try { await dereffer.resolve(); }
* catch(e) {
* if (e instanceof NonJsonRefError) { ... }
* }
* ```
*
*/
var NonJsonRefError = /** @class */ (function (_super) {
__extends(NonJsonRefError, _super);
function NonJsonRefError(schema, nonJson) {
return _super.call(this, [
"NonJsonRefError",
"The resolved value at the reference: " + schema.$ref + " was not JSON.parse 'able",
"The non-json content in question: " + nonJson,
].join("\n")) || this;
}
return NonJsonRefError;
}(Error));
exports.NonJsonRefError = NonJsonRefError;
/**
* Error thrown when a JSON pointer is provided but is not parseable as per the RFC6901
*
* @example
* ```typescript
*
* import Dereferencer, { InvalidJsonPointerRefError } from "@json-schema-tools/dereferencer";
* const dereffer = new Dereferencer({});
* try { await dereffer.resolve(); }
* catch(e) {
* if (e instanceof InvalidJsonPointerRefError) { ... }
* }
* ```
*
*/
var InvalidJsonPointerRefError = /** @class */ (function (_super) {
__extends(InvalidJsonPointerRefError, _super);
function InvalidJsonPointerRefError(schema) {
return _super.call(this, [
"InvalidJsonPointerRefError",
"The provided RFC6901 JSON Pointer is invalid: " + schema.$ref,
].join("\n")) || this;
}
return InvalidJsonPointerRefError;
}(Error));
exports.InvalidJsonPointerRefError = InvalidJsonPointerRefError;
/**
* Error thrown when given an invalid file system path as a reference.
*
* @example
* ```typescript
*
* import Dereferencer, { InvalidFileSystemPathError } from "@json-schema-tools/dereferencer";
* const dereffer = new Dereferencer({});
* try { await dereffer.resolve(); }
* catch(e) {
* if (e instanceof InvalidFileSystemPathError) { ... }
* }
* ```
*
*/
var InvalidFileSystemPathError = /** @class */ (function (_super) {
__extends(InvalidFileSystemPathError, _super);
function InvalidFileSystemPathError(ref) {
return _super.call(this, [
"InvalidFileSystemPathError",
"The path was not resolvable: " + ref,
"resolved path: " + path.resolve(process.cwd(), ref),
].join("\n")) || this;
}
return InvalidFileSystemPathError;
}(Error));
exports.InvalidFileSystemPathError = InvalidFileSystemPathError;
/**
* Error thrown when given an invalid file system path as a reference.
*
*/
var InvalidRemoteURLError = /** @class */ (function (_super) {
__extends(InvalidRemoteURLError, _super);
function InvalidRemoteURLError(ref) {
return _super.call(this, [
"InvalidRemoteURLError",
"The url was not resolvable: " + ref,
].join("\n")) || this;
}
return InvalidRemoteURLError;
}(Error));
exports.InvalidRemoteURLError = InvalidRemoteURLError;
/**
* When instantiated, represents a fully configured dereferencer. When constructed, references are pulled out.
* No references are fetched until .resolve is called.
*/
var Dereferencer = /** @class */ (function () {
function Dereferencer(schema, options) {
if (options === void 0) { options = exports.defaultDereferencerOptions; }
this.options = options;
this.refCache = {};
this.schema = schema; // shallow copy breaks recursive
this.refs = this.collectRefs();
}
/**
* Fetches the schemas for all the refs in the configured input schema(s)
*
* @returns a promise that will resolve a fully dereferenced schema, where all the
* promises for each ref has been resolved as well.
*
*
*/
Dereferencer.prototype.resolve = function () {
return __awaiter(this, void 0, void 0, function () {
var refMap, proms, _i, _a, ref, fetched, subDereffer, _b, subFetched, _c, _d, _e, _f, recurseResolve;
var _this = this;
return __generator(this, function (_g) {
switch (_g.label) {
case 0:
refMap = {};
if (this.schema === true || this.schema === false) {
return [2 /*return*/, Promise.resolve(this.schema)];
}
if (this.refs.length === 0) {
delete this.schema.definitions;
return [2 /*return*/, Promise.resolve(this.schema)];
}
proms = [];
_i = 0, _a = this.refs;
_g.label = 1;
case 1:
if (!(_i < _a.length)) return [3 /*break*/, 7];
ref = _a[_i];
fetched = this.fetchRef(ref);
proms.push(fetched);
if (!(this.options.recursive === true && ref[0] !== "#")) return [3 /*break*/, 4];
_b = Dereferencer.bind;
return [4 /*yield*/, fetched];
case 2:
subDereffer = new (_b.apply(Dereferencer, [void 0, _g.sent(), this.options]))();
subFetched = subDereffer.resolve();
proms.push(subFetched);
_c = refMap;
_d = ref;
return [4 /*yield*/, subFetched];
case 3:
_c[_d] = _g.sent();
return [3 /*break*/, 6];
case 4:
_e = refMap;
_f = ref;
return [4 /*yield*/, fetched];
case 5:
_e[_f] = _g.sent();
_g.label = 6;
case 6:
_i++;
return [3 /*break*/, 1];
case 7:
if (this.schema.$ref !== undefined) {
this.schema = refMap[this.schema.$ref];
}
else {
traverse_1.default(this.schema, function (s) {
if (s === true || s === false) {
return s;
}
if (s.$ref !== undefined) {
return refMap[s.$ref];
}
return s;
}, { mutable: true });
}
if (this.options.recursive === true) {
this.refs = this.collectRefs();
recurseResolve = this.resolve();
proms.push(recurseResolve);
}
return [2 /*return*/, Promise.all(proms).then(function () { return _this.schema; })];
}
});
});
};
Dereferencer.prototype.fetchRef = function (ref) {
return __awaiter(this, void 0, void 0, function () {
var withoutHash, pointer, reffedSchema, fileContents, reffedSchema, rs, _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
if (this.refCache[ref] !== undefined) {
return [2 /*return*/, Promise.resolve(this.refCache[ref])];
}
if (ref[0] === "#") {
withoutHash = ref.replace("#", "");
try {
pointer = json_pointer_1.default.parse(withoutHash);
reffedSchema = pointer.eval(this.schema);
this.refCache[ref] = reffedSchema;
return [2 /*return*/, Promise.resolve(reffedSchema)];
}
catch (e) {
throw new InvalidJsonPointerRefError({ $ref: ref });
}
}
return [4 /*yield*/, fileExistsAndReadable(ref)];
case 1:
if (!((_c.sent()) === true)) return [3 /*break*/, 3];
return [4 /*yield*/, readFile(ref)];
case 2:
fileContents = _c.sent();
reffedSchema = void 0;
try {
reffedSchema = JSON.parse(fileContents);
}
catch (e) {
throw new NonJsonRefError({ $ref: ref }, fileContents);
}
this.refCache[ref] = reffedSchema;
return [2 /*return*/, reffedSchema];
case 3:
if (["$", ".", "/", ".."].indexOf(ref[0]) !== -1) {
throw new InvalidFileSystemPathError(ref);
}
_c.label = 4;
case 4:
try {
rs = node_fetch_1.default(ref).then(function (r) { return r.json(); });
}
catch (e) {
throw new InvalidRemoteURLError(ref);
}
_a = this.refCache;
_b = ref;
return [4 /*yield*/, rs];
case 5:
_a[_b] = _c.sent();
return [2 /*return*/, rs];
}
});
});
};
/**
* First-pass traversal to collect all the refs that we can find. This allows us to
* optimize the async work required as well.
*/
Dereferencer.prototype.collectRefs = function () {
var refs = [];
traverse_1.default(this.schema, function (s) {
if (s === true || s === false) {
return s;
}
if (s.$ref && refs.indexOf(s.$ref) === -1) {
if (typeof s.$ref !== "string") {
throw new NonStringRefError(s);
}
refs.push(s.$ref);
}
return s;
});
return refs;
};
return Dereferencer;
}());
exports.Dereferencer = Dereferencer;
exports.default = Dereferencer;
exports.default = dereferencer_1.default(isomorphic_fetch_1.default, fs);

@@ -0,1 +1,8 @@

# [1.2.0](https://github.com/json-schema-tools/dereferencer/compare/1.1.0...1.2.0) (2020-07-22)
### Features
* isomorphic browser n node support ([0ef22b4](https://github.com/json-schema-tools/dereferencer/commit/0ef22b4687d3059f0cd68b142acff6e24a3f84cd))
# [1.1.0](https://github.com/json-schema-tools/dereferencer/compare/1.0.15...1.1.0) (2020-07-21)

@@ -2,0 +9,0 @@

{
"name": "@json-schema-tools/dereferencer",
"version": "1.1.0",
"version": "1.2.0",
"description": "Dereference (aka parse refs) from JSON Schemas",
"main": "build/index.js",
"browser": "build/index-web.js",
"publishConfig": {

@@ -10,5 +11,8 @@ "access": "public"

"scripts": {
"build": "tsc && typedoc --out docs && touch docs/.nojekyll",
"build": "npm run build:code && typedoc --out docs && touch docs/.nojekyll",
"build:code": "tsc",
"lint": "tslint --fix -p .",
"test": "npm run lint && jest --coverage"
"test": "npm run test:unit && npm run test:web",
"test:unit": "npm run lint && jest --coverage",
"test:web": "npm run build:code && webpack && rm -rf dist"
},

@@ -30,5 +34,5 @@ "author": "BelfordZ<belfordz66@gmail.com>",

"@json-schema-tools/meta-schema": "^1.3.0",
"@types/isomorphic-fetch": "0.0.35",
"@types/jest": "^26.0.3",
"@types/node": "^14.0.14",
"@types/node-fetch": "^2.5.7",
"jest": "^24.8.0",

@@ -38,3 +42,5 @@ "ts-jest": "^24.1.0",

"typedoc": "^0.17.8",
"typescript": "^3.9.6"
"typescript": "^3.9.6",
"webpack": "^4.31.0",
"webpack-cli": "^3.3.2"
},

@@ -44,4 +50,4 @@ "dependencies": {

"@json-schema-tools/traverse": "^1.4.2",
"node-fetch": "^2.6.0"
"isomorphic-fetch": "^2.2.1"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc