Skip to content

fix: load yaml file transform ref bug #1097

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 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
4 changes: 4 additions & 0 deletions packages/openapi-typescript/src/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ export default async function load(

const ref = parseRef(node.$ref);

// when ref.path is [], $ref has been transform, skip transform
if (ref.path.length === 0 && (ref.filename.startsWith("components[") || ref.filename.startsWith("external["))) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm this may not be true in all cases; $refs could also reference the operations interface as well.

This feels like masking a potential bug rather than pinpointing exactly why the $ref isn’t being transformed correctly.

Is this an invalid schema?

Or is this a specific bug with specific $refs?

Rather than change this, we should find out exactly what kind of $ref isn’t being transformed properly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for this bug is:
use items: &ref_0 and items: *ref_0, Causes the ref reference in the currentSchema to point to the same address, and the currentSchema data has changed, resulting in ref transform many times!
I use JSON.parse and JSON.stringify to handle schema data before walk currentSchema to refactor code.

return;
}
// local $ref: convert into TS path
if (ref.filename === ".") {
node.$ref = makeTSIndex(ref.path);
Expand Down
255 changes: 255 additions & 0 deletions packages/openapi-typescript/test/load.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,261 @@ describe("Load", () => {
});
expect(output["."].schema).toEqual(exampleSchema);
});
// Regression test for https://github.com/drwpow/openapi-typescript/issues/1093
test("ref transform .json .yaml", async () => {
const exampleSchemaTransformTest = {
"openapi": "3.1.0",
"info": {
"title": "custom title",
"license": {
"name": "This file is auto generated, do not edit!"
},
"version": "0.4.1"
},
"paths": {
"/root/v4/getQueryParams1-v4": {
"get": {
"tags": ["Test4"],
"responses": {
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
}
}
},
"parameters": [
{
"name": "activityBases",
"in": "query",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "components[\"schemas\"][\"ActivityBase\"]"
}
},
"description": "activityBases"
}
]
}
}
},
"components": {
"schemas": {
"getQueryParams1Request": {
"type": "object",
"properties": {
"activityBases": {
"description": "activityBases",
"type": "array",
"items": {
"$ref": "components[\"schemas\"][\"ActivityBase\"]"
}
}
},
"required": ["activityBases"]
},
"ActivityBase": {
"allOf": [
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": ["name"]
},
{
"type": "object",
"properties": {
"id": {
"type": "number"
}
},
"required": ["id"]
}
]
}
}
},
"tags": [
{
"name": "Test4",
"description": "Test3Controller 注释\n注释3"
}
]
};
const output1 = await load(new URL("https://example.com/openapi.json"), {
async fetch() {
const jsonData = `{
"openapi": "3.1.0",
"info": {
"title": "custom title",
"license": {
"name": "This file is auto generated, do not edit!"
},
"version": "0.4.1"
},
"paths": {
"/root/v4/getQueryParams1-v4": {
"get": {
"tags": ["Test4"],
"responses": {
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "string"
}
}
}
}
},
"parameters": [
{
"name": "activityBases",
"in": "query",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/ActivityBase"
}
},
"description": "activityBases"
}
]
}
}
},
"components": {
"schemas": {
"getQueryParams1Request": {
"type": "object",
"properties": {
"activityBases": {
"description": "activityBases",
"type": "array",
"items": {
"$ref": "#/components/schemas/ActivityBase"
}
}
},
"required": ["activityBases"]
},
"ActivityBase": {
"allOf": [
{
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": ["name"]
},
{
"type": "object",
"properties": {
"id": {
"type": "number"
}
},
"required": ["id"]
}
]
}
}
},
"tags": [
{
"name": "Test4",
"description": "Test3Controller 注释\\n注释3"
}
]
}
`;
return new Response(jsonData, {
headers: { "Content-Type": "text/plain" },
});
},
});
expect(output1["."].schema).toEqual(exampleSchemaTransformTest);

const output2 = await load(new URL("https://example.com/openapi.yaml"), {
async fetch() {
const yamlData =`openapi: 3.1.0
info:
title: custom title
license:
name: This file is auto generated, do not edit!
version: 0.4.1
paths:
/root/v4/getQueryParams1-v4:
get:
tags:
- Test4
responses:
'200':
description: Success
content:
text/plain:
schema:
type: string
parameters:
- name: activityBases
in: query
required: true
schema:
type: array
items: &ref_0
$ref: '#/components/schemas/ActivityBase'
description: activityBases
components:
schemas:
getQueryParams1Request:
type: object
properties:
activityBases:
description: activityBases
type: array
items: *ref_0
required:
- activityBases
ActivityBase:
allOf:
- type: object
properties:
name:
type: string
required:
- name
- type: object
properties:
id:
type: number
required:
- id
tags:
- name: Test4
description: |-
Test3Controller 注释
注释3
`;
return new Response(yamlData, {
headers: { "Content-Type": "text/plain" },
});
},
});
expect(output2["."].schema).toEqual(exampleSchemaTransformTest);
});
});
});
});
Expand Down