@apidevtools/json-schema-ref-parser 11.5.4 → 11.6.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.
@@ -1,6 +1,20 @@
1
1
  import type $RefParser from "./index";
2
2
  import type { ParserOptions } from "./index";
3
3
  import type { JSONSchema } from "./index";
4
+ export interface InventoryEntry {
5
+ $ref: any;
6
+ parent: any;
7
+ key: any;
8
+ pathFromRoot: any;
9
+ depth: any;
10
+ file: any;
11
+ hash: any;
12
+ value: any;
13
+ circular: any;
14
+ extended: any;
15
+ external: any;
16
+ indirections: any;
17
+ }
4
18
  /**
5
19
  * Bundles all external JSON references into the main JSON schema, thus resulting in a schema that
6
20
  * only has *internal* references, not any *external* references.
@@ -117,7 +117,8 @@ function inventory$Ref($refParent, $refKey, path, pathFromRoot, indirections, in
117
117
  if (pointer === null) {
118
118
  return;
119
119
  }
120
- const depth = pointer_js_1.default.parse(pathFromRoot).length;
120
+ const parsed = pointer_js_1.default.parse(pathFromRoot);
121
+ const depth = parsed.length;
121
122
  const file = url.stripHash(pointer.path);
122
123
  const hash = url.getHash(pointer.path);
123
124
  const external = file !== $refs._root$Ref.path;
@@ -244,8 +245,26 @@ function remap(inventory) {
244
245
  entry.$ref.$ref = entry.pathFromRoot;
245
246
  }
246
247
  }
247
- // console.log(' new value: %s', (entry.$ref && entry.$ref.$ref) ? entry.$ref.$ref : '[object Object]');
248
248
  }
249
+ // we want to ensure that any $refs that point to another $ref are remapped to point to the final value
250
+ // let hadChange = true;
251
+ // while (hadChange) {
252
+ // hadChange = false;
253
+ // for (const entry of inventory) {
254
+ // if (entry.$ref && typeof entry.$ref === "object" && "$ref" in entry.$ref) {
255
+ // const resolved = inventory.find((e: InventoryEntry) => e.pathFromRoot === entry.$ref.$ref);
256
+ // if (resolved) {
257
+ // const resolvedPointsToAnotherRef =
258
+ // resolved.$ref && typeof resolved.$ref === "object" && "$ref" in resolved.$ref;
259
+ // if (resolvedPointsToAnotherRef && entry.$ref.$ref !== resolved.$ref.$ref) {
260
+ // // console.log('Re-mapping $ref pointer "%s" at %s', entry.$ref.$ref, entry.pathFromRoot);
261
+ // entry.$ref.$ref = resolved.$ref.$ref;
262
+ // hadChange = true;
263
+ // }
264
+ // }
265
+ // }
266
+ // }
267
+ // }
249
268
  }
250
269
  /**
251
270
  * TODO
@@ -30,6 +30,7 @@ const ref_js_1 = __importDefault(require("./ref.js"));
30
30
  const pointer_js_1 = __importDefault(require("./pointer.js"));
31
31
  const ono_1 = require("@jsdevtools/ono");
32
32
  const url = __importStar(require("./util/url.js"));
33
+ const errors_1 = require("./util/errors");
33
34
  exports.default = dereference;
34
35
  /**
35
36
  * Crawls the JSON schema, finds all JSON references, and dereferences them.
@@ -39,8 +40,9 @@ exports.default = dereference;
39
40
  * @param options
40
41
  */
41
42
  function dereference(parser, options) {
43
+ const start = Date.now();
42
44
  // console.log('Dereferencing $ref pointers in %s', parser.$refs._root$Ref.path);
43
- const dereferenced = crawl(parser.schema, parser.$refs._root$Ref.path, "#", new Set(), new Set(), new Map(), parser.$refs, options);
45
+ const dereferenced = crawl(parser.schema, parser.$refs._root$Ref.path, "#", new Set(), new Set(), new Map(), parser.$refs, options, start);
44
46
  parser.$refs.circular = dereferenced.circular;
45
47
  parser.schema = dereferenced.value;
46
48
  }
