@speclynx/apidom-reference 4.7.1 → 4.9.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/CHANGELOG.md +10 -0
- package/dist/apidom-reference.browser.js +148 -36
- package/dist/apidom-reference.browser.min.js +1 -1
- package/package.json +28 -28
- package/src/dereference/strategies/arazzo-1/index.cjs +5 -1
- package/src/dereference/strategies/arazzo-1/index.mjs +5 -1
- package/src/dereference/strategies/arazzo-1/visitor.cjs +12 -3
- package/src/dereference/strategies/arazzo-1/visitor.mjs +12 -3
- package/src/dereference/strategies/asyncapi-2/index.cjs +5 -1
- package/src/dereference/strategies/asyncapi-2/index.mjs +5 -1
- package/src/dereference/strategies/asyncapi-2/visitor.cjs +20 -5
- package/src/dereference/strategies/asyncapi-2/visitor.mjs +20 -5
- package/src/dereference/strategies/openapi-2/index.cjs +5 -1
- package/src/dereference/strategies/openapi-2/index.mjs +5 -1
- package/src/dereference/strategies/openapi-2/visitor.cjs +28 -7
- package/src/dereference/strategies/openapi-2/visitor.mjs +28 -7
- package/src/dereference/strategies/openapi-3-0/index.cjs +5 -1
- package/src/dereference/strategies/openapi-3-0/index.mjs +5 -1
- package/src/dereference/strategies/openapi-3-0/visitor.cjs +20 -5
- package/src/dereference/strategies/openapi-3-0/visitor.mjs +20 -5
- package/src/dereference/strategies/openapi-3-1/index.cjs +5 -1
- package/src/dereference/strategies/openapi-3-1/index.mjs +5 -1
- package/src/dereference/strategies/openapi-3-1/visitor.cjs +25 -7
- package/src/dereference/strategies/openapi-3-1/visitor.mjs +25 -7
- package/types/dereference/strategies/arazzo-1/visitor.d.ts +3 -1
- package/types/dereference/strategies/asyncapi-2/visitor.d.ts +3 -1
- package/types/dereference/strategies/openapi-2/visitor.d.ts +3 -1
- package/types/dereference/strategies/openapi-3-0/visitor.d.ts +3 -1
- package/types/dereference/strategies/openapi-3-1/visitor.d.ts +3 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@speclynx/apidom-reference",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.9.0",
|
|
4
4
|
"description": "Advanced algorithms for semantic ApiDOM manipulations like dereferencing or resolution.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"apidom",
|
|
@@ -279,32 +279,32 @@
|
|
|
279
279
|
"license": "Apache-2.0",
|
|
280
280
|
"dependencies": {
|
|
281
281
|
"@babel/runtime-corejs3": "^7.28.4",
|
|
282
|
-
"@speclynx/apidom-core": "4.
|
|
283
|
-
"@speclynx/apidom-datamodel": "4.
|
|
284
|
-
"@speclynx/apidom-error": "4.
|
|
285
|
-
"@speclynx/apidom-json-pointer": "4.
|
|
286
|
-
"@speclynx/apidom-ns-arazzo-1": "4.
|
|
287
|
-
"@speclynx/apidom-ns-asyncapi-2": "4.
|
|
288
|
-
"@speclynx/apidom-ns-json-schema-2020-12": "4.
|
|
289
|
-
"@speclynx/apidom-ns-openapi-2": "4.
|
|
290
|
-
"@speclynx/apidom-ns-openapi-3-0": "4.
|
|
291
|
-
"@speclynx/apidom-ns-openapi-3-1": "4.
|
|
292
|
-
"@speclynx/apidom-ns-overlay-1": "4.
|
|
293
|
-
"@speclynx/apidom-parser-adapter-arazzo-json-1": "4.
|
|
294
|
-
"@speclynx/apidom-parser-adapter-arazzo-yaml-1": "4.
|
|
295
|
-
"@speclynx/apidom-parser-adapter-asyncapi-json-2": "4.
|
|
296
|
-
"@speclynx/apidom-parser-adapter-asyncapi-yaml-2": "4.
|
|
297
|
-
"@speclynx/apidom-parser-adapter-json": "4.
|
|
298
|
-
"@speclynx/apidom-parser-adapter-openapi-json-2": "4.
|
|
299
|
-
"@speclynx/apidom-parser-adapter-openapi-json-3-0": "4.
|
|
300
|
-
"@speclynx/apidom-parser-adapter-openapi-json-3-1": "4.
|
|
301
|
-
"@speclynx/apidom-parser-adapter-openapi-yaml-2": "4.
|
|
302
|
-
"@speclynx/apidom-parser-adapter-openapi-yaml-3-0": "4.
|
|
303
|
-
"@speclynx/apidom-parser-adapter-openapi-yaml-3-1": "4.
|
|
304
|
-
"@speclynx/apidom-parser-adapter-overlay-json-1": "4.
|
|
305
|
-
"@speclynx/apidom-parser-adapter-overlay-yaml-1": "4.
|
|
306
|
-
"@speclynx/apidom-parser-adapter-yaml-1-2": "4.
|
|
307
|
-
"@speclynx/apidom-traverse": "4.
|
|
282
|
+
"@speclynx/apidom-core": "4.9.0",
|
|
283
|
+
"@speclynx/apidom-datamodel": "4.9.0",
|
|
284
|
+
"@speclynx/apidom-error": "4.9.0",
|
|
285
|
+
"@speclynx/apidom-json-pointer": "4.9.0",
|
|
286
|
+
"@speclynx/apidom-ns-arazzo-1": "4.9.0",
|
|
287
|
+
"@speclynx/apidom-ns-asyncapi-2": "4.9.0",
|
|
288
|
+
"@speclynx/apidom-ns-json-schema-2020-12": "4.9.0",
|
|
289
|
+
"@speclynx/apidom-ns-openapi-2": "4.9.0",
|
|
290
|
+
"@speclynx/apidom-ns-openapi-3-0": "4.9.0",
|
|
291
|
+
"@speclynx/apidom-ns-openapi-3-1": "4.9.0",
|
|
292
|
+
"@speclynx/apidom-ns-overlay-1": "4.9.0",
|
|
293
|
+
"@speclynx/apidom-parser-adapter-arazzo-json-1": "4.9.0",
|
|
294
|
+
"@speclynx/apidom-parser-adapter-arazzo-yaml-1": "4.9.0",
|
|
295
|
+
"@speclynx/apidom-parser-adapter-asyncapi-json-2": "4.9.0",
|
|
296
|
+
"@speclynx/apidom-parser-adapter-asyncapi-yaml-2": "4.9.0",
|
|
297
|
+
"@speclynx/apidom-parser-adapter-json": "4.9.0",
|
|
298
|
+
"@speclynx/apidom-parser-adapter-openapi-json-2": "4.9.0",
|
|
299
|
+
"@speclynx/apidom-parser-adapter-openapi-json-3-0": "4.9.0",
|
|
300
|
+
"@speclynx/apidom-parser-adapter-openapi-json-3-1": "4.9.0",
|
|
301
|
+
"@speclynx/apidom-parser-adapter-openapi-yaml-2": "4.9.0",
|
|
302
|
+
"@speclynx/apidom-parser-adapter-openapi-yaml-3-0": "4.9.0",
|
|
303
|
+
"@speclynx/apidom-parser-adapter-openapi-yaml-3-1": "4.9.0",
|
|
304
|
+
"@speclynx/apidom-parser-adapter-overlay-json-1": "4.9.0",
|
|
305
|
+
"@speclynx/apidom-parser-adapter-overlay-yaml-1": "4.9.0",
|
|
306
|
+
"@speclynx/apidom-parser-adapter-yaml-1-2": "4.9.0",
|
|
307
|
+
"@speclynx/apidom-traverse": "4.9.0",
|
|
308
308
|
"@swaggerexpert/arazzo-runtime-expression": "^2.0.3",
|
|
309
309
|
"axios": "^1.15.0",
|
|
310
310
|
"picomatch": "^4.0.4",
|
|
@@ -326,5 +326,5 @@
|
|
|
326
326
|
"README.md",
|
|
327
327
|
"CHANGELOG.md"
|
|
328
328
|
],
|
|
329
|
-
"gitHead": "
|
|
329
|
+
"gitHead": "918b3a7102bc7a8991b0fe1b92aeeb0aaeb2b30f"
|
|
330
330
|
}
|
|
@@ -68,12 +68,16 @@ class Arazzo1DereferenceStrategy extends _DereferenceStrategy.default {
|
|
|
68
68
|
reference = mutableRefSet.find(ref => ref.uri === file.uri);
|
|
69
69
|
refSet = mutableRefSet;
|
|
70
70
|
}
|
|
71
|
+
const shouldDetectCircular = ['error', 'replace'].includes(options.dereference.circular);
|
|
71
72
|
const visitor = new _visitor.default({
|
|
72
73
|
reference,
|
|
73
74
|
options
|
|
74
75
|
});
|
|
75
76
|
const dereferencedElement = await (0, _apidomTraverse.traverseAsync)(refSet.rootRef.value, visitor, {
|
|
76
|
-
mutable: true
|
|
77
|
+
mutable: true,
|
|
78
|
+
...(shouldDetectCircular && {
|
|
79
|
+
skipVisited: true
|
|
80
|
+
})
|
|
77
81
|
});
|
|
78
82
|
|
|
79
83
|
/**
|
|
@@ -56,12 +56,16 @@ class Arazzo1DereferenceStrategy extends DereferenceStrategy {
|
|
|
56
56
|
reference = mutableRefSet.find(ref => ref.uri === file.uri);
|
|
57
57
|
refSet = mutableRefSet;
|
|
58
58
|
}
|
|
59
|
+
const shouldDetectCircular = ['error', 'replace'].includes(options.dereference.circular);
|
|
59
60
|
const visitor = new Arazzo1DereferenceVisitor({
|
|
60
61
|
reference,
|
|
61
62
|
options
|
|
62
63
|
});
|
|
63
64
|
const dereferencedElement = await traverseAsync(refSet.rootRef.value, visitor, {
|
|
64
|
-
mutable: true
|
|
65
|
+
mutable: true,
|
|
66
|
+
...(shouldDetectCircular && {
|
|
67
|
+
skipVisited: true
|
|
68
|
+
})
|
|
65
69
|
});
|
|
66
70
|
|
|
67
71
|
/**
|
|
@@ -36,6 +36,7 @@ class Arazzo1DereferenceVisitor {
|
|
|
36
36
|
indirections;
|
|
37
37
|
reference;
|
|
38
38
|
options;
|
|
39
|
+
visited;
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* Tracks element ancestors across dive-deep traversal boundaries.
|
|
@@ -47,12 +48,14 @@ class Arazzo1DereferenceVisitor {
|
|
|
47
48
|
reference,
|
|
48
49
|
options,
|
|
49
50
|
indirections = [],
|
|
50
|
-
ancestors = new _util3.AncestorLineage()
|
|
51
|
+
ancestors = new _util3.AncestorLineage(),
|
|
52
|
+
visited = new WeakSet()
|
|
51
53
|
}) {
|
|
52
54
|
this.indirections = indirections;
|
|
53
55
|
this.reference = reference;
|
|
54
56
|
this.options = options;
|
|
55
57
|
this.ancestors = new _util3.AncestorLineage(...ancestors);
|
|
58
|
+
this.visited = visited;
|
|
56
59
|
}
|
|
57
60
|
toAncestorLineage(path) {
|
|
58
61
|
const ancestorNodes = path.getAncestorNodes();
|
|
@@ -443,17 +446,23 @@ class Arazzo1DereferenceVisitor {
|
|
|
443
446
|
*/
|
|
444
447
|
const isNonEntryDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
|
|
445
448
|
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
|
|
446
|
-
if ((isExternalReference || isNonEntryDocument || (0, _apidomNsArazzo.isJSONSchemaElement)(referencedElement) && (0, _apidomDatamodel.isStringElement)(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
449
|
+
if ((isExternalReference || isNonEntryDocument || (0, _apidomNsArazzo.isJSONSchemaElement)(referencedElement) && (0, _apidomDatamodel.isStringElement)(referencedElement.$ref) || shouldDetectCircular && !this.visited.has(referencedElement)) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
450
|
+
if (shouldDetectCircular) {
|
|
451
|
+
this.visited.add(referencedElement);
|
|
452
|
+
}
|
|
453
|
+
|
|
447
454
|
// append referencing reference to ancestors lineage
|
|
448
455
|
directAncestors.add(referencingElement);
|
|
449
456
|
const visitor = new Arazzo1DereferenceVisitor({
|
|
450
457
|
reference,
|
|
451
458
|
indirections: [...this.indirections],
|
|
452
459
|
options: this.options,
|
|
460
|
+
visited: this.visited,
|
|
453
461
|
ancestors: ancestorsLineage
|
|
454
462
|
});
|
|
455
463
|
referencedElement = await (0, _apidomTraverse.traverseAsync)(referencedElement, visitor, {
|
|
456
|
-
mutable: true
|
|
464
|
+
mutable: true,
|
|
465
|
+
skipVisited: true
|
|
457
466
|
});
|
|
458
467
|
|
|
459
468
|
// remove referencing reference from ancestors lineage
|
|
@@ -29,6 +29,7 @@ class Arazzo1DereferenceVisitor {
|
|
|
29
29
|
indirections;
|
|
30
30
|
reference;
|
|
31
31
|
options;
|
|
32
|
+
visited;
|
|
32
33
|
|
|
33
34
|
/**
|
|
34
35
|
* Tracks element ancestors across dive-deep traversal boundaries.
|
|
@@ -40,12 +41,14 @@ class Arazzo1DereferenceVisitor {
|
|
|
40
41
|
reference,
|
|
41
42
|
options,
|
|
42
43
|
indirections = [],
|
|
43
|
-
ancestors = new AncestorLineage()
|
|
44
|
+
ancestors = new AncestorLineage(),
|
|
45
|
+
visited = new WeakSet()
|
|
44
46
|
}) {
|
|
45
47
|
this.indirections = indirections;
|
|
46
48
|
this.reference = reference;
|
|
47
49
|
this.options = options;
|
|
48
50
|
this.ancestors = new AncestorLineage(...ancestors);
|
|
51
|
+
this.visited = visited;
|
|
49
52
|
}
|
|
50
53
|
toAncestorLineage(path) {
|
|
51
54
|
const ancestorNodes = path.getAncestorNodes();
|
|
@@ -436,17 +439,23 @@ class Arazzo1DereferenceVisitor {
|
|
|
436
439
|
*/
|
|
437
440
|
const isNonEntryDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
|
|
438
441
|
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
|
|
439
|
-
if ((isExternalReference || isNonEntryDocument || isJSONSchemaElement(referencedElement) && isStringElement(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
442
|
+
if ((isExternalReference || isNonEntryDocument || isJSONSchemaElement(referencedElement) && isStringElement(referencedElement.$ref) || shouldDetectCircular && !this.visited.has(referencedElement)) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
443
|
+
if (shouldDetectCircular) {
|
|
444
|
+
this.visited.add(referencedElement);
|
|
445
|
+
}
|
|
446
|
+
|
|
440
447
|
// append referencing reference to ancestors lineage
|
|
441
448
|
directAncestors.add(referencingElement);
|
|
442
449
|
const visitor = new Arazzo1DereferenceVisitor({
|
|
443
450
|
reference,
|
|
444
451
|
indirections: [...this.indirections],
|
|
445
452
|
options: this.options,
|
|
453
|
+
visited: this.visited,
|
|
446
454
|
ancestors: ancestorsLineage
|
|
447
455
|
});
|
|
448
456
|
referencedElement = await traverseAsync(referencedElement, visitor, {
|
|
449
|
-
mutable: true
|
|
457
|
+
mutable: true,
|
|
458
|
+
skipVisited: true
|
|
450
459
|
});
|
|
451
460
|
|
|
452
461
|
// remove referencing reference from ancestors lineage
|
|
@@ -62,12 +62,16 @@ class AsyncAPI2DereferenceStrategy extends _DereferenceStrategy.default {
|
|
|
62
62
|
reference = mutableRefSet.find(ref => ref.uri === file.uri);
|
|
63
63
|
refSet = mutableRefSet;
|
|
64
64
|
}
|
|
65
|
+
const shouldDetectCircular = ['error', 'replace'].includes(options.dereference.circular);
|
|
65
66
|
const visitor = new _visitor.default({
|
|
66
67
|
reference,
|
|
67
68
|
options
|
|
68
69
|
});
|
|
69
70
|
const dereferencedElement = await (0, _apidomTraverse.traverseAsync)(refSet.rootRef.value, visitor, {
|
|
70
|
-
mutable: true
|
|
71
|
+
mutable: true,
|
|
72
|
+
...(shouldDetectCircular && {
|
|
73
|
+
skipVisited: true
|
|
74
|
+
})
|
|
71
75
|
});
|
|
72
76
|
|
|
73
77
|
/**
|
|
@@ -55,12 +55,16 @@ class AsyncAPI2DereferenceStrategy extends DereferenceStrategy {
|
|
|
55
55
|
reference = mutableRefSet.find(ref => ref.uri === file.uri);
|
|
56
56
|
refSet = mutableRefSet;
|
|
57
57
|
}
|
|
58
|
+
const shouldDetectCircular = ['error', 'replace'].includes(options.dereference.circular);
|
|
58
59
|
const visitor = new AsyncAPI2DereferenceVisitor({
|
|
59
60
|
reference,
|
|
60
61
|
options
|
|
61
62
|
});
|
|
62
63
|
const dereferencedElement = await traverseAsync(refSet.rootRef.value, visitor, {
|
|
63
|
-
mutable: true
|
|
64
|
+
mutable: true,
|
|
65
|
+
...(shouldDetectCircular && {
|
|
66
|
+
skipVisited: true
|
|
67
|
+
})
|
|
64
68
|
});
|
|
65
69
|
|
|
66
70
|
/**
|
|
@@ -30,6 +30,7 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
30
30
|
reference;
|
|
31
31
|
options;
|
|
32
32
|
refractCache;
|
|
33
|
+
visited;
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* Tracks element ancestors across dive-deep traversal boundaries.
|
|
@@ -42,13 +43,15 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
42
43
|
options,
|
|
43
44
|
indirections = [],
|
|
44
45
|
ancestors = new _util.AncestorLineage(),
|
|
45
|
-
refractCache = new WeakMap()
|
|
46
|
+
refractCache = new WeakMap(),
|
|
47
|
+
visited = new WeakSet()
|
|
46
48
|
}) {
|
|
47
49
|
this.indirections = indirections;
|
|
48
50
|
this.reference = reference;
|
|
49
51
|
this.options = options;
|
|
50
52
|
this.ancestors = new _util.AncestorLineage(...ancestors);
|
|
51
53
|
this.refractCache = refractCache;
|
|
54
|
+
this.visited = visited;
|
|
52
55
|
}
|
|
53
56
|
toAncestorLineage(path) {
|
|
54
57
|
const ancestorNodes = path.getAncestorNodes();
|
|
@@ -297,7 +300,11 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
297
300
|
*/
|
|
298
301
|
const isNonEntryDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
|
|
299
302
|
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
|
|
300
|
-
if ((isExternalReference || isNonEntryDocument || (0, _apidomNsAsyncapi.isReferenceElement)(referencedElement) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
303
|
+
if ((isExternalReference || isNonEntryDocument || (0, _apidomNsAsyncapi.isReferenceElement)(referencedElement) || shouldDetectCircular && !this.visited.has(referencedElement)) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
304
|
+
if (shouldDetectCircular) {
|
|
305
|
+
this.visited.add(referencedElement);
|
|
306
|
+
}
|
|
307
|
+
|
|
301
308
|
// append referencing reference to ancestors lineage
|
|
302
309
|
directAncestors.add(referencingElement);
|
|
303
310
|
const visitor = new AsyncAPI2DereferenceVisitor({
|
|
@@ -305,10 +312,12 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
305
312
|
indirections: [...this.indirections],
|
|
306
313
|
options: this.options,
|
|
307
314
|
refractCache: this.refractCache,
|
|
315
|
+
visited: this.visited,
|
|
308
316
|
ancestors: ancestorsLineage
|
|
309
317
|
});
|
|
310
318
|
referencedElement = await (0, _apidomTraverse.traverseAsync)(referencedElement, visitor, {
|
|
311
|
-
mutable: true
|
|
319
|
+
mutable: true,
|
|
320
|
+
skipVisited: true
|
|
312
321
|
});
|
|
313
322
|
|
|
314
323
|
// remove referencing reference from ancestors lineage
|
|
@@ -449,7 +458,11 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
449
458
|
*/
|
|
450
459
|
const isNonEntryDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
|
|
451
460
|
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
|
|
452
|
-
if ((isExternalReference || isNonEntryDocument || (0, _apidomNsAsyncapi.isChannelItemElement)(referencedElement) && (0, _apidomDatamodel.isStringElement)(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
461
|
+
if ((isExternalReference || isNonEntryDocument || (0, _apidomNsAsyncapi.isChannelItemElement)(referencedElement) && (0, _apidomDatamodel.isStringElement)(referencedElement.$ref) || shouldDetectCircular && !this.visited.has(referencedElement)) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
462
|
+
if (shouldDetectCircular) {
|
|
463
|
+
this.visited.add(referencedElement);
|
|
464
|
+
}
|
|
465
|
+
|
|
453
466
|
// append referencing reference to ancestors lineage
|
|
454
467
|
directAncestors.add(referencingElement);
|
|
455
468
|
const visitor = new AsyncAPI2DereferenceVisitor({
|
|
@@ -457,10 +470,12 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
457
470
|
indirections: [...this.indirections],
|
|
458
471
|
options: this.options,
|
|
459
472
|
refractCache: this.refractCache,
|
|
473
|
+
visited: this.visited,
|
|
460
474
|
ancestors: ancestorsLineage
|
|
461
475
|
});
|
|
462
476
|
referencedElement = await (0, _apidomTraverse.traverseAsync)(referencedElement, visitor, {
|
|
463
|
-
mutable: true
|
|
477
|
+
mutable: true,
|
|
478
|
+
skipVisited: true
|
|
464
479
|
});
|
|
465
480
|
|
|
466
481
|
// remove referencing reference from ancestors lineage
|
|
@@ -23,6 +23,7 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
23
23
|
reference;
|
|
24
24
|
options;
|
|
25
25
|
refractCache;
|
|
26
|
+
visited;
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Tracks element ancestors across dive-deep traversal boundaries.
|
|
@@ -35,13 +36,15 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
35
36
|
options,
|
|
36
37
|
indirections = [],
|
|
37
38
|
ancestors = new AncestorLineage(),
|
|
38
|
-
refractCache = new WeakMap()
|
|
39
|
+
refractCache = new WeakMap(),
|
|
40
|
+
visited = new WeakSet()
|
|
39
41
|
}) {
|
|
40
42
|
this.indirections = indirections;
|
|
41
43
|
this.reference = reference;
|
|
42
44
|
this.options = options;
|
|
43
45
|
this.ancestors = new AncestorLineage(...ancestors);
|
|
44
46
|
this.refractCache = refractCache;
|
|
47
|
+
this.visited = visited;
|
|
45
48
|
}
|
|
46
49
|
toAncestorLineage(path) {
|
|
47
50
|
const ancestorNodes = path.getAncestorNodes();
|
|
@@ -290,7 +293,11 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
290
293
|
*/
|
|
291
294
|
const isNonEntryDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
|
|
292
295
|
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
|
|
293
|
-
if ((isExternalReference || isNonEntryDocument || isReferenceElement(referencedElement) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
296
|
+
if ((isExternalReference || isNonEntryDocument || isReferenceElement(referencedElement) || shouldDetectCircular && !this.visited.has(referencedElement)) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
297
|
+
if (shouldDetectCircular) {
|
|
298
|
+
this.visited.add(referencedElement);
|
|
299
|
+
}
|
|
300
|
+
|
|
294
301
|
// append referencing reference to ancestors lineage
|
|
295
302
|
directAncestors.add(referencingElement);
|
|
296
303
|
const visitor = new AsyncAPI2DereferenceVisitor({
|
|
@@ -298,10 +305,12 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
298
305
|
indirections: [...this.indirections],
|
|
299
306
|
options: this.options,
|
|
300
307
|
refractCache: this.refractCache,
|
|
308
|
+
visited: this.visited,
|
|
301
309
|
ancestors: ancestorsLineage
|
|
302
310
|
});
|
|
303
311
|
referencedElement = await traverseAsync(referencedElement, visitor, {
|
|
304
|
-
mutable: true
|
|
312
|
+
mutable: true,
|
|
313
|
+
skipVisited: true
|
|
305
314
|
});
|
|
306
315
|
|
|
307
316
|
// remove referencing reference from ancestors lineage
|
|
@@ -442,7 +451,11 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
442
451
|
*/
|
|
443
452
|
const isNonEntryDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
|
|
444
453
|
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
|
|
445
|
-
if ((isExternalReference || isNonEntryDocument || isChannelItemElement(referencedElement) && isStringElement(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
454
|
+
if ((isExternalReference || isNonEntryDocument || isChannelItemElement(referencedElement) && isStringElement(referencedElement.$ref) || shouldDetectCircular && !this.visited.has(referencedElement)) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
455
|
+
if (shouldDetectCircular) {
|
|
456
|
+
this.visited.add(referencedElement);
|
|
457
|
+
}
|
|
458
|
+
|
|
446
459
|
// append referencing reference to ancestors lineage
|
|
447
460
|
directAncestors.add(referencingElement);
|
|
448
461
|
const visitor = new AsyncAPI2DereferenceVisitor({
|
|
@@ -450,10 +463,12 @@ class AsyncAPI2DereferenceVisitor {
|
|
|
450
463
|
indirections: [...this.indirections],
|
|
451
464
|
options: this.options,
|
|
452
465
|
refractCache: this.refractCache,
|
|
466
|
+
visited: this.visited,
|
|
453
467
|
ancestors: ancestorsLineage
|
|
454
468
|
});
|
|
455
469
|
referencedElement = await traverseAsync(referencedElement, visitor, {
|
|
456
|
-
mutable: true
|
|
470
|
+
mutable: true,
|
|
471
|
+
skipVisited: true
|
|
457
472
|
});
|
|
458
473
|
|
|
459
474
|
// remove referencing reference from ancestors lineage
|
|
@@ -62,12 +62,16 @@ class OpenAPI2DereferenceStrategy extends _DereferenceStrategy.default {
|
|
|
62
62
|
reference = mutableRefSet.find(ref => ref.uri === file.uri);
|
|
63
63
|
refSet = mutableRefSet;
|
|
64
64
|
}
|
|
65
|
+
const shouldDetectCircular = ['error', 'replace'].includes(options.dereference.circular);
|
|
65
66
|
const visitor = new _visitor.default({
|
|
66
67
|
reference: reference,
|
|
67
68
|
options
|
|
68
69
|
});
|
|
69
70
|
const dereferencedElement = await (0, _apidomTraverse.traverseAsync)(refSet.rootRef.value, visitor, {
|
|
70
|
-
mutable: true
|
|
71
|
+
mutable: true,
|
|
72
|
+
...(shouldDetectCircular && {
|
|
73
|
+
skipVisited: true
|
|
74
|
+
})
|
|
71
75
|
});
|
|
72
76
|
|
|
73
77
|
/**
|
|
@@ -55,12 +55,16 @@ class OpenAPI2DereferenceStrategy extends DereferenceStrategy {
|
|
|
55
55
|
reference = mutableRefSet.find(ref => ref.uri === file.uri);
|
|
56
56
|
refSet = mutableRefSet;
|
|
57
57
|
}
|
|
58
|
+
const shouldDetectCircular = ['error', 'replace'].includes(options.dereference.circular);
|
|
58
59
|
const visitor = new OpenAPI2DereferenceVisitor({
|
|
59
60
|
reference: reference,
|
|
60
61
|
options
|
|
61
62
|
});
|
|
62
63
|
const dereferencedElement = await traverseAsync(refSet.rootRef.value, visitor, {
|
|
63
|
-
mutable: true
|
|
64
|
+
mutable: true,
|
|
65
|
+
...(shouldDetectCircular && {
|
|
66
|
+
skipVisited: true
|
|
67
|
+
})
|
|
64
68
|
});
|
|
65
69
|
|
|
66
70
|
/**
|
|
@@ -30,6 +30,7 @@ class OpenAPI2DereferenceVisitor {
|
|
|
30
30
|
reference;
|
|
31
31
|
options;
|
|
32
32
|
refractCache;
|
|
33
|
+
visited;
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* Tracks element ancestors across dive-deep traversal boundaries.
|
|
@@ -42,13 +43,15 @@ class OpenAPI2DereferenceVisitor {
|
|
|
42
43
|
options,
|
|
43
44
|
indirections = [],
|
|
44
45
|
ancestors = new _util.AncestorLineage(),
|
|
45
|
-
refractCache = new WeakMap()
|
|
46
|
+
refractCache = new WeakMap(),
|
|
47
|
+
visited = new WeakSet()
|
|
46
48
|
}) {
|
|
47
49
|
this.indirections = indirections;
|
|
48
50
|
this.reference = reference;
|
|
49
51
|
this.options = options;
|
|
50
52
|
this.refractCache = refractCache;
|
|
51
53
|
this.ancestors = new _util.AncestorLineage(...ancestors);
|
|
54
|
+
this.visited = visited;
|
|
52
55
|
}
|
|
53
56
|
toAncestorLineage(path) {
|
|
54
57
|
const ancestorNodes = path.getAncestorNodes();
|
|
@@ -297,7 +300,11 @@ class OpenAPI2DereferenceVisitor {
|
|
|
297
300
|
*/
|
|
298
301
|
const isNonEntryDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
|
|
299
302
|
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
|
|
300
|
-
if ((isExternalReference || isNonEntryDocument || (0, _apidomNsOpenapi.isReferenceElement)(referencedElement) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
303
|
+
if ((isExternalReference || isNonEntryDocument || (0, _apidomNsOpenapi.isReferenceElement)(referencedElement) || shouldDetectCircular && !this.visited.has(referencedElement)) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
304
|
+
if (shouldDetectCircular) {
|
|
305
|
+
this.visited.add(referencedElement);
|
|
306
|
+
}
|
|
307
|
+
|
|
301
308
|
// append referencing reference to ancestors lineage
|
|
302
309
|
directAncestors.add(referencingElement);
|
|
303
310
|
const visitor = new OpenAPI2DereferenceVisitor({
|
|
@@ -305,10 +312,12 @@ class OpenAPI2DereferenceVisitor {
|
|
|
305
312
|
indirections: [...this.indirections],
|
|
306
313
|
options: this.options,
|
|
307
314
|
refractCache: this.refractCache,
|
|
315
|
+
visited: this.visited,
|
|
308
316
|
ancestors: ancestorsLineage
|
|
309
317
|
});
|
|
310
318
|
referencedElement = await (0, _apidomTraverse.traverseAsync)(referencedElement, visitor, {
|
|
311
|
-
mutable: true
|
|
319
|
+
mutable: true,
|
|
320
|
+
skipVisited: true
|
|
312
321
|
});
|
|
313
322
|
directAncestors.delete(referencingElement);
|
|
314
323
|
}
|
|
@@ -433,7 +442,11 @@ class OpenAPI2DereferenceVisitor {
|
|
|
433
442
|
*/
|
|
434
443
|
const isNonEntryDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
|
|
435
444
|
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
|
|
436
|
-
if ((isExternalReference || isNonEntryDocument || (0, _apidomNsOpenapi.isPathItemElement)(referencedElement) && (0, _apidomDatamodel.isStringElement)(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
445
|
+
if ((isExternalReference || isNonEntryDocument || (0, _apidomNsOpenapi.isPathItemElement)(referencedElement) && (0, _apidomDatamodel.isStringElement)(referencedElement.$ref) || shouldDetectCircular && !this.visited.has(referencedElement)) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
446
|
+
if (shouldDetectCircular) {
|
|
447
|
+
this.visited.add(referencedElement);
|
|
448
|
+
}
|
|
449
|
+
|
|
437
450
|
// append referencing reference to ancestors lineage
|
|
438
451
|
directAncestors.add(referencingElement);
|
|
439
452
|
const visitor = new OpenAPI2DereferenceVisitor({
|
|
@@ -441,10 +454,12 @@ class OpenAPI2DereferenceVisitor {
|
|
|
441
454
|
indirections: [...this.indirections],
|
|
442
455
|
options: this.options,
|
|
443
456
|
refractCache: this.refractCache,
|
|
457
|
+
visited: this.visited,
|
|
444
458
|
ancestors: ancestorsLineage
|
|
445
459
|
});
|
|
446
460
|
referencedElement = await (0, _apidomTraverse.traverseAsync)(referencedElement, visitor, {
|
|
447
|
-
mutable: true
|
|
461
|
+
mutable: true,
|
|
462
|
+
skipVisited: true
|
|
448
463
|
});
|
|
449
464
|
|
|
450
465
|
// remove referencing reference from ancestors lineage
|
|
@@ -588,7 +603,11 @@ class OpenAPI2DereferenceVisitor {
|
|
|
588
603
|
*/
|
|
589
604
|
const isNonEntryDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
|
|
590
605
|
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
|
|
591
|
-
if ((isExternalReference || isNonEntryDocument || (0, _apidomNsOpenapi.isJSONReferenceElement)(referencedElement) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
606
|
+
if ((isExternalReference || isNonEntryDocument || (0, _apidomNsOpenapi.isJSONReferenceElement)(referencedElement) || shouldDetectCircular && !this.visited.has(referencedElement)) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
607
|
+
if (shouldDetectCircular) {
|
|
608
|
+
this.visited.add(referencedElement);
|
|
609
|
+
}
|
|
610
|
+
|
|
592
611
|
// append referencing reference to ancestors lineage
|
|
593
612
|
directAncestors.add(referencingElement);
|
|
594
613
|
const visitor = new OpenAPI2DereferenceVisitor({
|
|
@@ -596,10 +615,12 @@ class OpenAPI2DereferenceVisitor {
|
|
|
596
615
|
indirections: [...this.indirections],
|
|
597
616
|
options: this.options,
|
|
598
617
|
refractCache: this.refractCache,
|
|
618
|
+
visited: this.visited,
|
|
599
619
|
ancestors: ancestorsLineage
|
|
600
620
|
});
|
|
601
621
|
referencedElement = await (0, _apidomTraverse.traverseAsync)(referencedElement, visitor, {
|
|
602
|
-
mutable: true
|
|
622
|
+
mutable: true,
|
|
623
|
+
skipVisited: true
|
|
603
624
|
});
|
|
604
625
|
|
|
605
626
|
// remove referencing reference from ancestors lineage
|
|
@@ -23,6 +23,7 @@ class OpenAPI2DereferenceVisitor {
|
|
|
23
23
|
reference;
|
|
24
24
|
options;
|
|
25
25
|
refractCache;
|
|
26
|
+
visited;
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Tracks element ancestors across dive-deep traversal boundaries.
|
|
@@ -35,13 +36,15 @@ class OpenAPI2DereferenceVisitor {
|
|
|
35
36
|
options,
|
|
36
37
|
indirections = [],
|
|
37
38
|
ancestors = new AncestorLineage(),
|
|
38
|
-
refractCache = new WeakMap()
|
|
39
|
+
refractCache = new WeakMap(),
|
|
40
|
+
visited = new WeakSet()
|
|
39
41
|
}) {
|
|
40
42
|
this.indirections = indirections;
|
|
41
43
|
this.reference = reference;
|
|
42
44
|
this.options = options;
|
|
43
45
|
this.refractCache = refractCache;
|
|
44
46
|
this.ancestors = new AncestorLineage(...ancestors);
|
|
47
|
+
this.visited = visited;
|
|
45
48
|
}
|
|
46
49
|
toAncestorLineage(path) {
|
|
47
50
|
const ancestorNodes = path.getAncestorNodes();
|
|
@@ -290,7 +293,11 @@ class OpenAPI2DereferenceVisitor {
|
|
|
290
293
|
*/
|
|
291
294
|
const isNonEntryDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
|
|
292
295
|
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
|
|
293
|
-
if ((isExternalReference || isNonEntryDocument || isReferenceElement(referencedElement) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
296
|
+
if ((isExternalReference || isNonEntryDocument || isReferenceElement(referencedElement) || shouldDetectCircular && !this.visited.has(referencedElement)) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
297
|
+
if (shouldDetectCircular) {
|
|
298
|
+
this.visited.add(referencedElement);
|
|
299
|
+
}
|
|
300
|
+
|
|
294
301
|
// append referencing reference to ancestors lineage
|
|
295
302
|
directAncestors.add(referencingElement);
|
|
296
303
|
const visitor = new OpenAPI2DereferenceVisitor({
|
|
@@ -298,10 +305,12 @@ class OpenAPI2DereferenceVisitor {
|
|
|
298
305
|
indirections: [...this.indirections],
|
|
299
306
|
options: this.options,
|
|
300
307
|
refractCache: this.refractCache,
|
|
308
|
+
visited: this.visited,
|
|
301
309
|
ancestors: ancestorsLineage
|
|
302
310
|
});
|
|
303
311
|
referencedElement = await traverseAsync(referencedElement, visitor, {
|
|
304
|
-
mutable: true
|
|
312
|
+
mutable: true,
|
|
313
|
+
skipVisited: true
|
|
305
314
|
});
|
|
306
315
|
directAncestors.delete(referencingElement);
|
|
307
316
|
}
|
|
@@ -426,7 +435,11 @@ class OpenAPI2DereferenceVisitor {
|
|
|
426
435
|
*/
|
|
427
436
|
const isNonEntryDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
|
|
428
437
|
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
|
|
429
|
-
if ((isExternalReference || isNonEntryDocument || isPathItemElement(referencedElement) && isStringElement(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
438
|
+
if ((isExternalReference || isNonEntryDocument || isPathItemElement(referencedElement) && isStringElement(referencedElement.$ref) || shouldDetectCircular && !this.visited.has(referencedElement)) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
439
|
+
if (shouldDetectCircular) {
|
|
440
|
+
this.visited.add(referencedElement);
|
|
441
|
+
}
|
|
442
|
+
|
|
430
443
|
// append referencing reference to ancestors lineage
|
|
431
444
|
directAncestors.add(referencingElement);
|
|
432
445
|
const visitor = new OpenAPI2DereferenceVisitor({
|
|
@@ -434,10 +447,12 @@ class OpenAPI2DereferenceVisitor {
|
|
|
434
447
|
indirections: [...this.indirections],
|
|
435
448
|
options: this.options,
|
|
436
449
|
refractCache: this.refractCache,
|
|
450
|
+
visited: this.visited,
|
|
437
451
|
ancestors: ancestorsLineage
|
|
438
452
|
});
|
|
439
453
|
referencedElement = await traverseAsync(referencedElement, visitor, {
|
|
440
|
-
mutable: true
|
|
454
|
+
mutable: true,
|
|
455
|
+
skipVisited: true
|
|
441
456
|
});
|
|
442
457
|
|
|
443
458
|
// remove referencing reference from ancestors lineage
|
|
@@ -581,7 +596,11 @@ class OpenAPI2DereferenceVisitor {
|
|
|
581
596
|
*/
|
|
582
597
|
const isNonEntryDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
|
|
583
598
|
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
|
|
584
|
-
if ((isExternalReference || isNonEntryDocument || isJSONReferenceElement(referencedElement) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
599
|
+
if ((isExternalReference || isNonEntryDocument || isJSONReferenceElement(referencedElement) || shouldDetectCircular && !this.visited.has(referencedElement)) && !ancestorsLineage.includesCycle(referencedElement)) {
|
|
600
|
+
if (shouldDetectCircular) {
|
|
601
|
+
this.visited.add(referencedElement);
|
|
602
|
+
}
|
|
603
|
+
|
|
585
604
|
// append referencing reference to ancestors lineage
|
|
586
605
|
directAncestors.add(referencingElement);
|
|
587
606
|
const visitor = new OpenAPI2DereferenceVisitor({
|
|
@@ -589,10 +608,12 @@ class OpenAPI2DereferenceVisitor {
|
|
|
589
608
|
indirections: [...this.indirections],
|
|
590
609
|
options: this.options,
|
|
591
610
|
refractCache: this.refractCache,
|
|
611
|
+
visited: this.visited,
|
|
592
612
|
ancestors: ancestorsLineage
|
|
593
613
|
});
|
|
594
614
|
referencedElement = await traverseAsync(referencedElement, visitor, {
|
|
595
|
-
mutable: true
|
|
615
|
+
mutable: true,
|
|
616
|
+
skipVisited: true
|
|
596
617
|
});
|
|
597
618
|
|
|
598
619
|
// remove referencing reference from ancestors lineage
|