@apidevtools/json-schema-ref-parser 10.0.0 → 10.1.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.
Files changed (103) hide show
  1. package/dist/lib/bundle.d.ts +10 -0
  2. package/dist/lib/bundle.js +265 -0
  3. package/dist/lib/dereference.d.ts +9 -0
  4. package/dist/lib/dereference.js +206 -0
  5. package/dist/lib/index.d.ts +206 -0
  6. package/dist/lib/index.js +223 -0
  7. package/dist/lib/normalize-args.d.ts +10 -0
  8. package/dist/lib/normalize-args.js +42 -0
  9. package/dist/lib/options.d.ts +77 -0
  10. package/dist/lib/options.js +119 -0
  11. package/dist/lib/parse.d.ts +8 -0
  12. package/dist/lib/parse.js +177 -0
  13. package/dist/lib/parsers/binary.d.ts +3 -0
  14. package/dist/lib/parsers/binary.js +35 -0
  15. package/dist/lib/parsers/json.d.ts +3 -0
  16. package/dist/lib/parsers/json.js +57 -0
  17. package/dist/lib/parsers/text.d.ts +3 -0
  18. package/dist/lib/parsers/text.js +42 -0
  19. package/dist/lib/parsers/yaml.d.ts +3 -0
  20. package/dist/lib/parsers/yaml.js +65 -0
  21. package/dist/lib/pointer.d.ts +87 -0
  22. package/dist/lib/pointer.js +256 -0
  23. package/dist/lib/ref.d.ts +181 -0
  24. package/dist/lib/ref.js +239 -0
  25. package/dist/lib/refs.d.ts +127 -0
  26. package/dist/lib/refs.js +223 -0
  27. package/dist/lib/resolve-external.d.ts +14 -0
  28. package/dist/lib/resolve-external.js +148 -0
  29. package/dist/lib/resolvers/file.d.ts +3 -0
  30. package/dist/lib/resolvers/file.js +76 -0
  31. package/dist/lib/resolvers/http.d.ts +3 -0
  32. package/dist/lib/resolvers/http.js +159 -0
  33. package/dist/lib/types/index.d.ts +104 -0
  34. package/dist/lib/types/index.js +2 -0
  35. package/dist/lib/util/errors.d.ts +50 -0
  36. package/dist/lib/util/errors.js +106 -0
  37. package/dist/lib/util/maybe.d.ts +3 -0
  38. package/dist/lib/util/maybe.js +24 -0
  39. package/dist/lib/util/next.d.ts +2 -0
  40. package/dist/lib/util/next.js +16 -0
  41. package/dist/lib/util/plugins.d.ts +36 -0
  42. package/dist/lib/util/plugins.js +144 -0
  43. package/dist/lib/util/url.d.ts +93 -0
  44. package/{cjs → dist/lib}/util/url.js +134 -102
  45. package/dist/vite.config.d.ts +2 -0
  46. package/dist/vite.config.js +23 -0
  47. package/lib/{bundle.js → bundle.ts} +105 -101
  48. package/lib/{dereference.js → dereference.ts} +113 -52
  49. package/lib/index.ts +413 -0
  50. package/lib/{normalize-args.js → normalize-args.ts} +7 -14
  51. package/lib/options.ts +202 -0
  52. package/lib/parse.ts +153 -0
  53. package/lib/parsers/binary.ts +39 -0
  54. package/lib/parsers/{json.js → json.ts} +9 -22
  55. package/lib/parsers/text.ts +46 -0
  56. package/lib/parsers/{yaml.js → yaml.ts} +15 -19
  57. package/lib/pointer.ts +296 -0
  58. package/lib/ref.ts +288 -0
  59. package/lib/refs.ts +238 -0
  60. package/lib/{resolve-external.js → resolve-external.ts} +39 -36
  61. package/lib/resolvers/file.ts +40 -0
  62. package/lib/resolvers/http.ts +136 -0
  63. package/lib/tsconfig.json +103 -0
  64. package/lib/types/index.ts +135 -0
  65. package/lib/util/errors.ts +141 -0
  66. package/lib/util/maybe.ts +22 -0
  67. package/lib/util/next.ts +13 -0
  68. package/lib/util/{plugins.js → plugins.ts} +58 -57
  69. package/lib/util/{url.js → url.ts} +64 -83
  70. package/package.json +44 -45
  71. package/cjs/bundle.js +0 -304
  72. package/cjs/dereference.js +0 -258
  73. package/cjs/index.js +0 -603
  74. package/cjs/normalize-args.js +0 -64
  75. package/cjs/options.js +0 -125
  76. package/cjs/package.json +0 -3
  77. package/cjs/parse.js +0 -338
  78. package/cjs/parsers/binary.js +0 -54
  79. package/cjs/parsers/json.js +0 -199
  80. package/cjs/parsers/text.js +0 -61
  81. package/cjs/parsers/yaml.js +0 -239
  82. package/cjs/pointer.js +0 -290
  83. package/cjs/ref.js +0 -333
  84. package/cjs/refs.js +0 -214
  85. package/cjs/resolve-external.js +0 -333
  86. package/cjs/resolvers/file.js +0 -106
  87. package/cjs/resolvers/http.js +0 -184
  88. package/cjs/util/errors.js +0 -401
  89. package/cjs/util/plugins.js +0 -159
  90. package/cjs/util/projectDir.cjs +0 -6
  91. package/lib/index.d.ts +0 -496
  92. package/lib/index.js +0 -290
  93. package/lib/options.js +0 -128
  94. package/lib/parse.js +0 -162
  95. package/lib/parsers/binary.js +0 -53
  96. package/lib/parsers/text.js +0 -64
  97. package/lib/pointer.js +0 -293
  98. package/lib/ref.js +0 -292
  99. package/lib/refs.js +0 -196
  100. package/lib/resolvers/file.js +0 -63
  101. package/lib/resolvers/http.js +0 -155
  102. package/lib/util/errors.js +0 -134
  103. package/lib/util/projectDir.cjs +0 -6
