@zuplo/cli 6.40.8 → 6.40.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/import-openapi-utils.test.js +4 -3
- package/dist/__tests__/import-openapi-utils.test.js.map +1 -1
- package/dist/cmds/project/import-openapi.d.ts.map +1 -1
- package/dist/cmds/project/import-openapi.js +7 -1
- package/dist/cmds/project/import-openapi.js.map +1 -1
- package/dist/project/import-openapi/handler.d.ts +1 -0
- package/dist/project/import-openapi/handler.d.ts.map +1 -1
- package/dist/project/import-openapi/handler.js +4 -3
- package/dist/project/import-openapi/handler.js.map +1 -1
- package/dist/project/import-openapi/utils.d.ts +0 -6
- package/dist/project/import-openapi/utils.d.ts.map +1 -1
- package/dist/project/import-openapi/utils.js +0 -178
- package/dist/project/import-openapi/utils.js.map +1 -1
- package/package.json +4 -3
|
@@ -3,7 +3,8 @@ import { describe, it } from "node:test";
|
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
import { addOperationIdsAsNecessary,
|
|
6
|
+
import { addOperationIdsAsNecessary, parseOpenApiFile, } from "../project/import-openapi/utils.js";
|
|
7
|
+
import { mergeOpenApiDocuments } from "@zuplo/openapi-tools";
|
|
7
8
|
import { baseRoutesFileOnImportTests, baseRoutesFileWOOperationIDs, } from "./oas-test-data.js";
|
|
8
9
|
import { BASE_TEMPLATE } from "../project/import-openapi/handler.js";
|
|
9
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -15,7 +16,7 @@ describe("Import open api utils", async function () {
|
|
|
15
16
|
const toImportContent = await fs.readFile(toImportPath, "utf-8");
|
|
16
17
|
const toImportOpenApiSpec = await parseOpenApiFile(".json", toImportContent);
|
|
17
18
|
const originalDocument = (await parseOpenApiFile(".json", JSON.stringify(baseRoutesFileOnImportTests)));
|
|
18
|
-
const { created, merged, retained } =
|
|
19
|
+
const { created, merged, retained } = mergeOpenApiDocuments(originalDocument, toImportOpenApiSpec, "path-method");
|
|
19
20
|
const expectedMergedResult = new Set().add("post>/v2/second/{userUid}/nature");
|
|
20
21
|
const expectedRetainedResult = new Set().add("post>/v1/second/{userUid}/nature");
|
|
21
22
|
expect(created).to.deep.equals(new Set());
|
|
@@ -27,7 +28,7 @@ describe("Import open api utils", async function () {
|
|
|
27
28
|
const toImportContent = await fs.readFile(toImportPath, "utf-8");
|
|
28
29
|
const toImportOpenApiSpec = await parseOpenApiFile(".json", toImportContent);
|
|
29
30
|
const originalDocument = (await parseOpenApiFile(".json", BASE_TEMPLATE));
|
|
30
|
-
const { created, merged, retained } =
|
|
31
|
+
const { created, merged, retained } = mergeOpenApiDocuments(originalDocument, toImportOpenApiSpec, "path-method");
|
|
31
32
|
expect(created).to.deep.equals(new Set().add("post>/v2/second/{userUid}/nature"));
|
|
32
33
|
expect(merged).to.deep.equals(new Set());
|
|
33
34
|
expect(retained).to.deep.equals(new Set());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-openapi-utils.test.js","sourceRoot":"","sources":["../../src/__tests__/import-openapi-utils.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from \"chai\";\nimport { describe, it } from \"node:test\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n addOperationIdsAsNecessary,\n generateMergeChangeset,\n parseOpenApiFile,\n} from \"../project/import-openapi/utils.js\";\nimport {\n baseRoutesFileOnImportTests,\n baseRoutesFileWOOperationIDs,\n} from \"./oas-test-data.js\";\nimport { ZuploOpenApiDocument } from \"../../../types/dist/open-api.js\";\nimport { BASE_TEMPLATE } from \"../project/import-openapi/handler.js\";\nconst __filename = fileURLToPath(import.meta.url); // get the resolved path to the file\nconst __dirname = path.dirname(__filename); // get the name of the directory\n\nconst testAssetsPath = path.join(\n __dirname,\n \"..\",\n \"..\",\n \"src\",\n \"__tests__\",\n \"test-assets\"\n);\n\ndescribe(\"Import open api utils\", async function () {\n it(\"should generate merge changes between two different oas files\", async function () {\n const toImportPath = path.join(testAssetsPath, \"toimport.oas.json\");\n const toImportContent = await fs.readFile(toImportPath, \"utf-8\");\n const toImportOpenApiSpec = await parseOpenApiFile(\n \".json\",\n toImportContent\n );\n\n const originalDocument = (await parseOpenApiFile(\n \".json\",\n JSON.stringify(baseRoutesFileOnImportTests)\n )) as ZuploOpenApiDocument;\n\n const { created, merged, retained } = generateMergeChangeset(\n originalDocument,\n toImportOpenApiSpec\n );\n\n const expectedMergedResult = new Set().add(\n \"post>/v2/second/{userUid}/nature\"\n );\n const expectedRetainedResult = new Set().add(\n \"post>/v1/second/{userUid}/nature\"\n );\n\n expect(created).to.deep.equals(new Set());\n expect(merged).to.deep.equals(expectedMergedResult);\n expect(retained).to.deep.equals(expectedRetainedResult);\n });\n\n it(\"should generate merge changes between a oas file and the default base template\", async function () {\n const toImportPath = path.join(testAssetsPath, \"toimport.oas.json\");\n const toImportContent = await fs.readFile(toImportPath, \"utf-8\");\n const toImportOpenApiSpec = await parseOpenApiFile(\n \".json\",\n toImportContent\n );\n\n const originalDocument = (await parseOpenApiFile(\n \".json\",\n BASE_TEMPLATE\n )) as ZuploOpenApiDocument;\n\n const { created, merged, retained } = generateMergeChangeset(\n originalDocument,\n toImportOpenApiSpec\n );\n\n expect(created).to.deep.equals(\n new Set().add(\"post>/v2/second/{userUid}/nature\")\n );\n expect(merged).to.deep.equals(new Set());\n expect(retained).to.deep.equals(new Set());\n });\n\n it(\"should generate missing operation ids\", async function () {\n const oasDocument = await parseOpenApiFile(\n \".json\",\n JSON.stringify(baseRoutesFileWOOperationIDs)\n );\n\n addOperationIdsAsNecessary(oasDocument);\n\n expect(oasDocument.paths).to.not.be.empty;\n // @ts-ignore\n expect(oasDocument.paths[\"/v2/second/{userUid}/nature\"]?.post?.operationId)\n .to.not.be.empty;\n });\n\n it(\"should not change existing operation ids\", async function () {\n const oasDocument = await parseOpenApiFile(\n \".json\",\n JSON.stringify(baseRoutesFileOnImportTests)\n );\n\n addOperationIdsAsNecessary(oasDocument);\n\n expect(oasDocument.paths).to.not.be.empty;\n expect(\n // @ts-ignore\n oasDocument.paths[\"/v1/second/{userUid}/nature\"]?.post?.operationId\n ).to.equal(\"12345\");\n expect(\n // @ts-ignore\n oasDocument.paths[\"/v2/second/{userUid}/nature\"]?.post?.operationId\n ).to.equal(\"67920\");\n });\n\n it(\"should successfully parse a yaml open api file\", async function () {\n const toImportPath = path.join(testAssetsPath, \"toimportv2.yaml\");\n const toImportContent = await fs.readFile(toImportPath, \"utf-8\");\n const toImportOpenApiSpec = await parseOpenApiFile(\n \".yaml\",\n toImportContent\n );\n\n expect(toImportOpenApiSpec).to.not.be.empty;\n expect(toImportOpenApiSpec.info).to.deep.equals({\n title: \"Protect API\",\n description: \"Buy & sell\",\n version: \"0.2.0\",\n contact: {\n name: \"Zuplo YAML Test\",\n url: \"https://zuplo.com/\",\n email: \"test@example.com\",\n },\n });\n expect(toImportOpenApiSpec.servers).to.deep.equals([\n {\n url: \"https://api.zuplo.com\",\n description: \"Production\",\n },\n ]);\n expect(toImportOpenApiSpec.tags).to.deep.equals([\n {\n name: \"Order\",\n },\n {\n name: \"Organization\",\n },\n {\n name: \"Site\",\n },\n {\n name: \"Supervisor\",\n },\n ]);\n\n expect(toImportOpenApiSpec.paths).to.not.be.empty;\n\n //@ts-ignore\n expect(toImportOpenApiSpec.paths[\"/v1/orders\"]).to.not.be.empty;\n //@ts-ignore\n expect(toImportOpenApiSpec.paths[\"/v1/orders/wa/{waaaa}\"]).to.not.be.empty;\n //@ts-ignore\n expect(toImportOpenApiSpec.paths[\"/v1/orders/{order}\"]).to.not.be.empty;\n //@ts-ignore\n expect(toImportOpenApiSpec.paths[\"/v1/orgs/{organization}\"]).to.not.be\n .empty;\n //@ts-ignore\n expect(toImportOpenApiSpec.paths[\"/v1/sites\"]).to.deep.equals({\n get: {\n operationId: \"get-sites\",\n summary: \"Get Sites\",\n description: \"Sites are locations\",\n tags: [\"Site\"],\n responses: {\n \"200\": {\n description: \"OK\",\n content: {\n \"application/json\": {\n schema: {\n type: \"array\",\n items: {\n $ref: \"#/components/schemas/Site\",\n },\n },\n },\n },\n headers: {\n \"Cache-Control\": {\n required: true,\n schema: {\n type: \"string\",\n },\n description:\n \"Responses are cacheable following standard HTTP headers.\",\n },\n },\n },\n },\n },\n });\n expect(toImportOpenApiSpec.components).to.not.be.empty;\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"import-openapi-utils.test.js","sourceRoot":"","sources":["../../src/__tests__/import-openapi-utils.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { expect } from \"chai\";\nimport { describe, it } from \"node:test\";\nimport fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n addOperationIdsAsNecessary,\n parseOpenApiFile,\n} from \"../project/import-openapi/utils.js\";\nimport { mergeOpenApiDocuments } from \"@zuplo/openapi-tools\";\nimport {\n baseRoutesFileOnImportTests,\n baseRoutesFileWOOperationIDs,\n} from \"./oas-test-data.js\";\nimport { ZuploOpenApiDocument } from \"../../../types/dist/open-api.js\";\nimport { BASE_TEMPLATE } from \"../project/import-openapi/handler.js\";\nconst __filename = fileURLToPath(import.meta.url); // get the resolved path to the file\nconst __dirname = path.dirname(__filename); // get the name of the directory\n\nconst testAssetsPath = path.join(\n __dirname,\n \"..\",\n \"..\",\n \"src\",\n \"__tests__\",\n \"test-assets\"\n);\n\ndescribe(\"Import open api utils\", async function () {\n it(\"should generate merge changes between two different oas files\", async function () {\n const toImportPath = path.join(testAssetsPath, \"toimport.oas.json\");\n const toImportContent = await fs.readFile(toImportPath, \"utf-8\");\n const toImportOpenApiSpec = await parseOpenApiFile(\n \".json\",\n toImportContent\n );\n\n const originalDocument = (await parseOpenApiFile(\n \".json\",\n JSON.stringify(baseRoutesFileOnImportTests)\n )) as ZuploOpenApiDocument;\n\n const { created, merged, retained } = mergeOpenApiDocuments(\n originalDocument,\n toImportOpenApiSpec,\n \"path-method\"\n );\n\n const expectedMergedResult = new Set().add(\n \"post>/v2/second/{userUid}/nature\"\n );\n const expectedRetainedResult = new Set().add(\n \"post>/v1/second/{userUid}/nature\"\n );\n\n expect(created).to.deep.equals(new Set());\n expect(merged).to.deep.equals(expectedMergedResult);\n expect(retained).to.deep.equals(expectedRetainedResult);\n });\n\n it(\"should generate merge changes between a oas file and the default base template\", async function () {\n const toImportPath = path.join(testAssetsPath, \"toimport.oas.json\");\n const toImportContent = await fs.readFile(toImportPath, \"utf-8\");\n const toImportOpenApiSpec = await parseOpenApiFile(\n \".json\",\n toImportContent\n );\n\n const originalDocument = (await parseOpenApiFile(\n \".json\",\n BASE_TEMPLATE\n )) as ZuploOpenApiDocument;\n\n const { created, merged, retained } = mergeOpenApiDocuments(\n originalDocument,\n toImportOpenApiSpec,\n \"path-method\"\n );\n\n expect(created).to.deep.equals(\n new Set().add(\"post>/v2/second/{userUid}/nature\")\n );\n expect(merged).to.deep.equals(new Set());\n expect(retained).to.deep.equals(new Set());\n });\n\n it(\"should generate missing operation ids\", async function () {\n const oasDocument = await parseOpenApiFile(\n \".json\",\n JSON.stringify(baseRoutesFileWOOperationIDs)\n );\n\n addOperationIdsAsNecessary(oasDocument);\n\n expect(oasDocument.paths).to.not.be.empty;\n // @ts-ignore\n expect(oasDocument.paths[\"/v2/second/{userUid}/nature\"]?.post?.operationId)\n .to.not.be.empty;\n });\n\n it(\"should not change existing operation ids\", async function () {\n const oasDocument = await parseOpenApiFile(\n \".json\",\n JSON.stringify(baseRoutesFileOnImportTests)\n );\n\n addOperationIdsAsNecessary(oasDocument);\n\n expect(oasDocument.paths).to.not.be.empty;\n expect(\n // @ts-ignore\n oasDocument.paths[\"/v1/second/{userUid}/nature\"]?.post?.operationId\n ).to.equal(\"12345\");\n expect(\n // @ts-ignore\n oasDocument.paths[\"/v2/second/{userUid}/nature\"]?.post?.operationId\n ).to.equal(\"67920\");\n });\n\n it(\"should successfully parse a yaml open api file\", async function () {\n const toImportPath = path.join(testAssetsPath, \"toimportv2.yaml\");\n const toImportContent = await fs.readFile(toImportPath, \"utf-8\");\n const toImportOpenApiSpec = await parseOpenApiFile(\n \".yaml\",\n toImportContent\n );\n\n expect(toImportOpenApiSpec).to.not.be.empty;\n expect(toImportOpenApiSpec.info).to.deep.equals({\n title: \"Protect API\",\n description: \"Buy & sell\",\n version: \"0.2.0\",\n contact: {\n name: \"Zuplo YAML Test\",\n url: \"https://zuplo.com/\",\n email: \"test@example.com\",\n },\n });\n expect(toImportOpenApiSpec.servers).to.deep.equals([\n {\n url: \"https://api.zuplo.com\",\n description: \"Production\",\n },\n ]);\n expect(toImportOpenApiSpec.tags).to.deep.equals([\n {\n name: \"Order\",\n },\n {\n name: \"Organization\",\n },\n {\n name: \"Site\",\n },\n {\n name: \"Supervisor\",\n },\n ]);\n\n expect(toImportOpenApiSpec.paths).to.not.be.empty;\n\n //@ts-ignore\n expect(toImportOpenApiSpec.paths[\"/v1/orders\"]).to.not.be.empty;\n //@ts-ignore\n expect(toImportOpenApiSpec.paths[\"/v1/orders/wa/{waaaa}\"]).to.not.be.empty;\n //@ts-ignore\n expect(toImportOpenApiSpec.paths[\"/v1/orders/{order}\"]).to.not.be.empty;\n //@ts-ignore\n expect(toImportOpenApiSpec.paths[\"/v1/orgs/{organization}\"]).to.not.be\n .empty;\n //@ts-ignore\n expect(toImportOpenApiSpec.paths[\"/v1/sites\"]).to.deep.equals({\n get: {\n operationId: \"get-sites\",\n summary: \"Get Sites\",\n description: \"Sites are locations\",\n tags: [\"Site\"],\n responses: {\n \"200\": {\n description: \"OK\",\n content: {\n \"application/json\": {\n schema: {\n type: \"array\",\n items: {\n $ref: \"#/components/schemas/Site\",\n },\n },\n },\n },\n headers: {\n \"Cache-Control\": {\n required: true,\n schema: {\n type: \"string\",\n },\n description:\n \"Responses are cacheable following standard HTTP headers.\",\n },\n },\n },\n },\n },\n });\n expect(toImportOpenApiSpec.components).to.not.be.empty;\n });\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-openapi.d.ts","sourceRoot":"","sources":["../../../src/cmds/project/import-openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;;;;qBAUV,IAAI,KAAG,IAAI,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"import-openapi.d.ts","sourceRoot":"","sources":["../../../src/cmds/project/import-openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;;;;qBAUV,IAAI,KAAG,IAAI,CAAC,OAAO,CAAC;oBA2Bf,OAAO;;AA9B/B,wBAkCE"}
|
|
@@ -21,7 +21,13 @@ export default {
|
|
|
21
21
|
type: "string",
|
|
22
22
|
describe: "The destination file name. Defaults to the inferred path from the source name",
|
|
23
23
|
})
|
|
24
|
-
.demandOption(["source", "destination"])
|
|
24
|
+
.demandOption(["source", "destination"])
|
|
25
|
+
.option("merge-mode", {
|
|
26
|
+
type: "string",
|
|
27
|
+
describe: "The merge mode to use when importing the OpenAPI file",
|
|
28
|
+
choices: ["path-method", "operation-id"],
|
|
29
|
+
default: "path-method",
|
|
30
|
+
});
|
|
25
31
|
},
|
|
26
32
|
handler: async (argv) => {
|
|
27
33
|
await captureEvent({ argv, event: "zup project import-open-api" });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-openapi.js","sourceRoot":"","sources":["../../../src/cmds/project/import-openapi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAEL,aAAa,GACd,MAAM,yCAAyC,CAAC;AAEjD,eAAe;IACb,IAAI,EAAE,gDAAgD;IACtD,OAAO,EAAE,gBAAgB;IACzB,OAAO,EAAE,CAAC,KAAW,EAAiB,EAAE;QACtC,OAAO,KAAK;aACT,MAAM,CAAC,KAAK,EAAE;YACb,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,uCAAuC;YACjD,OAAO,EAAE,GAAG;YACZ,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,IAAI;SACb,CAAC;aACD,MAAM,CAAC,QAAQ,EAAE;YAChB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,4BAA4B;YACtC,SAAS,EAAE,CAAC,YAAY,CAAC;SAC1B,CAAC;aACD,MAAM,CAAC,aAAa,EAAE;YACrB,IAAI,EAAE,QAAQ;YACd,QAAQ,EACN,+EAA+E;SAClF,CAAC;aACD,YAAY,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"import-openapi.js","sourceRoot":"","sources":["../../../src/cmds/project/import-openapi.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,EAEL,aAAa,GACd,MAAM,yCAAyC,CAAC;AAEjD,eAAe;IACb,IAAI,EAAE,gDAAgD;IACtD,OAAO,EAAE,gBAAgB;IACzB,OAAO,EAAE,CAAC,KAAW,EAAiB,EAAE;QACtC,OAAO,KAAK;aACT,MAAM,CAAC,KAAK,EAAE;YACb,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,uCAAuC;YACjD,OAAO,EAAE,GAAG;YACZ,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,IAAI;SACb,CAAC;aACD,MAAM,CAAC,QAAQ,EAAE;YAChB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,4BAA4B;YACtC,SAAS,EAAE,CAAC,YAAY,CAAC;SAC1B,CAAC;aACD,MAAM,CAAC,aAAa,EAAE;YACrB,IAAI,EAAE,QAAQ;YACd,QAAQ,EACN,+EAA+E;SAClF,CAAC;aACD,YAAY,CAAC,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;aACvC,MAAM,CAAC,YAAY,EAAE;YACpB,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,uDAAuD;YACjE,OAAO,EAAE,CAAC,aAAa,EAAE,cAAc,CAAC;YACxC,OAAO,EAAE,aAAa;SACvB,CAAC,CAAC;IACP,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,IAAa,EAAE,EAAE;QAC/B,MAAM,YAAY,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC;QACnE,MAAM,aAAa,CAAC,IAAiB,CAAC,CAAC;IACzC,CAAC;CACF,CAAC","sourcesContent":["import { Argv } from \"yargs\";\nimport { captureEvent } from \"../../common/analytics/lib.js\";\nimport {\n Arguments,\n importOpenApi,\n} from \"../../project/import-openapi/handler.js\";\n\nexport default {\n desc: \"Import an OpenAPI file into your Zuplo project\",\n command: \"import-openapi\",\n builder: (yargs: Argv): Argv<unknown> => {\n return yargs\n .option(\"dir\", {\n type: \"string\",\n describe: \"The directory containing your project\",\n default: \".\",\n normalize: true,\n hidden: true,\n })\n .option(\"source\", {\n type: \"string\",\n describe: \"The OpenAPI file to import\",\n conflicts: [\"source-url\"],\n })\n .option(\"destination\", {\n type: \"string\",\n describe:\n \"The destination file name. Defaults to the inferred path from the source name\",\n })\n .demandOption([\"source\", \"destination\"])\n .option(\"merge-mode\", {\n type: \"string\",\n describe: \"The merge mode to use when importing the OpenAPI file\",\n choices: [\"path-method\", \"operation-id\"],\n default: \"path-method\",\n });\n },\n handler: async (argv: unknown) => {\n await captureEvent({ argv, event: \"zup project import-open-api\" });\n await importOpenApi(argv as Arguments);\n },\n};\n"]}
|
|
@@ -5,6 +5,7 @@ export interface Arguments extends CommonArgs {
|
|
|
5
5
|
source: string;
|
|
6
6
|
destination: string;
|
|
7
7
|
"source-url": string;
|
|
8
|
+
"merge-mode"?: "path-method" | "operation-id";
|
|
8
9
|
}
|
|
9
10
|
export declare const BASE_TEMPLATE = "\n{\n \"openapi\": \"3.1.0\",\n \"info\": {\n \"version\": \"1.0.0\",\n \"title\": \"My Zuplo API\"\n },\n \"paths\": {}\n}\n\n";
|
|
10
11
|
export declare function importOpenApi(argv: Arguments): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/project/import-openapi/handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/project/import-openapi/handler.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAUlD,MAAM,WAAW,SAAU,SAAQ,UAAU;IAC3C,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,aAAa,GAAG,cAAc,CAAC;CAC/C;AAED,eAAO,MAAM,aAAa,8IAUzB,CAAC;AAGF,wBAAsB,aAAa,CAAC,IAAI,EAAE,SAAS,iBA+KlD"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { confirm } from "@inquirer/prompts";
|
|
2
|
+
import { mergeOpenApiDocuments } from "@zuplo/openapi-tools";
|
|
2
3
|
import jsYaml from "js-yaml";
|
|
3
4
|
import { existsSync, writeFileSync } from "node:fs";
|
|
4
5
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
@@ -7,7 +8,7 @@ import path, { basename, dirname, extname, join, relative } from "node:path";
|
|
|
7
8
|
import { format } from "prettier";
|
|
8
9
|
import { logger } from "../../common/logger.js";
|
|
9
10
|
import { printCriticalFailureToConsoleAndExit, printDiagnosticsToConsole, printResultToConsoleAndExitGracefully, } from "../../common/output.js";
|
|
10
|
-
import { addOperationIdsAsNecessary,
|
|
11
|
+
import { addOperationIdsAsNecessary, parseOpenApiFile } from "./utils.js";
|
|
11
12
|
export const BASE_TEMPLATE = `
|
|
12
13
|
{
|
|
13
14
|
"openapi": "3.1.0",
|
|
@@ -87,7 +88,8 @@ export async function importOpenApi(argv) {
|
|
|
87
88
|
const existingFileContent = existingOpenApiSpec.toString();
|
|
88
89
|
originalDocument = (await parseOpenApiFile(extName, existingFileContent));
|
|
89
90
|
}
|
|
90
|
-
const
|
|
91
|
+
const mergeMode = argv["merge-mode"] || "path-method";
|
|
92
|
+
const { created, merged, retained, mergedDocument } = mergeOpenApiDocuments(originalDocument, parsedOpenApiSpec, mergeMode);
|
|
91
93
|
printDiagnosticsToConsole("This import will...");
|
|
92
94
|
printDiagnosticsToConsole("");
|
|
93
95
|
if (created.size > 0) {
|
|
@@ -121,7 +123,6 @@ export async function importOpenApi(argv) {
|
|
|
121
123
|
await printResultToConsoleAndExitGracefully("Import cancelled.");
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
|
-
const mergedDocument = mergeOpenApiDocuments(originalDocument, parsedOpenApiSpec);
|
|
125
126
|
addOperationIdsAsNecessary(mergedDocument);
|
|
126
127
|
const formattedOpenApi = await format(JSON.stringify(mergedDocument), {
|
|
127
128
|
parser: "json-stringify",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/project/import-openapi/handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { confirm } from \"@inquirer/prompts\";\nimport jsYaml from \"js-yaml\";\nimport { existsSync, writeFileSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path, { basename, dirname, extname, join, relative } from \"node:path\";\nimport { format } from \"prettier\";\nimport { CommonArgs } from \"../../common/args.js\";\nimport { logger } from \"../../common/logger.js\";\nimport {\n printCriticalFailureToConsoleAndExit,\n printDiagnosticsToConsole,\n printResultToConsoleAndExitGracefully,\n} from \"../../common/output.js\";\nimport { ZuploOpenApiDocument } from \"./interfaces.js\";\nimport {\n addOperationIdsAsNecessary,\n generateMergeChangeset,\n mergeOpenApiDocuments,\n parseOpenApiFile,\n} from \"./utils.js\";\n\nexport interface Arguments extends CommonArgs {\n dir: string;\n prompt: boolean;\n source: string;\n destination: string;\n \"source-url\": string;\n}\n\nexport const BASE_TEMPLATE = `\n{\n \"openapi\": \"3.1.0\",\n \"info\": {\n \"version\": \"1.0.0\",\n \"title\": \"My Zuplo API\"\n },\n \"paths\": {}\n}\n\n`;\n\n// import is a reserved keyword so importSpec was used instead\nexport async function importOpenApi(argv: Arguments) {\n let normalizedFilePath: string;\n // First see if this is a url\n let handleAsUrl = true;\n try {\n new URL(argv.source);\n } catch {\n handleAsUrl = false;\n }\n\n if (handleAsUrl) {\n const parsedUrl = new URL(argv.source);\n const tempDir = tmpdir();\n const guessedFileName =\n basename(parsedUrl.pathname).replace(/\\.[^/.]+$/, \"\") ||\n `imported-${Buffer.from(argv.source).toString(\"base64\")}`;\n normalizedFilePath = join(tempDir, guessedFileName);\n await mkdir(dirname(normalizedFilePath), { recursive: true });\n\n try {\n const response = await fetch(parsedUrl);\n if (!response.ok) {\n await printCriticalFailureToConsoleAndExit(\n `Failed to download the remote OpenAPI file. Server responded with ${response.status} ${response.statusText}`\n );\n }\n\n const text = await response.text();\n\n try {\n // 1a. See if this is json else try to parse as yaml\n JSON.parse(text);\n normalizedFilePath = normalizedFilePath + \".json\";\n await writeFile(normalizedFilePath, text, { flag: \"w+\" });\n } catch {\n try {\n // 1b. See if this is yaml\n jsYaml.load(text);\n normalizedFilePath = normalizedFilePath + \".yaml\";\n await writeFile(normalizedFilePath, text, { flag: \"w+\" });\n } catch {\n await printCriticalFailureToConsoleAndExit(\n `Failed to parse the remote OpenAPI file as either JSON or YAML.`\n );\n }\n }\n } catch (err) {\n logger.error(err);\n await printCriticalFailureToConsoleAndExit(\n `Failed to download the remote OpenAPI file.`\n );\n }\n } else {\n // 1c. This is a normal file so we use the file extension\n const filePath = argv.source;\n normalizedFilePath = join(relative(process.cwd(), filePath));\n\n if (!existsSync(normalizedFilePath)) {\n await printCriticalFailureToConsoleAndExit(\n `The file ${normalizedFilePath} to import does not exist.`\n );\n }\n }\n\n const rawOpenApiSpec = await readFile(normalizedFilePath);\n const extName = extname(normalizedFilePath);\n const fileContent = rawOpenApiSpec.toString();\n const parsedOpenApiSpec = await parseOpenApiFile(extName, fileContent);\n\n const destination = argv.destination;\n\n if (!destination.endsWith(\".oas.json\")) {\n await printCriticalFailureToConsoleAndExit(\n `Destination file name must end with '.oas.json'`\n );\n }\n\n const destinationFilePath = join(relative(process.cwd(), destination));\n\n let originalDocument: ZuploOpenApiDocument;\n if (!existsSync(destinationFilePath)) {\n // This is an initial import\n originalDocument = (await parseOpenApiFile(\n \".json\",\n BASE_TEMPLATE\n )) as ZuploOpenApiDocument;\n } else {\n const existingOpenApiSpec = await readFile(destinationFilePath);\n const existingFileContent = existingOpenApiSpec.toString();\n originalDocument = (await parseOpenApiFile(\n extName,\n existingFileContent\n )) as ZuploOpenApiDocument;\n }\n const { created, merged, retained } = generateMergeChangeset(\n originalDocument,\n parsedOpenApiSpec\n );\n\n // Present the changes\n printDiagnosticsToConsole(\"This import will...\");\n printDiagnosticsToConsole(\"\");\n\n if (created.size > 0) {\n printDiagnosticsToConsole(\n `Create ${created.size} new ${\n created.size > 1 ? \"operations\" : \"operation\"\n }`\n );\n printDiagnosticsToConsole(\"\");\n created.forEach((operation) => {\n printDiagnosticsToConsole(operation);\n });\n printDiagnosticsToConsole(\"\");\n }\n\n if (merged.size > 0) {\n printDiagnosticsToConsole(\n `Merge ${merged.size} new ${merged.size > 1 ? \"operations\" : \"operation\"}`\n );\n printDiagnosticsToConsole(\"\");\n merged.forEach((operation) => {\n printDiagnosticsToConsole(operation);\n });\n printDiagnosticsToConsole(\"\");\n }\n\n if (retained.size > 0) {\n printDiagnosticsToConsole(\n `Retain ${retained.size} new ${\n retained.size > 1 ? \"operations\" : \"operation\"\n }`\n );\n printDiagnosticsToConsole(\"\");\n retained.forEach((operation) => {\n printDiagnosticsToConsole(operation);\n });\n printDiagnosticsToConsole(\"\");\n }\n\n if (argv.prompt) {\n printDiagnosticsToConsole(\"\");\n const answer = await confirm({ message: \"Proceed?\", default: true });\n if (!answer) {\n await printResultToConsoleAndExitGracefully(\"Import cancelled.\");\n }\n }\n\n const mergedDocument = mergeOpenApiDocuments(\n originalDocument,\n parsedOpenApiSpec\n );\n\n addOperationIdsAsNecessary(mergedDocument);\n\n const formattedOpenApi = await format(JSON.stringify(mergedDocument), {\n parser: \"json-stringify\",\n });\n\n // Create folder structure if needed\n if (!existsSync(destinationFilePath)) {\n // Get the directory path of the file\n const dir = path.dirname(destinationFilePath);\n\n // Ensure that the directory exists (creates parent directories if necessary)\n await mkdir(dir, { recursive: true });\n }\n\n writeFileSync(destinationFilePath, formattedOpenApi, {\n flag: \"w\",\n });\n\n await printResultToConsoleAndExitGracefully(\n `Import successful. File written to ${destinationFilePath}`\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/project/import-openapi/handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { confirm } from \"@inquirer/prompts\";\nimport { mergeOpenApiDocuments } from \"@zuplo/openapi-tools\";\nimport jsYaml from \"js-yaml\";\nimport { existsSync, writeFileSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path, { basename, dirname, extname, join, relative } from \"node:path\";\nimport { format } from \"prettier\";\nimport { CommonArgs } from \"../../common/args.js\";\nimport { logger } from \"../../common/logger.js\";\nimport {\n printCriticalFailureToConsoleAndExit,\n printDiagnosticsToConsole,\n printResultToConsoleAndExitGracefully,\n} from \"../../common/output.js\";\nimport { ZuploOpenApiDocument } from \"./interfaces.js\";\nimport { addOperationIdsAsNecessary, parseOpenApiFile } from \"./utils.js\";\n\nexport interface Arguments extends CommonArgs {\n dir: string;\n prompt: boolean;\n source: string;\n destination: string;\n \"source-url\": string;\n \"merge-mode\"?: \"path-method\" | \"operation-id\";\n}\n\nexport const BASE_TEMPLATE = `\n{\n \"openapi\": \"3.1.0\",\n \"info\": {\n \"version\": \"1.0.0\",\n \"title\": \"My Zuplo API\"\n },\n \"paths\": {}\n}\n\n`;\n\n// import is a reserved keyword so importSpec was used instead\nexport async function importOpenApi(argv: Arguments) {\n let normalizedFilePath: string;\n // First see if this is a url\n let handleAsUrl = true;\n try {\n new URL(argv.source);\n } catch {\n handleAsUrl = false;\n }\n\n if (handleAsUrl) {\n const parsedUrl = new URL(argv.source);\n const tempDir = tmpdir();\n const guessedFileName =\n basename(parsedUrl.pathname).replace(/\\.[^/.]+$/, \"\") ||\n `imported-${Buffer.from(argv.source).toString(\"base64\")}`;\n normalizedFilePath = join(tempDir, guessedFileName);\n await mkdir(dirname(normalizedFilePath), { recursive: true });\n\n try {\n const response = await fetch(parsedUrl);\n if (!response.ok) {\n await printCriticalFailureToConsoleAndExit(\n `Failed to download the remote OpenAPI file. Server responded with ${response.status} ${response.statusText}`\n );\n }\n\n const text = await response.text();\n\n try {\n // 1a. See if this is json else try to parse as yaml\n JSON.parse(text);\n normalizedFilePath = normalizedFilePath + \".json\";\n await writeFile(normalizedFilePath, text, { flag: \"w+\" });\n } catch {\n try {\n // 1b. See if this is yaml\n jsYaml.load(text);\n normalizedFilePath = normalizedFilePath + \".yaml\";\n await writeFile(normalizedFilePath, text, { flag: \"w+\" });\n } catch {\n await printCriticalFailureToConsoleAndExit(\n `Failed to parse the remote OpenAPI file as either JSON or YAML.`\n );\n }\n }\n } catch (err) {\n logger.error(err);\n await printCriticalFailureToConsoleAndExit(\n `Failed to download the remote OpenAPI file.`\n );\n }\n } else {\n // 1c. This is a normal file so we use the file extension\n const filePath = argv.source;\n normalizedFilePath = join(relative(process.cwd(), filePath));\n\n if (!existsSync(normalizedFilePath)) {\n await printCriticalFailureToConsoleAndExit(\n `The file ${normalizedFilePath} to import does not exist.`\n );\n }\n }\n\n const rawOpenApiSpec = await readFile(normalizedFilePath);\n const extName = extname(normalizedFilePath);\n const fileContent = rawOpenApiSpec.toString();\n const parsedOpenApiSpec = await parseOpenApiFile(extName, fileContent);\n\n const destination = argv.destination;\n\n if (!destination.endsWith(\".oas.json\")) {\n await printCriticalFailureToConsoleAndExit(\n `Destination file name must end with '.oas.json'`\n );\n }\n\n const destinationFilePath = join(relative(process.cwd(), destination));\n\n let originalDocument: ZuploOpenApiDocument;\n if (!existsSync(destinationFilePath)) {\n // This is an initial import\n originalDocument = (await parseOpenApiFile(\n \".json\",\n BASE_TEMPLATE\n )) as ZuploOpenApiDocument;\n } else {\n const existingOpenApiSpec = await readFile(destinationFilePath);\n const existingFileContent = existingOpenApiSpec.toString();\n originalDocument = (await parseOpenApiFile(\n extName,\n existingFileContent\n )) as ZuploOpenApiDocument;\n }\n\n // Default to path-method merging\n const mergeMode = argv[\"merge-mode\"] || \"path-method\";\n\n const { created, merged, retained, mergedDocument } = mergeOpenApiDocuments(\n originalDocument,\n parsedOpenApiSpec,\n mergeMode\n );\n\n // Present the changes\n printDiagnosticsToConsole(\"This import will...\");\n printDiagnosticsToConsole(\"\");\n\n if (created.size > 0) {\n printDiagnosticsToConsole(\n `Create ${created.size} new ${\n created.size > 1 ? \"operations\" : \"operation\"\n }`\n );\n printDiagnosticsToConsole(\"\");\n created.forEach((operation) => {\n printDiagnosticsToConsole(operation);\n });\n printDiagnosticsToConsole(\"\");\n }\n\n if (merged.size > 0) {\n printDiagnosticsToConsole(\n `Merge ${merged.size} new ${merged.size > 1 ? \"operations\" : \"operation\"}`\n );\n printDiagnosticsToConsole(\"\");\n merged.forEach((operation) => {\n printDiagnosticsToConsole(operation);\n });\n printDiagnosticsToConsole(\"\");\n }\n\n if (retained.size > 0) {\n printDiagnosticsToConsole(\n `Retain ${retained.size} new ${\n retained.size > 1 ? \"operations\" : \"operation\"\n }`\n );\n printDiagnosticsToConsole(\"\");\n retained.forEach((operation) => {\n printDiagnosticsToConsole(operation);\n });\n printDiagnosticsToConsole(\"\");\n }\n\n if (argv.prompt) {\n printDiagnosticsToConsole(\"\");\n const answer = await confirm({ message: \"Proceed?\", default: true });\n if (!answer) {\n await printResultToConsoleAndExitGracefully(\"Import cancelled.\");\n }\n }\n\n addOperationIdsAsNecessary(mergedDocument);\n\n const formattedOpenApi = await format(JSON.stringify(mergedDocument), {\n parser: \"json-stringify\",\n });\n\n // Create folder structure if needed\n if (!existsSync(destinationFilePath)) {\n // Get the directory path of the file\n const dir = path.dirname(destinationFilePath);\n\n // Ensure that the directory exists (creates parent directories if necessary)\n await mkdir(dir, { recursive: true });\n }\n\n writeFileSync(destinationFilePath, formattedOpenApi, {\n flag: \"w\",\n });\n\n await printResultToConsoleAndExitGracefully(\n `Import successful. File written to ${destinationFilePath}`\n );\n}\n"]}
|
|
@@ -4,10 +4,4 @@ export declare const OPERATION_PATH_MERGE_DELIMITER = ">";
|
|
|
4
4
|
export declare const OPEN_API_FILE_TYPES: string[];
|
|
5
5
|
export declare const parseOpenApiFile: (extName: string, fileText: string) => Promise<ZuploOpenApiDocument | OpenAPIV3_1.Document<{}>>;
|
|
6
6
|
export declare const addOperationIdsAsNecessary: (openApi: OpenAPIV3_1.Document | ZuploOpenApiDocument) => void;
|
|
7
|
-
export declare const mergeOpenApiDocuments: (originalDocument: ZuploOpenApiDocument, newDocument: OpenAPIV3_1.Document | ZuploOpenApiDocument) => ZuploOpenApiDocument;
|
|
8
|
-
export declare const generateMergeChangeset: (originalDocument: ZuploOpenApiDocument, newDocument: OpenAPIV3_1.Document | ZuploOpenApiDocument) => {
|
|
9
|
-
created: Set<string>;
|
|
10
|
-
merged: Set<string>;
|
|
11
|
-
retained: Set<string>;
|
|
12
|
-
};
|
|
13
7
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/project/import-openapi/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/project/import-openapi/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,eAAO,MAAM,8BAA8B,MAAM,CAAC;AAClD,eAAO,MAAM,mBAAmB,UAA6B,CAAC;AAE9D,eAAO,MAAM,gBAAgB,YAAmB,MAAM,YAAY,MAAM,6DAYvE,CAAC;AAMF,eAAO,MAAM,0BAA0B,YAC5B,WAAW,CAAC,QAAQ,GAAG,oBAAoB,SA4BrD,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import yaml from "js-yaml";
|
|
2
2
|
import { v4 } from "uuid";
|
|
3
|
-
import { ZUPLO_OPEN_API_PATH_KEY, ZUPLO_OPEN_API_ROUTE_KEY, } from "./interfaces.js";
|
|
4
3
|
export const OPERATION_PATH_MERGE_DELIMITER = ">";
|
|
5
4
|
export const OPEN_API_FILE_TYPES = [".json", ".yml", ".yaml"];
|
|
6
5
|
export const parseOpenApiFile = async (extName, fileText) => {
|
|
@@ -40,181 +39,4 @@ export const addOperationIdsAsNecessary = (openApi) => {
|
|
|
40
39
|
}
|
|
41
40
|
}
|
|
42
41
|
};
|
|
43
|
-
export const mergeOpenApiDocuments = (originalDocument, newDocument) => {
|
|
44
|
-
return mergeOpenApiDocumentOnPathMethod(originalDocument, newDocument);
|
|
45
|
-
};
|
|
46
|
-
const mergeOpenApiDocumentOnPathMethod = (originalDocument, newDocument) => {
|
|
47
|
-
let paths = originalDocument.paths;
|
|
48
|
-
if (newDocument.paths) {
|
|
49
|
-
paths = Object.entries(newDocument.paths).reduce((mergedPaths, [path, pathObject]) => {
|
|
50
|
-
const existingEntry = mergedPaths[path];
|
|
51
|
-
if (!existingEntry) {
|
|
52
|
-
mergedPaths[path] = pathObject;
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
mergedPaths[path] = mergePathItems(existingEntry, pathObject);
|
|
56
|
-
}
|
|
57
|
-
return mergedPaths;
|
|
58
|
-
}, originalDocument.paths ?? {});
|
|
59
|
-
}
|
|
60
|
-
return {
|
|
61
|
-
info: newDocument.info,
|
|
62
|
-
openapi: mergeOpenApiVersion(originalDocument.openapi, newDocument.openapi),
|
|
63
|
-
components: mergeComponents(originalDocument.components, newDocument.components),
|
|
64
|
-
jsonSchemaDialect: newDocument.jsonSchemaDialect ?? originalDocument.jsonSchemaDialect,
|
|
65
|
-
servers: newDocument.servers ?? originalDocument.servers,
|
|
66
|
-
security: newDocument.security ?? originalDocument.security,
|
|
67
|
-
tags: newDocument.tags ?? originalDocument.tags,
|
|
68
|
-
externalDocs: newDocument.externalDocs ?? originalDocument.externalDocs,
|
|
69
|
-
paths,
|
|
70
|
-
};
|
|
71
|
-
};
|
|
72
|
-
const mergeComponents = (originalComponents, newComponents) => {
|
|
73
|
-
if (!originalComponents) {
|
|
74
|
-
return newComponents;
|
|
75
|
-
}
|
|
76
|
-
if (!newComponents) {
|
|
77
|
-
return originalComponents;
|
|
78
|
-
}
|
|
79
|
-
const { schemas, responses, parameters, examples, requestBodies, headers, securitySchemes, links, callbacks, pathItems, } = originalComponents;
|
|
80
|
-
const { schemas: newSchemas, responses: newResponses, parameters: newParameters, examples: newExamples, requestBodies: newRequestBodies, headers: newHeaders, securitySchemes: newSecuritySchemes, links: newLinks, callbacks: newCallbacks, pathItems: newPathItems, } = newComponents;
|
|
81
|
-
return {
|
|
82
|
-
schemas: schemas ? { ...schemas, ...newSchemas } : newSchemas,
|
|
83
|
-
responses: responses ? { ...responses, ...newResponses } : newResponses,
|
|
84
|
-
parameters: parameters
|
|
85
|
-
? { ...parameters, ...newParameters }
|
|
86
|
-
: newParameters,
|
|
87
|
-
examples: examples ? { ...examples, ...newExamples } : newExamples,
|
|
88
|
-
requestBodies: requestBodies
|
|
89
|
-
? { ...requestBodies, ...newRequestBodies }
|
|
90
|
-
: newRequestBodies,
|
|
91
|
-
headers: headers ? { ...headers, ...newHeaders } : newHeaders,
|
|
92
|
-
securitySchemes: securitySchemes
|
|
93
|
-
? { ...securitySchemes, ...newSecuritySchemes }
|
|
94
|
-
: newSecuritySchemes,
|
|
95
|
-
links: links ? { ...links, ...newLinks } : newLinks,
|
|
96
|
-
callbacks: callbacks ? { ...callbacks, ...newCallbacks } : newCallbacks,
|
|
97
|
-
pathItems: pathItems ? { ...pathItems, ...newPathItems } : newPathItems,
|
|
98
|
-
};
|
|
99
|
-
};
|
|
100
|
-
const mergeOpenApiVersion = (originalVersion, newDocumentVersion) => {
|
|
101
|
-
if (originalVersion === "3.1.0") {
|
|
102
|
-
return originalVersion;
|
|
103
|
-
}
|
|
104
|
-
if (newDocumentVersion === "3.1.0") {
|
|
105
|
-
return newDocumentVersion;
|
|
106
|
-
}
|
|
107
|
-
return originalVersion;
|
|
108
|
-
};
|
|
109
|
-
const mergePathItems = (originalPathItem, newPathItem) => {
|
|
110
|
-
const { summary, description, get, put, post, delete: deleteOperation, options, head, patch, trace, servers, parameters, } = originalPathItem;
|
|
111
|
-
const zuploPathProperties = originalPathItem[ZUPLO_OPEN_API_PATH_KEY];
|
|
112
|
-
const newZuploPathProperty = typeof newPathItem === "object" &&
|
|
113
|
-
newPathItem !== null &&
|
|
114
|
-
ZUPLO_OPEN_API_PATH_KEY in newPathItem
|
|
115
|
-
? newPathItem[ZUPLO_OPEN_API_PATH_KEY]
|
|
116
|
-
: undefined;
|
|
117
|
-
const { summary: newSummary, description: newDescription, get: newGetOperation, put: newPutOperation, post: newPostOperation, delete: newDeleteOperation, options: newOptionsOperation, head: newHeadOperation, patch: newPatchOperation, trace: newTraceOperation, servers: newServers, parameters: newParameters, } = newPathItem;
|
|
118
|
-
return {
|
|
119
|
-
summary: newSummary ?? summary,
|
|
120
|
-
description: newDescription ?? description,
|
|
121
|
-
[ZUPLO_OPEN_API_PATH_KEY]: newZuploPathProperty ?? zuploPathProperties,
|
|
122
|
-
servers: newServers ?? servers,
|
|
123
|
-
parameters: newParameters ?? parameters,
|
|
124
|
-
get: mergeOperationObjects(get, newGetOperation),
|
|
125
|
-
put: mergeOperationObjects(put, newPutOperation),
|
|
126
|
-
post: mergeOperationObjects(post, newPostOperation),
|
|
127
|
-
delete: mergeOperationObjects(deleteOperation, newDeleteOperation),
|
|
128
|
-
options: mergeOperationObjects(options, newOptionsOperation),
|
|
129
|
-
head: mergeOperationObjects(head, newHeadOperation),
|
|
130
|
-
patch: mergeOperationObjects(patch, newPatchOperation),
|
|
131
|
-
trace: mergeOperationObjects(trace, newTraceOperation),
|
|
132
|
-
};
|
|
133
|
-
};
|
|
134
|
-
const mergeOperationObjects = (originalOperationObject, newOperationObject) => {
|
|
135
|
-
if (!newOperationObject) {
|
|
136
|
-
return originalOperationObject;
|
|
137
|
-
}
|
|
138
|
-
const originalZuploProperties = originalOperationObject?.[ZUPLO_OPEN_API_ROUTE_KEY];
|
|
139
|
-
return {
|
|
140
|
-
operationId: v4(),
|
|
141
|
-
[ZUPLO_OPEN_API_ROUTE_KEY]: originalZuploProperties,
|
|
142
|
-
...newOperationObject,
|
|
143
|
-
};
|
|
144
|
-
};
|
|
145
|
-
export const generateMergeChangeset = (originalDocument, newDocument) => {
|
|
146
|
-
return generatePathMethodMergeChangeset(originalDocument, newDocument);
|
|
147
|
-
};
|
|
148
|
-
const generatePathMethodMergeChangeset = (originalDocument, newDocument) => {
|
|
149
|
-
let created = new Set();
|
|
150
|
-
const merged = new Set();
|
|
151
|
-
let retained = new Set();
|
|
152
|
-
const originalPaths = originalDocument.paths;
|
|
153
|
-
const newPaths = newDocument.paths;
|
|
154
|
-
if (!originalPaths && !newPaths) {
|
|
155
|
-
return { created, merged, retained };
|
|
156
|
-
}
|
|
157
|
-
if (!originalPaths && newPaths) {
|
|
158
|
-
created = new Set(getAllOperationKeys(newPaths));
|
|
159
|
-
return { created, merged, retained };
|
|
160
|
-
}
|
|
161
|
-
if (!newPaths && originalPaths) {
|
|
162
|
-
retained = new Set(getAllOperationKeys(originalPaths));
|
|
163
|
-
return { created, merged, retained };
|
|
164
|
-
}
|
|
165
|
-
if (newPaths && originalPaths) {
|
|
166
|
-
const oldOperationKeys = getAllOperationKeys(originalPaths);
|
|
167
|
-
const newOperationKeys = getAllOperationKeys(newPaths);
|
|
168
|
-
const oldOperationKeysSet = new Set(oldOperationKeys);
|
|
169
|
-
const newOperationKeysSet = new Set(newOperationKeys);
|
|
170
|
-
newOperationKeys.forEach((operationKey) => {
|
|
171
|
-
if (oldOperationKeysSet.has(operationKey)) {
|
|
172
|
-
merged.add(operationKey);
|
|
173
|
-
}
|
|
174
|
-
else {
|
|
175
|
-
created.add(operationKey);
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
oldOperationKeys.forEach((operationKey) => {
|
|
179
|
-
if (!newOperationKeysSet.has(operationKey)) {
|
|
180
|
-
retained.add(operationKey);
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
return { created, merged, retained };
|
|
185
|
-
};
|
|
186
|
-
const getAllOperationKeys = (pathsObject) => {
|
|
187
|
-
return Object.entries(pathsObject)
|
|
188
|
-
.map(([path, pathObject]) => {
|
|
189
|
-
const pathItemObject = pathObject;
|
|
190
|
-
const { get, put, post, delete: deleteOperation, options, head, patch, trace, } = pathItemObject;
|
|
191
|
-
const operations = [];
|
|
192
|
-
if (get) {
|
|
193
|
-
operations.push("get");
|
|
194
|
-
}
|
|
195
|
-
if (put) {
|
|
196
|
-
operations.push("put");
|
|
197
|
-
}
|
|
198
|
-
if (post) {
|
|
199
|
-
operations.push("post");
|
|
200
|
-
}
|
|
201
|
-
if (deleteOperation) {
|
|
202
|
-
operations.push("delete");
|
|
203
|
-
}
|
|
204
|
-
if (options) {
|
|
205
|
-
operations.push("options");
|
|
206
|
-
}
|
|
207
|
-
if (head) {
|
|
208
|
-
operations.push("head");
|
|
209
|
-
}
|
|
210
|
-
if (patch) {
|
|
211
|
-
operations.push("patch");
|
|
212
|
-
}
|
|
213
|
-
if (trace) {
|
|
214
|
-
operations.push("trace");
|
|
215
|
-
}
|
|
216
|
-
return operations.map((operation) => `${operation}${OPERATION_PATH_MERGE_DELIMITER}${path}`);
|
|
217
|
-
})
|
|
218
|
-
.flat();
|
|
219
|
-
};
|
|
220
42
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/project/import-openapi/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import yaml from \"js-yaml\";\nimport { OpenAPIV3_1 } from \"openapi-types\";\nimport { v4 } from \"uuid\";\nimport {\n ZUPLO_OPEN_API_PATH_KEY,\n ZUPLO_OPEN_API_ROUTE_KEY,\n ZuploOpenApiDocument,\n ZuploOpenApiOperationObject,\n ZuploOpenApiPathItemObject,\n ZuploOpenApiPathsObject,\n} from \"./interfaces.js\";\n\nexport const OPERATION_PATH_MERGE_DELIMITER = \">\";\nexport const OPEN_API_FILE_TYPES = [\".json\", \".yml\", \".yaml\"];\n\nexport const parseOpenApiFile = async (extName: string, fileText: string) => {\n if (!OPEN_API_FILE_TYPES.includes(extName)) {\n throw new Error(\n `Invalid file type. Supported file types are: ${OPEN_API_FILE_TYPES.join(\n \", \"\n )}`\n );\n }\n if (extName.includes(\"json\")) {\n return JSON.parse(fileText) as OpenAPIV3_1.Document | ZuploOpenApiDocument;\n }\n return yaml.load(fileText) as OpenAPIV3_1.Document | ZuploOpenApiDocument;\n};\n\n/**\n * Add operation ID to any operations that don't have one, this makes\n * onboarding smoother for new users\n */\nexport const addOperationIdsAsNecessary = (\n openApi: OpenAPIV3_1.Document | ZuploOpenApiDocument\n) => {\n const paths = openApi.paths;\n if (!paths) {\n return;\n }\n for (const path of Object.keys(paths)) {\n const pathItem = paths[path];\n if (!pathItem) {\n continue;\n }\n const methods = [\n \"get\",\n \"put\",\n \"post\",\n \"delete\",\n \"options\",\n \"head\",\n \"patch\",\n \"trace\",\n ] as OpenAPIV3_1.HttpMethods[];\n for (const method of methods) {\n const operation = pathItem[method];\n if (operation && !operation.operationId) {\n operation.operationId = v4();\n }\n }\n }\n};\n\nexport const mergeOpenApiDocuments = (\n originalDocument: ZuploOpenApiDocument,\n newDocument: OpenAPIV3_1.Document | ZuploOpenApiDocument\n) => {\n return mergeOpenApiDocumentOnPathMethod(originalDocument, newDocument);\n};\n\nconst mergeOpenApiDocumentOnPathMethod = (\n originalDocument: ZuploOpenApiDocument,\n newDocument: ZuploOpenApiDocument | OpenAPIV3_1.Document\n): ZuploOpenApiDocument => {\n let paths = originalDocument.paths;\n if (newDocument.paths) {\n paths = Object.entries(newDocument.paths).reduce(\n (mergedPaths, [path, pathObject]) => {\n const existingEntry = mergedPaths[path];\n if (!existingEntry) {\n mergedPaths[path] = pathObject;\n } else {\n mergedPaths[path] = mergePathItems(existingEntry, pathObject);\n }\n return mergedPaths;\n },\n originalDocument.paths ?? {}\n );\n }\n\n return {\n info: newDocument.info,\n openapi: mergeOpenApiVersion(originalDocument.openapi, newDocument.openapi),\n components: mergeComponents(\n originalDocument.components,\n newDocument.components\n ),\n jsonSchemaDialect:\n newDocument.jsonSchemaDialect ?? originalDocument.jsonSchemaDialect,\n servers: newDocument.servers ?? originalDocument.servers,\n security: newDocument.security ?? originalDocument.security,\n tags: newDocument.tags ?? originalDocument.tags,\n externalDocs: newDocument.externalDocs ?? originalDocument.externalDocs,\n paths,\n };\n};\n\nconst mergeComponents = (\n originalComponents?: OpenAPIV3_1.ComponentsObject,\n newComponents?: OpenAPIV3_1.ComponentsObject\n) => {\n if (!originalComponents) {\n return newComponents;\n }\n\n if (!newComponents) {\n return originalComponents;\n }\n\n // We have to merge each component property to make sure old ones don't get\n // get deleted\n const {\n schemas,\n responses,\n parameters,\n examples,\n requestBodies,\n headers,\n securitySchemes,\n links,\n callbacks,\n pathItems,\n } = originalComponents;\n\n const {\n schemas: newSchemas,\n responses: newResponses,\n parameters: newParameters,\n examples: newExamples,\n requestBodies: newRequestBodies,\n headers: newHeaders,\n securitySchemes: newSecuritySchemes,\n links: newLinks,\n callbacks: newCallbacks,\n pathItems: newPathItems,\n } = newComponents;\n\n return {\n schemas: schemas ? { ...schemas, ...newSchemas } : newSchemas,\n responses: responses ? { ...responses, ...newResponses } : newResponses,\n parameters: parameters\n ? { ...parameters, ...newParameters }\n : newParameters,\n examples: examples ? { ...examples, ...newExamples } : newExamples,\n requestBodies: requestBodies\n ? { ...requestBodies, ...newRequestBodies }\n : newRequestBodies,\n headers: headers ? { ...headers, ...newHeaders } : newHeaders,\n securitySchemes: securitySchemes\n ? { ...securitySchemes, ...newSecuritySchemes }\n : newSecuritySchemes,\n links: links ? { ...links, ...newLinks } : newLinks,\n callbacks: callbacks ? { ...callbacks, ...newCallbacks } : newCallbacks,\n pathItems: pathItems ? { ...pathItems, ...newPathItems } : newPathItems,\n };\n};\n\n/**\n * @description OpenAPI 3.1.0 is a superset of 3.0 so we should keep the\n * document as 3.1 if it already is, or upgrade it to 3.1 if the new document is\n */\nconst mergeOpenApiVersion = (\n originalVersion: string,\n newDocumentVersion: string\n) => {\n if (originalVersion === \"3.1.0\") {\n return originalVersion;\n }\n if (newDocumentVersion === \"3.1.0\") {\n return newDocumentVersion;\n }\n return originalVersion;\n};\n\nconst mergePathItems = (\n originalPathItem: ZuploOpenApiPathItemObject,\n newPathItem: ZuploOpenApiPathItemObject | OpenAPIV3_1.PathItemObject\n): ZuploOpenApiPathItemObject => {\n const {\n summary,\n description,\n get,\n put,\n post,\n delete: deleteOperation,\n options,\n head,\n patch,\n trace,\n servers,\n parameters,\n } = originalPathItem;\n const zuploPathProperties = originalPathItem[ZUPLO_OPEN_API_PATH_KEY];\n\n const newZuploPathProperty =\n typeof newPathItem === \"object\" &&\n newPathItem !== null &&\n ZUPLO_OPEN_API_PATH_KEY in newPathItem\n ? newPathItem[ZUPLO_OPEN_API_PATH_KEY]\n : undefined;\n const {\n summary: newSummary,\n description: newDescription,\n get: newGetOperation,\n put: newPutOperation,\n post: newPostOperation,\n delete: newDeleteOperation,\n options: newOptionsOperation,\n head: newHeadOperation,\n patch: newPatchOperation,\n trace: newTraceOperation,\n servers: newServers,\n parameters: newParameters,\n } = newPathItem;\n return {\n summary: newSummary ?? summary,\n description: newDescription ?? description,\n [ZUPLO_OPEN_API_PATH_KEY]: newZuploPathProperty ?? zuploPathProperties,\n servers: newServers ?? servers,\n parameters: newParameters ?? parameters,\n get: mergeOperationObjects(get, newGetOperation),\n put: mergeOperationObjects(put, newPutOperation),\n post: mergeOperationObjects(post, newPostOperation),\n delete: mergeOperationObjects(deleteOperation, newDeleteOperation),\n options: mergeOperationObjects(options, newOptionsOperation),\n head: mergeOperationObjects(head, newHeadOperation),\n patch: mergeOperationObjects(patch, newPatchOperation),\n trace: mergeOperationObjects(trace, newTraceOperation),\n };\n};\n\nconst mergeOperationObjects = (\n originalOperationObject?: ZuploOpenApiOperationObject,\n newOperationObject?: ZuploOpenApiOperationObject | OpenAPIV3_1.OperationObject\n): ZuploOpenApiOperationObject | undefined => {\n if (!newOperationObject) {\n // If it stopped existing in the new version, we leave the original untouched\n return originalOperationObject;\n }\n\n // We preserve the gateway's behavior unless explicitly overridden\n const originalZuploProperties =\n originalOperationObject?.[ZUPLO_OPEN_API_ROUTE_KEY];\n return {\n operationId: v4(),\n [ZUPLO_OPEN_API_ROUTE_KEY]: originalZuploProperties,\n ...newOperationObject,\n };\n};\n\nexport const generateMergeChangeset = (\n originalDocument: ZuploOpenApiDocument,\n newDocument: OpenAPIV3_1.Document | ZuploOpenApiDocument\n // mergeMode: MergeMode TODO: Support merging on operation ID\n) => {\n return generatePathMethodMergeChangeset(originalDocument, newDocument);\n};\n\nconst generatePathMethodMergeChangeset = (\n originalDocument: ZuploOpenApiDocument,\n newDocument: OpenAPIV3_1.Document | ZuploOpenApiDocument\n): {\n created: Set<string>;\n merged: Set<string>;\n retained: Set<string>;\n} => {\n let created: Set<string> = new Set();\n const merged: Set<string> = new Set();\n let retained: Set<string> = new Set();\n\n const originalPaths = originalDocument.paths;\n const newPaths = newDocument.paths;\n\n if (!originalPaths && !newPaths) {\n // Nothing changes\n return { created, merged, retained };\n }\n\n // All paths are considered created\n if (!originalPaths && newPaths) {\n created = new Set(getAllOperationKeys(newPaths));\n return { created, merged, retained };\n }\n\n // All paths are considered retained\n if (!newPaths && originalPaths) {\n retained = new Set(getAllOperationKeys(originalPaths));\n return { created, merged, retained };\n }\n\n // Typescript won't infer these as non-null because they can change between if\n // statements I guess?\n if (newPaths && originalPaths) {\n const oldOperationKeys = getAllOperationKeys(originalPaths);\n const newOperationKeys = getAllOperationKeys(newPaths);\n const oldOperationKeysSet = new Set(oldOperationKeys);\n const newOperationKeysSet = new Set(newOperationKeys);\n newOperationKeys.forEach((operationKey) => {\n if (oldOperationKeysSet.has(operationKey)) {\n merged.add(operationKey);\n } else {\n created.add(operationKey);\n }\n });\n oldOperationKeys.forEach((operationKey) => {\n if (!newOperationKeysSet.has(operationKey)) {\n retained.add(operationKey);\n }\n });\n }\n\n return { created, merged, retained };\n};\n\nconst getAllOperationKeys = (\n pathsObject: ZuploOpenApiPathsObject | OpenAPIV3_1.PathsObject\n) => {\n return Object.entries(pathsObject)\n .map(([path, pathObject]) => {\n const pathItemObject:\n | ZuploOpenApiPathItemObject\n | OpenAPIV3_1.PathItemObject = pathObject;\n const {\n get,\n put,\n post,\n delete: deleteOperation,\n options,\n head,\n patch,\n trace,\n } = pathItemObject;\n const operations = [];\n if (get) {\n operations.push(\"get\");\n }\n if (put) {\n operations.push(\"put\");\n }\n if (post) {\n operations.push(\"post\");\n }\n if (deleteOperation) {\n operations.push(\"delete\");\n }\n if (options) {\n operations.push(\"options\");\n }\n if (head) {\n operations.push(\"head\");\n }\n if (patch) {\n operations.push(\"patch\");\n }\n if (trace) {\n operations.push(\"trace\");\n }\n return operations.map(\n (operation) => `${operation}${OPERATION_PATH_MERGE_DELIMITER}${path}`\n );\n })\n .flat();\n};\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/project/import-openapi/utils.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,SAAS,CAAC;AAE3B,OAAO,EAAE,EAAE,EAAE,MAAM,MAAM,CAAC;AAG1B,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAAG,CAAC;AAClD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAE9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,OAAe,EAAE,QAAgB,EAAE,EAAE;IAC1E,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CACb,gDAAgD,mBAAmB,CAAC,IAAI,CACtE,IAAI,CACL,EAAE,CACJ,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAgD,CAAC;IAC7E,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAgD,CAAC;AAC5E,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,OAAoD,EACpD,EAAE;IACF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;IACT,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,SAAS;QACX,CAAC;QACD,MAAM,OAAO,GAAG;YACd,KAAK;YACL,KAAK;YACL,MAAM;YACN,QAAQ;YACR,SAAS;YACT,MAAM;YACN,OAAO;YACP,OAAO;SACqB,CAAC;QAC/B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;YACnC,IAAI,SAAS,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;gBACxC,SAAS,CAAC,WAAW,GAAG,EAAE,EAAE,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC,CAAC","sourcesContent":["import yaml from \"js-yaml\";\nimport { OpenAPIV3_1 } from \"openapi-types\";\nimport { v4 } from \"uuid\";\nimport { ZuploOpenApiDocument } from \"./interfaces.js\";\n\nexport const OPERATION_PATH_MERGE_DELIMITER = \">\";\nexport const OPEN_API_FILE_TYPES = [\".json\", \".yml\", \".yaml\"];\n\nexport const parseOpenApiFile = async (extName: string, fileText: string) => {\n if (!OPEN_API_FILE_TYPES.includes(extName)) {\n throw new Error(\n `Invalid file type. Supported file types are: ${OPEN_API_FILE_TYPES.join(\n \", \"\n )}`\n );\n }\n if (extName.includes(\"json\")) {\n return JSON.parse(fileText) as OpenAPIV3_1.Document | ZuploOpenApiDocument;\n }\n return yaml.load(fileText) as OpenAPIV3_1.Document | ZuploOpenApiDocument;\n};\n\n/**\n * Add operation ID to any operations that don't have one, this makes\n * onboarding smoother for new users\n */\nexport const addOperationIdsAsNecessary = (\n openApi: OpenAPIV3_1.Document | ZuploOpenApiDocument\n) => {\n const paths = openApi.paths;\n if (!paths) {\n return;\n }\n for (const path of Object.keys(paths)) {\n const pathItem = paths[path];\n if (!pathItem) {\n continue;\n }\n const methods = [\n \"get\",\n \"put\",\n \"post\",\n \"delete\",\n \"options\",\n \"head\",\n \"patch\",\n \"trace\",\n ] as OpenAPIV3_1.HttpMethods[];\n for (const method of methods) {\n const operation = pathItem[method];\n if (operation && !operation.operationId) {\n operation.operationId = v4();\n }\n }\n }\n};\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zuplo/cli",
|
|
3
|
-
"version": "6.40.
|
|
3
|
+
"version": "6.40.11",
|
|
4
4
|
"repository": "https://github.com/zuplo/zuplo",
|
|
5
5
|
"author": "Zuplo, Inc.",
|
|
6
6
|
"type": "module",
|
|
@@ -29,8 +29,9 @@
|
|
|
29
29
|
"@opentelemetry/api": "^1.8.0",
|
|
30
30
|
"@sentry/node": "^8.50.0",
|
|
31
31
|
"@swc/core": "1.7.22",
|
|
32
|
-
"@zuplo/core": "^6.40.
|
|
33
|
-
"@zuplo/
|
|
32
|
+
"@zuplo/core": "^6.40.11",
|
|
33
|
+
"@zuplo/openapi-tools": "^6.40.11",
|
|
34
|
+
"@zuplo/runtime": "^6.40.11",
|
|
34
35
|
"as-table": "^1.0.55",
|
|
35
36
|
"chalk": "^5.3.0",
|
|
36
37
|
"chokidar": "^3.5.3",
|