diff --git a/packages/apidom-reference/src/dereference/strategies/openapi-3-1/visitor.ts b/packages/apidom-reference/src/dereference/strategies/openapi-3-1/visitor.ts index 0f7490d8c5..3c6ca3c10c 100644 --- a/packages/apidom-reference/src/dereference/strategies/openapi-3-1/visitor.ts +++ b/packages/apidom-reference/src/dereference/strategies/openapi-3-1/visitor.ts @@ -242,13 +242,17 @@ const OpenApi3_1DereferenceVisitor = stampit({ * * Cases to consider: * 1. We're crossing document boundary - * 2. Fragment is a Reference Object. We need to follow it to get the eventual value - * 3. We are dereferencing the fragment lazily/eagerly depending on circular mode + * 2. Fragment is from non-root document + * 3. Fragment is a Reference Object. We need to follow it to get the eventual value + * 4. We are dereferencing the fragment lazily/eagerly depending on circular mode */ + const isNonRootDocument = reference.refSet.rootRef.uri !== reference.uri; + const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular); if ( (isExternalReference || + isNonRootDocument || isReferenceElement(referencedElement) || - ['error', 'replace'].includes(this.options.dereference.circular)) && + shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement) ) { // append referencing reference to ancestors lineage @@ -425,13 +429,17 @@ const OpenApi3_1DereferenceVisitor = stampit({ * * Cases to consider: * 1. We're crossing document boundary - * 2. Fragment is a Path Item Object with $ref field. We need to follow it to get the eventual value - * 3. We are dereferencing the fragment lazily/eagerly depending on circular mode + * 2. Fragment is from non-root document + * 3. Fragment is a Path Item Object with $ref field. We need to follow it to get the eventual value + * 4. We are dereferencing the fragment lazily/eagerly depending on circular mode */ + const isNonRootDocument = reference.refSet.rootRef.uri !== reference.uri; + const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular); if ( (isExternalReference || + isNonRootDocument || (isPathItemElement(referencedElement) && isStringElement(referencedElement.$ref)) || - ['error', 'replace'].includes(this.options.dereference.circular)) && + shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement) ) { // append referencing reference to ancestors lineage @@ -845,13 +853,17 @@ const OpenApi3_1DereferenceVisitor = stampit({ * * Cases to consider: * 1. We're crossing document boundary - * 2. Fragment is a Schema Object with $ref field. We need to follow it to get the eventual value - * 3. We are dereferencing the fragment lazily/eagerly depending on circular mode + * 2. Fragment is from non-root document + * 3. Fragment is a Schema Object with $ref field. We need to follow it to get the eventual value + * 4. We are dereferencing the fragment lazily/eagerly depending on circular mode */ + const isNonRootDocument = reference.refSet.rootRef.uri !== reference.uri; + const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular); if ( (isExternalReference || + isNonRootDocument || (isSchemaElement(referencedElement) && isStringElement(referencedElement.$ref)) || - ['error', 'replace'].includes(this.options.dereference.circular)) && + shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement) ) { // append referencing reference to ancestors lineage diff --git a/packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/dereferenced.json b/packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/dereferenced.json index 85fde7c64f..dd63827a5f 100644 --- a/packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/dereferenced.json +++ b/packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/dereferenced.json @@ -9,11 +9,10 @@ "profile": { "type": "object", "properties": { - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" + "sentAt": { + "type": "string", + "format": "date-time", + "description": "Date and time when the message was sent." } } } diff --git a/packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/ex.json b/packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/ex.json index c115310b05..36de5eedcb 100644 --- a/packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/ex.json +++ b/packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/ex.json @@ -1,16 +1,21 @@ { "type": "object", "$defs": { - "UserProfile": { + "schema1": { + "$ref": "#/$defs/somePayload" + }, + "somePayload": { "type": "object", "properties": { - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" + "sentAt": { + "$ref": "#/$defs/sentAt" } } + }, + "sentAt": { + "type": "string", + "format": "date-time", + "description": "Date and time when the message was sent." } } } diff --git a/packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/root.json b/packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/root.json index 15ee3edf1c..ec4513e634 100644 --- a/packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/root.json +++ b/packages/apidom-reference/test/dereference/strategies/openapi-3-1/schema-object/fixtures/external-only/root.json @@ -6,7 +6,7 @@ "type": "object", "properties": { "profile": { - "$ref": "./ex.json#/$defs/UserProfile" + "$ref": "./ex.json#/$defs/schema1" } } }