package/lib/index.ts ADDED
@@ -0,0 +1,413 @@
1
+ import $Refs from "./refs.js";
2
+ import _parse from "./parse.js";
3
+ import normalizeArgs from "./normalize-args.js";
4
+ import resolveExternal from "./resolve-external.js";
5
+ import _bundle from "./bundle.js";
6
+ import _dereference from "./dereference.js";
7
+ import * as url from "./util/url.js";
8
+ import {
9
+ JSONParserError,
10
+ InvalidPointerError,
11
+ MissingPointerError,
12
+ ResolverError,
13
+ ParserError,
14
+ UnmatchedParserError,
15
+ UnmatchedResolverError,
16
+ isHandledError,
17
+ JSONParserErrorGroup,
18
+ } from "./util/errors.js";
19
+ import { ono } from "@jsdevtools/ono";
20
+ import maybe from "./util/maybe.js";
21
+ import type { ParserOptions } from "./options.js";
22
+ import type { $RefsCallback, JSONSchema, SchemaCallback } from "./types/index.js";
23
+
24
+ export { JSONParserError };
25
+ export { InvalidPointerError };
26
+ export { MissingPointerError };
27
+ export { ResolverError };
28
+ export { ParserError };
29
+ export { UnmatchedParserError };
30
+ export { UnmatchedResolverError };
31
+
32
+ type RefParserSchema = string | JSONSchema;
33
+
34
+ /**
35
+ * This class parses a JSON schema, builds a map of its JSON references and their resolved values,
36
+ * and provides methods for traversing, manipulating, and dereferencing those references.
37
+ *
38
+ * @class
39
+ */
40
+ export class $RefParser {
41
+ /**
42
+ * The parsed (and possibly dereferenced) JSON schema object
43
+ *
44
+ * @type {object}
45
+ * @readonly
46
+ */
47
+ public schema: JSONSchema | null = null;
48
+
49
+ /**
50
+ * The resolved JSON references
51
+ *
52
+ * @type {$Refs}
53
+ * @readonly
54
+ */
55
+ $refs = new $Refs();
56
+
57
+ /**
58
+ * Parses the given JSON schema.
59
+ * This method does not resolve any JSON references.
60
+ * It just reads a single file in JSON or YAML format, and parse it as a JavaScript object.
61
+ *
62
+ * @param [path] - The file path or URL of the JSON schema
63
+ * @param [schema] - A JSON schema object. This object will be used instead of reading from `path`.
64
+ * @param [options] - Options that determine how the schema is parsed
65
+ * @param [callback] - An error-first callback. The second parameter is the parsed JSON schema object.
66
+ * @returns - The returned promise resolves with the parsed JSON schema object.
67
+ */
68
+ public parse(schema: RefParserSchema): Promise<JSONSchema>;
69
+ public parse(schema: RefParserSchema, callback: SchemaCallback): Promise<void>;
70
+ public parse(schema: RefParserSchema, options: ParserOptions): Promise<JSONSchema>;
71
+ public parse(schema: RefParserSchema, options: ParserOptions, callback: SchemaCallback): Promise<void>;
72
+ public parse(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise<JSONSchema>;
73
+ public parse(
74
+ baseUrl: string,
75
+ schema: RefParserSchema,
76
+ options: ParserOptions,
77
+ callback: SchemaCallback,
78
+ ): Promise<void>;
79
+
80
+ async parse() {
81
+ const args = normalizeArgs(arguments as any);
82
+ let promise;
83
+
84
+ if (!args.path && !args.schema) {
85
+ const err = ono(`Expected a file path, URL, or object. Got ${args.path || args.schema}`);
86
+ return maybe(args.callback, Promise.reject(err));
87
+ }
88
+
89
+ // Reset everything
90
+ this.schema = null;
91
+ this.$refs = new $Refs();
92
+
93
+ // If the path is a filesystem path, then convert it to a URL.
94
+ // NOTE: According to the JSON Reference spec, these should already be URLs,
95
+ // but, in practice, many people use local filesystem paths instead.
96
+ // So we're being generous here and doing the conversion automatically.
97
+ // This is not intended to be a 100% bulletproof solution.
98
+ // If it doesn't work for your use-case, then use a URL instead.
99
+ let pathType = "http";
100
+ if (url.isFileSystemPath(args.path)) {
101
+ args.path = url.fromFileSystemPath(args.path);
102
+ pathType = "file";
103
+ }
104
+
105
+ // Resolve the absolute path of the schema
106
+ args.path = url.resolve(url.cwd(), args.path);
107
+
108
+ if (args.schema && typeof args.schema === "object") {
109
+ // A schema object was passed-in.
110
+ // So immediately add a new $Ref with the schema object as its value
111
+ const $ref = this.$refs._add(args.path);
112
+ $ref.value = args.schema;
113
+ $ref.pathType = pathType;
114
+ promise = Promise.resolve(args.schema);
115
+ } else {
116
+ // Parse the schema file/url
117
+ promise = _parse(args.path, this.$refs, args.options);
118
+ }
119
+
120
+ try {
121
+ const result = await promise;
122
+
123
+ if (result !== null && typeof result === "object" && !Buffer.isBuffer(result)) {
124
+ this.schema = result;
125
+ return maybe(args.callback, Promise.resolve(this.schema!));
126
+ } else if (args.options.continueOnError) {
127
+ this.schema = null; // it's already set to null at line 79, but let's set it again for the sake of readability
128
+ return maybe(args.callback, Promise.resolve(this.schema!));
129
+ } else {
130
+ throw ono.syntax(`"${this.$refs._root$Ref.path || result}" is not a valid JSON Schema`);
131
+ }
132
+ } catch (err) {
133
+ if (!args.options.continueOnError || !isHandledError(err)) {
134
+ return maybe(args.callback, Promise.reject(err));
135
+ }
136
+
137
+ if (this.$refs._$refs[url.stripHash(args.path)]) {
138
+ this.$refs._$refs[url.stripHash(args.path)].addError(err);
139
+ }
140
+
141
+ return maybe(args.callback, Promise.resolve(null));
142
+ }
143
+ }
144
+
145
+ public static parse(schema: RefParserSchema): Promise<JSONSchema>;
146
+ public static parse(schema: RefParserSchema, callback: SchemaCallback): Promise<void>;
147
+ public static parse(schema: RefParserSchema, options: ParserOptions): Promise<JSONSchema>;
148
+ public static parse(schema: RefParserSchema, options: ParserOptions, callback: SchemaCallback): Promise<void>;
149
+ public static parse(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise<JSONSchema>;
150
+ public static parse(
151
+ baseUrl: string,
152
+ schema: RefParserSchema,
153
+ options: ParserOptions,
154
+ callback: SchemaCallback,
155
+ ): Promise<void>;
156
+ public static parse(): Promise<JSONSchema> | Promise<void> {
157
+ const parser = new $RefParser();
158
+ return parser.parse.apply(parser, arguments as any);
159
+ }
160
+
161
+ /**
162
+ * *This method is used internally by other methods, such as `bundle` and `dereference`. You probably won't need to call this method yourself.*
163
+ *
164
+ * Resolves all JSON references (`$ref` pointers) in the given JSON Schema file. If it references any other files/URLs, then they will be downloaded and resolved as well. This method **does not** dereference anything. It simply gives you a `$Refs` object, which is a map of all the resolved references and their values.
165
+ *
166
+ * See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#resolveschema-options-callback
167
+ *
168
+ * @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info.
169
+ * @param options (optional)
170
+ * @param callback (optional) A callback that will receive a `$Refs` object
171
+ */
172
+ public resolve(schema: RefParserSchema): Promise<$Refs>;
173
+ public resolve(schema: RefParserSchema, callback: $RefsCallback): Promise<void>;
174
+ public resolve(schema: RefParserSchema, options: ParserOptions): Promise<$Refs>;
175
+ public resolve(schema: RefParserSchema, options: ParserOptions, callback: $RefsCallback): Promise<void>;
176
+ public resolve(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise<$Refs>;
177
+ public resolve(
178
+ baseUrl: string,
179
+ schema: RefParserSchema,
180
+ options: ParserOptions,
181
+ callback: $RefsCallback,
182
+ ): Promise<void>;
183
+ /**
184
+ * Parses the given JSON schema and resolves any JSON references, including references in
185
+ * externally-referenced files.
186
+ *
187
+ * @param [path] - The file path or URL of the JSON schema
188
+ * @param [schema] - A JSON schema object. This object will be used instead of reading from `path`.
189
+ * @param [options] - Options that determine how the schema is parsed and resolved
190
+ * @param [callback]
191
+ * - An error-first callback. The second parameter is a {@link $Refs} object containing the resolved JSON references
192
+ *
193
+ * @returns
194
+ * The returned promise resolves with a {@link $Refs} object containing the resolved JSON references
195
+ */
196
+ async resolve() {
197
+ const args = normalizeArgs(arguments);
198
+
199
+ try {
200
+ await this.parse(args.path, args.schema, args.options);
201
+ await resolveExternal(this, args.options);
202
+ finalize(this);
203
+ return maybe(args.callback, Promise.resolve(this.$refs));
204
+ } catch (err) {
205
+ return maybe(args.callback, Promise.reject(err));
206
+ }
207
+ }
208
+
209
+ /**
210
+ * *This method is used internally by other methods, such as `bundle` and `dereference`. You probably won't need to call this method yourself.*
211
+ *
212
+ * Resolves all JSON references (`$ref` pointers) in the given JSON Schema file. If it references any other files/URLs, then they will be downloaded and resolved as well. This method **does not** dereference anything. It simply gives you a `$Refs` object, which is a map of all the resolved references and their values.
213
+ *
214
+ * See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#resolveschema-options-callback
215
+ *
216
+ * @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info.
217
+ * @param options (optional)
218
+ * @param callback (optional) A callback that will receive a `$Refs` object
219
+ */
220
+ public static resolve(schema: RefParserSchema): Promise<$Refs>;
221
+ public static resolve(schema: RefParserSchema, callback: $RefsCallback): Promise<void>;
222
+ public static resolve(schema: RefParserSchema, options: ParserOptions): Promise<$Refs>;
223
+ public static resolve(schema: RefParserSchema, options: ParserOptions, callback: $RefsCallback): Promise<void>;
224
+ public static resolve(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise<$Refs>;
225
+ public static resolve(
226
+ baseUrl: string,
227
+ schema: RefParserSchema,
228
+ options: ParserOptions,
229
+ callback: $RefsCallback,
230
+ ): Promise<void>;
231
+ static resolve(): Promise<JSONSchema> | Promise<void> {
232
+ const instance = new $RefParser();
233
+ return instance.resolve.apply(instance, arguments as any);
234
+ }
235
+
236
+ /**
237
+ * Parses the given JSON schema, resolves any JSON references, and bundles all external references
238
+ * into the main JSON schema. This produces a JSON schema that only has *internal* references,
239
+ * not any *external* references.
240
+ *
241
+ * @param [path] - The file path or URL of the JSON schema
242
+ * @param [schema] - A JSON schema object. This object will be used instead of reading from `path`.
243
+ * @param [options] - Options that determine how the schema is parsed, resolved, and dereferenced
244
+ * @param [callback] - An error-first callback. The second parameter is the bundled JSON schema object
245
+ * @returns - The returned promise resolves with the bundled JSON schema object.
246
+ */
247
+ /**
248
+ * 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.
249
+ *
250
+ * This also eliminates the risk of circular references, so the schema can be safely serialized using `JSON.stringify()`.
251
+ *
252
+ * See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#bundleschema-options-callback
253
+ *
254
+ * @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info.
255
+ * @param options (optional)
256
+ * @param callback (optional) A callback that will receive the bundled schema object
257
+ */
258
+ public static bundle(schema: RefParserSchema): Promise<JSONSchema>;
259
+ public static bundle(schema: RefParserSchema, callback: SchemaCallback): Promise<void>;
260
+ public static bundle(schema: RefParserSchema, options: ParserOptions): Promise<JSONSchema>;
261
+ public static bundle(schema: RefParserSchema, options: ParserOptions, callback: SchemaCallback): Promise<void>;
262
+ public static bundle(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise<JSONSchema>;
263
+ public static bundle(
264
+ baseUrl: string,
265
+ schema: RefParserSchema,
266
+ options: ParserOptions,
267
+ callback: SchemaCallback,
268
+ ): Promise<JSONSchema>;
269
+ static bundle(): Promise<JSONSchema> | Promise<void> {
270
+ const instance = new $RefParser();
271
+ return instance.bundle.apply(instance, arguments as any);
272
+ }
273
+
274
+ /**
275
+ * Parses the given JSON schema, resolves any JSON references, and bundles all external references
276
+ * into the main JSON schema. This produces a JSON schema that only has *internal* references,
277
+ * not any *external* references.
278
+ *
279
+ * @param [path] - The file path or URL of the JSON schema
280
+ * @param [schema] - A JSON schema object. This object will be used instead of reading from `path`.
281
+ * @param [options] - Options that determine how the schema is parsed, resolved, and dereferenced
282
+ * @param [callback] - An error-first callback. The second parameter is the bundled JSON schema object
283
+ * @returns - The returned promise resolves with the bundled JSON schema object.
284
+ */
285
+ /**
286
+ * 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.
287
+ *
288
+ * This also eliminates the risk of circular references, so the schema can be safely serialized using `JSON.stringify()`.
289
+ *
290
+ * See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#bundleschema-options-callback
291
+ *
292
+ * @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info.
293
+ * @param options (optional)
294
+ * @param callback (optional) A callback that will receive the bundled schema object
295
+ */
296
+ public bundle(schema: RefParserSchema): Promise<JSONSchema>;
297
+ public bundle(schema: RefParserSchema, callback: SchemaCallback): Promise<void>;
298
+ public bundle(schema: RefParserSchema, options: ParserOptions): Promise<JSONSchema>;
299
+ public bundle(schema: RefParserSchema, options: ParserOptions, callback: SchemaCallback): Promise<void>;
300
+ public bundle(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise<JSONSchema>;
301
+ public bundle(
302
+ baseUrl: string,
303
+ schema: RefParserSchema,
304
+ options: ParserOptions,
305
+ callback: SchemaCallback,
306
+ ): Promise<void>;
307
+ async bundle() {
308
+ const args = normalizeArgs(arguments);
309
+ try {
310
+ await this.resolve(args.path, args.schema, args.options);
311
+ _bundle(this, args.options);
312
+ finalize(this);
313
+ return maybe(args.callback, Promise.resolve(this.schema!));
314
+ } catch (err) {
315
+ return maybe(args.callback, Promise.reject(err));
316
+ }
317
+ }
318
+
319
+ /**
320
+ * Parses the given JSON schema, resolves any JSON references, and dereferences the JSON schema.
321
+ * That is, all JSON references are replaced with their resolved values.
322
+ *
323
+ * @param [path] - The file path or URL of the JSON schema
324
+ * @param [schema] - A JSON schema object. This object will be used instead of reading from `path`.
325
+ * @param [options] - Options that determine how the schema is parsed, resolved, and dereferenced
326
+ * @param [callback] - An error-first callback. The second parameter is the dereferenced JSON schema object
327
+ * @returns - The returned promise resolves with the dereferenced JSON schema object.
328
+ */
329
+ /**
330
+ * 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.
331
+ *
332
+ * The dereference method maintains object reference equality, meaning that all `$ref` pointers that point to the same object will be replaced with references to the same object. Again, this is great for programmatic usage, but it does introduce the risk of circular references, so be careful if you intend to serialize the schema using `JSON.stringify()`. Consider using the bundle method instead, which does not create circular references.
333
+ *
334
+ * See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#dereferenceschema-options-callback
335
+ *
336
+ * @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info.
337
+ * @param options (optional)
338
+ * @param callback (optional) A callback that will receive the dereferenced schema object
339
+ */
340
+ public static dereference(schema: RefParserSchema): Promise<JSONSchema>;
341
+ public static dereference(schema: RefParserSchema, callback: SchemaCallback): Promise<void>;
342
+ public static dereference(schema: RefParserSchema, options: ParserOptions): Promise<JSONSchema>;
343
+ public static dereference(schema: RefParserSchema, options: ParserOptions, callback: SchemaCallback): Promise<void>;
344
+ public static dereference(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise<JSONSchema>;
345
+ public static dereference(
346
+ baseUrl: string,
347
+ schema: RefParserSchema,
348
+ options: ParserOptions,
349
+ callback: SchemaCallback,
350
+ ): Promise<void>;
351
+ static dereference(): Promise<JSONSchema> | Promise<void> {
352
+ const instance = new $RefParser();
353
+ return instance.dereference.apply(instance, arguments as any);
354
+ }
355
+
356
+ /**
357
+ * Parses the given JSON schema, resolves any JSON references, and dereferences the JSON schema.
358
+ * That is, all JSON references are replaced with their resolved values.
359
+ *
360
+ * @param [path] - The file path or URL of the JSON schema
361
+ * @param [schema] - A JSON schema object. This object will be used instead of reading from `path`.
362
+ * @param [options] - Options that determine how the schema is parsed, resolved, and dereferenced
363
+ * @param [callback] - An error-first callback. The second parameter is the dereferenced JSON schema object
364
+ * @returns - The returned promise resolves with the dereferenced JSON schema object.
365
+ */
366
+ /**
367
+ * 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.
368
+ *
369
+ * The dereference method maintains object reference equality, meaning that all `$ref` pointers that point to the same object will be replaced with references to the same object. Again, this is great for programmatic usage, but it does introduce the risk of circular references, so be careful if you intend to serialize the schema using `JSON.stringify()`. Consider using the bundle method instead, which does not create circular references.
370
+ *
371
+ * See https://apitools.dev/json-schema-ref-parser/docs/ref-parser.html#dereferenceschema-options-callback
372
+ *
373
+ * @param schema A JSON Schema object, or the file path or URL of a JSON Schema file. See the `parse` method for more info.
374
+ * @param options (optional)
375
+ * @param callback (optional) A callback that will receive the dereferenced schema object
376
+ */
377
+ public dereference(
378
+ baseUrl: string,
379
+ schema: RefParserSchema,
380
+ options: ParserOptions,
381
+ callback: SchemaCallback,
382
+ ): Promise<void>;
383
+ public dereference(schema: RefParserSchema, options: ParserOptions, callback: SchemaCallback): Promise<void>;
384
+ public dereference(schema: RefParserSchema, callback: SchemaCallback): Promise<void>;
385
+ public dereference(baseUrl: string, schema: RefParserSchema, options: ParserOptions): Promise<JSONSchema>;
386
+ public dereference(schema: RefParserSchema, options: ParserOptions): Promise<JSONSchema>;
387
+ public dereference(schema: RefParserSchema): Promise<JSONSchema>;
388
+ async dereference() {
389
+ const args = normalizeArgs(arguments);
390
+
391
+ try {
392
+ await this.resolve(args.path, args.schema, args.options);
393
+ _dereference(this, args.options);
394
+ finalize(this);
395
+ return maybe(args.callback, Promise.resolve(this.schema));
396
+ } catch (err) {
397
+ return maybe(args.callback, Promise.reject(err));
398
+ }
399
+ }
400
+ }
401
+ export default $RefParser;
402
+
403
+ function finalize(parser: any) {
404
+ const errors = JSONParserErrorGroup.getParserErrors(parser);
405
+ if (errors.length > 0) {
406
+ throw new JSONParserErrorGroup(parser);
407
+ }
408
+ }
409
+
410
+ export const parse = $RefParser.parse;
411
+ export const resolve = $RefParser.resolve;
412
+ export const bundle = $RefParser.bundle;
413
+ export const dereference = $RefParser.dereference;
@@ -1,16 +1,13 @@
1
- import Options from "./options.js";
1
+ import { getNewOptions } from "./options.js";
2
2
 
3
3
  export default normalizeArgs;
4
4
 
5
5
  /**
6
6
  * Normalizes the given arguments, accounting for optional args.
7
- *
8
- * @param {Arguments} args
9
- * @returns {object}
10
7
  */
11
- function normalizeArgs (args) {
8
+ function normalizeArgs(_args: Partial<IArguments>) {
12
9
  let path, schema, options, callback;
13
- args = Array.prototype.slice.call(args);
10
+ const args = Array.prototype.slice.call(_args) as any[];
14
11
 
15
12
  if (typeof args[args.length - 1] === "function") {
16
13
  // The last parameter is a callback function
@@ -24,28 +21,24 @@ function normalizeArgs (args) {
24
21
  // The second parameter is the schema, and the third parameter is the options
25
22
  schema = args[1];
26
23
  options = args[2];
27
- }
28
- else {
24
+ } else {
29
25
  // The second parameter is the options
30
26
  schema = undefined;
31
27
  options = args[1];
32
28
  }
33
- }
34
- else {
29
+ } else {
35
30
  // The first parameter is the schema
36
31
  path = "";
37
32
  schema = args[0];
38
33
  options = args[1];
39
34
  }
40
35
 
41
- if (!(options instanceof Options)) {
42
- options = new Options(options);
43
- }
36
+ options = getNewOptions(options);
44
37
 
45
38
  return {
46
39
  path,
47
40
  schema,
48
41
  options,
49
- callback
42
+ callback,
50
43
  };
51
44
  }
package/lib/options.ts ADDED
@@ -0,0 +1,202 @@
1
+ import jsonParser from "./parsers/json.js";
2
+ import yamlParser from "./parsers/yaml.js";
3
+ import textParser from "./parsers/text.js";
4
+ import binaryParser from "./parsers/binary.js";
5
+ import fileResolver from "./resolvers/file.js";
6
+ import httpResolver from "./resolvers/http.js";
7
+ import cloneDeep from "lodash.clonedeep";
8
+
9
+ import type { HTTPResolverOptions, JSONSchemaObject, Plugin, ResolverOptions } from "./types/index.js";
10
+
11
+ type DeepPartial<T> = T extends object
12
+ ? {
13
+ [P in keyof T]?: DeepPartial<T[P]>;
14
+ }
15
+ : T;
16
+ /**
17
+ * Options that determine how JSON schemas are parsed, resolved, and dereferenced.
18
+ *
19
+ * @param [options] - Overridden options
20
+ * @class
21
+ */
22
+ interface $RefParserOptions {
23
+ /**
24
+ * The `parse` options determine how different types of files will be parsed.
25
+ *
26
+ * JSON Schema `$Ref` Parser comes with built-in JSON, YAML, plain-text, and binary parsers, any of which you can configure or disable. You can also add your own custom parsers if you want.
27
+ */
28
+ parse: {
29
+ json?: Plugin | boolean;
30
+ yaml?: Plugin | boolean;
31
+ binary?: Plugin | boolean;
32
+ text?: (Plugin & { encoding?: string }) | boolean;
33
+ [key: string]: Plugin | boolean | undefined;
34
+ };
35
+
36
+ /**
37
+ * The `resolve` options control how JSON Schema $Ref Parser will resolve file paths and URLs, and how those files will be read/downloaded.
38
+ *
39
+ * JSON Schema `$Ref` Parser comes with built-in support for HTTP and HTTPS, as well as support for local files (when running in Node.js). You can configure or disable either of these built-in resolvers. You can also add your own custom resolvers if you want.
40
+ */
41
+ resolve: {
42
+ /**
43
+ * Determines whether external $ref pointers will be resolved. If this option is disabled, then external `$ref` pointers will simply be ignored.
44
+ */
45
+ external?: boolean;
46
+ file?: Partial<ResolverOptions> | boolean;
47
+ http?: HTTPResolverOptions | boolean;
48
+ } & {
49
+ [key: string]: Partial<ResolverOptions> | HTTPResolverOptions | boolean | undefined;
50
+ };
51
+
52
+ /**
53
+ * By default, JSON Schema $Ref Parser throws the first error it encounters. Setting `continueOnError` to `true`
54
+ * causes it to keep processing as much as possible and then throw a single error that contains all errors
55
+ * that were encountered.
56
+ */
57
+ continueOnError: boolean;
58
+
59
+ /**
60
+ * The `dereference` options control how JSON Schema `$Ref` Parser will dereference `$ref` pointers within the JSON schema.
61
+ */
62
+ dereference: {
63
+ /**
64
+ * Determines whether circular `$ref` pointers are handled.
65
+ *
66
+ * If set to `false`, then a `ReferenceError` will be thrown if the schema contains any circular references.
67
+ *
68
+ * If set to `"ignore"`, then circular references will simply be ignored. No error will be thrown, but the `$Refs.circular` property will still be set to `true`.
69
+ */
70
+ circular?: boolean | "ignore";
71
+
72
+ /**
73
+ * A function, called for each path, which can return true to stop this path and all
74
+ * subpaths from being dereferenced further. This is useful in schemas where some
75
+ * subpaths contain literal $ref keys that should not be dereferenced.
76
+ */
77
+ excludedPathMatcher?(path: string): boolean;
78
+
79
+ /**
80
+ * Callback invoked during dereferencing.
81
+ *
82
+ * @argument {string} path The path being dereferenced (ie. the `$ref` string).
83
+ * @argument {JSONSchemaObject} object The JSON-Schema that the `$ref` resolved to.
84
+ */
85
+ onDereference?(path: string, value: JSONSchemaObject): void;
86
+ };
87
+ }
88
+
89
+ const getDefaults = () => {
90
+ const defaults = {
91
+ /**
92
+ * Determines how different types of files will be parsed.
93
+ *
94
+ * You can add additional parsers of your own, replace an existing one with
95
+ * your own implementation, or disable any parser by setting it to false.
96
+ */
97
+ parse: {
98
+ json: jsonParser,
99
+ yaml: yamlParser,
100
+ text: textParser,
101
+ binary: binaryParser,
102
+ },
103
+
104
+ /**
105
+ * Determines how JSON References will be resolved.
106
+ *
107
+ * You can add additional resolvers of your own, replace an existing one with
108
+ * your own implementation, or disable any resolver by setting it to false.
109
+ */
110
+ resolve: {
111
+ file: fileResolver,
112
+ http: httpResolver,
113
+
114
+ /**
115
+ * Determines whether external $ref pointers will be resolved.
116
+ * If this option is disabled, then none of above resolvers will be called.
117
+ * Instead, external $ref pointers will simply be ignored.
118
+ *
119
+ * @type {boolean}
120
+ */
121
+ external: true,
122
+ },
123
+
124
+ /**
125
+ * By default, JSON Schema $Ref Parser throws the first error it encounters. Setting `continueOnError` to `true`
126
+ * causes it to keep processing as much as possible and then throw a single error that contains all errors
127
+ * that were encountered.
128
+ */
129
+ continueOnError: false,
130
+
131
+ /**
132
+ * Determines the types of JSON references that are allowed.
133
+ */
134
+ dereference: {
135
+ /**
136
+ * Dereference circular (recursive) JSON references?
137
+ * If false, then a {@link ReferenceError} will be thrown if a circular reference is found.
138
+ * If "ignore", then circular references will not be dereferenced.
139
+ *
140
+ * @type {boolean|string}
141
+ */
142
+ circular: true,
143
+
144
+ /**
145
+ * A function, called for each path, which can return true to stop this path and all
146
+ * subpaths from being dereferenced further. This is useful in schemas where some
147
+ * subpaths contain literal $ref keys that should not be dereferenced.
148
+ *
149
+ * @type {function}
150
+ */
151
+ excludedPathMatcher: () => false,
152
+ },
153
+ };
154
+ return cloneDeep(defaults);
155
+ };
156
+
157
+ export const getNewOptions = (options: DeepPartial<$RefParserOptions>): $RefParserOptions => {
158
+ const newOptions = getDefaults();
159
+ if (options) {
160
+ merge(newOptions, options);
161
+ }
162
+ return newOptions;
163
+ };
164
+ export type Options = $RefParserOptions;
165
+ export type ParserOptions = DeepPartial<$RefParserOptions>;
166
+ /**
167
+ * Merges the properties of the source object into the target object.
168
+ *
169
+ * @param target - The object that we're populating
170
+ * @param source - The options that are being merged
171
+ * @returns
172
+ */
173
+ function merge(target: any, source: any) {
174
+ if (isMergeable(source)) {
175
+ const keys = Object.keys(source);
176
+ for (let i = 0; i < keys.length; i++) {
177
+ const key = keys[i];
178
+ const sourceSetting = source[key];
179
+ const targetSetting = target[key];
180
+
181
+ if (isMergeable(sourceSetting)) {
182
+ // It's a nested object, so merge it recursively
183
+ target[key] = merge(targetSetting || {}, sourceSetting);
184
+ } else if (sourceSetting !== undefined) {
185
+ // It's a scalar value, function, or array. No merging necessary. Just overwrite the target value.
186
+ target[key] = sourceSetting;
187
+ }
188
+ }
189
+ }
190
+ return target;
191
+ }
192
+ /**
193
+ * Determines whether the given value can be merged,
194
+ * or if it is a scalar value that should just override the target value.
195
+ *
196
+ * @param val
197
+ * @returns
198
+ */
199
+ function isMergeable(val: any) {
200
+ return val && typeof val === "object" && !Array.isArray(val) && !(val instanceof RegExp) && !(val instanceof Date);
201
+ }
202
+ export default $RefParserOptions;