@hey-api/json-schema-ref-parser 1.3.0 → 1.3.1
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/dist/index.mjs +56 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- 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 +53 -7
- package/src/index.ts +34 -10
package/src/bundle.ts
CHANGED
|
@@ -157,11 +157,31 @@ const inventory$Ref = <S extends object = JSONSchema>({
|
|
|
157
157
|
pointer = $refs._resolve($refPath, pathFromRoot, options);
|
|
158
158
|
} catch (error) {
|
|
159
159
|
if (error instanceof MissingPointerError) {
|
|
160
|
-
//
|
|
161
|
-
|
|
162
|
-
|
|
160
|
+
// The ref couldn't be resolved in the target file. This commonly
|
|
161
|
+
// happens when a wrapper file redirects via $ref to a versioned
|
|
162
|
+
// file, and the bundler's crawl path retains the wrapper URL.
|
|
163
|
+
// Try resolving the hash fragment against other files in $refs
|
|
164
|
+
// that might contain the target schema.
|
|
165
|
+
const hash = url.getHash($refPath);
|
|
166
|
+
if (hash) {
|
|
167
|
+
const baseFile = url.stripHash($refPath);
|
|
168
|
+
for (const filePath of Object.keys($refs._$refs)) {
|
|
169
|
+
if (filePath === baseFile) continue;
|
|
170
|
+
try {
|
|
171
|
+
pointer = $refs._resolve(filePath + hash, pathFromRoot, options);
|
|
172
|
+
if (pointer) break;
|
|
173
|
+
} catch {
|
|
174
|
+
// try next file
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (!pointer) {
|
|
179
|
+
console.warn(`Skipping unresolvable $ref: ${$refPath}`);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
throw error;
|
|
163
184
|
}
|
|
164
|
-
throw error; // Re-throw unexpected errors
|
|
165
185
|
}
|
|
166
186
|
|
|
167
187
|
if (pointer) {
|
|
@@ -217,8 +237,19 @@ const inventory$Ref = <S extends object = JSONSchema>({
|
|
|
217
237
|
inventory.push(newEntry);
|
|
218
238
|
inventoryLookup.add(newEntry);
|
|
219
239
|
|
|
220
|
-
// Recursively crawl the resolved value
|
|
240
|
+
// Recursively crawl the resolved value.
|
|
241
|
+
// When the resolution followed a $ref chain to a different file,
|
|
242
|
+
// use the resolved file as the base path so that local $ref values
|
|
243
|
+
// (e.g. #/components/schemas/SiblingSchema) inside the resolved
|
|
244
|
+
// value resolve against the correct file.
|
|
221
245
|
if (!existingEntry || external) {
|
|
246
|
+
let crawlPath = pointer.path;
|
|
247
|
+
|
|
248
|
+
const originalFile = url.stripHash($refPath);
|
|
249
|
+
if (file !== originalFile) {
|
|
250
|
+
crawlPath = file + url.getHash(pointer.path);
|
|
251
|
+
}
|
|
252
|
+
|
|
222
253
|
crawl({
|
|
223
254
|
$refs,
|
|
224
255
|
indirections: indirections + 1,
|
|
@@ -227,7 +258,7 @@ const inventory$Ref = <S extends object = JSONSchema>({
|
|
|
227
258
|
key: null,
|
|
228
259
|
options,
|
|
229
260
|
parent: pointer.value,
|
|
230
|
-
path:
|
|
261
|
+
path: crawlPath,
|
|
231
262
|
pathFromRoot,
|
|
232
263
|
resolvedRefs,
|
|
233
264
|
visitedObjects,
|
|
@@ -586,7 +617,22 @@ function remap(parser: $RefParser, inventory: Array<InventoryEntry>) {
|
|
|
586
617
|
} catch {
|
|
587
618
|
// Ignore errors
|
|
588
619
|
}
|
|
589
|
-
|
|
620
|
+
|
|
621
|
+
// Try without prefix first (cleaner names)
|
|
622
|
+
const schemaName = lastToken(entry.hash);
|
|
623
|
+
let proposed = schemaName;
|
|
624
|
+
|
|
625
|
+
// Check if this name would conflict with existing schemas from other files
|
|
626
|
+
if (!usedNamesByObj.has(container)) {
|
|
627
|
+
usedNamesByObj.set(container, new Set<string>(Object.keys(container || {})));
|
|
628
|
+
}
|
|
629
|
+
const used = usedNamesByObj.get(container)!;
|
|
630
|
+
|
|
631
|
+
// If the name is already used, add the file prefix
|
|
632
|
+
if (used.has(proposed)) {
|
|
633
|
+
proposed = `${proposedBase}_${schemaName}`;
|
|
634
|
+
}
|
|
635
|
+
|
|
590
636
|
defName = uniqueName(container, proposed);
|
|
591
637
|
namesForPrefix.set(targetKey, defName);
|
|
592
638
|
// Store the resolved value under the container
|
package/src/index.ts
CHANGED
|
@@ -527,20 +527,44 @@ export class $RefParser {
|
|
|
527
527
|
}
|
|
528
528
|
}
|
|
529
529
|
|
|
530
|
+
const HTTP_METHODS = new Set([
|
|
531
|
+
'delete',
|
|
532
|
+
'get',
|
|
533
|
+
'head',
|
|
534
|
+
'options',
|
|
535
|
+
'patch',
|
|
536
|
+
'post',
|
|
537
|
+
'put',
|
|
538
|
+
'trace',
|
|
539
|
+
]);
|
|
540
|
+
|
|
530
541
|
const srcPaths = (schema.paths || {}) as Record<string, any>;
|
|
531
542
|
for (const [p, item] of Object.entries(srcPaths)) {
|
|
532
|
-
let targetPath = p;
|
|
533
543
|
if (merged.paths[p]) {
|
|
534
|
-
const
|
|
535
|
-
|
|
544
|
+
const newMethods = Object.keys(item as object).filter((k) => HTTP_METHODS.has(k));
|
|
545
|
+
const hasMethodConflict = newMethods.some((m) => merged.paths[p][m] !== undefined);
|
|
546
|
+
const rewritten = cloneAndRewrite(
|
|
547
|
+
item,
|
|
548
|
+
refMap,
|
|
549
|
+
tagMap,
|
|
550
|
+
prefix,
|
|
551
|
+
url.stripHash(sourcePath),
|
|
552
|
+
);
|
|
553
|
+
if (hasMethodConflict) {
|
|
554
|
+
const trimmed = p.startsWith('/') ? p.substring(1) : p;
|
|
555
|
+
merged.paths[`/${prefix}/${trimmed}`] = rewritten;
|
|
556
|
+
} else {
|
|
557
|
+
Object.assign(merged.paths[p], rewritten);
|
|
558
|
+
}
|
|
559
|
+
} else {
|
|
560
|
+
merged.paths[p] = cloneAndRewrite(
|
|
561
|
+
item,
|
|
562
|
+
refMap,
|
|
563
|
+
tagMap,
|
|
564
|
+
prefix,
|
|
565
|
+
url.stripHash(sourcePath),
|
|
566
|
+
);
|
|
536
567
|
}
|
|
537
|
-
merged.paths[targetPath] = cloneAndRewrite(
|
|
538
|
-
item,
|
|
539
|
-
refMap,
|
|
540
|
-
tagMap,
|
|
541
|
-
prefix,
|
|
542
|
-
url.stripHash(sourcePath),
|
|
543
|
-
);
|
|
544
568
|
}
|
|
545
569
|
}
|
|
546
570
|
|