routie dev init since i didn't adhere to any proper guidance up until now
This commit is contained in:
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export default function convertPathToPosix(filePath: string): string;
|
||||
Generated
Vendored
+14
@@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.default = convertPathToPosix;
|
||||
const path_1 = __importDefault(require("path"));
|
||||
function convertPathToPosix(filePath) {
|
||||
const isExtendedLengthPath = filePath.startsWith("\\\\?\\");
|
||||
if (isExtendedLengthPath) {
|
||||
return filePath;
|
||||
}
|
||||
return filePath.split(path_1.default?.win32?.sep).join(path_1.default?.posix?.sep ?? "/");
|
||||
}
|
||||
Generated
Vendored
+73
@@ -0,0 +1,73 @@
|
||||
import type $RefParser from "../index.js";
|
||||
import type { ParserOptions } from "../index.js";
|
||||
import type { JSONSchema } from "../index.js";
|
||||
export type JSONParserErrorType = "EUNKNOWN" | "EPARSER" | "EUNMATCHEDPARSER" | "ETIMEOUT" | "ERESOLVER" | "EUNMATCHEDRESOLVER" | "EMISSINGPOINTER" | "EINVALIDPOINTER";
|
||||
/**
|
||||
* Custom JSON serializer for Error objects.
|
||||
* Returns all built-in error properties, as well as extended properties.
|
||||
*/
|
||||
export declare function toJSON<T extends Error>(this: T): Error & T;
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
export declare function getDeepKeys(obj: object, omit?: Array<string | symbol>): Set<string | symbol>;
|
||||
export declare class JSONParserError extends Error {
|
||||
readonly name: string;
|
||||
readonly message: string;
|
||||
source: string | undefined;
|
||||
path: Array<string | number> | null;
|
||||
readonly code: JSONParserErrorType;
|
||||
constructor(message: string, source?: string);
|
||||
toJSON: () => Error;
|
||||
get footprint(): string;
|
||||
}
|
||||
export declare class JSONParserErrorGroup<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>> extends Error {
|
||||
files: $RefParser<S, O>;
|
||||
constructor(parser: $RefParser<S, O>);
|
||||
toJSON: () => Error;
|
||||
static getParserErrors<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(parser: $RefParser<S, O>): JSONParserError[];
|
||||
get errors(): Array<JSONParserError | InvalidPointerError | ResolverError | ParserError | MissingPointerError | UnmatchedParserError | UnmatchedResolverError>;
|
||||
}
|
||||
export declare class ParserError extends JSONParserError {
|
||||
code: JSONParserErrorType;
|
||||
name: string;
|
||||
constructor(message: any, source: any);
|
||||
}
|
||||
export declare class UnmatchedParserError extends JSONParserError {
|
||||
code: JSONParserErrorType;
|
||||
name: string;
|
||||
constructor(source: string);
|
||||
}
|
||||
export declare class ResolverError extends JSONParserError {
|
||||
code: JSONParserErrorType;
|
||||
name: string;
|
||||
ioErrorCode?: string;
|
||||
constructor(ex: Error | any, source?: string);
|
||||
}
|
||||
export declare class UnmatchedResolverError extends JSONParserError {
|
||||
code: JSONParserErrorType;
|
||||
name: string;
|
||||
constructor(source: any);
|
||||
}
|
||||
export declare class MissingPointerError extends JSONParserError {
|
||||
code: JSONParserErrorType;
|
||||
name: string;
|
||||
targetToken: any;
|
||||
targetRef: string;
|
||||
targetFound: string;
|
||||
parentPath: string;
|
||||
constructor(token: any, path: any, targetRef: any, targetFound: any, parentPath: any);
|
||||
}
|
||||
export declare class TimeoutError extends JSONParserError {
|
||||
code: JSONParserErrorType;
|
||||
name: string;
|
||||
constructor(timeout: number);
|
||||
}
|
||||
export declare class InvalidPointerError extends JSONParserError {
|
||||
code: JSONParserErrorType;
|
||||
name: string;
|
||||
constructor(pointer: string, path: string);
|
||||
}
|
||||
export declare function isHandledError(err: any): err is JSONParserError;
|
||||
export declare function normalizeError(err: any): any;
|
||||
Generated
Vendored
+170
@@ -0,0 +1,170 @@
|
||||
"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 {
|
||||
name;
|
||||
message;
|
||||
source;
|
||||
path;
|
||||
code;
|
||||
constructor(message, source) {
|
||||
super();
|
||||
this.code = "EUNKNOWN";
|
||||
this.name = "JSONParserError";
|
||||
this.message = message;
|
||||
this.source = source;
|
||||
this.path = null;
|
||||
}
|
||||
toJSON = toJSON.bind(this);
|
||||
get footprint() {
|
||||
return `${this.path}+${this.source}+${this.code}+${this.message}`;
|
||||
}
|
||||
}
|
||||
exports.JSONParserError = JSONParserError;
|
||||
class JSONParserErrorGroup extends Error {
|
||||
files;
|
||||
constructor(parser) {
|
||||
super();
|
||||
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)}'`;
|
||||
}
|
||||
toJSON = toJSON.bind(this);
|
||||
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 {
|
||||
code = "EPARSER";
|
||||
name = "ParserError";
|
||||
constructor(message, source) {
|
||||
super(`Error parsing ${source}: ${message}`, source);
|
||||
}
|
||||
}
|
||||
exports.ParserError = ParserError;
|
||||
class UnmatchedParserError extends JSONParserError {
|
||||
code = "EUNMATCHEDPARSER";
|
||||
name = "UnmatchedParserError";
|
||||
constructor(source) {
|
||||
super(`Could not find parser for "${source}"`, source);
|
||||
}
|
||||
}
|
||||
exports.UnmatchedParserError = UnmatchedParserError;
|
||||
class ResolverError extends JSONParserError {
|
||||
code = "ERESOLVER";
|
||||
name = "ResolverError";
|
||||
ioErrorCode;
|
||||
constructor(ex, source) {
|
||||
super(ex.message || `Error reading file "${source}"`, source);
|
||||
if ("code" in ex) {
|
||||
this.ioErrorCode = String(ex.code);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.ResolverError = ResolverError;
|
||||
class UnmatchedResolverError extends JSONParserError {
|
||||
code = "EUNMATCHEDRESOLVER";
|
||||
name = "UnmatchedResolverError";
|
||||
constructor(source) {
|
||||
super(`Could not find resolver for "${source}"`, source);
|
||||
}
|
||||
}
|
||||
exports.UnmatchedResolverError = UnmatchedResolverError;
|
||||
class MissingPointerError extends JSONParserError {
|
||||
code = "EMISSINGPOINTER";
|
||||
name = "MissingPointerError";
|
||||
targetToken;
|
||||
targetRef;
|
||||
targetFound;
|
||||
parentPath;
|
||||
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.targetToken = token;
|
||||
this.targetRef = targetRef;
|
||||
this.targetFound = targetFound;
|
||||
this.parentPath = parentPath;
|
||||
}
|
||||
}
|
||||
exports.MissingPointerError = MissingPointerError;
|
||||
class TimeoutError extends JSONParserError {
|
||||
code = "ETIMEOUT";
|
||||
name = "TimeoutError";
|
||||
constructor(timeout) {
|
||||
super(`Dereferencing timeout reached: ${timeout}ms`);
|
||||
}
|
||||
}
|
||||
exports.TimeoutError = TimeoutError;
|
||||
class InvalidPointerError extends JSONParserError {
|
||||
code = "EUNMATCHEDRESOLVER";
|
||||
name = "InvalidPointerError";
|
||||
constructor(pointer, path) {
|
||||
super(`Invalid $ref pointer "${pointer}". Pointers must begin with "#/"`, (0, url_js_1.stripHash)(path));
|
||||
}
|
||||
}
|
||||
exports.InvalidPointerError = InvalidPointerError;
|
||||
function isHandledError(err) {
|
||||
return err instanceof JSONParserError || err instanceof JSONParserErrorGroup;
|
||||
}
|
||||
function normalizeError(err) {
|
||||
if (err.path === null) {
|
||||
err.path = [];
|
||||
}
|
||||
return err;
|
||||
}
|
||||
Generated
Vendored
+1
@@ -0,0 +1 @@
|
||||
export declare const isWindows: () => boolean;
|
||||
Generated
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.isWindows = void 0;
|
||||
const isWindowsConst = /^win/.test(globalThis.process ? globalThis.process.platform : "");
|
||||
const isWindows = () => isWindowsConst;
|
||||
exports.isWindows = isWindows;
|
||||
Generated
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
type MaybeParams<T> = (err: Error | any | null, result?: T) => void;
|
||||
export default function maybe<T>(cb: MaybeParams<T> | undefined, promise: Promise<T>): Promise<T> | void;
|
||||
export {};
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.default = maybe;
|
||||
const next_js_1 = __importDefault(require("./next.js"));
|
||||
function maybe(cb, promise) {
|
||||
if (cb) {
|
||||
promise.then(function (result) {
|
||||
(0, next_js_1.default)(function () {
|
||||
cb(null, result);
|
||||
});
|
||||
}, function (err) {
|
||||
(0, next_js_1.default)(function () {
|
||||
cb(err);
|
||||
});
|
||||
});
|
||||
return undefined;
|
||||
}
|
||||
else {
|
||||
return promise;
|
||||
}
|
||||
}
|
||||
Generated
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
declare const _default: (callback: Function, ...args: any[]) => void;
|
||||
export default _default;
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
function makeNext() {
|
||||
if (typeof process === "object" && typeof process.nextTick === "function") {
|
||||
return process.nextTick;
|
||||
}
|
||||
else if (typeof setImmediate === "function") {
|
||||
return setImmediate;
|
||||
}
|
||||
else {
|
||||
return function next(f) {
|
||||
setTimeout(f, 0);
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.default = makeNext();
|
||||
Generated
Vendored
+34
@@ -0,0 +1,34 @@
|
||||
import type { FileInfo, JSONSchema } from "../types/index.js";
|
||||
import type { ParserOptions } from "../options.js";
|
||||
import type { ResolverOptions } from "../types/index.js";
|
||||
import type $Refs from "../refs.js";
|
||||
import type { Plugin } from "../types/index.js";
|
||||
/**
|
||||
* Returns the given plugins as an array, rather than an object map.
|
||||
* All other methods in this module expect an array of plugins rather than an object map.
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
export declare function all<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(plugins: O["resolve"]): Plugin[];
|
||||
/**
|
||||
* Filters the given plugins, returning only the ones return `true` for the given method.
|
||||
*/
|
||||
export declare function filter(plugins: Plugin[], method: any, file: any): Plugin[];
|
||||
/**
|
||||
* Sorts the given plugins, in place, by their `order` property.
|
||||
*/
|
||||
export declare function sort(plugins: Plugin[]): Plugin[];
|
||||
export interface PluginResult<S extends object = JSONSchema> {
|
||||
plugin: Plugin;
|
||||
result?: string | Buffer | S;
|
||||
error?: any;
|
||||
}
|
||||
/**
|
||||
* Runs the specified method of the given plugins, in order, until one of them returns a successful result.
|
||||
* Each method can return a synchronous value, a Promise, or call an error-first callback.
|
||||
* If the promise resolves successfully, or the callback is called without an error, then the result
|
||||
* is immediately returned and no further plugins are called.
|
||||
* If the promise rejects, or the callback is called with an error, then the next plugin is called.
|
||||
* If ALL plugins fail, then the last error is thrown.
|
||||
*/
|
||||
export declare function run<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(plugins: Plugin[], method: keyof Plugin | keyof ResolverOptions<S>, file: FileInfo, $refs: $Refs<S, O>): Promise<PluginResult<S>>;
|
||||
Generated
Vendored
+132
@@ -0,0 +1,132 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.all = all;
|
||||
exports.filter = filter;
|
||||
exports.sort = sort;
|
||||
exports.run = run;
|
||||
/**
|
||||
* Returns the given plugins as an array, rather than an object map.
|
||||
* All other methods in this module expect an array of plugins rather than an object map.
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
function all(plugins) {
|
||||
return Object.keys(plugins || {})
|
||||
.filter((key) => {
|
||||
return typeof plugins[key] === "object";
|
||||
})
|
||||
.map((key) => {
|
||||
plugins[key].name = key;
|
||||
return plugins[key];
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Filters the given plugins, returning only the ones return `true` for the given method.
|
||||
*/
|
||||
function filter(plugins, method, file) {
|
||||
return plugins.filter((plugin) => {
|
||||
return !!getResult(plugin, method, file);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Sorts the given plugins, in place, by their `order` property.
|
||||
*/
|
||||
function sort(plugins) {
|
||||
for (const plugin of plugins) {
|
||||
plugin.order = plugin.order || Number.MAX_SAFE_INTEGER;
|
||||
}
|
||||
return plugins.sort((a, b) => {
|
||||
return a.order - b.order;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Runs the specified method of the given plugins, in order, until one of them returns a successful result.
|
||||
* Each method can return a synchronous value, a Promise, or call an error-first callback.
|
||||
* If the promise resolves successfully, or the callback is called without an error, then the result
|
||||
* is immediately returned and no further plugins are called.
|
||||
* If the promise rejects, or the callback is called with an error, then the next plugin is called.
|
||||
* If ALL plugins fail, then the last error is thrown.
|
||||
*/
|
||||
async function run(plugins, method, file, $refs) {
|
||||
let plugin;
|
||||
let lastError;
|
||||
let index = 0;
|
||||
return new Promise((resolve, reject) => {
|
||||
runNextPlugin();
|
||||
function runNextPlugin() {
|
||||
plugin = plugins[index++];
|
||||
if (!plugin) {
|
||||
// There are no more functions, so re-throw the last error
|
||||
return reject(lastError);
|
||||
}
|
||||
try {
|
||||
// console.log(' %s', plugin.name);
|
||||
const result = getResult(plugin, method, file, callback, $refs);
|
||||
if (result && typeof result.then === "function") {
|
||||
// A promise was returned
|
||||
result.then(onSuccess, onError);
|
||||
}
|
||||
else if (result !== undefined) {
|
||||
// A synchronous result was returned
|
||||
onSuccess(result);
|
||||
}
|
||||
else if (index === plugins.length) {
|
||||
throw new Error("No promise has been returned or callback has been called.");
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
onError(e);
|
||||
}
|
||||
}
|
||||
function callback(err, result) {
|
||||
if (err) {
|
||||
onError(err);
|
||||
}
|
||||
else {
|
||||
onSuccess(result);
|
||||
}
|
||||
}
|
||||
function onSuccess(result) {
|
||||
// console.log(' success');
|
||||
resolve({
|
||||
plugin,
|
||||
result: result,
|
||||
});
|
||||
}
|
||||
function onError(error) {
|
||||
// console.log(' %s', err.message || err);
|
||||
lastError = {
|
||||
plugin,
|
||||
error,
|
||||
};
|
||||
runNextPlugin();
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Returns the value of the given property.
|
||||
* If the property is a function, then the result of the function is returned.
|
||||
* If the value is a RegExp, then it will be tested against the file URL.
|
||||
* If the value is an array, then it will be compared against the file extension.
|
||||
*/
|
||||
function getResult(obj, prop, file, callback, $refs) {
|
||||
const value = obj[prop];
|
||||
if (typeof value === "function") {
|
||||
return value.apply(obj, [file, callback, $refs]);
|
||||
}
|
||||
if (!callback) {
|
||||
// The synchronous plugin functions (canParse and canRead)
|
||||
// allow a "shorthand" syntax, where the user can match
|
||||
// files by RegExp or by file extension.
|
||||
if (value instanceof RegExp) {
|
||||
return value.test(file.url);
|
||||
}
|
||||
else if (typeof value === "string") {
|
||||
return value === file.extension;
|
||||
}
|
||||
else if (Array.isArray(value)) {
|
||||
return value.indexOf(file.extension) !== -1;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
export declare const parse: (u: string | URL) => URL;
|
||||
/**
|
||||
* Returns resolved target URL relative to a base URL in a manner similar to that of a Web browser resolving an anchor tag HREF.
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
export declare function resolve(from: string, to: string): string;
|
||||
/**
|
||||
* Returns the current working directory (in Node) or the current page URL (in browsers).
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
export declare function cwd(): string;
|
||||
/**
|
||||
* Returns the protocol of the given URL, or `undefined` if it has no protocol.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
export declare function getProtocol(path: string | undefined): string | undefined;
|
||||
/**
|
||||
* Returns the lowercased file extension of the given URL,
|
||||
* or an empty string if it has no extension.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
export declare function getExtension(path: any): any;
|
||||
/**
|
||||
* Removes the query, if any, from the given path.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
export declare function stripQuery(path: any): any;
|
||||
/**
|
||||
* Returns the hash (URL fragment), of the given path.
|
||||
* If there is no hash, then the root hash ("#") is returned.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
export declare function getHash(path: undefined | string): string;
|
||||
/**
|
||||
* Removes the hash (URL fragment), if any, from the given path.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
export declare function stripHash(path?: string | undefined): string;
|
||||
/**
|
||||
* Determines whether the given path is an HTTP(S) URL.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
export declare function isHttp(path: string): boolean;
|
||||
/**
|
||||
* Determines whether the given url is an unsafe or internal url.
|
||||
*
|
||||
* @param path - The URL or path to check
|
||||
* @returns true if the URL is unsafe/internal, false otherwise
|
||||
*/
|
||||
export declare function isUnsafeUrl(path: string | unknown): boolean;
|
||||
/**
|
||||
* Determines whether the given path is a filesystem path.
|
||||
* This includes "file://" URLs.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
export declare function isFileSystemPath(path: string | undefined): boolean;
|
||||
/**
|
||||
* Converts a filesystem path to a properly-encoded URL.
|
||||
*
|
||||
* This is intended to handle situations where JSON Schema $Ref Parser is called
|
||||
* with a filesystem path that contains characters which are not allowed in URLs.
|
||||
*
|
||||
* @example
|
||||
* The following filesystem paths would be converted to the following URLs:
|
||||
*
|
||||
* <"!@#$%^&*+=?'>.json ==> %3C%22!@%23$%25%5E&*+=%3F\'%3E.json
|
||||
* C:\\My Documents\\File (1).json ==> C:/My%20Documents/File%20(1).json
|
||||
* file://Project #42/file.json ==> file://Project%20%2342/file.json
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
export declare function fromFileSystemPath(path: string): string;
|
||||
/**
|
||||
* Converts a URL to a local filesystem path.
|
||||
*/
|
||||
export declare function toFileSystemPath(path: string | undefined, keepFileProtocol?: boolean): string;
|
||||
/**
|
||||
* Converts a $ref pointer to a valid JSON Path.
|
||||
*
|
||||
* @param pointer
|
||||
* @returns
|
||||
*/
|
||||
export declare function safePointerToPath(pointer: any): any;
|
||||
export declare function relative(from: string, to: string): string;
|
||||
+491
@@ -0,0 +1,491 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || (function () {
|
||||
var ownKeys = function(o) {
|
||||
ownKeys = Object.getOwnPropertyNames || function (o) {
|
||||
var ar = [];
|
||||
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
||||
return ar;
|
||||
};
|
||||
return ownKeys(o);
|
||||
};
|
||||
return function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parse = void 0;
|
||||
exports.resolve = resolve;
|
||||
exports.cwd = cwd;
|
||||
exports.getProtocol = getProtocol;
|
||||
exports.getExtension = getExtension;
|
||||
exports.stripQuery = stripQuery;
|
||||
exports.getHash = getHash;
|
||||
exports.stripHash = stripHash;
|
||||
exports.isHttp = isHttp;
|
||||
exports.isUnsafeUrl = isUnsafeUrl;
|
||||
exports.isFileSystemPath = isFileSystemPath;
|
||||
exports.fromFileSystemPath = fromFileSystemPath;
|
||||
exports.toFileSystemPath = toFileSystemPath;
|
||||
exports.safePointerToPath = safePointerToPath;
|
||||
exports.relative = relative;
|
||||
const convert_path_to_posix_1 = __importDefault(require("./convert-path-to-posix"));
|
||||
const path_1 = __importStar(require("path"));
|
||||
const forwardSlashPattern = /\//g;
|
||||
const protocolPattern = /^(\w{2,}):\/\//i;
|
||||
const jsonPointerSlash = /~1/g;
|
||||
const jsonPointerTilde = /~0/g;
|
||||
const path_2 = require("path");
|
||||
const is_windows_1 = require("./is-windows");
|
||||
// RegExp patterns to URL-encode special characters in local filesystem paths
|
||||
const urlEncodePatterns = [
|
||||
[/\?/g, "%3F"],
|
||||
[/#/g, "%23"],
|
||||
];
|
||||
// RegExp patterns to URL-decode special characters for local filesystem paths
|
||||
const urlDecodePatterns = [/%23/g, "#", /%24/g, "$", /%26/g, "&", /%2C/g, ",", /%40/g, "@"];
|
||||
const parse = (u) => new URL(u);
|
||||
exports.parse = parse;
|
||||
/**
|
||||
* Returns resolved target URL relative to a base URL in a manner similar to that of a Web browser resolving an anchor tag HREF.
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
function resolve(from, to) {
|
||||
// we use a non-existent URL to check if its a relative URL
|
||||
const fromUrl = new URL((0, convert_path_to_posix_1.default)(from), "https://aaa.nonexistanturl.com");
|
||||
const resolvedUrl = new URL((0, convert_path_to_posix_1.default)(to), fromUrl);
|
||||
const endSpaces = to.match(/(\s*)$/)?.[1] || "";
|
||||
if (resolvedUrl.hostname === "aaa.nonexistanturl.com") {
|
||||
// `from` is a relative URL.
|
||||
const { pathname, search, hash } = resolvedUrl;
|
||||
return pathname + search + hash + endSpaces;
|
||||
}
|
||||
return resolvedUrl.toString() + endSpaces;
|
||||
}
|
||||
/**
|
||||
* Returns the current working directory (in Node) or the current page URL (in browsers).
|
||||
*
|
||||
* @returns
|
||||
*/
|
||||
function cwd() {
|
||||
if (typeof window !== "undefined" && window.location && window.location.href) {
|
||||
const href = window.location.href;
|
||||
if (!href || !href.startsWith("http")) {
|
||||
// try parsing as url, and if it fails, return root url /
|
||||
try {
|
||||
new URL(href);
|
||||
return href;
|
||||
}
|
||||
catch {
|
||||
return "/";
|
||||
}
|
||||
}
|
||||
return href;
|
||||
}
|
||||
if (typeof process !== "undefined" && process.cwd) {
|
||||
const path = process.cwd();
|
||||
const lastChar = path.slice(-1);
|
||||
if (lastChar === "/" || lastChar === "\\") {
|
||||
return path;
|
||||
}
|
||||
else {
|
||||
return path + "/";
|
||||
}
|
||||
}
|
||||
return "/";
|
||||
}
|
||||
/**
|
||||
* Returns the protocol of the given URL, or `undefined` if it has no protocol.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
function getProtocol(path) {
|
||||
const match = protocolPattern.exec(path || "");
|
||||
if (match) {
|
||||
return match[1].toLowerCase();
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
/**
|
||||
* Returns the lowercased file extension of the given URL,
|
||||
* or an empty string if it has no extension.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
function getExtension(path) {
|
||||
const lastDot = path.lastIndexOf(".");
|
||||
if (lastDot >= 0) {
|
||||
return stripQuery(path.substring(lastDot).toLowerCase());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
/**
|
||||
* Removes the query, if any, from the given path.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
function stripQuery(path) {
|
||||
const queryIndex = path.indexOf("?");
|
||||
if (queryIndex >= 0) {
|
||||
path = path.substring(0, queryIndex);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
/**
|
||||
* Returns the hash (URL fragment), of the given path.
|
||||
* If there is no hash, then the root hash ("#") is returned.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
function getHash(path) {
|
||||
if (!path) {
|
||||
return "#";
|
||||
}
|
||||
const hashIndex = path.indexOf("#");
|
||||
if (hashIndex >= 0) {
|
||||
return path.substring(hashIndex);
|
||||
}
|
||||
return "#";
|
||||
}
|
||||
/**
|
||||
* Removes the hash (URL fragment), if any, from the given path.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
function stripHash(path) {
|
||||
if (!path) {
|
||||
return "";
|
||||
}
|
||||
const hashIndex = path.indexOf("#");
|
||||
if (hashIndex >= 0) {
|
||||
path = path.substring(0, hashIndex);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
/**
|
||||
* Determines whether the given path is an HTTP(S) URL.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
function isHttp(path) {
|
||||
const protocol = getProtocol(path);
|
||||
if (protocol === "http" || protocol === "https") {
|
||||
return true;
|
||||
}
|
||||
else if (protocol === undefined) {
|
||||
// There is no protocol. If we're running in a browser, then assume it's HTTP.
|
||||
return typeof window !== "undefined";
|
||||
}
|
||||
else {
|
||||
// It's some other protocol, such as "ftp://", "mongodb://", etc.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Determines whether the given url is an unsafe or internal url.
|
||||
*
|
||||
* @param path - The URL or path to check
|
||||
* @returns true if the URL is unsafe/internal, false otherwise
|
||||
*/
|
||||
function isUnsafeUrl(path) {
|
||||
if (!path || typeof path !== "string") {
|
||||
return true;
|
||||
}
|
||||
// Trim whitespace and convert to lowercase for comparison
|
||||
const normalizedPath = path.trim().toLowerCase();
|
||||
// Empty or just whitespace
|
||||
if (!normalizedPath) {
|
||||
return true;
|
||||
}
|
||||
// JavaScript protocols
|
||||
if (normalizedPath.startsWith("javascript:") ||
|
||||
normalizedPath.startsWith("vbscript:") ||
|
||||
normalizedPath.startsWith("data:")) {
|
||||
return true;
|
||||
}
|
||||
// File protocol
|
||||
if (normalizedPath.startsWith("file:")) {
|
||||
return true;
|
||||
}
|
||||
// if we're in the browser, we assume that it is safe
|
||||
if (typeof window !== "undefined" && window.location && window.location.href) {
|
||||
return false;
|
||||
}
|
||||
// Local/internal network addresses
|
||||
const localPatterns = [
|
||||
// Localhost variations
|
||||
"localhost",
|
||||
"127.0.0.1",
|
||||
"::1",
|
||||
// Private IP ranges (RFC 1918)
|
||||
"10.",
|
||||
"172.16.",
|
||||
"172.17.",
|
||||
"172.18.",
|
||||
"172.19.",
|
||||
"172.20.",
|
||||
"172.21.",
|
||||
"172.22.",
|
||||
"172.23.",
|
||||
"172.24.",
|
||||
"172.25.",
|
||||
"172.26.",
|
||||
"172.27.",
|
||||
"172.28.",
|
||||
"172.29.",
|
||||
"172.30.",
|
||||
"172.31.",
|
||||
"192.168.",
|
||||
// Link-local addresses
|
||||
"169.254.",
|
||||
// Internal domains
|
||||
".local",
|
||||
".internal",
|
||||
".intranet",
|
||||
".corp",
|
||||
".home",
|
||||
".lan",
|
||||
];
|
||||
try {
|
||||
// Try to parse as URL
|
||||
const url = new URL(normalizedPath.startsWith("//") ? "http:" + normalizedPath : normalizedPath);
|
||||
const hostname = url.hostname.toLowerCase();
|
||||
// Check against local patterns
|
||||
for (const pattern of localPatterns) {
|
||||
if (hostname === pattern || hostname.startsWith(pattern) || hostname.endsWith(pattern)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Check for IP addresses in private ranges
|
||||
if (isPrivateIP(hostname)) {
|
||||
return true;
|
||||
}
|
||||
// Check for non-standard ports that might indicate internal services
|
||||
const port = url.port;
|
||||
if (port && isInternalPort(parseInt(port))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch {
|
||||
// If URL parsing fails, check if it's a relative path or contains suspicious patterns
|
||||
// Relative paths starting with / are generally safe for same-origin
|
||||
if (normalizedPath.startsWith("/") && !normalizedPath.startsWith("//")) {
|
||||
return false;
|
||||
}
|
||||
// Check for localhost patterns in non-URL strings
|
||||
for (const pattern of localPatterns) {
|
||||
if (normalizedPath.includes(pattern)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Helper function to check if an IP address is in a private range
|
||||
*/
|
||||
function isPrivateIP(ip) {
|
||||
const ipRegex = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
||||
const match = ip.match(ipRegex);
|
||||
if (!match) {
|
||||
return false;
|
||||
}
|
||||
const [, a, b, c, d] = match.map(Number);
|
||||
// Validate IP format
|
||||
if (a > 255 || b > 255 || c > 255 || d > 255) {
|
||||
return false;
|
||||
}
|
||||
// Private IP ranges
|
||||
return (a === 10 || a === 127 || (a === 172 && b >= 16 && b <= 31) || (a === 192 && b === 168) || (a === 169 && b === 254) // Link-local
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Helper function to check if a port is typically used for internal services
|
||||
*/
|
||||
function isInternalPort(port) {
|
||||
const internalPorts = [
|
||||
22, // SSH
|
||||
23, // Telnet
|
||||
25, // SMTP
|
||||
53, // DNS
|
||||
135, // RPC
|
||||
139, // NetBIOS
|
||||
445, // SMB
|
||||
993, // IMAPS
|
||||
995, // POP3S
|
||||
1433, // SQL Server
|
||||
1521, // Oracle
|
||||
3306, // MySQL
|
||||
3389, // RDP
|
||||
5432, // PostgreSQL
|
||||
5900, // VNC
|
||||
6379, // Redis
|
||||
8080, // Common internal web
|
||||
8443, // Common internal HTTPS
|
||||
9200, // Elasticsearch
|
||||
27017, // MongoDB
|
||||
];
|
||||
return internalPorts.includes(port);
|
||||
}
|
||||
/**
|
||||
* Determines whether the given path is a filesystem path.
|
||||
* This includes "file://" URLs.
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
function isFileSystemPath(path) {
|
||||
// @ts-ignore
|
||||
if (typeof window !== "undefined" || (typeof process !== "undefined" && process.browser)) {
|
||||
// We're running in a browser, so assume that all paths are URLs.
|
||||
// This way, even relative paths will be treated as URLs rather than as filesystem paths
|
||||
return false;
|
||||
}
|
||||
const protocol = getProtocol(path);
|
||||
return protocol === undefined || protocol === "file";
|
||||
}
|
||||
/**
|
||||
* Converts a filesystem path to a properly-encoded URL.
|
||||
*
|
||||
* This is intended to handle situations where JSON Schema $Ref Parser is called
|
||||
* with a filesystem path that contains characters which are not allowed in URLs.
|
||||
*
|
||||
* @example
|
||||
* The following filesystem paths would be converted to the following URLs:
|
||||
*
|
||||
* <"!@#$%^&*+=?'>.json ==> %3C%22!@%23$%25%5E&*+=%3F\'%3E.json
|
||||
* C:\\My Documents\\File (1).json ==> C:/My%20Documents/File%20(1).json
|
||||
* file://Project #42/file.json ==> file://Project%20%2342/file.json
|
||||
*
|
||||
* @param path
|
||||
* @returns
|
||||
*/
|
||||
function fromFileSystemPath(path) {
|
||||
// Step 1: On Windows, replace backslashes with forward slashes,
|
||||
// rather than encoding them as "%5C"
|
||||
if ((0, is_windows_1.isWindows)()) {
|
||||
const projectDir = cwd();
|
||||
const upperPath = path.toUpperCase();
|
||||
const projectDirPosixPath = (0, convert_path_to_posix_1.default)(projectDir);
|
||||
const posixUpper = projectDirPosixPath.toUpperCase();
|
||||
const hasProjectDir = upperPath.includes(posixUpper);
|
||||
const hasProjectUri = upperPath.includes(posixUpper);
|
||||
const isAbsolutePath = path_1.win32?.isAbsolute(path) ||
|
||||
path.startsWith("http://") ||
|
||||
path.startsWith("https://") ||
|
||||
path.startsWith("file://");
|
||||
if (!(hasProjectDir || hasProjectUri || isAbsolutePath) && !projectDir.startsWith("http")) {
|
||||
path = (0, path_2.join)(projectDir, path);
|
||||
}
|
||||
path = (0, convert_path_to_posix_1.default)(path);
|
||||
}
|
||||
// Step 2: `encodeURI` will take care of MOST characters
|
||||
path = encodeURI(path);
|
||||
// Step 3: Manually encode characters that are not encoded by `encodeURI`.
|
||||
// This includes characters such as "#" and "?", which have special meaning in URLs,
|
||||
// but are just normal characters in a filesystem path.
|
||||
for (const pattern of urlEncodePatterns) {
|
||||
path = path.replace(pattern[0], pattern[1]);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
/**
|
||||
* Converts a URL to a local filesystem path.
|
||||
*/
|
||||
function toFileSystemPath(path, keepFileProtocol) {
|
||||
// Step 1: `decodeURI` will decode characters such as Cyrillic characters, spaces, etc.
|
||||
path = decodeURI(path);
|
||||
// Step 2: Manually decode characters that are not decoded by `decodeURI`.
|
||||
// This includes characters such as "#" and "?", which have special meaning in URLs,
|
||||
// but are just normal characters in a filesystem path.
|
||||
for (let i = 0; i < urlDecodePatterns.length; i += 2) {
|
||||
path = path.replace(urlDecodePatterns[i], urlDecodePatterns[i + 1]);
|
||||
}
|
||||
// Step 3: If it's a "file://" URL, then format it consistently
|
||||
// or convert it to a local filesystem path
|
||||
let isFileUrl = path.toLowerCase().startsWith("file://");
|
||||
if (isFileUrl) {
|
||||
// Strip-off the protocol, and the initial "/", if there is one
|
||||
path = path.replace(/^file:\/\//, "").replace(/^\//, "");
|
||||
// insert a colon (":") after the drive letter on Windows
|
||||
if ((0, is_windows_1.isWindows)() && path[1] === "/") {
|
||||
path = `${path[0]}:${path.substring(1)}`;
|
||||
}
|
||||
if (keepFileProtocol) {
|
||||
// Return the consistently-formatted "file://" URL
|
||||
path = "file:///" + path;
|
||||
}
|
||||
else {
|
||||
// Convert the "file://" URL to a local filesystem path.
|
||||
// On Windows, it will start with something like "C:/".
|
||||
// On Posix, it will start with "/"
|
||||
isFileUrl = false;
|
||||
path = (0, is_windows_1.isWindows)() ? path : "/" + path;
|
||||
}
|
||||
}
|
||||
// Step 4: Normalize Windows paths (unless it's a "file://" URL)
|
||||
if ((0, is_windows_1.isWindows)() && !isFileUrl) {
|
||||
// Replace forward slashes with backslashes
|
||||
path = path.replace(forwardSlashPattern, "\\");
|
||||
// Capitalize the drive letter
|
||||
if (path.match(/^[a-z]:\\/i)) {
|
||||
path = path[0].toUpperCase() + path.substring(1);
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
/**
|
||||
* Converts a $ref pointer to a valid JSON Path.
|
||||
*
|
||||
* @param pointer
|
||||
* @returns
|
||||
*/
|
||||
function safePointerToPath(pointer) {
|
||||
if (pointer.length <= 1 || pointer[0] !== "#" || pointer[1] !== "/") {
|
||||
return [];
|
||||
}
|
||||
return pointer
|
||||
.slice(2)
|
||||
.split("/")
|
||||
.map((value) => {
|
||||
return decodeURIComponent(value).replace(jsonPointerSlash, "/").replace(jsonPointerTilde, "~");
|
||||
});
|
||||
}
|
||||
function relative(from, to) {
|
||||
if (!isFileSystemPath(from) || !isFileSystemPath(to)) {
|
||||
return resolve(from, to);
|
||||
}
|
||||
const fromDir = path_1.default.dirname(stripHash(from));
|
||||
const toPath = stripHash(to);
|
||||
const result = path_1.default.relative(fromDir, toPath);
|
||||
return result + getHash(to);
|
||||
}
|
||||
Reference in New Issue
Block a user