Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/smart-points-pull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@redocly/openapi-core": patch
---

Fixed an issue where references were not resolved when used inside other properties alongside the `$ref` keyword.
18 changes: 18 additions & 0 deletions __tests__/bundle/sibling-refs-asyncapi/asyncapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
asyncapi: '3.0.0'
info:
title: Account Service
version: 1.0.0
components:
schemas:
Parent:
type: object
properties:
field:
description:
$ref: './description.md'
$ref: '#/components/schemas/Child'
Child:
type: object
properties:
name:
type: string
1 change: 1 addition & 0 deletions __tests__/bundle/sibling-refs-asyncapi/description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a description resolved from a reference file.
3 changes: 3 additions & 0 deletions __tests__/bundle/sibling-refs-asyncapi/redocly.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
apis:
main:
root: ./asyncapi.yaml
21 changes: 21 additions & 0 deletions __tests__/bundle/sibling-refs-asyncapi/snapshot.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
info:
title: Account Service
version: 1.0.0
components:
schemas:
Parent:
type: object
properties:
field:
description: |
This is a description resolved from a reference file.
$ref: '#/components/schemas/Child'
Child:
type: object
properties:
name:
type: string
asyncapi: 3.0.0

bundling asyncapi.yaml using configuration for api 'main'...
📦 Created a bundle for asyncapi.yaml at stdout <test>ms.
1 change: 1 addition & 0 deletions __tests__/bundle/sibling-refs-asyncapi/summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Summary from reference
1 change: 1 addition & 0 deletions __tests__/bundle/sibling-refs-oas/description.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a description resolved from a reference file.
28 changes: 28 additions & 0 deletions __tests__/bundle/sibling-refs-oas/openapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
openapi: 3.1.0
info:
title: Inline Test
version: 1.0.0
paths:
/test:
get:
responses:
'200':
content:
application/json:
schema:
type: object
properties:
field:
description:
$ref: './description.md'
summary:
$ref: './summary.md'
$ref: '#/components/schemas/Child'
components:
schemas:
Child:
type: object
description: 'should not win'
properties:
name:
type: string
3 changes: 3 additions & 0 deletions __tests__/bundle/sibling-refs-oas/redocly.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
apis:
main:
root: ./openapi.yaml
31 changes: 31 additions & 0 deletions __tests__/bundle/sibling-refs-oas/snapshot.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
openapi: 3.1.0
info:
title: Inline Test
version: 1.0.0
paths:
/test:
get:
responses:
'200':
content:
application/json:
schema:
type: object
properties:
field:
description: |
This is a description resolved from a reference file.
summary: |
Summary from reference
$ref: '#/components/schemas/Child'
components:
schemas:
Child:
type: object
description: should not win
properties:
name:
type: string

bundling openapi.yaml using configuration for api 'main'...
📦 Created a bundle for openapi.yaml at stdout <test>ms.
1 change: 1 addition & 0 deletions __tests__/bundle/sibling-refs-oas/summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Summary from reference
141 changes: 141 additions & 0 deletions packages/core/src/__tests__/__snapshots__/bundle.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -374,3 +374,144 @@ components:
$ref: '#/components/schemas/NestedSchema'

`;

exports[`sibling $ref resolution by spec > should not resolve non-description/summary sibling ref 1`] = `
openapi: 3.1.0
info:
title: Non summary desc
version: 1.0.0
paths:
/test:
get:
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
field:
test:
$ref: ./description.md
$ref: '#/components/schemas/Child'
components:
schemas:
Child:
type: object
properties:
name:
type: string

`;

exports[`sibling $ref resolution by spec > should resolve RequestBody.description as $ref sibling to RequestBody $ref (non-Schema context) 1`] = `
openapi: 3.1.0
info:
title: RequestBody Sibling Ref
version: 1.0.0
paths:
/users:
post:
requestBody:
description: |
This is a description resolved from a reference file.
$ref: '#/components/requestBodies/User'
responses:
'200':
description: OK
components:
requestBodies:
User:
content:
application/json:
schema:
type: object

`;

exports[`sibling $ref resolution by spec > should resolve description and summary refs alongside $ref in Schema - AsyncAPI 3 1`] = `
asyncapi: 3.0.0
info:
title: Account Service
version: 1.0.0
components:
schemas:
Parent:
type: object
properties:
field:
description: |
This is a description resolved from a reference file.
$ref: '#/components/schemas/Child'
Child:
type: object
properties:
name:
type: string

