Skip to content

Commit

Permalink
fix $ref bug
Browse files Browse the repository at this point in the history
  • Loading branch information
rpmccarter committed Nov 5, 2024
1 parent e6cffd6 commit a124ee8
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 7 deletions.
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ These scripts use [`turbo`](https://turbo.build/) to build all the dependencies
| `pnpm dev:client:app` | Runs the API Client desktop app in a browser dev environment (with HMR\*) |
| `pnpm dev:client:modal` | Runs the API Client modal layout (with HMR\*) |
| `pnpm dev:client:web` | Runs the API Client client web app (with HMR\*) |
| `pnpm dev:components` | Runs storybook for `@mintlify/components` |
| `pnpm dev:components` | Runs storybook for `@mintlify/components` |
| `pnpm dev:nuxt` | Runs the [Nuxt](https://nuxt.com/) package |
| `pnpm dev:proxy-server` | Runs the Scalar proxy server locally |
| `pnpm dev:reference` | Runs the API References dev environment (with HMR\*) |
Expand Down
55 changes: 55 additions & 0 deletions packages/openapi-parser/src/utils/dereference.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,61 @@ it('dereferences a simple reference', async () => {
})
})

it("doesn't attempt to dereference properties named $ref", async () => {
const openapi = {
openapi: '3.1.0',
info: {
title: 'Hello World',
version: '1.0.0',
},
paths: {
'/test': {
get: {
responses: {
'200': {
// TODO: This is valid in @apidevtools/swagger, but not with our implementation
description: 'foobar',
content: {
'application/json': {
schema: {
properties: {
$ref: {
type: 'string',
},
},
},
},
},
},
},
},
},
},
}

const result = await dereference(openapi)

expect(result.errors).toStrictEqual([])

// Original
expect(
result.specification.paths['/test'].get.responses['200'].content[
'application/json'
].schema.properties,
).toEqual({
$ref: { type: 'string' },
})

// Resolved references
expect(
result.schema.paths['/test'].get.responses['200'].content[
'application/json'
].schema.properties,
).toEqual({
$ref: { type: 'string' },
})
})

it('throws an error', async () => {
expect(async () => {
await dereference(
Expand Down
18 changes: 12 additions & 6 deletions packages/openapi-parser/src/utils/resolveReferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,14 @@ export function resolveReferences(
schema: AnyObject,
resolveFilesystem: Filesystem,
resolveFile: FilesystemEntry,
isDynamicProperty?: boolean,
): DereferenceResult {
let result: DereferenceResult | undefined

// Iterate over the whole objecct
Object.entries(schema ?? {}).forEach(([_, value]) => {
Object.entries(schema ?? {}).forEach(([key, value]) => {
// Ignore parts without a reference
if (schema.$ref !== undefined) {
if (schema.$ref !== undefined && !isDynamicProperty) {
// Find the referenced content
const target = resolveUri(
schema.$ref,
Expand All @@ -123,16 +124,21 @@ export function resolveReferences(
delete schema.$ref

if (typeof target === 'object') {
Object.keys(target).forEach((key) => {
if (schema[key] === undefined) {
schema[key] = target[key]
Object.keys(target).forEach((targetKey) => {
if (schema[targetKey] === undefined) {
schema[targetKey] = target[targetKey]
}
})
}
}

if (typeof value === 'object' && !isCircular(value)) {
result = resolve(value, resolveFilesystem, resolveFile)
result = resolve(
value,
resolveFilesystem,
resolveFile,
key === 'properties' && !isDynamicProperty,
)
}
})

Expand Down

0 comments on commit a124ee8

Please sign in to comment.