Skip to content

Commit ff039fe

Browse files
authored
fix(reference): fix regression in OpenAPI 3.1.0 dereferencing (#3978)
Refs #3974
1 parent 45d706f commit ff039fe

File tree

4 files changed

+37
-21
lines changed

4 files changed

+37
-21
lines changed

packages/apidom-reference/src/dereference/strategies/openapi-3-1/visitor.ts

+21-9
Original file line numberDiff line numberDiff line change
@@ -242,13 +242,17 @@ const OpenApi3_1DereferenceVisitor = stampit({
242242
*
243243
* Cases to consider:
244244
* 1. We're crossing document boundary
245-
* 2. Fragment is a Reference Object. We need to follow it to get the eventual value
246-
* 3. We are dereferencing the fragment lazily/eagerly depending on circular mode
245+
* 2. Fragment is from non-root document
246+
* 3. Fragment is a Reference Object. We need to follow it to get the eventual value
247+
* 4. We are dereferencing the fragment lazily/eagerly depending on circular mode
247248
*/
249+
const isNonRootDocument = reference.refSet.rootRef.uri !== reference.uri;
250+
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
248251
if (
249252
(isExternalReference ||
253+
isNonRootDocument ||
250254
isReferenceElement(referencedElement) ||
251-
['error', 'replace'].includes(this.options.dereference.circular)) &&
255+
shouldDetectCircular) &&
252256
!ancestorsLineage.includesCycle(referencedElement)
253257
) {
254258
// append referencing reference to ancestors lineage
@@ -425,13 +429,17 @@ const OpenApi3_1DereferenceVisitor = stampit({
425429
*
426430
* Cases to consider:
427431
* 1. We're crossing document boundary
428-
* 2. Fragment is a Path Item Object with $ref field. We need to follow it to get the eventual value
429-
* 3. We are dereferencing the fragment lazily/eagerly depending on circular mode
432+
* 2. Fragment is from non-root document
433+
* 3. Fragment is a Path Item Object with $ref field. We need to follow it to get the eventual value
434+
* 4. We are dereferencing the fragment lazily/eagerly depending on circular mode
430435
*/
436+
const isNonRootDocument = reference.refSet.rootRef.uri !== reference.uri;
437+
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
431438
if (
432439
(isExternalReference ||
440+
isNonRootDocument ||
433441
(isPathItemElement(referencedElement) && isStringElement(referencedElement.$ref)) ||
434-
['error', 'replace'].includes(this.options.dereference.circular)) &&
442+
shouldDetectCircular) &&
435443
!ancestorsLineage.includesCycle(referencedElement)
436444
) {
437445
// append referencing reference to ancestors lineage
@@ -845,13 +853,17 @@ const OpenApi3_1DereferenceVisitor = stampit({
845853
*
846854
* Cases to consider:
847855
* 1. We're crossing document boundary
848-
* 2. Fragment is a Schema Object with $ref field. We need to follow it to get the eventual value
849-
* 3. We are dereferencing the fragment lazily/eagerly depending on circular mode
856+
* 2. Fragment is from non-root document
857+
* 3. Fragment is a Schema Object with $ref field. We need to follow it to get the eventual value
858+
* 4. We are dereferencing the fragment lazily/eagerly depending on circular mode
850859
*/
860+
const isNonRootDocument = reference.refSet.rootRef.uri !== reference.uri;
861+
const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
851862
if (
852863
(isExternalReference ||
864+
isNonRootDocument ||
853865
(isSchemaElement(referencedElement) && isStringElement(referencedElement.$ref)) ||
854-
['error', 'replace'].includes(this.options.dereference.circular)) &&
866+
shouldDetectCircular) &&
855867
!ancestorsLineage.includesCycle(referencedElement)
856868
) {
857869
// append referencing reference to ancestors lineage

packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/dereferenced.json

+4-5
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,10 @@
99
"profile": {
1010
"type": "object",
1111
"properties": {
12-
"firstName": {
13-
"type": "string"
14-
},
15-
"lastName": {
16-
"type": "string"
12+
"sentAt": {
13+
"type": "string",
14+
"format": "date-time",
15+
"description": "Date and time when the message was sent."
1716
}
1817
}
1918
}
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
{
22
"type": "object",
33
"$defs": {
4-
"UserProfile": {
4+
"schema1": {
5+
"$ref": "#/$defs/somePayload"
6+
},
7+
"somePayload": {
58
"type": "object",
69
"properties": {
7-
"firstName": {
8-
"type": "string"
9-
},
10-
"lastName": {
11-
"type": "string"
10+
"sentAt": {
11+
"$ref": "#/$defs/sentAt"
1212
}
1313
}
14+
},
15+
"sentAt": {
16+
"type": "string",
17+
"format": "date-time",
18+
"description": "Date and time when the message was sent."
1419
}
1520
}
1621
}

packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/root.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"type": "object",
77
"properties": {
88
"profile": {
9-
"$ref": "./ex.json#/$defs/UserProfile"
9+
"$ref": "./ex.json#/$defs/schema1"
1010
}
1111
}
1212
}

0 commit comments

Comments
 (0)