@speclynx/apidom-reference 6.0.6 → 6.1.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/CHANGELOG.md +13 -0
- package/dist/apidom-reference.browser.js +1208 -1116
- package/dist/apidom-reference.browser.min.js +1 -1
- package/package.json +29 -29
- package/src/bundle/strategies/asyncapi-2/visitor.cjs +5 -0
- package/src/bundle/strategies/asyncapi-2/visitor.mjs +5 -0
- package/src/bundle/strategies/openapi-2/visitor.cjs +4 -0
- package/src/bundle/strategies/openapi-2/visitor.mjs +4 -0
- package/src/bundle/strategies/openapi-3-0/visitor.cjs +97 -82
- package/src/bundle/strategies/openapi-3-0/visitor.mjs +97 -82
- package/src/bundle/strategies/openapi-3-1/visitor.cjs +5 -0
- package/src/bundle/strategies/openapi-3-1/visitor.mjs +5 -0
- package/src/dereference/strategies/asyncapi-2/visitor.cjs +5 -0
- package/src/dereference/strategies/asyncapi-2/visitor.mjs +5 -0
- package/src/dereference/strategies/openapi-2/visitor.cjs +10 -0
- package/src/dereference/strategies/openapi-2/visitor.mjs +10 -0
- package/src/dereference/strategies/openapi-3-0/visitor.cjs +5 -0
- package/src/dereference/strategies/openapi-3-0/visitor.mjs +5 -0
- package/src/dereference/strategies/openapi-3-1/visitor.cjs +5 -0
- package/src/dereference/strategies/openapi-3-1/visitor.mjs +5 -0
- package/src/dereference/strategies/overlay-1/extends.cjs +52 -28
- package/src/dereference/strategies/overlay-1/extends.mjs +52 -28
- package/src/dereference/strategies/overlay-1/index.cjs +22 -10
- package/src/dereference/strategies/overlay-1/index.mjs +23 -11
- package/src/dereference/strategies/overlay-1/visitor.cjs +27 -2
- package/src/dereference/strategies/overlay-1/visitor.mjs +27 -3
- package/src/parse/parsers/overlay-json-1/extends.cjs +33 -13
- package/src/parse/parsers/overlay-json-1/extends.mjs +33 -14
- package/types/bundle/strategies/openapi-3-0/visitor.d.ts +8 -3
- package/types/dereference/strategies/overlay-1/visitor.d.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@speclynx/apidom-reference",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.1.1",
|
|
4
4
|
"description": "Advanced algorithms for semantic ApiDOM manipulations like dereferencing or resolution.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"apidom",
|
|
@@ -299,33 +299,33 @@
|
|
|
299
299
|
"author": "Vladimir Gorej",
|
|
300
300
|
"license": "Apache-2.0",
|
|
301
301
|
"dependencies": {
|
|
302
|
-
"@babel/runtime-corejs3": "^8.0.
|
|
303
|
-
"@speclynx/apidom-core": "6.
|
|
304
|
-
"@speclynx/apidom-datamodel": "6.
|
|
305
|
-
"@speclynx/apidom-error": "6.
|
|
306
|
-
"@speclynx/apidom-json-pointer": "6.
|
|
307
|
-
"@speclynx/apidom-ns-arazzo-1": "6.
|
|
308
|
-
"@speclynx/apidom-ns-asyncapi-2": "6.
|
|
309
|
-
"@speclynx/apidom-ns-json-schema-2020-12": "6.
|
|
310
|
-
"@speclynx/apidom-ns-openapi-2": "6.
|
|
311
|
-
"@speclynx/apidom-ns-openapi-3-0": "6.
|
|
312
|
-
"@speclynx/apidom-ns-openapi-3-1": "6.
|
|
313
|
-
"@speclynx/apidom-ns-overlay-1": "6.
|
|
314
|
-
"@speclynx/apidom-parser-adapter-arazzo-json-1": "6.
|
|
315
|
-
"@speclynx/apidom-parser-adapter-arazzo-yaml-1": "6.
|
|
316
|
-
"@speclynx/apidom-parser-adapter-asyncapi-json-2": "6.
|
|
317
|
-
"@speclynx/apidom-parser-adapter-asyncapi-yaml-2": "6.
|
|
318
|
-
"@speclynx/apidom-parser-adapter-json": "6.
|
|
319
|
-
"@speclynx/apidom-parser-adapter-openapi-json-2": "6.
|
|
320
|
-
"@speclynx/apidom-parser-adapter-openapi-json-3-0": "6.
|
|
321
|
-
"@speclynx/apidom-parser-adapter-openapi-json-3-1": "6.
|
|
322
|
-
"@speclynx/apidom-parser-adapter-openapi-yaml-2": "6.
|
|
323
|
-
"@speclynx/apidom-parser-adapter-openapi-yaml-3-0": "6.
|
|
324
|
-
"@speclynx/apidom-parser-adapter-openapi-yaml-3-1": "6.
|
|
325
|
-
"@speclynx/apidom-parser-adapter-overlay-json-1": "6.
|
|
326
|
-
"@speclynx/apidom-parser-adapter-overlay-yaml-1": "6.
|
|
327
|
-
"@speclynx/apidom-parser-adapter-yaml-1-2": "6.
|
|
328
|
-
"@speclynx/apidom-traverse": "6.
|
|
302
|
+
"@babel/runtime-corejs3": "^8.0.8",
|
|
303
|
+
"@speclynx/apidom-core": "6.1.1",
|
|
304
|
+
"@speclynx/apidom-datamodel": "6.1.1",
|
|
305
|
+
"@speclynx/apidom-error": "6.1.1",
|
|
306
|
+
"@speclynx/apidom-json-pointer": "6.1.1",
|
|
307
|
+
"@speclynx/apidom-ns-arazzo-1": "6.1.1",
|
|
308
|
+
"@speclynx/apidom-ns-asyncapi-2": "6.1.1",
|
|
309
|
+
"@speclynx/apidom-ns-json-schema-2020-12": "6.1.1",
|
|
310
|
+
"@speclynx/apidom-ns-openapi-2": "6.1.1",
|
|
311
|
+
"@speclynx/apidom-ns-openapi-3-0": "6.1.1",
|
|
312
|
+
"@speclynx/apidom-ns-openapi-3-1": "6.1.1",
|
|
313
|
+
"@speclynx/apidom-ns-overlay-1": "6.1.1",
|
|
314
|
+
"@speclynx/apidom-parser-adapter-arazzo-json-1": "6.1.1",
|
|
315
|
+
"@speclynx/apidom-parser-adapter-arazzo-yaml-1": "6.1.1",
|
|
316
|
+
"@speclynx/apidom-parser-adapter-asyncapi-json-2": "6.1.1",
|
|
317
|
+
"@speclynx/apidom-parser-adapter-asyncapi-yaml-2": "6.1.1",
|
|
318
|
+
"@speclynx/apidom-parser-adapter-json": "6.1.1",
|
|
319
|
+
"@speclynx/apidom-parser-adapter-openapi-json-2": "6.1.1",
|
|
320
|
+
"@speclynx/apidom-parser-adapter-openapi-json-3-0": "6.1.1",
|
|
321
|
+
"@speclynx/apidom-parser-adapter-openapi-json-3-1": "6.1.1",
|
|
322
|
+
"@speclynx/apidom-parser-adapter-openapi-yaml-2": "6.1.1",
|
|
323
|
+
"@speclynx/apidom-parser-adapter-openapi-yaml-3-0": "6.1.1",
|
|
324
|
+
"@speclynx/apidom-parser-adapter-openapi-yaml-3-1": "6.1.1",
|
|
325
|
+
"@speclynx/apidom-parser-adapter-overlay-json-1": "6.1.1",
|
|
326
|
+
"@speclynx/apidom-parser-adapter-overlay-yaml-1": "6.1.1",
|
|
327
|
+
"@speclynx/apidom-parser-adapter-yaml-1-2": "6.1.1",
|
|
328
|
+
"@speclynx/apidom-traverse": "6.1.1",
|
|
329
329
|
"@swaggerexpert/arazzo-runtime-expression": "^3.2.0",
|
|
330
330
|
"axios": "^1.20.0",
|
|
331
331
|
"picomatch": "^4.0.7",
|
|
@@ -346,5 +346,5 @@
|
|
|
346
346
|
"README.md",
|
|
347
347
|
"CHANGELOG.md"
|
|
348
348
|
],
|
|
349
|
-
"gitHead": "
|
|
349
|
+
"gitHead": "c25778097fd33bf5f0d61de6843a6240571f94b3"
|
|
350
350
|
}
|
|
@@ -345,6 +345,11 @@ class AsyncAPI2BundleVisitor {
|
|
|
345
345
|
}
|
|
346
346
|
async ReferenceElement(path) {
|
|
347
347
|
const referencingElement = path.node;
|
|
348
|
+
|
|
349
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
350
|
+
if (!(0, _apidomDatamodel.isStringElement)(referencingElement.$ref)) {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
348
353
|
const $ref = (0, _apidomCore.toValue)(referencingElement.$ref);
|
|
349
354
|
const retrievalURI = this.toBaseURI($ref);
|
|
350
355
|
const isInternalReference = this.entryURI === retrievalURI;
|
|
@@ -337,6 +337,11 @@ class AsyncAPI2BundleVisitor {
|
|
|
337
337
|
}
|
|
338
338
|
async ReferenceElement(path) {
|
|
339
339
|
const referencingElement = path.node;
|
|
340
|
+
|
|
341
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
342
|
+
if (!isStringElement(referencingElement.$ref)) {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
340
345
|
const $ref = toValue(referencingElement.$ref);
|
|
341
346
|
const retrievalURI = this.toBaseURI($ref);
|
|
342
347
|
const isInternalReference = this.entryURI === retrievalURI;
|
|
@@ -313,6 +313,10 @@ class OpenAPI2BundleVisitor {
|
|
|
313
313
|
* and refraction helpers, so the shared logic is parameterized here.
|
|
314
314
|
*/
|
|
315
315
|
async bundleReference(path, referencingElement, isSemanticReference, isReferenceLike, refractReferenceFn, label) {
|
|
316
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
317
|
+
if (!(0, _apidomDatamodel.isStringElement)(referencingElement.$ref)) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
316
320
|
const $ref = (0, _apidomCore.toValue)(referencingElement.$ref);
|
|
317
321
|
const retrievalURI = this.toBaseURI($ref);
|
|
318
322
|
const isInternalReference = this.entryURI === retrievalURI;
|
|
@@ -305,6 +305,10 @@ class OpenAPI2BundleVisitor {
|
|
|
305
305
|
* and refraction helpers, so the shared logic is parameterized here.
|
|
306
306
|
*/
|
|
307
307
|
async bundleReference(path, referencingElement, isSemanticReference, isReferenceLike, refractReferenceFn, label) {
|
|
308
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
309
|
+
if (!isStringElement(referencingElement.$ref)) {
|
|
310
|
+
return;
|
|
311
|
+
}
|
|
308
312
|
const $ref = toValue(referencingElement.$ref);
|
|
309
313
|
const retrievalURI = this.toBaseURI($ref);
|
|
310
314
|
const isInternalReference = this.entryURI === retrievalURI;
|
|
@@ -324,6 +324,11 @@ class OpenAPI3_0BundleVisitor {
|
|
|
324
324
|
}
|
|
325
325
|
async ReferenceElement(path) {
|
|
326
326
|
const referencingElement = path.node;
|
|
327
|
+
|
|
328
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
329
|
+
if (!(0, _apidomDatamodel.isStringElement)(referencingElement.$ref)) {
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
327
332
|
const $ref = (0, _apidomCore.toValue)(referencingElement.$ref);
|
|
328
333
|
const retrievalURI = this.toBaseURI($ref);
|
|
329
334
|
const isInternalReference = this.entryURI === retrievalURI;
|
|
@@ -459,98 +464,108 @@ class OpenAPI3_0BundleVisitor {
|
|
|
459
464
|
* Path Item Object is not a Components Object field in OpenAPI 3.0
|
|
460
465
|
* (unlike 3.1 which has `components.pathItems`). An external Path Item
|
|
461
466
|
* reference therefore cannot be hoisted; it is inlined in place instead,
|
|
462
|
-
* after bundling its own external references.
|
|
467
|
+
* after bundling its own external references. It is inlined on leave, once
|
|
468
|
+
* the sibling fields of the referencing Path Item have been bundled, so the
|
|
469
|
+
* traversal doesn't descend into the inlined copy and inline the `$ref` left
|
|
470
|
+
* in it to break a cycle again.
|
|
463
471
|
*/
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
// ignore Path Item Objects without a $ref field
|
|
468
|
-
if (!(0, _apidomDatamodel.isStringElement)(pathItemElement.$ref)) {
|
|
469
|
-
return;
|
|
470
|
-
}
|
|
471
|
-
const $ref = (0, _apidomCore.toValue)(pathItemElement.$ref);
|
|
472
|
-
const retrievalURI = this.toBaseURI($ref);
|
|
473
|
-
const isInternalReference = this.entryURI === retrievalURI;
|
|
474
|
-
const isExternalReference = !isInternalReference;
|
|
475
|
-
if (isInternalReference) {
|
|
476
|
-
// normalize self-references to a bare fragment so the bundled
|
|
477
|
-
// document stays transferable; bare fragments are left untouched
|
|
478
|
-
pathItemElement.set('$ref', this.normalizeSelfReference($ref));
|
|
479
|
-
return;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
// honor the resolve.external switch
|
|
483
|
-
if (!this.options.resolve.external && isExternalReference) {
|
|
484
|
-
return;
|
|
485
|
-
}
|
|
486
|
-
const $refBaseURI = url.resolve(retrievalURI, $ref);
|
|
487
|
-
const jsonPointer = _apidomJsonPointer.URIFragmentIdentifier.fromURIReference($refBaseURI);
|
|
488
|
-
const canonicalKey = `${retrievalURI}#${jsonPointer}`;
|
|
472
|
+
PathItemElement = {
|
|
473
|
+
leave: async path => {
|
|
474
|
+
const pathItemElement = path.node;
|
|
489
475
|
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
476
|
+
// ignore Path Item Objects without a $ref field
|
|
477
|
+
if (!(0, _apidomDatamodel.isStringElement)(pathItemElement.$ref)) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
const $ref = (0, _apidomCore.toValue)(pathItemElement.$ref);
|
|
481
|
+
const retrievalURI = this.toBaseURI($ref);
|
|
482
|
+
const isInternalReference = this.entryURI === retrievalURI;
|
|
483
|
+
const isExternalReference = !isInternalReference;
|
|
484
|
+
if (isInternalReference) {
|
|
485
|
+
// normalize self-references to a bare fragment so the bundled
|
|
486
|
+
// document stays transferable; bare fragments are left untouched
|
|
487
|
+
pathItemElement.set('$ref', this.normalizeSelfReference($ref));
|
|
488
|
+
return;
|
|
502
489
|
}
|
|
503
|
-
const reference = await this.toReference($ref);
|
|
504
|
-
let referencedElement = (0, _apidomJsonPointer.evaluate)(reference.value.result, jsonPointer);
|
|
505
490
|
|
|
506
|
-
//
|
|
507
|
-
if (!
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
491
|
+
// honor the resolve.external switch
|
|
492
|
+
if (!this.options.resolve.external && isExternalReference) {
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
const $refBaseURI = url.resolve(retrievalURI, $ref);
|
|
496
|
+
const jsonPointer = _apidomJsonPointer.URIFragmentIdentifier.fromURIReference($refBaseURI);
|
|
497
|
+
const canonicalKey = `${retrievalURI}#${jsonPointer}`;
|
|
498
|
+
|
|
499
|
+
// a circular external Path Item reference cannot be inlined without
|
|
500
|
+
// recursing forever; leave the $ref in place to break the cycle. It ends
|
|
501
|
+
// up in the entry document, so it has to resolve from there
|
|
502
|
+
if (this.inlineStack.has(canonicalKey)) {
|
|
503
|
+
const targetURI = url.resolve(this.reference.uri, $ref);
|
|
504
|
+
if (url.resolve(this.entryURI, $ref) !== targetURI) {
|
|
505
|
+
pathItemElement.set('$ref', url.relative(this.entryURI, targetURI));
|
|
515
506
|
}
|
|
507
|
+
return;
|
|
516
508
|
}
|
|
517
|
-
|
|
518
|
-
// own a copy and bundle the external references it contains
|
|
519
|
-
const inlinedElement = (0, _apidomDatamodel.cloneDeep)(referencedElement);
|
|
520
|
-
this.inlineStack.add(canonicalKey);
|
|
521
|
-
const visitor = new OpenAPI3_0BundleVisitor({
|
|
522
|
-
reference,
|
|
523
|
-
options: this.options,
|
|
524
|
-
assignments: this.assignments,
|
|
525
|
-
reservedNames: this.reservedNames,
|
|
526
|
-
refractCache: this.refractCache,
|
|
527
|
-
inlineStack: this.inlineStack
|
|
528
|
-
});
|
|
529
|
-
let bundledElement;
|
|
530
509
|
try {
|
|
531
|
-
|
|
532
|
-
|
|
510
|
+
// detect maximum depth of bundling
|
|
511
|
+
if (this.reference.depth >= this.options.bundle.maxDepth) {
|
|
512
|
+
throw new _MaximumBundleDepthError.default(`Maximum bundle depth of "${this.options.bundle.maxDepth}" has been exceeded in file "${this.reference.uri}"`, {
|
|
513
|
+
maxDepth: this.options.bundle.maxDepth,
|
|
514
|
+
uri: this.reference.uri
|
|
515
|
+
});
|
|
516
|
+
}
|
|
517
|
+
const reference = await this.toReference($ref);
|
|
518
|
+
let referencedElement = (0, _apidomJsonPointer.evaluate)(reference.value.result, jsonPointer);
|
|
519
|
+
|
|
520
|
+
// apply Path Item semantics to the referenced fragment
|
|
521
|
+
if (!(0, _apidomNsOpenapi.isPathItemElement)(referencedElement)) {
|
|
522
|
+
const cached = this.getRefracted(referencedElement, 'pathItem');
|
|
523
|
+
if (cached !== undefined) {
|
|
524
|
+
referencedElement = cached;
|
|
525
|
+
} else {
|
|
526
|
+
const sourceElement = referencedElement;
|
|
527
|
+
referencedElement = (0, _apidomNsOpenapi.refractPathItem)(referencedElement);
|
|
528
|
+
this.setRefracted(sourceElement, 'pathItem', referencedElement);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// own a copy and bundle the external references it contains
|
|
533
|
+
const inlinedElement = (0, _apidomDatamodel.cloneDeep)(referencedElement);
|
|
534
|
+
this.inlineStack.add(canonicalKey);
|
|
535
|
+
const visitor = new OpenAPI3_0BundleVisitor({
|
|
536
|
+
reference,
|
|
537
|
+
options: this.options,
|
|
538
|
+
assignments: this.assignments,
|
|
539
|
+
reservedNames: this.reservedNames,
|
|
540
|
+
refractCache: this.refractCache,
|
|
541
|
+
inlineStack: this.inlineStack
|
|
533
542
|
});
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
543
|
+
let bundledElement;
|
|
544
|
+
try {
|
|
545
|
+
bundledElement = await (0, _apidomTraverse.traverseAsync)(inlinedElement, visitor, {
|
|
546
|
+
mutable: true
|
|
547
|
+
});
|
|
548
|
+
} finally {
|
|
549
|
+
this.inlineStack.delete(canonicalKey);
|
|
550
|
+
}
|
|
537
551
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
+
// merge sibling fields from the referencing Path Item over the referenced
|
|
553
|
+
// one. The referencing `$ref` is being resolved away and is skipped; the
|
|
554
|
+
// referenced element keeps its own `$ref` if one survived (i.e. it was
|
|
555
|
+
// left in place to break a circular external Path Item chain).
|
|
556
|
+
pathItemElement.forEach((_value, keyElement, item) => {
|
|
557
|
+
const key = (0, _apidomCore.toValue)(keyElement);
|
|
558
|
+
if (key === '$ref') return;
|
|
559
|
+
bundledElement.remove(key);
|
|
560
|
+
bundledElement.content.push(item);
|
|
561
|
+
});
|
|
562
|
+
bundledElement.meta.set('ref-origin', reference.uri);
|
|
563
|
+
path.replaceWith(bundledElement);
|
|
564
|
+
} catch (error) {
|
|
565
|
+
this.handleError(`Error while bundling Path Item Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, pathItemElement, '$ref', $ref, path);
|
|
566
|
+
}
|
|
552
567
|
}
|
|
553
|
-
}
|
|
568
|
+
};
|
|
554
569
|
|
|
555
570
|
/**
|
|
556
571
|
* Example Object `externalValue` points at arbitrary external content that
|
|
@@ -316,6 +316,11 @@ class OpenAPI3_0BundleVisitor {
|
|
|
316
316
|
}
|
|
317
317
|
async ReferenceElement(path) {
|
|
318
318
|
const referencingElement = path.node;
|
|
319
|
+
|
|
320
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
321
|
+
if (!isStringElement(referencingElement.$ref)) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
319
324
|
const $ref = toValue(referencingElement.$ref);
|
|
320
325
|
const retrievalURI = this.toBaseURI($ref);
|
|
321
326
|
const isInternalReference = this.entryURI === retrievalURI;
|
|
@@ -451,98 +456,108 @@ class OpenAPI3_0BundleVisitor {
|
|
|
451
456
|
* Path Item Object is not a Components Object field in OpenAPI 3.0
|
|
452
457
|
* (unlike 3.1 which has `components.pathItems`). An external Path Item
|
|
453
458
|
* reference therefore cannot be hoisted; it is inlined in place instead,
|
|
454
|
-
* after bundling its own external references.
|
|
459
|
+
* after bundling its own external references. It is inlined on leave, once
|
|
460
|
+
* the sibling fields of the referencing Path Item have been bundled, so the
|
|
461
|
+
* traversal doesn't descend into the inlined copy and inline the `$ref` left
|
|
462
|
+
* in it to break a cycle again.
|
|
455
463
|
*/
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
// ignore Path Item Objects without a $ref field
|
|
460
|
-
if (!isStringElement(pathItemElement.$ref)) {
|
|
461
|
-
return;
|
|
462
|
-
}
|
|
463
|
-
const $ref = toValue(pathItemElement.$ref);
|
|
464
|
-
const retrievalURI = this.toBaseURI($ref);
|
|
465
|
-
const isInternalReference = this.entryURI === retrievalURI;
|
|
466
|
-
const isExternalReference = !isInternalReference;
|
|
467
|
-
if (isInternalReference) {
|
|
468
|
-
// normalize self-references to a bare fragment so the bundled
|
|
469
|
-
// document stays transferable; bare fragments are left untouched
|
|
470
|
-
pathItemElement.set('$ref', this.normalizeSelfReference($ref));
|
|
471
|
-
return;
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
// honor the resolve.external switch
|
|
475
|
-
if (!this.options.resolve.external && isExternalReference) {
|
|
476
|
-
return;
|
|
477
|
-
}
|
|
478
|
-
const $refBaseURI = url.resolve(retrievalURI, $ref);
|
|
479
|
-
const jsonPointer = URIFragmentIdentifier.fromURIReference($refBaseURI);
|
|
480
|
-
const canonicalKey = `${retrievalURI}#${jsonPointer}`;
|
|
464
|
+
PathItemElement = {
|
|
465
|
+
leave: async path => {
|
|
466
|
+
const pathItemElement = path.node;
|
|
481
467
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
468
|
+
// ignore Path Item Objects without a $ref field
|
|
469
|
+
if (!isStringElement(pathItemElement.$ref)) {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
const $ref = toValue(pathItemElement.$ref);
|
|
473
|
+
const retrievalURI = this.toBaseURI($ref);
|
|
474
|
+
const isInternalReference = this.entryURI === retrievalURI;
|
|
475
|
+
const isExternalReference = !isInternalReference;
|
|
476
|
+
if (isInternalReference) {
|
|
477
|
+
// normalize self-references to a bare fragment so the bundled
|
|
478
|
+
// document stays transferable; bare fragments are left untouched
|
|
479
|
+
pathItemElement.set('$ref', this.normalizeSelfReference($ref));
|
|
480
|
+
return;
|
|
494
481
|
}
|
|
495
|
-
const reference = await this.toReference($ref);
|
|
496
|
-
let referencedElement = evaluate(reference.value.result, jsonPointer);
|
|
497
482
|
|
|
498
|
-
//
|
|
499
|
-
if (!
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
483
|
+
// honor the resolve.external switch
|
|
484
|
+
if (!this.options.resolve.external && isExternalReference) {
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
const $refBaseURI = url.resolve(retrievalURI, $ref);
|
|
488
|
+
const jsonPointer = URIFragmentIdentifier.fromURIReference($refBaseURI);
|
|
489
|
+
const canonicalKey = `${retrievalURI}#${jsonPointer}`;
|
|
490
|
+
|
|
491
|
+
// a circular external Path Item reference cannot be inlined without
|
|
492
|
+
// recursing forever; leave the $ref in place to break the cycle. It ends
|
|
493
|
+
// up in the entry document, so it has to resolve from there
|
|
494
|
+
if (this.inlineStack.has(canonicalKey)) {
|
|
495
|
+
const targetURI = url.resolve(this.reference.uri, $ref);
|
|
496
|
+
if (url.resolve(this.entryURI, $ref) !== targetURI) {
|
|
497
|
+
pathItemElement.set('$ref', url.relative(this.entryURI, targetURI));
|
|
507
498
|
}
|
|
499
|
+
return;
|
|
508
500
|
}
|
|
509
|
-
|
|
510
|
-
// own a copy and bundle the external references it contains
|
|
511
|
-
const inlinedElement = cloneDeep(referencedElement);
|
|
512
|
-
this.inlineStack.add(canonicalKey);
|
|
513
|
-
const visitor = new OpenAPI3_0BundleVisitor({
|
|
514
|
-
reference,
|
|
515
|
-
options: this.options,
|
|
516
|
-
assignments: this.assignments,
|
|
517
|
-
reservedNames: this.reservedNames,
|
|
518
|
-
refractCache: this.refractCache,
|
|
519
|
-
inlineStack: this.inlineStack
|
|
520
|
-
});
|
|
521
|
-
let bundledElement;
|
|
522
501
|
try {
|
|
523
|
-
|
|
524
|
-
|
|
502
|
+
// detect maximum depth of bundling
|
|
503
|
+
if (this.reference.depth >= this.options.bundle.maxDepth) {
|
|
504
|
+
throw new MaximumBundleDepthError(`Maximum bundle depth of "${this.options.bundle.maxDepth}" has been exceeded in file "${this.reference.uri}"`, {
|
|
505
|
+
maxDepth: this.options.bundle.maxDepth,
|
|
506
|
+
uri: this.reference.uri
|
|
507
|
+
});
|
|
508
|
+
}
|
|
509
|
+
const reference = await this.toReference($ref);
|
|
510
|
+
let referencedElement = evaluate(reference.value.result, jsonPointer);
|
|
511
|
+
|
|
512
|
+
// apply Path Item semantics to the referenced fragment
|
|
513
|
+
if (!isPathItemElement(referencedElement)) {
|
|
514
|
+
const cached = this.getRefracted(referencedElement, 'pathItem');
|
|
515
|
+
if (cached !== undefined) {
|
|
516
|
+
referencedElement = cached;
|
|
517
|
+
} else {
|
|
518
|
+
const sourceElement = referencedElement;
|
|
519
|
+
referencedElement = refractPathItem(referencedElement);
|
|
520
|
+
this.setRefracted(sourceElement, 'pathItem', referencedElement);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// own a copy and bundle the external references it contains
|
|
525
|
+
const inlinedElement = cloneDeep(referencedElement);
|
|
526
|
+
this.inlineStack.add(canonicalKey);
|
|
527
|
+
const visitor = new OpenAPI3_0BundleVisitor({
|
|
528
|
+
reference,
|
|
529
|
+
options: this.options,
|
|
530
|
+
assignments: this.assignments,
|
|
531
|
+
reservedNames: this.reservedNames,
|
|
532
|
+
refractCache: this.refractCache,
|
|
533
|
+
inlineStack: this.inlineStack
|
|
525
534
|
});
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
535
|
+
let bundledElement;
|
|
536
|
+
try {
|
|
537
|
+
bundledElement = await traverseAsync(inlinedElement, visitor, {
|
|
538
|
+
mutable: true
|
|
539
|
+
});
|
|
540
|
+
} finally {
|
|
541
|
+
this.inlineStack.delete(canonicalKey);
|
|
542
|
+
}
|
|
529
543
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
+
// merge sibling fields from the referencing Path Item over the referenced
|
|
545
|
+
// one. The referencing `$ref` is being resolved away and is skipped; the
|
|
546
|
+
// referenced element keeps its own `$ref` if one survived (i.e. it was
|
|
547
|
+
// left in place to break a circular external Path Item chain).
|
|
548
|
+
pathItemElement.forEach((_value, keyElement, item) => {
|
|
549
|
+
const key = toValue(keyElement);
|
|
550
|
+
if (key === '$ref') return;
|
|
551
|
+
bundledElement.remove(key);
|
|
552
|
+
bundledElement.content.push(item);
|
|
553
|
+
});
|
|
554
|
+
bundledElement.meta.set('ref-origin', reference.uri);
|
|
555
|
+
path.replaceWith(bundledElement);
|
|
556
|
+
} catch (error) {
|
|
557
|
+
this.handleError(`Error while bundling Path Item Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, pathItemElement, '$ref', $ref, path);
|
|
558
|
+
}
|
|
544
559
|
}
|
|
545
|
-
}
|
|
560
|
+
};
|
|
546
561
|
|
|
547
562
|
/**
|
|
548
563
|
* Example Object `externalValue` points at arbitrary external content that
|
|
@@ -422,6 +422,11 @@ class OpenAPI3_1BundleVisitor {
|
|
|
422
422
|
};
|
|
423
423
|
async ReferenceElement(path) {
|
|
424
424
|
const referencingElement = path.node;
|
|
425
|
+
|
|
426
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
427
|
+
if (!(0, _apidomDatamodel.isStringElement)(referencingElement.$ref)) {
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
425
430
|
const $ref = (0, _apidomCore.toValue)(referencingElement.$ref);
|
|
426
431
|
const retrievalURI = this.toBaseURI($ref);
|
|
427
432
|
const isInternalReference = this.entryURI === retrievalURI;
|
|
@@ -414,6 +414,11 @@ class OpenAPI3_1BundleVisitor {
|
|
|
414
414
|
};
|
|
415
415
|
async ReferenceElement(path) {
|
|
416
416
|
const referencingElement = path.node;
|
|
417
|
+
|
|
418
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
419
|
+
if (!isStringElement(referencingElement.$ref)) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
417
422
|
const $ref = toValue(referencingElement.$ref);
|
|
418
423
|
const retrievalURI = this.toBaseURI($ref);
|
|
419
424
|
const isInternalReference = this.entryURI === retrievalURI;
|
|
@@ -202,6 +202,11 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
202
202
|
async ReferenceElement(path) {
|
|
203
203
|
const referencingElement = path.node;
|
|
204
204
|
|
|
205
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
206
|
+
if (!(0, _apidomDatamodel.isStringElement)(referencingElement.$ref)) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
205
210
|
// skip current referencing element as it's already been access
|
|
206
211
|
if (this.indirections.includes(referencingElement)) {
|
|
207
212
|
path.skip();
|
|
@@ -193,6 +193,11 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
193
193
|
async ReferenceElement(path) {
|
|
194
194
|
const referencingElement = path.node;
|
|
195
195
|
|
|
196
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
197
|
+
if (!isStringElement(referencingElement.$ref)) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
196
201
|
// skip current referencing element as it's already been access
|
|
197
202
|
if (this.indirections.includes(referencingElement)) {
|
|
198
203
|
path.skip();
|
|
@@ -202,6 +202,11 @@ class OpenAPI2DereferenceVisitor {
|
|
|
202
202
|
async ReferenceElement(path) {
|
|
203
203
|
const referencingElement = path.node;
|
|
204
204
|
|
|
205
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
206
|
+
if (!(0, _apidomDatamodel.isStringElement)(referencingElement.$ref)) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
205
210
|
// skip current referencing element as it's already been access
|
|
206
211
|
if (this.indirections.includes(referencingElement)) {
|
|
207
212
|
path.skip();
|
|
@@ -505,6 +510,11 @@ class OpenAPI2DereferenceVisitor {
|
|
|
505
510
|
async JSONReferenceElement(path) {
|
|
506
511
|
const referencingElement = path.node;
|
|
507
512
|
|
|
513
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
514
|
+
if (!(0, _apidomDatamodel.isStringElement)(referencingElement.$ref)) {
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
|
|
508
518
|
// skip current referencing element as it's already been access
|
|
509
519
|
if (this.indirections.includes(referencingElement)) {
|
|
510
520
|
path.skip();
|
|
@@ -193,6 +193,11 @@ class OpenAPI2DereferenceVisitor {
|
|
|
193
193
|
async ReferenceElement(path) {
|
|
194
194
|
const referencingElement = path.node;
|
|
195
195
|
|
|
196
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
197
|
+
if (!isStringElement(referencingElement.$ref)) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
196
201
|
// skip current referencing element as it's already been access
|
|
197
202
|
if (this.indirections.includes(referencingElement)) {
|
|
198
203
|
path.skip();
|
|
@@ -496,6 +501,11 @@ class OpenAPI2DereferenceVisitor {
|
|
|
496
501
|
async JSONReferenceElement(path) {
|
|
497
502
|
const referencingElement = path.node;
|
|
498
503
|
|
|
504
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
505
|
+
if (!isStringElement(referencingElement.$ref)) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
|
|
499
509
|
// skip current referencing element as it's already been access
|
|
500
510
|
if (this.indirections.includes(referencingElement)) {
|
|
501
511
|
path.skip();
|
|
@@ -203,6 +203,11 @@ class OpenAPI3_0DereferenceVisitor {
|
|
|
203
203
|
async ReferenceElement(path) {
|
|
204
204
|
const referencingElement = path.node;
|
|
205
205
|
|
|
206
|
+
// ignore Reference Object without a string $ref, e.g. an empty YAML value
|
|
207
|
+
if (!(0, _apidomDatamodel.isStringElement)(referencingElement.$ref)) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
206
211
|
// skip current referencing element as it's already been access
|
|
207
212
|
if (this.indirections.includes(referencingElement)) {
|
|
208
213
|
path.skip();
|