@apidevtools/json-schema-ref-parser 10.1.0 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,9 +15,5 @@ exports.default = (0, config_1.defineConfig)({
15
15
  passWithNoTests: true,
16
16
  reporters: ["verbose"],
17
17
  coverage: { reporter: ["lcov", "html", "text"] },
18
- deps: {
19
- fallbackCJS: true,
20
- registerNodeLoader: true,
21
- },
22
18
  },
23
19
  });
package/lib/bundle.ts CHANGED
@@ -94,6 +94,7 @@ function crawl(
94
94
  * @param $refParent - The object that contains a JSON Reference as one of its keys
95
95
  * @param $refKey - The key in `$refParent` that is a JSON Reference
96
96
  * @param path - The full path of the JSON Reference at `$refKey`, possibly with a JSON Pointer in the hash
97
+ * @param indirections - unknown
97
98
  * @param pathFromRoot - The path of the JSON Reference at `$refKey`, from the schema root
98
99
  * @param inventory - An array of already-inventoried $ref pointers
99
100
  * @param $refs
package/lib/ref.ts CHANGED
@@ -4,7 +4,6 @@ import { InvalidPointerError, isHandledError, normalizeError } from "./util/erro
4
4
  import { safePointerToPath, stripHash, getHash } from "./util/url.js";
5
5
  import type $Refs from "./refs.js";
6
6
  import type $RefParserOptions from "./options.js";
7
- import type { JSONSchema } from "./types";
8
7
 
9
8
  type $RefError = JSONParserError | ResolverError | ParserError | MissingPointerError;
10
9
 
@@ -167,7 +166,7 @@ class $Ref {
167
166
  * @param value - The value to inspect
168
167
  * @returns
169
168
  */
170
- static isExternal$Ref(value: any): value is JSONSchema {
169
+ static isExternal$Ref(value: any): boolean {
171
170
  return $Ref.is$Ref(value) && value.$ref![0] !== "#";
172
171
  }
173
172
 
package/lib/refs.ts CHANGED
@@ -4,9 +4,7 @@ import * as url from "./util/url.js";
4
4
  import type { JSONSchema4Type, JSONSchema6Type, JSONSchema7Type } from "json-schema";
5
5
  import type { JSONSchema } from "./types/index.js";
6
6
  import type $RefParserOptions from "./options.js";
7
-
8
- const isWindows = /^win/.test(globalThis.process ? globalThis.process.platform : "");
9
- const getPathFromOs = (filePath: string): string => (isWindows ? filePath.replace(/\\/g, "/") : filePath);
7
+ import convertPathToPosix from "./util/convert-path-to-posix";
10
8
 
11
9
  interface $RefsMap {
12
10
  [url: string]: $Ref;
@@ -36,7 +34,7 @@ export default class $Refs {
36
34
  paths(...types: string[]): string[] {
37
35
  const paths = getPaths(this._$refs, types);
38
36
  return paths.map((path) => {
39
- return getPathFromOs(path.decoded);
37
+ return convertPathToPosix(path.decoded);
40
38
  });
41
39
  }
42
40
 
@@ -51,7 +49,7 @@ export default class $Refs {
51
49
  const $refs = this._$refs;
52
50
  const paths = getPaths($refs, types);
53
51
  return paths.reduce<Record<string, any>>((obj, path) => {
54
- obj[getPathFromOs(path.decoded)] = $refs[path.encoded].value;
52
+ obj[convertPathToPosix(path.decoded)] = $refs[path.encoded].value;
55
53
  return obj;
56
54
  }, {});
57
55
  }
@@ -40,6 +40,7 @@ function resolveExternal(parser: $RefParser, options: Options) {
40
40
  *
41
41
  * @param obj - The value to crawl. If it's not an object or array, it will be ignored.
42
42
  * @param path - The full path of `obj`, possibly with a JSON Pointer in the hash
43
+ * @param {boolean} external - Whether `obj` was found in an external document.
43
44
  * @param $refs
44
45
  * @param options
45
46
  * @param seen - Internal.
@@ -56,6 +57,7 @@ function crawl(
56
57
  $refs: $Refs,
57
58
  options: Options,
58
59
  seen?: Set<any>,
60
+ external?: boolean,
59
61
  ) {
60
62
  seen ||= new Set();
61
63
  let promises: any = [];
@@ -64,17 +66,13 @@ function crawl(
64
66
  seen.add(obj); // Track previously seen objects to avoid infinite recursion
65
67
  if ($Ref.isExternal$Ref(obj)) {
66
68
  promises.push(resolve$Ref(obj, path, $refs, options));
67
- } else {
68
- for (const key of Object.keys(obj)) {
69
- const keyPath = Pointer.join(path, key);
70
- const value = obj[key] as string | JSONSchema | Buffer | undefined;
71
-
72
- if ($Ref.isExternal$Ref(value)) {
73
- promises.push(resolve$Ref(value, keyPath, $refs, options));
74
- } else {
75
- promises = promises.concat(crawl(value, keyPath, $refs, options, seen));
76
- }
77
- }
69
+ }
70
+
71
+ const keys = Object.keys(obj) as (keyof typeof obj)[];
72
+ for (const key of keys) {
73
+ const keyPath = Pointer.join(path, key);
74
+ const value = obj[key] as string | JSONSchema | Buffer | undefined;
75
+ promises = promises.concat(crawl(value, keyPath, $refs, options, seen, external));
78
76
  }
79
77
  }
80
78
 
@@ -99,6 +97,8 @@ async function resolve$Ref($ref: JSONSchema, path: string, $refs: $Refs, options
99
97
  const resolvedPath = url.resolve(path, $ref.$ref);
100
98
  const withoutHash = url.stripHash(resolvedPath);
101
99
 
100
+ // $ref.$ref = url.relative($refs._root$Ref.path, resolvedPath);
101
+
102
102
  // Do we already have this $ref?
103
103
  $ref = $refs._$refs[withoutHash];
104
104
  if ($ref) {
@@ -112,7 +112,7 @@ async function resolve$Ref($ref: JSONSchema, path: string, $refs: $Refs, options
112
112
 
113
113
  // Crawl the parsed value
114
114
  // console.log('Resolving $ref pointers in %s', withoutHash);
115
- const promises = crawl(result, withoutHash + "#", $refs, options);
115
+ const promises = crawl(result, withoutHash + "#", $refs, options, new Set(), true);
116
116
 
117
117
  return Promise.all(promises);
118
118
  } catch (err) {
@@ -1,4 +1,4 @@
1
- import fs from "fs/promises";
1
+ import { promises as fs } from "fs";
2
2
  import { ono } from "@jsdevtools/ono";
3
3
  import * as url from "../util/url.js";
4
4
  import { ResolverError } from "../util/errors.js";
@@ -0,0 +1,11 @@
1
+ import path from "path";
2
+
3
+ export default function convertPathToPosix(filePath: string) {
4
+ const isExtendedLengthPath = filePath.startsWith("\\\\?\\");
5
+
6
+ if (isExtendedLengthPath) {
7
+ return filePath;
8
+ }
9
+
10
+ return filePath.split(path.win32.sep).join(path.posix.sep);
11
+ }
@@ -0,0 +1,2 @@
1
+ const isWindowsConst = /^win/.test(globalThis.process ? globalThis.process.platform : "");
2
+ export const isWindows = () => isWindowsConst;
package/lib/util/url.ts CHANGED
@@ -1,9 +1,13 @@
1
- const isWindows = /^win/.test(globalThis.process ? globalThis.process.platform : ""),
2
- forwardSlashPattern = /\//g,
3
- protocolPattern = /^(\w{2,}):\/\//i,
4
- jsonPointerSlash = /~1/g,
5
- jsonPointerTilde = /~0/g;
1
+ import convertPathToPosix from "./convert-path-to-posix";
2
+ import path, { win32 } from "path";
3
+
4
+ const forwardSlashPattern = /\//g;
5
+ const protocolPattern = /^(\w{2,}):\/\//i;
6
+ const jsonPointerSlash = /~1/g;
7
+ const jsonPointerTilde = /~0/g;
8
+
6
9
  import { join } from "path";
10
+ import { isWindows } from "./is-windows";
7
11
 
8
12
  const projectDir = join(__dirname, "..", "..");
9
13
  // RegExp patterns to URL-encode special characters in local filesystem paths
@@ -55,8 +59,8 @@ export function cwd() {
55
59
  * @param path
56
60
  * @returns
57
61
  */
58
- export function getProtocol(path: any) {
59
- const match = protocolPattern.exec(path);
62
+ export function getProtocol(path: string | undefined) {
63
+ const match = protocolPattern.exec(path || "");
60
64
  if (match) {
61
65
  return match[1].toLowerCase();
62
66
  }
@@ -146,7 +150,7 @@ export function isHttp(path: any) {
146
150
  * @param path
147
151
  * @returns
148
152
  */
149
- export function isFileSystemPath(path: any) {
153
+ export function isFileSystemPath(path: string | undefined) {
150
154
  // @ts-ignore
151
155
  if (typeof window !== "undefined" || process.browser) {
152
156
  // We're running in a browser, so assume that all paths are URLs.
@@ -177,14 +181,18 @@ export function isFileSystemPath(path: any) {
177
181
  export function fromFileSystemPath(path: any) {
178
182
  // Step 1: On Windows, replace backslashes with forward slashes,
179
183
  // rather than encoding them as "%5C"
180
- if (isWindows) {
181
- const hasProjectDir = path.toUpperCase().includes(projectDir.replace(/\\/g, "\\").toUpperCase());
182
- const hasProjectUri = path.toUpperCase().includes(projectDir.replace(/\\/g, "/").toUpperCase());
183
- if (hasProjectDir || hasProjectUri) {
184
- path = path.replace(/\\/g, "/");
185
- } else {
186
- path = `${projectDir}/${path}`.replace(/\\/g, "/");
184
+ if (isWindows()) {
185
+ const upperPath = path.toUpperCase();
186
+ const projectDirPosixPath = convertPathToPosix(projectDir);
187
+ const posixUpper = projectDirPosixPath.toUpperCase();
188
+ const hasProjectDir = upperPath.includes(posixUpper);
189
+ const hasProjectUri = upperPath.includes(posixUpper);
190
+ const isAbsolutePath = win32.isAbsolute(path);
191
+
192
+ if (!(hasProjectDir || hasProjectUri || isAbsolutePath)) {
193
+ path = join(projectDir, path);
187
194
  }
195
+ path = convertPathToPosix(path);
188
196
  }
189
197
 
190
198
  // Step 2: `encodeURI` will take care of MOST characters
@@ -222,7 +230,7 @@ export function toFileSystemPath(path: string | undefined, keepFileProtocol?: bo
222
230
  path = path[7] === "/" ? path.substr(8) : path.substr(7);
223
231
 
224
232
  // insert a colon (":") after the drive letter on Windows
225
- if (isWindows && path[1] === "/") {
233
+ if (isWindows() && path[1] === "/") {
226
234
  path = path[0] + ":" + path.substr(1);
227
235
  }
228
236
 
@@ -234,12 +242,12 @@ export function toFileSystemPath(path: string | undefined, keepFileProtocol?: bo
234
242
  // On Windows, it will start with something like "C:/".
235
243
  // On Posix, it will start with "/"
236
244
  isFileUrl = false;
237
- path = isWindows ? path : "/" + path;
245
+ path = isWindows() ? path : "/" + path;
238
246
  }
239
247
  }
240
248
 
241
249
  // Step 4: Normalize Windows paths (unless it's a "file://" URL)
242
- if (isWindows && !isFileUrl) {
250
+ if (isWindows() && !isFileUrl) {
243
251
  // Replace forward slashes with backslashes
244
252
  path = path.replace(forwardSlashPattern, "\\");
245
253
 
@@ -270,3 +278,15 @@ export function safePointerToPath(pointer: any) {
270
278
  return decodeURIComponent(value).replace(jsonPointerSlash, "/").replace(jsonPointerTilde, "~");
271
279
  });
272
280
  }
281
+
282
+ export function relative(from: string | undefined, to: string | undefined) {
283
+ if (!isFileSystemPath(from) || !isFileSystemPath(to)) {
284
+ return resolve(from, to);
285
+ }
286
+
287
+ const fromDir = path.dirname(stripHash(from));
288
+ const toPath = stripHash(to);
289
+
290
+ const result = path.relative(fromDir, toPath);
291
+ return result + getHash(to);
292
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apidevtools/json-schema-ref-parser",
3
- "version": "10.1.0",
3
+ "version": "11.0.0",
4
4
  "description": "Parse, Resolve, and Dereference JSON Schema $ref pointers",
5
5
  "keywords": [
6
6
  "json",
@@ -67,33 +67,32 @@
67
67
  "test:watch": "vitest -w"
68
68
  },
69
69
  "devDependencies": {
70
- "@types/eslint": "8.4.10",
71
- "@types/js-yaml": "^4.0.5",
72
- "@types/node": "^18.11.18",
73
- "@typescript-eslint/eslint-plugin": "^5.48.2",
74
- "@typescript-eslint/eslint-plugin-tslint": "^5.48.2",
75
- "@typescript-eslint/parser": "^5.48.2",
76
- "@vitest/coverage-c8": "^0.28.1",
70
+ "@types/eslint": "8.44.2",
71
+ "@types/js-yaml": "^4.0.6",
72
+ "@types/node": "^20.6.2",
73
+ "@typescript-eslint/eslint-plugin": "^6.7.2",
74
+ "@typescript-eslint/eslint-plugin-tslint": "^6.7.2",
75
+ "@typescript-eslint/parser": "^6.7.2",
76
+ "@vitest/coverage-v8": "^0.34.4",
77
77
  "abortcontroller-polyfill": "^1.7.5",
78
- "c8": "^7.12.0",
79
78
  "cross-env": "^7.0.3",
80
- "eslint": "^8.32.0",
81
- "eslint-config-prettier": "^8.6.0",
82
- "eslint-config-standard": "^17.0.0",
83
- "eslint-plugin-import": "^2.27.5",
84
- "eslint-plugin-prettier": "^4.2.1",
79
+ "eslint": "^8.49.0",
80
+ "eslint-config-prettier": "^9.0.0",
81
+ "eslint-config-standard": "^17.1.0",
82
+ "eslint-plugin-import": "^2.28.1",
83
+ "eslint-plugin-prettier": "^5.0.0",
85
84
  "eslint-plugin-promise": "^6.1.1",
86
- "eslint-plugin-unused-imports": "^2.0.0",
87
- "jsdom": "^21.1.0",
88
- "lint-staged": "^13.1.0",
89
- "node-fetch": "^3.3.0",
90
- "prettier": "^2.8.3",
91
- "typescript": "^4.9.4",
92
- "vitest": "^0.28.1"
85
+ "eslint-plugin-unused-imports": "^3.0.0",
86
+ "jsdom": "^22.1.0",
87
+ "lint-staged": "^14.0.1",
88
+ "node-fetch": "^3.3.2",
89
+ "prettier": "^3.0.3",
90
+ "typescript": "^5.2.2",
91
+ "vitest": "^0.34.4"
93
92
  },
94
93
  "dependencies": {
95
94
  "@jsdevtools/ono": "^7.1.3",
96
- "@types/json-schema": "^7.0.11",
95
+ "@types/json-schema": "^7.0.13",
97
96
  "@types/lodash.clonedeep": "^4.5.7",
98
97
  "js-yaml": "^4.1.0",
99
98
  "lodash.clonedeep": "^4.5.0"