`;

exports[`sibling $ref resolution by spec > should resolve description and summary refs alongside $ref in Schema - OAS 3 1`] = `
openapi: 3.1.0
info:
title: Inline Test
version: 1.0.0
paths:
/test:
get:
responses:
'200':
description: OK
content:
application/json:
schema:
type: object
properties:
field:
description: |
This is a description resolved from a reference file.
summary: |
Summary from reference
$ref: '#/components/schemas/Child'
components:
schemas:
Child:
type: object
description: should not win
properties:
name:
type: string

`;

exports[`sibling $ref resolution by spec > should resolve description and summary refs alongside $ref in Schema contexts - Arazzo 1 1`] = `
arazzo: 1.0.0
info:
title: Arazzo Test
version: 1.0.0
sourceDescriptions:
- name: example-source
type: arazzo
url: https://example.com
workflows:
- workflowId: example-workflow
steps: []
inputs:
type: object
properties:
field:
description: |
This is a description resolved from a reference file.
summary: |
Summary from reference
$ref: '#/components/inputs/Child'
components:
inputs:
Child:
type: object
properties:
name:
type: string

`;
62 changes: 62 additions & 0 deletions packages/core/src/__tests__/bundle.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,3 +482,65 @@ describe('bundle async', () => {
expect(res.parsed).toMatchSnapshot();
});
});

describe('sibling $ref resolution by spec', () => {
it('should resolve description and summary refs alongside $ref in Schema - OAS 3', async () => {
const { bundle: res, problems } = await bundle({
config: await createConfig({}),
ref: path.join(__dirname, 'fixtures/sibling-refs/openapi.yaml'),
});
expect(problems).toHaveLength(0);
expect(res.parsed).toMatchSnapshot();
});

it('should resolve description and summary refs alongside $ref in Schema - AsyncAPI 3', async () => {
const { bundle: res, problems } = await bundle({
config: await createConfig({}),
ref: path.join(__dirname, 'fixtures/sibling-refs/asyncapi.yaml'),
});
expect(problems).toHaveLength(0);
expect(res.parsed).toMatchSnapshot();
});

it('should resolve description and summary refs alongside $ref in Schema contexts - Arazzo 1', async () => {
const { bundle: res, problems } = await bundle({
config: await createConfig({}),
ref: path.join(__dirname, 'fixtures/sibling-refs/arazzo.yaml'),
});
expect(problems).toHaveLength(0);
expect(res.parsed).toMatchSnapshot();
});

it('should not resolve non-description/summary sibling ref', async () => {
const { bundle: res, problems } = await bundle({
config: await createConfig({}),
ref: path.join(__dirname, 'fixtures/sibling-refs/openapi-non-summary-desc-ref.yaml'),
});
expect(problems).toHaveLength(0);
expect(res.parsed).toMatchSnapshot();
});

it('should prefer description from sibling ref over target schema description', async () => {
const { bundle: res, problems } = await bundle({
config: await createConfig({}),
ref: path.join(__dirname, 'fixtures/sibling-refs/openapi-with-description-ref.yaml'),
});

const field = (res.parsed as any).paths['/test'].get.responses['200'].content[
'application/json'
].schema.properties.field;

expect(problems).toHaveLength(0);
expect(field.description).toBe('This is a description resolved from a reference file.\n');
});

it('should resolve RequestBody.description as $ref sibling to RequestBody $ref (non-Schema context)', async () => {
const { bundle: res, problems } = await bundle({
config: await createConfig({}),
ref: path.join(__dirname, 'fixtures/sibling-refs/openapi-request-body.yaml'),
});

expect(problems).toHaveLength(0);
expect(res.parsed).toMatchSnapshot();
});
});
27 changes: 27 additions & 0 deletions packages/core/src/__tests__/fixtures/sibling-refs/arazzo.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
arazzo: 1.0.0
info:
title: Arazzo Test
version: 1.0.0
sourceDescriptions:
- name: example-source
type: arazzo
url: https://example.com
workflows:
- workflowId: example-workflow
steps: []
inputs:
type: object
properties:
field:
description:
$ref: './description.md'
summary:
$ref: './summary.md'
$ref: '#/components/inputs/Child'
components:
inputs:
Child:
type: object
properties:
name:
type: string
18 changes: 18 additions & 0 deletions packages/core/src/__tests__/fixtures/sibling-refs/asyncapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
asyncapi: 3.0.0
info:
title: Account Service
version: 1.0.0
components:
schemas:
Parent:
type: object
properties:
field:
description:
$ref: './description.md'
$ref: '#/components/schemas/Child'
Child:
type: object
properties:
name:
type: string
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is a description resolved from a reference file.
Loading
Loading