@@ -55,14 +57,20 @@ function dereference(parser, options) {
55
57
  * @param dereferencedCache - An map of all the dereferenced objects
56
58
  * @param $refs
57
59
  * @param options
60
+ * @param startTime - The time when the dereferencing started
58
61
  * @returns
59
62
  */
60
- function crawl(obj, path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options) {
63
+ function crawl(obj, path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options, startTime) {
61
64
  let dereferenced;
62
65
  const result = {
63
66
  value: obj,
64
67
  circular: false,
65
68
  };
69
+ if (options && options.timeoutMs) {
70
+ if (Date.now() - startTime > options.timeoutMs) {
71
+ throw new errors_1.TimeoutError(options.timeoutMs);
72
+ }
73
+ }
66
74
  const derefOptions = (options.dereference || {});
67
75
  const isExcludedPath = derefOptions.excludedPathMatcher || (() => false);
68
76
  if (derefOptions?.circular === "ignore" || !processedObjects.has(obj)) {
@@ -70,7 +78,7 @@ function crawl(obj, path, pathFromRoot, parents, processedObjects, dereferencedC
70
78
  parents.add(obj);
71
79
  processedObjects.add(obj);
72
80
  if (ref_js_1.default.isAllowed$Ref(obj, options)) {
73
- dereferenced = dereference$Ref(obj, path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options);
81
+ dereferenced = dereference$Ref(obj, path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options, startTime);
74
82
  result.circular = dereferenced.circular;
75
83
  result.value = dereferenced.value;
76
84
  }
@@ -84,7 +92,7 @@ function crawl(obj, path, pathFromRoot, parents, processedObjects, dereferencedC
84
92
  const value = obj[key];
85
93
  let circular = false;
86
94
  if (ref_js_1.default.isAllowed$Ref(value, options)) {
87
- dereferenced = dereference$Ref(value, keyPath, keyPathFromRoot, parents, processedObjects, dereferencedCache, $refs, options);
95
+ dereferenced = dereference$Ref(value, keyPath, keyPathFromRoot, parents, processedObjects, dereferencedCache, $refs, options, startTime);
88
96
  circular = dereferenced.circular;
89
97
  // Avoid pointless mutations; breaks frozen objects to no profit
90
98
  if (obj[key] !== dereferenced.value) {
@@ -94,7 +102,7 @@ function crawl(obj, path, pathFromRoot, parents, processedObjects, dereferencedC
94
102
  }
95
103
  else {
96
104
  if (!parents.has(value)) {
97
- dereferenced = crawl(value, keyPath, keyPathFromRoot, parents, processedObjects, dereferencedCache, $refs, options);
105
+ dereferenced = crawl(value, keyPath, keyPathFromRoot, parents, processedObjects, dereferencedCache, $refs, options, startTime);
98
106
  circular = dereferenced.circular;
99
107
  // Avoid pointless mutations; breaks frozen objects to no profit
100
108
  if (obj[key] !== dereferenced.value) {
@@ -127,7 +135,7 @@ function crawl(obj, path, pathFromRoot, parents, processedObjects, dereferencedC
127
135
  * @param options
128
136
  * @returns
129
137
  */
130
- function dereference$Ref($ref, path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options) {
138
+ function dereference$Ref($ref, path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options, startTime) {
131
139
  const isExternalRef = ref_js_1.default.isExternal$Ref($ref);
132
140
  const shouldResolveOnCwd = isExternalRef && options?.dereference?.externalReferenceResolution === "root";
133
141
  const $refPath = url.resolve(shouldResolveOnCwd ? url.cwd() : path, $ref.$ref);
@@ -165,7 +173,7 @@ function dereference$Ref($ref, path, pathFromRoot, parents, processedObjects, de
165
173
  // Crawl the dereferenced value (unless it's circular)
166
174
  if (!circular) {
167
175
  // Determine if the dereferenced value is circular
168
- const dereferenced = crawl(dereferencedValue, pointer.path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options);
176
+ const dereferenced = crawl(dereferencedValue, pointer.path, pathFromRoot, parents, processedObjects, dereferencedCache, $refs, options, startTime);
169
177
  circular = dereferenced.circular;
170
178
  dereferencedValue = dereferenced.value;
171
179
  }
@@ -35,18 +35,18 @@ export declare class $RefParser<S extends object = JSONSchema, O extends ParserO
35
35
  * @param [callback] - An error-first callback. The second parameter is the parsed JSON schema object.
36
36
  * @returns - The returned promise resolves with the parsed JSON schema object.
37
37
  */
38
- parse(schema: S | string): Promise<S>;
39
- parse(schema: S | string, callback: SchemaCallback<S>): Promise<void>;
40
- parse(schema: S | string, options: O): Promise<S>;
41
- parse(schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
42
- parse(baseUrl: string, schema: S | string, options: O): Promise<S>;
43
- parse(baseUrl: string, schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
44
- static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string): Promise<S>;
45
- static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string, callback: SchemaCallback<S>): Promise<void>;
46
- static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string, options: O): Promise<S>;
47
- static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
48
- static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string, options: O): Promise<S>;
49
- static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
38
+ parse(schema: S | string | unknown): Promise<S>;
39
+ parse(schema: S | string | unknown, callback: SchemaCallback<S>): Promise<void>;
40
+ parse(schema: S | string | unknown, options: O): Promise<S>;
41
+ parse(schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
42
+ parse(baseUrl: string, schema: S | string | unknown, options: O): Promise<S>;
43
+ parse(baseUrl: string, schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
44
+ static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown): Promise<S>;
45
+ static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown, callback: SchemaCallback<S>): Promise<void>;
46
+ static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown, options: O): Promise<S>;
47
+ static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
48
+ static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string | unknown, options: O): Promise<S>;
49
+ static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
50
50
  /**
51
51
  * *This method is used internally by other methods, such as `bundle` and `dereference`. You probably won't need to call this method yourself.*
52
52
  *
@@ -58,12 +58,12 @@ export declare class $RefParser<S extends object = JSONSchema, O extends ParserO
58
58
  * @param options (optional)
59
59
  * @param callback (optional) A callback that will receive a `$Refs` object
60
60
  */
61
- resolve(schema: S | string): Promise<$Refs<S, O>>;
62
- resolve(schema: S | string, callback: $RefsCallback<S, O>): Promise<void>;
63
- resolve(schema: S | string, options: O): Promise<$Refs<S, O>>;
64
- resolve(schema: S | string, options: O, callback: $RefsCallback<S, O>): Promise<void>;
65
- resolve(baseUrl: string, schema: S | string, options: O): Promise<$Refs<S, O>>;
66
- resolve(baseUrl: string, schema: S | string, options: O, callback: $RefsCallback<S, O>): Promise<void>;
61
+ resolve(schema: S | string | unknown): Promise<$Refs<S, O>>;
62
+ resolve(schema: S | string | unknown, callback: $RefsCallback<S, O>): Promise<void>;
63
+ resolve(schema: S | string | unknown, options: O): Promise<$Refs<S, O>>;
64
+ resolve(schema: S | string | unknown, options: O, callback: $RefsCallback<S, O>): Promise<void>;
65
+ resolve(baseUrl: string, schema: S | string | unknown, options: O): Promise<$Refs<S, O>>;
66
+ resolve(baseUrl: string, schema: S | string | unknown, options: O, callback: $RefsCallback<S, O>): Promise<void>;
67
67
  /**
68
68
  * *This method is used internally by other methods, such as `bundle` and `dereference`. You probably won't need to call this method yourself.*
69
69
  *
@@ -75,12 +75,12 @@ export declare class $RefParser<S extends object = JSONSchema, O extends ParserO
75
75
  * @param options (optional)
76
76
  * @param callback (optional) A callback that will receive a `$Refs` object
77
77
  */
78
- static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string): Promise<$Refs<S, O>>;
79
- static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string, callback: $RefsCallback<S, O>): Promise<void>;
80
- static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string, options: O): Promise<$Refs<S, O>>;
81
- static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string, options: O, callback: $RefsCallback<S, O>): Promise<void>;
82
- static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string, options: O): Promise<$Refs<S, O>>;
83
- static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string, options: O, callback: $RefsCallback<S, O>): Promise<void>;
78
+ static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown): Promise<$Refs<S, O>>;
79
+ static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown, callback: $RefsCallback<S, O>): Promise<void>;
80
+ static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown, options: O): Promise<$Refs<S, O>>;
81
+ static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown, options: O, callback: $RefsCallback<S, O>): Promise<void>;
82
+ static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string | unknown, options: O): Promise<$Refs<S, O>>;
83
+ static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string | unknown, options: O, callback: $RefsCallback<S, O>): Promise<void>;
84
84
  /**
85
85
  * Bundles all referenced files/URLs into a single schema that only has internal `$ref` pointers. This lets you split-up your schema however you want while you're building it, but easily combine all those files together when it's time to package or distribute the schema to other people. The resulting schema size will be small, since it will still contain internal JSON references rather than being fully-dereferenced.
86
86
  *
@@ -92,12 +92,12 @@ export declare class $RefParser<S extends object = JSONSchema, O extends ParserO
92
92
  * @param options (optional)
93
93
  * @param callback (optional) A callback that will receive the bundled schema object
94
94
  */
