Skip to content

Commit 902fde1

Browse files
authored
Fix mutating $refs in Node.js API (#1203)
1 parent 26436b9 commit 902fde1

File tree

3 files changed

+34
-15
lines changed

3 files changed

+34
-15
lines changed

.changeset/fresh-dancers-joke.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"openapi-typescript": patch
3+
---
4+
5+
Fix mutating $refs in Node.js API

packages/openapi-typescript/src/load.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export default async function load(schema: URL | Subschema | Readable, options:
173173
else if (typeof schema === "object") {
174174
options.schemas[schemaID] = {
175175
hint: "OpenAPI3",
176-
schema: schema as any,
176+
schema: JSON.parse(JSON.stringify(schema)), // create deep clone of inline schema (don’t mutate)
177177
};
178178
}
179179
// 1d. failsafe

packages/openapi-typescript/test/index.test.ts

+28-14
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,7 @@ export type operations = Record<string, never>;
189189
"/post/{id}": {
190190
get: {
191191
operationId: "getPost",
192-
parameters: [
193-
{ name: "format", in: "query", schema: { type: "string" } },
194-
{ $ref: "#/components/parameters/post_id" },
195-
],
192+
parameters: [{ name: "format", in: "query", schema: { type: "string" } }, { $ref: "#/components/parameters/post_id" }],
196193
responses: {
197194
200: {
198195
description: "OK",
@@ -447,11 +444,7 @@ export type operations = Record<string, never>;
447444
components: {
448445
schemas: {
449446
Pet: {
450-
oneOf: [
451-
{ $ref: "#/components/schemas/Cat" },
452-
{ $ref: "#/components/schemas/Dog" },
453-
{ $ref: "#/components/schemas/Lizard" },
454-
],
447+
oneOf: [{ $ref: "#/components/schemas/Cat" }, { $ref: "#/components/schemas/Dog" }, { $ref: "#/components/schemas/Lizard" }],
455448
discriminator: {
456449
propertyName: "petType",
457450
mapping: {
@@ -539,10 +532,7 @@ export type operations = Record<string, never>;
539532
},
540533
},
541534
AllOf: {
542-
allOf: [
543-
{ $ref: "#/components/schemas/Entity/properties/foo" },
544-
{ $ref: "#/components/schemas/Thingy/properties/bar" },
545-
],
535+
allOf: [{ $ref: "#/components/schemas/Entity/properties/foo" }, { $ref: "#/components/schemas/Thingy/properties/bar" }],
546536
},
547537
},
548538
},
@@ -730,7 +720,7 @@ export type operations = Record<string, never>;
730720
},
731721
put: {
732722
parameters: [{ name: "user_id", in: "path" }],
733-
}
723+
},
734724
},
735725
},
736726
};
@@ -982,6 +972,30 @@ export type operations = Record<string, never>;
982972
});
983973
});
984974

975+
it("does not mutate original reference", async () => {
976+
const schema: OpenAPI3 = {
977+
openapi: "3.1",
978+
info: { title: "test", version: "1.0" },
979+
components: {},
980+
paths: {
981+
"/": {
982+
get: {
983+
responses: {
984+
200: {
985+
description: "ok",
986+
$ref: "#/components/schemas/OKResponse",
987+
},
988+
},
989+
},
990+
},
991+
},
992+
};
993+
const before = JSON.stringify(schema);
994+
await openapiTS(schema);
995+
const after = JSON.stringify(schema);
996+
expect(before).toBe(after);
997+
});
998+
985999
// note: this tests the Node API; the snapshots in cli.test.ts test the CLI
9861000
describe("snapshots", () => {
9871001
const EXAMPLES_DIR = new URL("../examples/", import.meta.url);

0 commit comments

Comments
 (0)