@hey-api/json-schema-ref-parser 1.3.0 → 1.4.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.
- package/README.md +130 -1
- package/dist/index.d.mts +33 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +131 -98
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -8
- package/src/__tests__/__snapshots__/circular-ref-with-description.json +11 -0
- package/src/__tests__/__snapshots__/main-with-external-siblings.json +78 -0
- package/src/__tests__/__snapshots__/multiple-refs.json +48 -0
- package/src/__tests__/__snapshots__/redfish-like.json +87 -0
- package/src/__tests__/bundle.test.ts +367 -33
- package/src/bundle.ts +60 -14
- package/src/dereference.ts +1 -1
- package/src/index.ts +56 -18
- package/src/parsers/yaml.ts +2 -4
- package/src/pointer.ts +5 -5
- package/src/ref.ts +2 -2
- package/src/refs.ts +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
import { Ono, ono } from "@jsdevtools/ono";
|
|
2
2
|
import { join, win32 } from "node:path";
|
|
3
|
-
import
|
|
3
|
+
import { parse } from "yaml";
|
|
4
4
|
import fs from "fs";
|
|
5
|
-
|
|
6
5
|
//#region src/util/convert-path-to-posix.ts
|
|
7
6
|
function convertPathToPosix(filePath) {
|
|
8
7
|
if (filePath.startsWith("\\\\?\\")) return filePath;
|
|
9
8
|
return filePath.replaceAll("\\", "/");
|
|
10
9
|
}
|
|
11
|
-
|
|
12
10
|
//#endregion
|
|
13
11
|
//#region src/util/is-windows.ts
|
|
14
12
|
const isWindowsConst = /^win/.test(globalThis.process ? globalThis.process.platform : "");
|
|
15
13
|
const isWindows = () => isWindowsConst;
|
|
16
|
-
|
|
17
14
|
//#endregion
|
|
18
15
|
//#region src/util/url.ts
|
|
19
16
|
const forwardSlashPattern = /\//g;
|
|
@@ -181,7 +178,6 @@ function toFileSystemPath(path, keepFileProtocol) {
|
|
|
181
178
|
}
|
|
182
179
|
return path;
|
|
183
180
|
}
|
|
184
|
-
|
|
185
181
|
//#endregion
|
|
186
182
|
//#region src/util/errors.ts
|
|
187
183
|
var JSONParserError = class extends Error {
|
|
@@ -228,6 +224,13 @@ var ParserError = class extends JSONParserError {
|
|
|
228
224
|
super(`Error parsing ${source}: ${message}`, source);
|
|
229
225
|
}
|
|
230
226
|
};
|
|
227
|
+
var UnmatchedParserError = class extends JSONParserError {
|
|
228
|
+
code = "EUNMATCHEDPARSER";
|
|
229
|
+
name = "UnmatchedParserError";
|
|
230
|
+
constructor(source) {
|
|
231
|
+
super(`Could not find parser for "${source}"`, source);
|
|
232
|
+
}
|
|
233
|
+
};
|
|
231
234
|
var ResolverError = class extends JSONParserError {
|
|
232
235
|
code = "ERESOLVER";
|
|
233
236
|
name = "ResolverError";
|
|
@@ -237,6 +240,13 @@ var ResolverError = class extends JSONParserError {
|
|
|
237
240
|
if ("code" in ex) this.ioErrorCode = String(ex.code);
|
|
238
241
|
}
|
|
239
242
|
};
|
|
243
|
+
var UnmatchedResolverError = class extends JSONParserError {
|
|
244
|
+
code = "EUNMATCHEDRESOLVER";
|
|
245
|
+
name = "UnmatchedResolverError";
|
|
246
|
+
constructor(source) {
|
|
247
|
+
super(`Could not find resolver for "${source}"`, source);
|
|
248
|
+
}
|
|
249
|
+
};
|
|
240
250
|
var MissingPointerError = class extends JSONParserError {
|
|
241
251
|
code = "EMISSINGPOINTER";
|
|
242
252
|
name = "MissingPointerError";
|
|
@@ -244,6 +254,13 @@ var MissingPointerError = class extends JSONParserError {
|
|
|
244
254
|
super(`Missing $ref pointer "${getHash(path)}". Token "${token}" does not exist.`, stripHash(path));
|
|
245
255
|
}
|
|
246
256
|
};
|
|
257
|
+
var TimeoutError = class extends JSONParserError {
|
|
258
|
+
code = "ETIMEOUT";
|
|
259
|
+
name = "TimeoutError";
|
|
260
|
+
constructor(timeout) {
|
|
261
|
+
super(`Dereferencing timeout reached: ${timeout}ms`);
|
|
262
|
+
}
|
|
263
|
+
};
|
|
247
264
|
var InvalidPointerError = class extends JSONParserError {
|
|
248
265
|
code = "EUNMATCHEDRESOLVER";
|
|
249
266
|
name = "InvalidPointerError";
|
|
@@ -258,7 +275,6 @@ function normalizeError(err) {
|
|
|
258
275
|
if (err.path === null) err.path = [];
|
|
259
276
|
return err;
|
|
260
277
|
}
|
|
261
|
-
|
|
262
278
|
//#endregion
|
|
263
279
|
//#region src/ref.ts
|
|
264
280
|
/**
|
|
@@ -292,7 +308,7 @@ var $Ref = class $Ref {
|
|
|
292
308
|
*/
|
|
293
309
|
$refs;
|
|
294
310
|
/**
|
|
295
|
-
* Indicates the type of {@link $Ref#path} (e.g
|
|
311
|
+
* Indicates the type of {@link $Ref#path} (e.g., "file", "http", etc.)
|
|
296
312
|
*/
|
|
297
313
|
pathType;
|
|
298
314
|
/**
|
|
@@ -349,7 +365,7 @@ var $Ref = class $Ref {
|
|
|
349
365
|
* @returns
|
|
350
366
|
*/
|
|
351
367
|
resolve(path, options, friendlyPath, pathFromRoot) {
|
|
352
|
-
return new
|
|
368
|
+
return new Pointer(this, path, friendlyPath).resolve(this.value, options, pathFromRoot);
|
|
353
369
|
}
|
|
354
370
|
/**
|
|
355
371
|
* Sets the value of a nested property within this {@link $Ref#value}.
|
|
@@ -359,7 +375,7 @@ var $Ref = class $Ref {
|
|
|
359
375
|
* @param value - The value to assign
|
|
360
376
|
*/
|
|
361
377
|
set(path, value) {
|
|
362
|
-
this.value = new
|
|
378
|
+
this.value = new Pointer(this, path).set(this.value, value);
|
|
363
379
|
}
|
|
364
380
|
/**
|
|
365
381
|
* Determines whether the given value is a JSON reference.
|
|
@@ -368,7 +384,7 @@ var $Ref = class $Ref {
|
|
|
368
384
|
* @returns
|
|
369
385
|
*/
|
|
370
386
|
static is$Ref(value) {
|
|
371
|
-
return Boolean(value) && typeof value === "object" && value !== null && "$ref" in value && typeof value.$ref === "string" && value.$ref.length
|
|
387
|
+
return Boolean(value) && typeof value === "object" && value !== null && "$ref" in value && typeof value.$ref === "string" && Boolean(value.$ref.length);
|
|
372
388
|
}
|
|
373
389
|
/**
|
|
374
390
|
* Determines whether the given value is an external JSON reference.
|
|
@@ -469,8 +485,6 @@ var $Ref = class $Ref {
|
|
|
469
485
|
} else return resolvedValue;
|
|
470
486
|
}
|
|
471
487
|
};
|
|
472
|
-
var ref_default = $Ref;
|
|
473
|
-
|
|
474
488
|
//#endregion
|
|
475
489
|
//#region src/pointer.ts
|
|
476
490
|
const slashes = /\//g;
|
|
@@ -565,7 +579,7 @@ var Pointer = class Pointer {
|
|
|
565
579
|
errors.push(new MissingPointerError(token, decodeURI(this.originalPath)));
|
|
566
580
|
} else this.value = this.value[token];
|
|
567
581
|
}
|
|
568
|
-
if (errors.length
|
|
582
|
+
if (errors.length) throw errors.length === 1 ? errors[0] : new AggregateError(errors, "Multiple missing pointer errors");
|
|
569
583
|
if (!this.value || this.value.$ref && resolve(this.path, this.value.$ref) !== pathFromRoot) resolveIf$Ref(this, options, pathFromRoot);
|
|
570
584
|
return this;
|
|
571
585
|
}
|
|
@@ -582,7 +596,7 @@ var Pointer = class Pointer {
|
|
|
582
596
|
set(obj, value, options) {
|
|
583
597
|
const tokens = Pointer.parse(this.path);
|
|
584
598
|
let token;
|
|
585
|
-
if (tokens.length
|
|
599
|
+
if (!tokens.length) {
|
|
586
600
|
this.value = value;
|
|
587
601
|
return value;
|
|
588
602
|
}
|
|
@@ -601,7 +615,7 @@ var Pointer = class Pointer {
|
|
|
601
615
|
/**
|
|
602
616
|
* Parses a JSON pointer (or a path containing a JSON pointer in the hash)
|
|
603
617
|
* and returns an array of the pointer's tokens.
|
|
604
|
-
* (e.g
|
|
618
|
+
* (e.g., "schema.json#/definitions/person/name" => ["definitions", "person", "name"])
|
|
605
619
|
*
|
|
606
620
|
* The pointer is parsed according to RFC 6901
|
|
607
621
|
* {@link https://tools.ietf.org/html/rfc6901#section-3}
|
|
@@ -621,8 +635,8 @@ var Pointer = class Pointer {
|
|
|
621
635
|
/**
|
|
622
636
|
* Creates a JSON pointer path, by joining one or more tokens to a base path.
|
|
623
637
|
*
|
|
624
|
-
* @param base - The base path (e.g
|
|
625
|
-
* @param tokens - The token(s) to append (e.g
|
|
638
|
+
* @param base - The base path (e.g., "schema.json#/definitions/person")
|
|
639
|
+
* @param tokens - The token(s) to append (e.g., ["name", "first"])
|
|
626
640
|
* @returns
|
|
627
641
|
*/
|
|
628
642
|
static join(base, tokens) {
|
|
@@ -647,15 +661,15 @@ var Pointer = class Pointer {
|
|
|
647
661
|
* @returns - Returns `true` if the resolution path changed
|
|
648
662
|
*/
|
|
649
663
|
function resolveIf$Ref(pointer, options, pathFromRoot) {
|
|
650
|
-
if (
|
|
664
|
+
if ($Ref.isAllowed$Ref(pointer.value)) {
|
|
651
665
|
const $refPath = resolve(pointer.path, pointer.value.$ref);
|
|
652
666
|
if ($refPath === pointer.path && !isRootPath(pathFromRoot)) pointer.circular = true;
|
|
653
667
|
else {
|
|
654
668
|
const resolved = pointer.$ref.$refs._resolve($refPath, pointer.path, options);
|
|
655
669
|
if (resolved === null) return false;
|
|
656
670
|
pointer.indirections += resolved.indirections + 1;
|
|
657
|
-
if (
|
|
658
|
-
pointer.value =
|
|
671
|
+
if ($Ref.isExtended$Ref(pointer.value)) {
|
|
672
|
+
pointer.value = $Ref.dereference(pointer.value, resolved.value);
|
|
659
673
|
return false;
|
|
660
674
|
} else {
|
|
661
675
|
pointer.$ref = resolved.$ref;
|
|
@@ -666,7 +680,6 @@ function resolveIf$Ref(pointer, options, pathFromRoot) {
|
|
|
666
680
|
}
|
|
667
681
|
}
|
|
668
682
|
}
|
|
669
|
-
var pointer_default = Pointer;
|
|
670
683
|
/**
|
|
671
684
|
* Sets the specified token value of the {@link Pointer#value}.
|
|
672
685
|
*
|
|
@@ -691,7 +704,6 @@ function unwrapOrThrow(value) {
|
|
|
691
704
|
function isRootPath(pathFromRoot) {
|
|
692
705
|
return typeof pathFromRoot == "string" && Pointer.parse(pathFromRoot).length == 0;
|
|
693
706
|
}
|
|
694
|
-
|
|
695
707
|
//#endregion
|
|
696
708
|
//#region src/bundle.ts
|
|
697
709
|
/**
|
|
@@ -729,7 +741,7 @@ const createInventoryLookup = () => {
|
|
|
729
741
|
* @returns The container type: "schemas", "parameters", "requestBodies", "responses", or "headers"
|
|
730
742
|
*/
|
|
731
743
|
const getContainerTypeFromPath = (path) => {
|
|
732
|
-
const tokens =
|
|
744
|
+
const tokens = Pointer.parse(path);
|
|
733
745
|
const has = (t) => tokens.includes(t);
|
|
734
746
|
if (has("parameters")) return "parameters";
|
|
735
747
|
if (has("requestBody")) return "requestBodies";
|
|
@@ -739,7 +751,7 @@ const getContainerTypeFromPath = (path) => {
|
|
|
739
751
|
return "schemas";
|
|
740
752
|
};
|
|
741
753
|
/**
|
|
742
|
-
* Inventories the given JSON Reference (i.e
|
|
754
|
+
* Inventories the given JSON Reference (i.e., records detailed information about it so we can
|
|
743
755
|
* optimize all $refs in the schema), and then crawls the resolved value.
|
|
744
756
|
*/
|
|
745
757
|
const inventory$Ref = ({ $refKey, $refParent, $refs, indirections, inventory, inventoryLookup, options, path, pathFromRoot, resolvedRefs = /* @__PURE__ */ new Map(), visitedObjects = /* @__PURE__ */ new WeakSet() }) => {
|
|
@@ -751,19 +763,31 @@ const inventory$Ref = ({ $refKey, $refParent, $refs, indirections, inventory, in
|
|
|
751
763
|
pointer = $refs._resolve($refPath, pathFromRoot, options);
|
|
752
764
|
} catch (error) {
|
|
753
765
|
if (error instanceof MissingPointerError) {
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
766
|
+
const hash = getHash($refPath);
|
|
767
|
+
if (hash) {
|
|
768
|
+
const baseFile = stripHash($refPath);
|
|
769
|
+
for (const filePath of Object.keys($refs._$refs)) {
|
|
770
|
+
if (filePath === baseFile) continue;
|
|
771
|
+
try {
|
|
772
|
+
pointer = $refs._resolve(filePath + hash, pathFromRoot, options);
|
|
773
|
+
if (pointer) break;
|
|
774
|
+
} catch {}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
if (!pointer) {
|
|
778
|
+
console.warn(`Skipping unresolvable $ref: ${$refPath}`);
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
} else throw error;
|
|
758
782
|
}
|
|
759
783
|
if (pointer) resolvedRefs.set($refPath, pointer);
|
|
760
784
|
}
|
|
761
785
|
if (pointer === null) return;
|
|
762
|
-
const depth =
|
|
786
|
+
const depth = Pointer.parse(pathFromRoot).length;
|
|
763
787
|
const file = stripHash(pointer.path);
|
|
764
788
|
const hash = getHash(pointer.path);
|
|
765
789
|
const external = file !== $refs._root$Ref.path;
|
|
766
|
-
const extended =
|
|
790
|
+
const extended = $Ref.isExtended$Ref($ref);
|
|
767
791
|
indirections += pointer.indirections;
|
|
768
792
|
const existingEntry = inventoryLookup.find($refParent, $refKey);
|
|
769
793
|
if (existingEntry && existingEntry.pathFromRoot === pathFromRoot) if (depth < existingEntry.depth || indirections < existingEntry.indirections) {
|
|
@@ -787,19 +811,23 @@ const inventory$Ref = ({ $refKey, $refParent, $refs, indirections, inventory, in
|
|
|
787
811
|
};
|
|
788
812
|
inventory.push(newEntry);
|
|
789
813
|
inventoryLookup.add(newEntry);
|
|
790
|
-
if (!existingEntry || external)
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
814
|
+
if (!existingEntry || external) {
|
|
815
|
+
let crawlPath = pointer.path;
|
|
816
|
+
if (file !== stripHash($refPath)) crawlPath = file + getHash(pointer.path);
|
|
817
|
+
crawl$1({
|
|
818
|
+
$refs,
|
|
819
|
+
indirections: indirections + 1,
|
|
820
|
+
inventory,
|
|
821
|
+
inventoryLookup,
|
|
822
|
+
key: null,
|
|
823
|
+
options,
|
|
824
|
+
parent: pointer.value,
|
|
825
|
+
path: crawlPath,
|
|
826
|
+
pathFromRoot,
|
|
827
|
+
resolvedRefs,
|
|
828
|
+
visitedObjects
|
|
829
|
+
});
|
|
830
|
+
}
|
|
803
831
|
};
|
|
804
832
|
/**
|
|
805
833
|
* Recursively crawls the given value, and inventories all JSON references.
|
|
@@ -808,7 +836,7 @@ const crawl$1 = ({ $refs, indirections, inventory, inventoryLookup, key, options
|
|
|
808
836
|
const obj = key === null ? parent : parent[key];
|
|
809
837
|
if (obj && typeof obj === "object" && !ArrayBuffer.isView(obj)) {
|
|
810
838
|
if (visitedObjects.has(obj)) return;
|
|
811
|
-
if (
|
|
839
|
+
if ($Ref.isAllowed$Ref(obj)) inventory$Ref({
|
|
812
840
|
$refKey: key,
|
|
813
841
|
$refParent: parent,
|
|
814
842
|
$refs,
|
|
@@ -828,12 +856,12 @@ const crawl$1 = ({ $refs, indirections, inventory, inventoryLookup, key, options
|
|
|
828
856
|
else if (b === "definitions") return 1;
|
|
829
857
|
else return a.length - b.length;
|
|
830
858
|
});
|
|
831
|
-
for (const key
|
|
832
|
-
const keyPath =
|
|
833
|
-
const keyPathFromRoot =
|
|
834
|
-
const value = obj[key
|
|
835
|
-
if (
|
|
836
|
-
$refKey: key
|
|
859
|
+
for (const key of keys) {
|
|
860
|
+
const keyPath = Pointer.join(path, key);
|
|
861
|
+
const keyPathFromRoot = Pointer.join(pathFromRoot, key);
|
|
862
|
+
const value = obj[key];
|
|
863
|
+
if ($Ref.isAllowed$Ref(value)) inventory$Ref({
|
|
864
|
+
$refKey: key,
|
|
837
865
|
$refParent: obj,
|
|
838
866
|
$refs,
|
|
839
867
|
indirections,
|
|
@@ -850,7 +878,7 @@ const crawl$1 = ({ $refs, indirections, inventory, inventoryLookup, key, options
|
|
|
850
878
|
indirections,
|
|
851
879
|
inventory,
|
|
852
880
|
inventoryLookup,
|
|
853
|
-
key
|
|
881
|
+
key,
|
|
854
882
|
options,
|
|
855
883
|
parent: obj,
|
|
856
884
|
path: keyPath,
|
|
@@ -883,8 +911,8 @@ function remap(parser, inventory) {
|
|
|
883
911
|
}
|
|
884
912
|
});
|
|
885
913
|
const ensureContainer = (type) => {
|
|
886
|
-
const isOas3 =
|
|
887
|
-
const isOas2 =
|
|
914
|
+
const isOas3 = Boolean(root && typeof root === "object" && typeof root.openapi === "string");
|
|
915
|
+
const isOas2 = Boolean(root && typeof root === "object" && typeof root.swagger === "string");
|
|
888
916
|
if (isOas3) {
|
|
889
917
|
if (!root.components || typeof root.components !== "object") root.components = {};
|
|
890
918
|
if (!root.components[type] || typeof root.components[type] !== "object") root.components[type] = {};
|
|
@@ -1009,7 +1037,11 @@ function remap(parser, inventory) {
|
|
|
1009
1037
|
if (mapped && typeof mapped === "string") proposedBase = mapped;
|
|
1010
1038
|
}
|
|
1011
1039
|
} catch {}
|
|
1012
|
-
|
|
1040
|
+
const schemaName = lastToken(entry.hash);
|
|
1041
|
+
let proposed = schemaName;
|
|
1042
|
+
if (!usedNamesByObj.has(container)) usedNamesByObj.set(container, new Set(Object.keys(container || {})));
|
|
1043
|
+
if (usedNamesByObj.get(container).has(proposed)) proposed = `${proposedBase}_${schemaName}`;
|
|
1044
|
+
defName = uniqueName(container, proposed);
|
|
1013
1045
|
namesForPrefix.set(targetKey, defName);
|
|
1014
1046
|
container[defName] = entry.value;
|
|
1015
1047
|
}
|
|
@@ -1050,7 +1082,6 @@ function bundle(parser, options) {
|
|
|
1050
1082
|
});
|
|
1051
1083
|
remap(parser, inventory);
|
|
1052
1084
|
}
|
|
1053
|
-
|
|
1054
1085
|
//#endregion
|
|
1055
1086
|
//#region src/parsers/binary.ts
|
|
1056
1087
|
const BINARY_REGEXP = /\.(jpeg|jpg|gif|png|bmp|ico)$/i;
|
|
@@ -1059,7 +1090,6 @@ const binaryParser = {
|
|
|
1059
1090
|
handler: (file) => Buffer.isBuffer(file.data) ? file.data : Buffer.from(file.data),
|
|
1060
1091
|
name: "binary"
|
|
1061
1092
|
};
|
|
1062
|
-
|
|
1063
1093
|
//#endregion
|
|
1064
1094
|
//#region src/parsers/json.ts
|
|
1065
1095
|
const jsonParser = {
|
|
@@ -1076,14 +1106,13 @@ const jsonParser = {
|
|
|
1076
1106
|
const firstCurlyBrace = data.indexOf("{");
|
|
1077
1107
|
data = data.slice(firstCurlyBrace);
|
|
1078
1108
|
return JSON.parse(data);
|
|
1079
|
-
} catch (error
|
|
1080
|
-
throw new ParserError(error
|
|
1109
|
+
} catch (error) {
|
|
1110
|
+
throw new ParserError(error.message, file.url);
|
|
1081
1111
|
}
|
|
1082
1112
|
}
|
|
1083
1113
|
},
|
|
1084
1114
|
name: "json"
|
|
1085
1115
|
};
|
|
1086
|
-
|
|
1087
1116
|
//#endregion
|
|
1088
1117
|
//#region src/parsers/text.ts
|
|
1089
1118
|
const TEXT_REGEXP = /\.(txt|htm|html|md|xml|js|min|map|css|scss|less|svg)$/i;
|
|
@@ -1096,7 +1125,6 @@ const textParser = {
|
|
|
1096
1125
|
},
|
|
1097
1126
|
name: "text"
|
|
1098
1127
|
};
|
|
1099
|
-
|
|
1100
1128
|
//#endregion
|
|
1101
1129
|
//#region src/parsers/yaml.ts
|
|
1102
1130
|
const yamlParser = {
|
|
@@ -1109,14 +1137,13 @@ const yamlParser = {
|
|
|
1109
1137
|
const data = Buffer.isBuffer(file.data) ? file.data.toString() : file.data;
|
|
1110
1138
|
if (typeof data !== "string") return data;
|
|
1111
1139
|
try {
|
|
1112
|
-
return
|
|
1140
|
+
return parse(data);
|
|
1113
1141
|
} catch (error) {
|
|
1114
1142
|
throw new ParserError(error?.message || "Parser Error", file.url);
|
|
1115
1143
|
}
|
|
1116
1144
|
},
|
|
1117
1145
|
name: "yaml"
|
|
1118
1146
|
};
|
|
1119
|
-
|
|
1120
1147
|
//#endregion
|
|
1121
1148
|
//#region src/options.ts
|
|
1122
1149
|
const getJsonSchemaRefParserDefaultOptions = () => ({
|
|
@@ -1132,7 +1159,6 @@ const getJsonSchemaRefParserDefaultOptions = () => ({
|
|
|
1132
1159
|
yaml: { ...yamlParser }
|
|
1133
1160
|
}
|
|
1134
1161
|
});
|
|
1135
|
-
|
|
1136
1162
|
//#endregion
|
|
1137
1163
|
//#region src/util/plugins.ts
|
|
1138
1164
|
/**
|
|
@@ -1147,13 +1173,13 @@ async function run(plugins, file) {
|
|
|
1147
1173
|
let index = 0;
|
|
1148
1174
|
let lastError;
|
|
1149
1175
|
let plugin;
|
|
1150
|
-
return new Promise((resolve
|
|
1176
|
+
return new Promise((resolve, reject) => {
|
|
1151
1177
|
const runNextPlugin = async () => {
|
|
1152
1178
|
plugin = plugins[index++];
|
|
1153
1179
|
if (!plugin) return reject(lastError);
|
|
1154
1180
|
try {
|
|
1155
1181
|
const result = await plugin.handler(file);
|
|
1156
|
-
if (result !== void 0) return resolve
|
|
1182
|
+
if (result !== void 0) return resolve({
|
|
1157
1183
|
plugin,
|
|
1158
1184
|
result
|
|
1159
1185
|
});
|
|
@@ -1169,7 +1195,6 @@ async function run(plugins, file) {
|
|
|
1169
1195
|
runNextPlugin();
|
|
1170
1196
|
});
|
|
1171
1197
|
}
|
|
1172
|
-
|
|
1173
1198
|
//#endregion
|
|
1174
1199
|
//#region src/parse.ts
|
|
1175
1200
|
/**
|
|
@@ -1211,7 +1236,6 @@ async function parseFile(file, options) {
|
|
|
1211
1236
|
throw new ParserError(error.error.message, file.url);
|
|
1212
1237
|
}
|
|
1213
1238
|
}
|
|
1214
|
-
|
|
1215
1239
|
//#endregion
|
|
1216
1240
|
//#region src/refs.ts
|
|
1217
1241
|
/**
|
|
@@ -1316,7 +1340,7 @@ var $Refs = class {
|
|
|
1316
1340
|
*/
|
|
1317
1341
|
_add(path) {
|
|
1318
1342
|
const withoutHash = stripHash(path);
|
|
1319
|
-
const $ref = new
|
|
1343
|
+
const $ref = new $Ref(this);
|
|
1320
1344
|
$ref.path = withoutHash;
|
|
1321
1345
|
this._$refs[withoutHash] = $ref;
|
|
1322
1346
|
this._root$Ref = this._root$Ref || $ref;
|
|
@@ -1396,13 +1420,12 @@ var $Refs = class {
|
|
|
1396
1420
|
function getPaths($refs, types) {
|
|
1397
1421
|
let paths = Object.keys($refs);
|
|
1398
1422
|
types = Array.isArray(types[0]) ? types[0] : Array.prototype.slice.call(types);
|
|
1399
|
-
if (types.length
|
|
1423
|
+
if (types.length && types[0]) paths = paths.filter((key) => types.includes($refs[key].pathType));
|
|
1400
1424
|
return paths.map((path) => ({
|
|
1401
1425
|
decoded: $refs[path].pathType === "file" ? toFileSystemPath(path, true) : path,
|
|
1402
1426
|
encoded: path
|
|
1403
1427
|
}));
|
|
1404
1428
|
}
|
|
1405
|
-
|
|
1406
1429
|
//#endregion
|
|
1407
1430
|
//#region src/resolvers/file.ts
|
|
1408
1431
|
const fileResolver = { handler: async ({ file }) => {
|
|
@@ -1418,7 +1441,6 @@ const fileResolver = { handler: async ({ file }) => {
|
|
|
1418
1441
|
throw new ResolverError(ono(error, `Error opening file "${path}"`), path);
|
|
1419
1442
|
}
|
|
1420
1443
|
} };
|
|
1421
|
-
|
|
1422
1444
|
//#endregion
|
|
1423
1445
|
//#region src/resolvers/url.ts
|
|
1424
1446
|
const sendRequest = async ({ fetchOptions, redirects = [], timeout = 6e4, url }) => {
|
|
@@ -1467,7 +1489,6 @@ const urlResolver = { handler: async ({ arrayBuffer, fetch: _fetch, file }) => {
|
|
|
1467
1489
|
}
|
|
1468
1490
|
file.data = Buffer.from(data);
|
|
1469
1491
|
} };
|
|
1470
|
-
|
|
1471
1492
|
//#endregion
|
|
1472
1493
|
//#region src/resolve-external.ts
|
|
1473
1494
|
/**
|
|
@@ -1501,7 +1522,7 @@ function crawl(obj, { $refs, external = false, options, path, seen = /* @__PURE_
|
|
|
1501
1522
|
let promises = [];
|
|
1502
1523
|
if (obj && typeof obj === "object" && !ArrayBuffer.isView(obj) && !seen.has(obj)) {
|
|
1503
1524
|
seen.add(obj);
|
|
1504
|
-
if (
|
|
1525
|
+
if ($Ref.isExternal$Ref(obj)) promises.push(resolve$Ref(obj, {
|
|
1505
1526
|
$refs,
|
|
1506
1527
|
options,
|
|
1507
1528
|
path,
|
|
@@ -1511,7 +1532,7 @@ function crawl(obj, { $refs, external = false, options, path, seen = /* @__PURE_
|
|
|
1511
1532
|
$refs,
|
|
1512
1533
|
external,
|
|
1513
1534
|
options,
|
|
1514
|
-
path:
|
|
1535
|
+
path: Pointer.join(path, key),
|
|
1515
1536
|
seen
|
|
1516
1537
|
}));
|
|
1517
1538
|
}
|
|
@@ -1567,7 +1588,6 @@ async function resolve$Ref($ref, { $refs, options, path, seen }) {
|
|
|
1567
1588
|
throw error;
|
|
1568
1589
|
}
|
|
1569
1590
|
}
|
|
1570
|
-
|
|
1571
1591
|
//#endregion
|
|
1572
1592
|
//#region src/index.ts
|
|
1573
1593
|
function getResolvedInput({ pathOrUrlOrSchema }) {
|
|
@@ -1623,35 +1643,35 @@ var $RefParser = class {
|
|
|
1623
1643
|
*
|
|
1624
1644
|
* @param pathOrUrlOrSchema A JSON Schema object, or the file path or URL of a JSON Schema file.
|
|
1625
1645
|
*/
|
|
1626
|
-
async bundle({ arrayBuffer, fetch
|
|
1646
|
+
async bundle({ arrayBuffer, fetch, pathOrUrlOrSchema, resolvedInput }) {
|
|
1627
1647
|
await this.parse({
|
|
1628
1648
|
arrayBuffer,
|
|
1629
|
-
fetch
|
|
1649
|
+
fetch,
|
|
1630
1650
|
pathOrUrlOrSchema,
|
|
1631
1651
|
resolvedInput
|
|
1632
1652
|
});
|
|
1633
1653
|
await resolveExternal(this, this.options);
|
|
1634
|
-
if (JSONParserErrorGroup.getParserErrors(this).length
|
|
1654
|
+
if (JSONParserErrorGroup.getParserErrors(this).length) throw new JSONParserErrorGroup(this);
|
|
1635
1655
|
bundle(this, this.options);
|
|
1636
|
-
if (JSONParserErrorGroup.getParserErrors(this).length
|
|
1656
|
+
if (JSONParserErrorGroup.getParserErrors(this).length) throw new JSONParserErrorGroup(this);
|
|
1637
1657
|
return this.schema;
|
|
1638
1658
|
}
|
|
1639
1659
|
/**
|
|
1640
1660
|
* Bundles multiple roots (files/URLs/objects) into a single schema by creating a synthetic root
|
|
1641
1661
|
* that references each input, resolving all externals, and then hoisting via the existing bundler.
|
|
1642
1662
|
*/
|
|
1643
|
-
async bundleMany({ arrayBuffer, fetch
|
|
1663
|
+
async bundleMany({ arrayBuffer, fetch, pathOrUrlOrSchemas, resolvedInputs }) {
|
|
1644
1664
|
await this.parseMany({
|
|
1645
1665
|
arrayBuffer,
|
|
1646
|
-
fetch
|
|
1666
|
+
fetch,
|
|
1647
1667
|
pathOrUrlOrSchemas,
|
|
1648
1668
|
resolvedInputs
|
|
1649
1669
|
});
|
|
1650
1670
|
this.mergeMany();
|
|
1651
1671
|
await resolveExternal(this, this.options);
|
|
1652
|
-
if (JSONParserErrorGroup.getParserErrors(this).length
|
|
1672
|
+
if (JSONParserErrorGroup.getParserErrors(this).length) throw new JSONParserErrorGroup(this);
|
|
1653
1673
|
bundle(this, this.options);
|
|
1654
|
-
if (JSONParserErrorGroup.getParserErrors(this).length
|
|
1674
|
+
if (JSONParserErrorGroup.getParserErrors(this).length) throw new JSONParserErrorGroup(this);
|
|
1655
1675
|
return this.schema;
|
|
1656
1676
|
}
|
|
1657
1677
|
/**
|
|
@@ -1662,7 +1682,7 @@ var $RefParser = class {
|
|
|
1662
1682
|
* @param pathOrUrlOrSchema A JSON Schema object, or the file path or URL of a JSON Schema file.
|
|
1663
1683
|
* @returns - The returned promise resolves with the parsed JSON schema object.
|
|
1664
1684
|
*/
|
|
1665
|
-
async parse({ arrayBuffer, fetch
|
|
1685
|
+
async parse({ arrayBuffer, fetch, pathOrUrlOrSchema, resolvedInput: _resolvedInput }) {
|
|
1666
1686
|
const resolvedInput = _resolvedInput || getResolvedInput({ pathOrUrlOrSchema });
|
|
1667
1687
|
const { path, type } = resolvedInput;
|
|
1668
1688
|
let { schema } = resolvedInput;
|
|
@@ -1679,7 +1699,7 @@ var $RefParser = class {
|
|
|
1679
1699
|
try {
|
|
1680
1700
|
await (type === "file" ? fileResolver : urlResolver).handler({
|
|
1681
1701
|
arrayBuffer,
|
|
1682
|
-
fetch
|
|
1702
|
+
fetch,
|
|
1683
1703
|
file
|
|
1684
1704
|
});
|
|
1685
1705
|
const parseResult = await parseFile(file, this.options.parse);
|
|
@@ -1694,7 +1714,7 @@ var $RefParser = class {
|
|
|
1694
1714
|
this.schema = schema;
|
|
1695
1715
|
return { schema };
|
|
1696
1716
|
}
|
|
1697
|
-
async parseMany({ arrayBuffer, fetch
|
|
1717
|
+
async parseMany({ arrayBuffer, fetch, pathOrUrlOrSchemas, resolvedInputs: _resolvedInputs }) {
|
|
1698
1718
|
const resolvedInputs = [..._resolvedInputs || []];
|
|
1699
1719
|
resolvedInputs.push(...pathOrUrlOrSchemas.map((schema) => getResolvedInput({ pathOrUrlOrSchema: schema })) || []);
|
|
1700
1720
|
this.schemaMany = [];
|
|
@@ -1711,7 +1731,7 @@ var $RefParser = class {
|
|
|
1711
1731
|
try {
|
|
1712
1732
|
await (type === "file" ? fileResolver : urlResolver).handler({
|
|
1713
1733
|
arrayBuffer: arrayBuffer?.[i],
|
|
1714
|
-
fetch
|
|
1734
|
+
fetch,
|
|
1715
1735
|
file
|
|
1716
1736
|
});
|
|
1717
1737
|
const parseResult = await parseFile(file, this.options.parse);
|
|
@@ -1730,7 +1750,7 @@ var $RefParser = class {
|
|
|
1730
1750
|
}
|
|
1731
1751
|
mergeMany() {
|
|
1732
1752
|
const schemas = this.schemaMany || [];
|
|
1733
|
-
if (schemas.length
|
|
1753
|
+
if (!schemas.length) throw ono("mergeMany called with no schemas. Did you run parseMany?");
|
|
1734
1754
|
const merged = {};
|
|
1735
1755
|
let chosenOpenapi;
|
|
1736
1756
|
let chosenSwagger;
|
|
@@ -1748,7 +1768,7 @@ var $RefParser = class {
|
|
|
1748
1768
|
for (const [k, v] of Object.entries(info)) if (infoAccumulator[k] === void 0 && v !== void 0) infoAccumulator[k] = JSON.parse(JSON.stringify(v));
|
|
1749
1769
|
}
|
|
1750
1770
|
}
|
|
1751
|
-
if (Object.keys(infoAccumulator).length
|
|
1771
|
+
if (Object.keys(infoAccumulator).length) merged.info = infoAccumulator;
|
|
1752
1772
|
const servers = [];
|
|
1753
1773
|
const seenServers = /* @__PURE__ */ new Set();
|
|
1754
1774
|
for (const s of schemas) {
|
|
@@ -1763,7 +1783,7 @@ var $RefParser = class {
|
|
|
1763
1783
|
}
|
|
1764
1784
|
}
|
|
1765
1785
|
}
|
|
1766
|
-
if (servers.length
|
|
1786
|
+
if (servers.length) merged.servers = servers;
|
|
1767
1787
|
merged.paths = {};
|
|
1768
1788
|
merged.components = {};
|
|
1769
1789
|
const componentSections = [
|
|
@@ -1864,14 +1884,27 @@ var $RefParser = class {
|
|
|
1864
1884
|
merged.components[sec][newName] = cloneAndRewrite(val, refMap, tagMap, prefix, stripHash(sourcePath));
|
|
1865
1885
|
}
|
|
1866
1886
|
}
|
|
1887
|
+
const HTTP_METHODS = new Set([
|
|
1888
|
+
"delete",
|
|
1889
|
+
"get",
|
|
1890
|
+
"head",
|
|
1891
|
+
"options",
|
|
1892
|
+
"patch",
|
|
1893
|
+
"post",
|
|
1894
|
+
"put",
|
|
1895
|
+
"trace"
|
|
1896
|
+
]);
|
|
1867
1897
|
const srcPaths = schema.paths || {};
|
|
1868
|
-
for (const [p, item] of Object.entries(srcPaths)) {
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1898
|
+
for (const [p, item] of Object.entries(srcPaths)) if (merged.paths[p]) {
|
|
1899
|
+
const hasMethodConflict = Object.keys(item).filter((k) => HTTP_METHODS.has(k)).some((m) => merged.paths[p][m] !== void 0);
|
|
1900
|
+
const rewritten = cloneAndRewrite(item, refMap, tagMap, prefix, stripHash(sourcePath));
|
|
1901
|
+
if (hasMethodConflict) {
|
|
1902
|
+
const trimmed = p.startsWith("/") ? p.substring(1) : p;
|
|
1903
|
+
merged.paths[`/${prefix}/${trimmed}`] = rewritten;
|
|
1904
|
+
} else Object.assign(merged.paths[p], rewritten);
|
|
1905
|
+
} else merged.paths[p] = cloneAndRewrite(item, refMap, tagMap, prefix, stripHash(sourcePath));
|
|
1873
1906
|
}
|
|
1874
|
-
if (tags.length
|
|
1907
|
+
if (tags.length) merged.tags = tags;
|
|
1875
1908
|
const rootPath = this.schemaManySources[0] || cwd();
|
|
1876
1909
|
this.$refs = new $Refs();
|
|
1877
1910
|
const rootRef = this.$refs._add(rootPath);
|
|
@@ -1881,7 +1914,7 @@ var $RefParser = class {
|
|
|
1881
1914
|
return merged;
|
|
1882
1915
|
}
|
|
1883
1916
|
};
|
|
1884
|
-
|
|
1885
1917
|
//#endregion
|
|
1886
|
-
export { $RefParser, getResolvedInput, sendRequest };
|
|
1918
|
+
export { $RefParser, InvalidPointerError, JSONParserError, JSONParserErrorGroup, MissingPointerError, ParserError, ResolverError, TimeoutError, UnmatchedParserError, UnmatchedResolverError, getResolvedInput, isHandledError, normalizeError, sendRequest };
|
|
1919
|
+
|
|
1887
1920
|
//# sourceMappingURL=index.mjs.map
|