95
- static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string): Promise<S>;
96
- static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string, callback: SchemaCallback<S>): Promise<void>;
97
- static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string, options: O): Promise<S>;
98
- static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
99
- static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string, options: O): Promise<S>;
100
- static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string, options: O, callback: SchemaCallback<S>): Promise<S>;
95
+ static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown): Promise<S>;
96
+ static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown, callback: SchemaCallback<S>): Promise<void>;
97
+ static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown, options: O): Promise<S>;
98
+ static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
99
+ static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string | unknown, options: O): Promise<S>;
100
+ static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<S>;
101
101
  /**
102
102
  * Bundles all referenced files/URLs into a single schema that only has internal `$ref` pointers. This lets you split-up your schema however you want while you're building it, but easily combine all those files together when it's time to package or distribute the schema to other people. The resulting schema size will be small, since it will still contain internal JSON references rather than being fully-dereferenced.
103
103
  *
@@ -109,12 +109,12 @@ export declare class $RefParser<S extends object = JSONSchema, O extends ParserO
109
109
  * @param options (optional)
110
110
  * @param callback (optional) A callback that will receive the bundled schema object
111
111
  */
112
- bundle(schema: S | string): Promise<S>;
113
- bundle(schema: S | string, callback: SchemaCallback<S>): Promise<void>;
114
- bundle(schema: S | string, options: O): Promise<S>;
115
- bundle(schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
116
- bundle(baseUrl: string, schema: S | string, options: O): Promise<S>;
117
- bundle(baseUrl: string, schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
112
+ bundle(schema: S | string | unknown): Promise<S>;
113
+ bundle(schema: S | string | unknown, callback: SchemaCallback<S>): Promise<void>;
114
+ bundle(schema: S | string | unknown, options: O): Promise<S>;
115
+ bundle(schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
116
+ bundle(baseUrl: string, schema: S | string | unknown, options: O): Promise<S>;
117
+ bundle(baseUrl: string, schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
118
118
  /**
119
119
  * Dereferences all `$ref` pointers in the JSON Schema, replacing each reference with its resolved value. This results in a schema object that does not contain any `$ref` pointers. Instead, it's a normal JavaScript object tree that can easily be crawled and used just like any other JavaScript object. This is great for programmatic usage, especially when using tools that don't understand JSON references.
120
120
  *
@@ -126,12 +126,12 @@ export declare class $RefParser<S extends object = JSONSchema, O extends ParserO
126
126
  * @param options (optional)
127
127
  * @param callback (optional) A callback that will receive the dereferenced schema object
128
128
  */
129
- static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string): Promise<S>;
130
- static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string, callback: SchemaCallback<S>): Promise<void>;
131
- static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string, options: O): Promise<S>;
132
- static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
133
- static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string, options: O): Promise<S>;
134
- static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
129
+ static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown): Promise<S>;
130
+ static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown, callback: SchemaCallback<S>): Promise<void>;
131
+ static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown, options: O): Promise<S>;
132
+ static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
133
+ static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string | unknown, options: O): Promise<S>;
134
+ static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(baseUrl: string, schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
135
135
  /**
136
136
  * Dereferences all `$ref` pointers in the JSON Schema, replacing each reference with its resolved value. This results in a schema object that does not contain any `$ref` pointers. Instead, it's a normal JavaScript object tree that can easily be crawled and used just like any other JavaScript object. This is great for programmatic usage, especially when using tools that don't understand JSON references.
137
137
  *
@@ -144,12 +144,12 @@ export declare class $RefParser<S extends object = JSONSchema, O extends ParserO
144
144
  * @param options (optional)
145
145
  * @param callback (optional) A callback that will receive the dereferenced schema object
146
146
  */
147
- dereference(baseUrl: string, schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
148
- dereference(schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
149
- dereference(schema: S | string, callback: SchemaCallback<S>): Promise<void>;
150
- dereference(baseUrl: string, schema: S | string, options: O): Promise<S>;
151
- dereference(schema: S | string, options: O): Promise<S>;
152
- dereference(schema: S | string): Promise<S>;
147
+ dereference(baseUrl: string, schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
148
+ dereference(schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
149
+ dereference(schema: S | string | unknown, callback: SchemaCallback<S>): Promise<void>;
150
+ dereference(baseUrl: string, schema: S | string | unknown, options: O): Promise<S>;
151
+ dereference(schema: S | string | unknown, options: O): Promise<S>;
152
+ dereference(schema: S | string | unknown): Promise<S>;
153
153
  }
154
154
  export default $RefParser;
155
155
  export declare const parse: typeof $RefParser.parse;
@@ -50,9 +50,7 @@ export interface $RefParserOptions<S extends object = JSONSchema> {
50
50
  json?: Plugin | boolean;
51
51
  yaml?: Plugin | boolean;
52
52
  binary?: Plugin | boolean;
53
- text?: (Plugin & {
54
- encoding?: string;
55
- }) | boolean;
53
+ text?: Plugin | boolean;
56
54
  [key: string]: Plugin | boolean | undefined;
57
55
  };
58
56
  /**
@@ -86,6 +84,11 @@ export interface $RefParserOptions<S extends object = JSONSchema> {
86
84
  * Default: `true` due to mutating the input being the default behavior historically
87
85
  */
88
86
  mutateInputSchema?: boolean;
87
+ /**
88
+ * The maximum amount of time (in milliseconds) that JSON Schema $Ref Parser will spend dereferencing a single schema.
89
+ * It will throw a timeout error if the operation takes longer than this.
90
+ */
91
+ timeoutMs?: number;
89
92
  }
90
93
  export declare const getJsonSchemaRefParserDefaultOptions: () => $RefParserOptions<JSONSchema>;
91
94
  export declare const getNewOptions: <S extends object = JSONSchema, O extends {
@@ -207,7 +210,7 @@ export declare const getNewOptions: <S extends object = JSONSchema, O extends {
207
210
  order?: number | undefined;
208
211
  allowEmpty?: boolean | undefined;
209
212
  allowBOM?: boolean | undefined;
210
- encoding?: "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "base64url" | "latin1" | "binary" | "hex" | undefined;
213
+ encoding?: BufferEncoding | undefined;
211
214
  canParse?: string | boolean | {
212
215
  exec?: {} | undefined;
213
216
  test?: {} | undefined;
@@ -369,6 +372,7 @@ export declare const getNewOptions: <S extends object = JSONSchema, O extends {
369
372
  externalReferenceResolution?: "relative" | "root" | undefined;
370
373
  } | undefined;
371
374
  mutateInputSchema?: boolean | undefined;
375
+ timeoutMs?: number | undefined;
372
376
  } = {
373
377
  parse?: {
374
378
  [x: string]: boolean | {
@@ -488,7 +492,7 @@ export declare const getNewOptions: <S extends object = JSONSchema, O extends {
488
492
  order?: number | undefined;
489
493
  allowEmpty?: boolean | undefined;
490
494
  allowBOM?: boolean | undefined;
491
- encoding?: "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "base64url" | "latin1" | "binary" | "hex" | undefined;
495
+ encoding?: BufferEncoding | undefined;
492
496
  canParse?: string | boolean | {
493
497
  exec?: {} | undefined;
494
498
  test?: {} | undefined;
@@ -650,6 +654,7 @@ export declare const getNewOptions: <S extends object = JSONSchema, O extends {
650
654
  externalReferenceResolution?: "relative" | "root" | undefined;
651
655
  } | undefined;
652
656
  mutateInputSchema?: boolean | undefined;
657
+ timeoutMs?: number | undefined;
653
658
  }>(options: O | undefined) => O & $RefParserOptions<S>;
654
659
  export type Options<S extends object = JSONSchema> = $RefParserOptions<S>;
655
660
  export type ParserOptions<S extends object = JSONSchema> = DeepPartial<$RefParserOptions<S>>;
@@ -1,7 +1,7 @@
1
1
  import type $RefParser from "../index.js";
2
2
  import type { ParserOptions } from "../index.js";
3
3
  import type { JSONSchema } from "../index.js";
4
- export type JSONParserErrorType = "EUNKNOWN" | "EPARSER" | "EUNMATCHEDPARSER" | "ERESOLVER" | "EUNMATCHEDRESOLVER" | "EMISSINGPOINTER" | "EINVALIDPOINTER";
4
+ export type JSONParserErrorType = "EUNKNOWN" | "EPARSER" | "EUNMATCHEDPARSER" | "ETIMEOUT" | "ERESOLVER" | "EUNMATCHEDRESOLVER" | "EMISSINGPOINTER" | "EINVALIDPOINTER";
5
5
  export declare class JSONParserError extends Error {
6
6
  readonly name: string;
7
7
  readonly message: string;
@@ -43,6 +43,11 @@ export declare class MissingPointerError extends JSONParserError {
43
43
  name: string;
44
44
  constructor(token: any, path: any);
45
45
  }
46
+ export declare class TimeoutError extends JSONParserError {
47
+ code: JSONParserErrorType;
48
+ name: string;
49
+ constructor(timeout: number);
50
+ }
46
51
  export declare class InvalidPointerError extends JSONParserError {
47
52
  code: JSONParserErrorType;
48
53
  name: string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.normalizeError = exports.isHandledError = exports.InvalidPointerError = exports.MissingPointerError = exports.UnmatchedResolverError = exports.ResolverError = exports.UnmatchedParserError = exports.ParserError = exports.JSONParserErrorGroup = exports.JSONParserError = void 0;
3
+ exports.normalizeError = exports.isHandledError = exports.InvalidPointerError = exports.TimeoutError = exports.MissingPointerError = exports.UnmatchedResolverError = exports.ResolverError = exports.UnmatchedParserError = exports.ParserError = exports.JSONParserErrorGroup = exports.JSONParserError = void 0;
4
4
  const ono_1 = require("@jsdevtools/ono");
5
5
  const url_js_1 = require("./url.js");
6
6
  class JSONParserError extends Error {
@@ -83,6 +83,14 @@ class MissingPointerError extends JSONParserError {
83
83
  }
84
84
  }
85
85
  exports.MissingPointerError = MissingPointerError;
86
+ class TimeoutError extends JSONParserError {
87
+ constructor(timeout) {
88
+ super(`Dereferencing timeout reached: ${timeout}ms`);
89
+ this.code = "ETIMEOUT";
90
+ this.name = "TimeoutError";
91
+ }
92
+ }
93
+ exports.TimeoutError = TimeoutError;
86
94
  class InvalidPointerError extends JSONParserError {
87
95
  constructor(pointer, path) {
88
96
  super(`Invalid $ref pointer "${pointer}". Pointers must begin with "#/"`, (0, url_js_1.stripHash)(path));
package/lib/bundle.ts CHANGED
@@ -6,6 +6,20 @@ import type $RefParser from "./index";
6
6
  import type { ParserOptions } from "./index";
7
7
  import type { JSONSchema } from "./index";
8
8
 
9
+ export interface InventoryEntry {
10
+ $ref: any;
11
+ parent: any;
12
+ key: any;
13
+ pathFromRoot: any;
14
+ depth: any;
15
+ file: any;
16
+ hash: any;
17
+ value: any;
18
+ circular: any;
19
+ extended: any;
20
+ external: any;
21
+ indirections: any;
22
+ }
9
23
  /**
10
24
  * Bundles all external JSON references into the main JSON schema, thus resulting in a schema that
11
25
  * only has *internal* references, not any *external* references.
@@ -21,7 +35,7 @@ function bundle<S extends object = JSONSchema, O extends ParserOptions<S> = Pars
21
35
  // console.log('Bundling $ref pointers in %s', parser.$refs._root$Ref.path);
22
36
 
23
37
  // Build an inventory of all $ref pointers in the JSON Schema
24
- const inventory: any = [];
38
+ const inventory: InventoryEntry[] = [];
25
39
  crawl<S, O>(parser, "schema", parser.$refs._root$Ref.path + "#", "#", 0, inventory, parser.$refs, options);
26
40
 
27
41
  // Remap all $ref pointers
@@ -41,16 +55,16 @@ function bundle<S extends object = JSONSchema, O extends ParserOptions<S> = Pars
41
55
  * @param options
42
56
  */
43
57
  function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
44
- parent: any,
58
+ parent: object | $RefParser<S, O>,
45
59
  key: string | null,
46
60
  path: string,
47
61
  pathFromRoot: string,
48
62
  indirections: number,
49
- inventory: unknown[],
63
+ inventory: InventoryEntry[],
50
64
  $refs: $Refs<S, O>,
51
65
  options: O,
52
66
  ) {
53
- const obj = key === null ? parent : parent[key];
67
+ const obj = key === null ? parent : parent[key as keyof typeof parent];
54
68
 
55
69
  if (obj && typeof obj === "object" && !ArrayBuffer.isView(obj)) {
56
70
  if ($Ref.isAllowed$Ref(obj)) {
@@ -71,7 +85,7 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
71
85
  // This produces the shortest possible bundled references
72
86
  return a.length - b.length;
73
87
  }
74
- });
88
+ }) as (keyof typeof obj)[];
75
89
 
76
90
  // eslint-disable-next-line no-shadow
77
91
  for (const key of keys) {
@@ -104,11 +118,11 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
104
118
  */
105
119
  function inventory$Ref<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
106
120
  $refParent: any,
107
- $refKey: any,
121
+ $refKey: string | null,
108
122
  path: string,
109
- pathFromRoot: any,
110
- indirections: any,
111
- inventory: any,
123
+ pathFromRoot: string,
124
+ indirections: number,
125
+ inventory: InventoryEntry[],
112
126
  $refs: $Refs<S, O>,
113
127
  options: O,
114
128
  ) {
@@ -118,7 +132,8 @@ function inventory$Ref<S extends object = JSONSchema, O extends ParserOptions<S>
118
132
  if (pointer === null) {
119
133
  return;
120
134
  }
121
- const depth = Pointer.parse(pathFromRoot).length;
135
+ const parsed = Pointer.parse(pathFromRoot);
136
+ const depth = parsed.length;
122
137
  const file = url.stripHash(pointer.path);
123
138
  const hash = url.getHash(pointer.path);
124
139
  const external = file !== $refs._root$Ref.path;
@@ -178,9 +193,9 @@ function inventory$Ref<S extends object = JSONSchema, O extends ParserOptions<S>
178
193
  *
179
194
  * @param inventory
180
195
  */
181
- function remap(inventory: any) {
196
+ function remap(inventory: InventoryEntry[]) {
182
197
  // Group & sort all the $ref pointers, so they're in the order that we need to dereference/remap them
183
- inventory.sort((a: any, b: any) => {
198
+ inventory.sort((a: InventoryEntry, b: InventoryEntry) => {
184
199
  if (a.file !== b.file) {
185
200
  // Group all the $refs that point to the same file
186
201
  return a.file < b.file ? -1 : +1;
@@ -243,15 +258,33 @@ function remap(inventory: any) {
243
258
  entry.$ref.$ref = entry.pathFromRoot;
244
259
  }
245
260
  }
246
-
247
- // console.log(' new value: %s', (entry.$ref && entry.$ref.$ref) ? entry.$ref.$ref : '[object Object]');
248
261
  }
262
+
263
+ // we want to ensure that any $refs that point to another $ref are remapped to point to the final value
264
+ // let hadChange = true;
265
+ // while (hadChange) {
266
+ // hadChange = false;
267
+ // for (const entry of inventory) {
268
+ // if (entry.$ref && typeof entry.$ref === "object" && "$ref" in entry.$ref) {
269
+ // const resolved = inventory.find((e: InventoryEntry) => e.pathFromRoot === entry.$ref.$ref);
270
+ // if (resolved) {
271
+ // const resolvedPointsToAnotherRef =
272
+ // resolved.$ref && typeof resolved.$ref === "object" && "$ref" in resolved.$ref;
273
+ // if (resolvedPointsToAnotherRef && entry.$ref.$ref !== resolved.$ref.$ref) {
274
+ // // console.log('Re-mapping $ref pointer "%s" at %s', entry.$ref.$ref, entry.pathFromRoot);
275
+ // entry.$ref.$ref = resolved.$ref.$ref;
276
+ // hadChange = true;
277
+ // }
278
+ // }
279
+ // }
280
+ // }
281
+ // }
249
282
  }
250
283
 
251
284
  /**
252
285
  * TODO
253
286
  */
254
- function findInInventory(inventory: any, $refParent: any, $refKey: any) {
287
+ function findInInventory(inventory: InventoryEntry[], $refParent: any, $refKey: any) {
255
288
  for (const existingEntry of inventory) {
256
289
  if (existingEntry && existingEntry.parent === $refParent && existingEntry.key === $refKey) {
257
290
  return existingEntry;
@@ -259,7 +292,7 @@ function findInInventory(inventory: any, $refParent: any, $refKey: any) {
259
292
  }
260
293
  }
261
294
 
262
- function removeFromInventory(inventory: any, entry: any) {
295
+ function removeFromInventory(inventory: InventoryEntry[], entry: any) {
263
296
  const index = inventory.indexOf(entry);
264
297
  inventory.splice(index, 1);
265
298
  }
@@ -6,6 +6,7 @@ import type $Refs from "./refs.js";
6
6
  import type { DereferenceOptions, ParserOptions } from "./options.js";
7
7
  import type { JSONSchema } from "./types";
8
8
  import type $RefParser from "./index";
9
+ import { TimeoutError } from "./util/errors";
9
10
 
10
11
  export default dereference;
11
12
 
@@ -20,6 +21,7 @@ function dereference<S extends object = JSONSchema, O extends ParserOptions<S> =
20
21
  parser: $RefParser<S, O>,
21
22
  options: O,
22
23
  ) {
24
+ const start = Date.now();
23
25
  // console.log('Dereferencing $ref pointers in %s', parser.$refs._root$Ref.path);
24
26
  const dereferenced = crawl<S, O>(
25
27
  parser.schema,
@@ -30,6 +32,7 @@ function dereference<S extends object = JSONSchema, O extends ParserOptions<S> =
30
32
  new Map(),
31
33
  parser.$refs,
32
34
  options,
35
+ start,
33
36
  );
34
37
  parser.$refs.circular = dereferenced.circular;
35
38
  parser.schema = dereferenced.value;
@@ -46,6 +49,7 @@ function dereference<S extends object = JSONSchema, O extends ParserOptions<S> =
46
49
  * @param dereferencedCache - An map of all the dereferenced objects
47
50
  * @param $refs
48
51
  * @param options
52
+ * @param startTime - The time when the dereferencing started
49
53
  * @returns
50
54
  */
51
55
  function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
@@ -57,6 +61,7 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
57
61
  dereferencedCache: any,
58
62
  $refs: $Refs<S, O>,
59
63
  options: O,
64
+ startTime: number,
60
65
  ) {
61
66
  let dereferenced;
62
67
  const result = {
@@ -64,6 +69,11 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
64
69
  circular: false,
65
70
  };
66
71
 
72
+ if (options && options.timeoutMs) {
73
+ if (Date.now() - startTime > options.timeoutMs) {
74
+ throw new TimeoutError(options.timeoutMs);
75
+ }
76
+ }
67
77
  const derefOptions = (options.dereference || {}) as DereferenceOptions;
68
78
  const isExcludedPath = derefOptions.excludedPathMatcher || (() => false);
69
79
 
@@ -82,6 +92,7 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
82
92
  dereferencedCache,
83
93
  $refs,
84
94
  options,
95
+ startTime,
85
96
  );
86
97
  result.circular = dereferenced.circular;
87
98
  result.value = dereferenced.value;
@@ -107,6 +118,7 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
107
118
  dereferencedCache,
108
119
  $refs,
109
120
  options,
121
+ startTime,
110
122
  );
111
123
  circular = dereferenced.circular;
112
124
  // Avoid pointless mutations; breaks frozen objects to no profit
@@ -125,6 +137,7 @@ function crawl<S extends object = JSONSchema, O extends ParserOptions<S> = Parse
125
137
  dereferencedCache,
126
138
  $refs,
127
139
  options,
140
+ startTime,
128
141
  );
129
142
  circular = dereferenced.circular;
130
143
  // Avoid pointless mutations; breaks frozen objects to no profit
@@ -170,6 +183,7 @@ function dereference$Ref<S extends object = JSONSchema, O extends ParserOptions<
170
183
  dereferencedCache: any,
171
184
  $refs: $Refs<S, O>,
172
185
  options: O,
186
+ startTime: number,
173
187
  ) {
174
188
  const isExternalRef = $Ref.isExternal$Ref($ref);
175
189
  const shouldResolveOnCwd = isExternalRef && options?.dereference?.externalReferenceResolution === "root";
@@ -224,6 +238,7 @@ function dereference$Ref<S extends object = JSONSchema, O extends ParserOptions<
224
238
  dereferencedCache,
225
239
  $refs,
226
240
  options,
241
+ startTime,
227
242
  );
228
243
  circular = dereferenced.circular;
229
244
  dereferencedValue = dereferenced.value;
package/lib/index.ts CHANGED
@@ -65,12 +65,12 @@ export class $RefParser<S extends object = JSONSchema, O extends ParserOptions<S
65
65
  * @param [callback] - An error-first callback. The second parameter is the parsed JSON schema object.
66
66
  * @returns - The returned promise resolves with the parsed JSON schema object.
67
67
  */
68
- public parse(schema: S | string): Promise<S>;
69
- public parse(schema: S | string, callback: SchemaCallback<S>): Promise<void>;
70
- public parse(schema: S | string, options: O): Promise<S>;
71
- public parse(schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
72
- public parse(baseUrl: string, schema: S | string, options: O): Promise<S>;
73
- public parse(baseUrl: string, schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
68
+ public parse(schema: S | string | unknown): Promise<S>;
69
+ public parse(schema: S | string | unknown, callback: SchemaCallback<S>): Promise<void>;
70
+ public parse(schema: S | string | unknown, options: O): Promise<S>;
71
+ public parse(schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
72
+ public parse(baseUrl: string, schema: S | string | unknown, options: O): Promise<S>;
73
+ public parse(baseUrl: string, schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
74
74
  async parse() {
75
75
  const args = normalizeArgs<S, O>(arguments as any);
76
76
  let promise;
@@ -144,29 +144,29 @@ export class $RefParser<S extends object = JSONSchema, O extends ParserOptions<S
144
144
  }
145
145
 
146
146
  public static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
147
- schema: S | string,
147
+ schema: S | string | unknown,
148
148
  ): Promise<S>;
149
149
  public static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
150
- schema: S | string,
150
+ schema: S | string | unknown,
151
151
  callback: SchemaCallback<S>,
152
152
  ): Promise<void>;
153
153
  public static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
154
- schema: S | string,
154
+ schema: S | string | unknown,
155
155
  options: O,
156
156
  ): Promise<S>;
157
157
  public static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
158
- schema: S | string,
158
+ schema: S | string | unknown,
159
159
  options: O,
160
160
  callback: SchemaCallback<S>,
161
161
  ): Promise<void>;
162
162
  public static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
163
163
  baseUrl: string,
164
- schema: S | string,
164
+ schema: S | string | unknown,
165
165
  options: O,
166
166
  ): Promise<S>;
167
167
  public static parse<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
168
168
  baseUrl: string,
169
- schema: S | string,
169
+ schema: S | string | unknown,
170
170
  options: O,
171
171
  callback: SchemaCallback<S>,
172
172
  ): Promise<void>;
@@ -188,12 +188,17 @@ export class $RefParser<S extends object = JSONSchema, O extends ParserOptions<S
188
188
  * @param options (optional)
189
189
  * @param callback (optional) A callback that will receive a `$Refs` object
190
190
  */
191
- public resolve(schema: S | string): Promise<$Refs<S, O>>;
192
- public resolve(schema: S | string, callback: $RefsCallback<S, O>): Promise<void>;
193
- public resolve(schema: S | string, options: O): Promise<$Refs<S, O>>;
194
- public resolve(schema: S | string, options: O, callback: $RefsCallback<S, O>): Promise<void>;
195
- public resolve(baseUrl: string, schema: S | string, options: O): Promise<$Refs<S, O>>;
196
- public resolve(baseUrl: string, schema: S | string, options: O, callback: $RefsCallback<S, O>): Promise<void>;
191
+ public resolve(schema: S | string | unknown): Promise<$Refs<S, O>>;
192
+ public resolve(schema: S | string | unknown, callback: $RefsCallback<S, O>): Promise<void>;
193
+ public resolve(schema: S | string | unknown, options: O): Promise<$Refs<S, O>>;
194
+ public resolve(schema: S | string | unknown, options: O, callback: $RefsCallback<S, O>): Promise<void>;
195
+ public resolve(baseUrl: string, schema: S | string | unknown, options: O): Promise<$Refs<S, O>>;
196
+ public resolve(
197
+ baseUrl: string,
198
+ schema: S | string | unknown,
199
+ options: O,
200
+ callback: $RefsCallback<S, O>,
201
+ ): Promise<void>;
197
202
  async resolve() {
198
203
  const args = normalizeArgs<S, O>(arguments);
199
204
 
@@ -219,29 +224,29 @@ export class $RefParser<S extends object = JSONSchema, O extends ParserOptions<S
219
224
  * @param callback (optional) A callback that will receive a `$Refs` object
220
225
  */
221
226
  public static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
222
- schema: S | string,
227
+ schema: S | string | unknown,
223
228
  ): Promise<$Refs<S, O>>;
224
229
  public static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
225
- schema: S | string,
230
+ schema: S | string | unknown,
226
231
  callback: $RefsCallback<S, O>,
227
232
  ): Promise<void>;
228
233
  public static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
229
- schema: S | string,
234
+ schema: S | string | unknown,
230
235
  options: O,
231
236
  ): Promise<$Refs<S, O>>;
232
237
  public static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
233
- schema: S | string,
238
+ schema: S | string | unknown,
234
239
  options: O,
235
240
  callback: $RefsCallback<S, O>,
236
241
  ): Promise<void>;
237
242
  public static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
238
243
  baseUrl: string,
239
- schema: S | string,
244
+ schema: S | string | unknown,
240
245
  options: O,
241
246
  ): Promise<$Refs<S, O>>;
242
247
  public static resolve<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
243
248
  baseUrl: string,
244
- schema: S | string,
249
+ schema: S | string | unknown,
245
250
  options: O,
246
251
  callback: $RefsCallback<S, O>,
247
252
  ): Promise<void>;
@@ -264,29 +269,29 @@ export class $RefParser<S extends object = JSONSchema, O extends ParserOptions<S
264
269
  * @param callback (optional) A callback that will receive the bundled schema object
265
270
  */
266
271
  public static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
267
- schema: S | string,
272
+ schema: S | string | unknown,
268
273
  ): Promise<S>;
269
274
  public static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
270
- schema: S | string,
275
+ schema: S | string | unknown,
271
276
  callback: SchemaCallback<S>,
272
277
  ): Promise<void>;
273
278
  public static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
274
- schema: S | string,
279
+ schema: S | string | unknown,
275
280
  options: O,
276
281
  ): Promise<S>;
277
282
  public static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
278
- schema: S | string,
283
+ schema: S | string | unknown,
279
284
  options: O,
280
285
  callback: SchemaCallback<S>,
281
286
  ): Promise<void>;
282
287
  public static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
283
288
  baseUrl: string,
284
- schema: S | string,
289
+ schema: S | string | unknown,
285
290
  options: O,
286
291
  ): Promise<S>;
287
292
  public static bundle<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
288
293
  baseUrl: string,
289
- schema: S | string,
294
+ schema: S | string | unknown,
290
295
  options: O,
291
296
  callback: SchemaCallback<S>,
292
297
  ): Promise<S>;
@@ -308,12 +313,12 @@ export class $RefParser<S extends object = JSONSchema, O extends ParserOptions<S
308
313
  * @param options (optional)
309
314
  * @param callback (optional) A callback that will receive the bundled schema object
310
315
  */
311
- public bundle(schema: S | string): Promise<S>;
312
- public bundle(schema: S | string, callback: SchemaCallback<S>): Promise<void>;
313
- public bundle(schema: S | string, options: O): Promise<S>;
314
- public bundle(schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
315
- public bundle(baseUrl: string, schema: S | string, options: O): Promise<S>;
316
- public bundle(baseUrl: string, schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
316
+ public bundle(schema: S | string | unknown): Promise<S>;
317
+ public bundle(schema: S | string | unknown, callback: SchemaCallback<S>): Promise<void>;
318
+ public bundle(schema: S | string | unknown, options: O): Promise<S>;
319
+ public bundle(schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
320
+ public bundle(baseUrl: string, schema: S | string | unknown, options: O): Promise<S>;
321
+ public bundle(baseUrl: string, schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
317
322
  async bundle() {
318
323
  const args = normalizeArgs<S, O>(arguments);
319
324
  try {
@@ -338,29 +343,29 @@ export class $RefParser<S extends object = JSONSchema, O extends ParserOptions<S
338
343
  * @param callback (optional) A callback that will receive the dereferenced schema object
339
344
  */
340
345
  public static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
341
- schema: S | string,
346
+ schema: S | string | unknown,
342
347
  ): Promise<S>;
343
348
  public static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
344
- schema: S | string,
349
+ schema: S | string | unknown,
345
350
  callback: SchemaCallback<S>,
346
351
  ): Promise<void>;
347
352
  public static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
348
- schema: S | string,
353
+ schema: S | string | unknown,
349
354
  options: O,
350
355
  ): Promise<S>;
351
356
  public static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
352
- schema: S | string,
357
+ schema: S | string | unknown,
353
358
  options: O,
354
359
  callback: SchemaCallback<S>,
355
360
  ): Promise<void>;
356
361
  public static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
357
362
  baseUrl: string,
358
- schema: S | string,
363
+ schema: S | string | unknown,
359
364
  options: O,
360
365
  ): Promise<S>;
361
366
  public static dereference<S extends object = JSONSchema, O extends ParserOptions<S> = ParserOptions<S>>(
362
367
  baseUrl: string,
363
- schema: S | string,
368
+ schema: S | string | unknown,
364
369
  options: O,
365
370
  callback: SchemaCallback<S>,
366
371
  ): Promise<void>;
@@ -383,12 +388,17 @@ export class $RefParser<S extends object = JSONSchema, O extends ParserOptions<S
383
388
  * @param options (optional)
384
389
  * @param callback (optional) A callback that will receive the dereferenced schema object
385
390
  */
386
- public dereference(baseUrl: string, schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
387
- public dereference(schema: S | string, options: O, callback: SchemaCallback<S>): Promise<void>;
388
- public dereference(schema: S | string, callback: SchemaCallback<S>): Promise<void>;
389
- public dereference(baseUrl: string, schema: S | string, options: O): Promise<S>;
390
- public dereference(schema: S | string, options: O): Promise<S>;
391
- public dereference(schema: S | string): Promise<S>;
391
+ public dereference(
392
+ baseUrl: string,
393
+ schema: S | string | unknown,
394
+ options: O,
395
+ callback: SchemaCallback<S>,
396
+ ): Promise<void>;
397
+ public dereference(schema: S | string | unknown, options: O, callback: SchemaCallback<S>): Promise<void>;
398
+ public dereference(schema: S | string | unknown, callback: SchemaCallback<S>): Promise<void>;
399
+ public dereference(baseUrl: string, schema: S | string | unknown, options: O): Promise<S>;
400
+ public dereference(schema: S | string | unknown, options: O): Promise<S>;
401
+ public dereference(schema: S | string | unknown): Promise<S>;
392
402
  async dereference() {
393
403
  const args = normalizeArgs<S, O>(arguments);
394
404
 
package/lib/options.ts CHANGED
@@ -63,7 +63,7 @@ export interface $RefParserOptions<S extends object = JSONSchema> {
63
63
  json?: Plugin | boolean;
64
64
  yaml?: Plugin | boolean;
65
65
  binary?: Plugin | boolean;
66
- text?: (Plugin & { encoding?: string }) | boolean;
66
+ text?: Plugin | boolean;
67
67
  [key: string]: Plugin | boolean | undefined;
68
68
  };
69
69
 
@@ -101,6 +101,12 @@ export interface $RefParserOptions<S extends object = JSONSchema> {
101
101
  * Default: `true` due to mutating the input being the default behavior historically
102
102
  */
103
103
  mutateInputSchema?: boolean;
104
+
105
+ /**
106
+ * The maximum amount of time (in milliseconds) that JSON Schema $Ref Parser will spend dereferencing a single schema.
107
+ * It will throw a timeout error if the operation takes longer than this.
108
+ */
109
+ timeoutMs?: number;
104
110
  }
105
111
 
106
112
  export const getJsonSchemaRefParserDefaultOptions = () => {
@@ -9,6 +9,7 @@ export type JSONParserErrorType =
9
9
  | "EUNKNOWN"
10
10
  | "EPARSER"
11
11
  | "EUNMATCHEDPARSER"
12
+ | "ETIMEOUT"
12
13
  | "ERESOLVER"
13
14
  | "EUNMATCHEDRESOLVER"
14
15
  | "EMISSINGPOINTER"
@@ -127,6 +128,14 @@ export class MissingPointerError extends JSONParserError {
127
128
  }
128
129
  }
129
130
 
131
+ export class TimeoutError extends JSONParserError {
132
+ code = "ETIMEOUT" as JSONParserErrorType;
133
+ name = "TimeoutError";
134
+ constructor(timeout: number) {
135
+ super(`Dereferencing timeout reached: ${timeout}ms`);
136
+ }
137
+ }
138
+
130
139
  export class InvalidPointerError extends JSONParserError {
131
140
  code = "EUNMATCHEDRESOLVER" as JSONParserErrorType;
132
141
  name = "InvalidPointerError";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apidevtools/json-schema-ref-parser",
3
- "version": "11.5.4",
3
+ "version": "11.6.0",
4
4
  "description": "Parse, Resolve, and Dereference JSON Schema $ref pointers",
5
5
  "keywords": [
6
6
  "json",
@@ -67,12 +67,12 @@
67
67
  "test:watch": "vitest -w"
68
68
  },
69
69
  "devDependencies": {
70
- "@types/eslint": "8.56.5",
70
+ "@types/eslint": "8.56.9",
71
71
  "@types/js-yaml": "^4.0.9",
72
72
  "@types/node": "^18.19.21",
73
- "@typescript-eslint/eslint-plugin": "^7.1.1",
74
- "@typescript-eslint/parser": "^7.1.1",
75
- "@vitest/coverage-v8": "^1.3.1",
73
+ "@typescript-eslint/eslint-plugin": "^7.6.0",
74
+ "@typescript-eslint/parser": "^7.6.0",
75
+ "@vitest/coverage-v8": "^1.5.0",
76
76
  "cross-env": "^7.0.3",
77
77
  "eslint": "^8.57.0",
78
78
  "eslint-config-prettier": "^9.1.0",
@@ -84,8 +84,8 @@
84
84
  "jsdom": "^24.0.0",
85
85
  "prettier": "^3.2.5",
86
86
  "rimraf": "^5.0.5",
87
- "typescript": "^5.4.2",
88
- "vitest": "^1.3.1"
87
+ "typescript": "^5.4.5",
88
+ "vitest": "^1.5.0"
89
89
  },
90
90
  "dependencies": {
91
91
  "@jsdevtools/ono": "^7.1.3",