From 62a652478668100fb5b0c63fa7b4ee65877db1c1 Mon Sep 17 00:00:00 2001 From: Drew Powers Date: Thu, 6 Jul 2023 18:07:25 -0500 Subject: [PATCH] Fix mutating $refs in Node.js API --- .changeset/fresh-dancers-joke.md | 5 +++ packages/openapi-typescript/src/load.ts | 2 +- .../openapi-typescript/test/index.test.ts | 42 ++++++++++++------- 3 files changed, 34 insertions(+), 15 deletions(-) create mode 100644 .changeset/fresh-dancers-joke.md diff --git a/.changeset/fresh-dancers-joke.md b/.changeset/fresh-dancers-joke.md new file mode 100644 index 000000000..dd5d69e83 --- /dev/null +++ b/.changeset/fresh-dancers-joke.md @@ -0,0 +1,5 @@ +--- +"openapi-typescript": patch +--- + +Fix mutating $refs in Node.js API diff --git a/packages/openapi-typescript/src/load.ts b/packages/openapi-typescript/src/load.ts index 141bfad03..41e5df5f4 100644 --- a/packages/openapi-typescript/src/load.ts +++ b/packages/openapi-typescript/src/load.ts @@ -173,7 +173,7 @@ export default async function load(schema: URL | Subschema | Readable, options: else if (typeof schema === "object") { options.schemas[schemaID] = { hint: "OpenAPI3", - schema: schema as any, + schema: JSON.parse(JSON.stringify(schema)), // create deep clone of inline schema (don’t mutate) }; } // 1d. failsafe diff --git a/packages/openapi-typescript/test/index.test.ts b/packages/openapi-typescript/test/index.test.ts index 629978677..a965d4494 100644 --- a/packages/openapi-typescript/test/index.test.ts +++ b/packages/openapi-typescript/test/index.test.ts @@ -189,10 +189,7 @@ export type operations = Record; "/post/{id}": { get: { operationId: "getPost", - parameters: [ - { name: "format", in: "query", schema: { type: "string" } }, - { $ref: "#/components/parameters/post_id" }, - ], + parameters: [{ name: "format", in: "query", schema: { type: "string" } }, { $ref: "#/components/parameters/post_id" }], responses: { 200: { description: "OK", @@ -447,11 +444,7 @@ export type operations = Record; components: { schemas: { Pet: { - oneOf: [ - { $ref: "#/components/schemas/Cat" }, - { $ref: "#/components/schemas/Dog" }, - { $ref: "#/components/schemas/Lizard" }, - ], + oneOf: [{ $ref: "#/components/schemas/Cat" }, { $ref: "#/components/schemas/Dog" }, { $ref: "#/components/schemas/Lizard" }], discriminator: { propertyName: "petType", mapping: { @@ -539,10 +532,7 @@ export type operations = Record; }, }, AllOf: { - allOf: [ - { $ref: "#/components/schemas/Entity/properties/foo" }, - { $ref: "#/components/schemas/Thingy/properties/bar" }, - ], + allOf: [{ $ref: "#/components/schemas/Entity/properties/foo" }, { $ref: "#/components/schemas/Thingy/properties/bar" }], }, }, }, @@ -730,7 +720,7 @@ export type operations = Record; }, put: { parameters: [{ name: "user_id", in: "path" }], - } + }, }, }, }; @@ -982,6 +972,30 @@ export type operations = Record; }); }); + it("does not mutate original reference", async () => { + const schema: OpenAPI3 = { + openapi: "3.1", + info: { title: "test", version: "1.0" }, + components: {}, + paths: { + "/": { + get: { + responses: { + 200: { + description: "ok", + $ref: "#/components/schemas/OKResponse", + }, + }, + }, + }, + }, + }; + const before = JSON.stringify(schema); + await openapiTS(schema); + const after = JSON.stringify(schema); + expect(before).toBe(after); + }); + // note: this tests the Node API; the snapshots in cli.test.ts test the CLI describe("snapshots", () => { const EXAMPLES_DIR = new URL("../examples/", import.meta.url);