@zuplo/cli 6.65.9 → 6.66.3

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.
Files changed (72) hide show
  1. package/dist/__tests__/import-openapi.test.js +90 -1
  2. package/dist/__tests__/import-openapi.test.js.map +1 -1
  3. package/dist/open-api/convert/handler.js +2 -2
  4. package/dist/open-api/convert/handler.js.map +1 -1
  5. package/dist/open-api/merge/handler.d.ts +1 -1
  6. package/dist/open-api/merge/handler.d.ts.map +1 -1
  7. package/dist/open-api/merge/handler.js +4 -5
  8. package/dist/open-api/merge/handler.js.map +1 -1
  9. package/dist/open-api/overlay/handler.js +1 -2
  10. package/dist/open-api/overlay/handler.js.map +1 -1
  11. package/dist/tsconfig.tsbuildinfo +1 -1
  12. package/package.json +4 -4
  13. package/dist/__tests__/import-openapi-utils.test.d.ts +0 -2
  14. package/dist/__tests__/import-openapi-utils.test.d.ts.map +0 -1
  15. package/dist/__tests__/import-openapi-utils.test.js +0 -125
  16. package/dist/__tests__/import-openapi-utils.test.js.map +0 -1
  17. package/dist/__tests__/oas-test-data.d.ts +0 -98
  18. package/dist/__tests__/oas-test-data.d.ts.map +0 -1
  19. package/dist/__tests__/oas-test-data.js +0 -114
  20. package/dist/__tests__/oas-test-data.js.map +0 -1
  21. package/dist/common/file-format.d.ts +0 -25
  22. package/dist/common/file-format.d.ts.map +0 -1
  23. package/dist/common/file-format.js +0 -72
  24. package/dist/common/file-format.js.map +0 -1
  25. package/dist/common/open-api/constants.d.ts +0 -13
  26. package/dist/common/open-api/constants.d.ts.map +0 -1
  27. package/dist/common/open-api/constants.js +0 -16
  28. package/dist/common/open-api/constants.js.map +0 -1
  29. package/dist/common/open-api/index.d.ts +0 -3
  30. package/dist/common/open-api/index.d.ts.map +0 -1
  31. package/dist/common/open-api/index.js +0 -3
  32. package/dist/common/open-api/index.js.map +0 -1
  33. package/dist/common/open-api/validation.d.ts +0 -297
  34. package/dist/common/open-api/validation.d.ts.map +0 -1
  35. package/dist/common/open-api/validation.js +0 -88
  36. package/dist/common/open-api/validation.js.map +0 -1
  37. package/dist/open-api/convert/convert-engine.d.ts +0 -26
  38. package/dist/open-api/convert/convert-engine.d.ts.map +0 -1
  39. package/dist/open-api/convert/convert-engine.js +0 -20
  40. package/dist/open-api/convert/convert-engine.js.map +0 -1
  41. package/dist/open-api/convert/convert-engine.spec.d.ts +0 -2
  42. package/dist/open-api/convert/convert-engine.spec.d.ts.map +0 -1
  43. package/dist/open-api/convert/convert-engine.spec.js +0 -268
  44. package/dist/open-api/convert/convert-engine.spec.js.map +0 -1
  45. package/dist/open-api/merge/ajv.d.ts +0 -34
  46. package/dist/open-api/merge/ajv.d.ts.map +0 -1
  47. package/dist/open-api/merge/ajv.js +0 -2
  48. package/dist/open-api/merge/ajv.js.map +0 -1
  49. package/dist/open-api/merge/interfaces.d.ts +0 -72
  50. package/dist/open-api/merge/interfaces.d.ts.map +0 -1
  51. package/dist/open-api/merge/interfaces.js +0 -5
  52. package/dist/open-api/merge/interfaces.js.map +0 -1
  53. package/dist/open-api/merge/merge-engine.d.ts +0 -20
  54. package/dist/open-api/merge/merge-engine.d.ts.map +0 -1
  55. package/dist/open-api/merge/merge-engine.js +0 -34
  56. package/dist/open-api/merge/merge-engine.js.map +0 -1
  57. package/dist/open-api/merge/merge-engine.spec.d.ts +0 -2
  58. package/dist/open-api/merge/merge-engine.spec.d.ts.map +0 -1
  59. package/dist/open-api/merge/merge-engine.spec.js +0 -117
  60. package/dist/open-api/merge/merge-engine.spec.js.map +0 -1
  61. package/dist/open-api/merge/utils.d.ts +0 -11
  62. package/dist/open-api/merge/utils.d.ts.map +0 -1
  63. package/dist/open-api/merge/utils.js +0 -33
  64. package/dist/open-api/merge/utils.js.map +0 -1
  65. package/dist/open-api/overlay/overlay-engine.d.ts +0 -45
  66. package/dist/open-api/overlay/overlay-engine.d.ts.map +0 -1
  67. package/dist/open-api/overlay/overlay-engine.js +0 -309
  68. package/dist/open-api/overlay/overlay-engine.js.map +0 -1
  69. package/dist/open-api/overlay/overlay-engine.spec.d.ts +0 -2
  70. package/dist/open-api/overlay/overlay-engine.spec.d.ts.map +0 -1
  71. package/dist/open-api/overlay/overlay-engine.spec.js +0 -687
  72. package/dist/open-api/overlay/overlay-engine.spec.js.map +0 -1
@@ -5,7 +5,96 @@ import { fileURLToPath } from "node:url";
5
5
  import { expect } from "chai";
6
6
  import { createSandbox } from "sinon";
7
7
  import { importOpenApi } from "../open-api/merge/handler.js";
8
- import { baseRoutesFileOnImportTests } from "./oas-test-data.js";
8
+ const baseRoutesFileOnImportTests = {
9
+ info: {
10
+ version: "v2",
11
+ title: "Zuplo test API V2",
12
+ description: "Test api v2",
13
+ contact: {
14
+ name: "Zuplo test",
15
+ url: "www.zuplo.com",
16
+ },
17
+ },
18
+ openapi: "3.1.0",
19
+ components: {
20
+ parameters: {
21
+ userUid: {
22
+ name: "userUid",
23
+ in: "path",
24
+ description: "Unique UUID of the user.",
25
+ required: true,
26
+ schema: {
27
+ type: "string",
28
+ format: "uuid",
29
+ },
30
+ },
31
+ },
32
+ securitySchemes: {
33
+ authorization: {
34
+ type: "http",
35
+ description: "Firebase JWT auth token",
36
+ scheme: "bearer",
37
+ },
38
+ },
39
+ },
40
+ servers: [
41
+ {
42
+ url: "https://api.stage.example.com",
43
+ description: "Stage",
44
+ },
45
+ {
46
+ url: "https://api.example.com",
47
+ description: "Prod",
48
+ },
49
+ ],
50
+ security: [{}],
51
+ tags: [],
52
+ paths: {
53
+ "/v1/second/{userUid}/nature": {
54
+ post: {
55
+ summary: "Test route",
56
+ operationId: "12345",
57
+ parameters: [
58
+ {
59
+ $ref: "#/components/parameters/userUid",
60
+ },
61
+ ],
62
+ responses: {
63
+ "200": {
64
+ description: "",
65
+ },
66
+ },
67
+ security: [{}],
68
+ servers: [
69
+ {
70
+ url: "https://api.stage.example.com",
71
+ description: "stage",
72
+ },
73
+ {
74
+ url: "https://api.example.com",
75
+ description: "production",
76
+ },
77
+ ],
78
+ },
79
+ },
80
+ "/v2/second/{userUid}/nature": {
81
+ post: {
82
+ operationId: "67920",
83
+ summary: "Test route v2",
84
+ parameters: [
85
+ {
86
+ $ref: "#/components/parameters/userUid",
87
+ },
88
+ ],
89
+ responses: {
90
+ "200": {
91
+ description: "",
92
+ },
93
+ },
94
+ },
95
+ },
96
+ },
97
+ };
9
98
  const __filename = fileURLToPath(import.meta.url);
10
99
  const __dirname = path.dirname(__filename);
11
100
  const testAssetsPath = path.join(__dirname, "..", "..", "src", "__tests__", "test-assets");
@@ -1 +1 @@
1
- {"version":3,"file":"import-openapi.test.js","sourceRoot":"","sources":["../../src/__tests__/import-openapi.test.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { afterEach, beforeEach, describe, it } from \"node:test\";\nimport { fileURLToPath } from \"node:url\";\nimport { expect } from \"chai\";\nimport { createSandbox, SinonSandbox, SinonStub } from \"sinon\";\nimport { importOpenApi } from \"../open-api/merge/handler.js\";\nimport { baseRoutesFileOnImportTests } from \"./oas-test-data.js\";\n\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\nconst testTmpPath = path.join(\n __dirname,\n \"..\",\n \"..\",\n \"src\",\n \"__tests__\",\n \"test-tmp\"\n);\n\nasync function createOASFile(content: string, destinationPath: string) {\n try {\n // Get the directory path of the file\n const dir = path.dirname(destinationPath);\n\n // Ensure that the directory exists (creates parent directories if necessary)\n await fs.mkdir(dir, { recursive: true });\n\n // Write the content to the file (creates the file if it doesn't exist)\n await fs.writeFile(destinationPath, content, \"utf8\");\n\n console.log(`File created successfully at ${destinationPath}`);\n } catch (error) {\n console.error(`Error creating file at ${destinationPath}:`, error);\n }\n}\n\nlet sandbox: SinonSandbox;\ndescribe(\"Import open api file\", async function () {\n let printExit: SinonStub;\n beforeEach(async function () {\n sandbox = createSandbox();\n // @NOTE - need to wrap this or else the cli code kills test run\n printExit = sandbox.stub(process, \"exit\");\n });\n\n afterEach(() => {\n sandbox.restore();\n });\n\n it(\"should merge two existing files correctly\", async function () {\n const destinationPath = path.join(\n testTmpPath,\n \"config\",\n \"routes-test-one.oas.json\"\n );\n // setup by creating the destination file first\n await createOASFile(\n JSON.stringify(baseRoutesFileOnImportTests),\n destinationPath\n );\n\n await importOpenApi({\n prompt: false,\n source: path.join(testAssetsPath, \"toimport.oas.json\"),\n destination: destinationPath,\n });\n\n const mergedContent = await fs.readFile(destinationPath, \"utf-8\");\n\n const jsonContent = JSON.parse(mergedContent);\n\n expect(jsonContent.paths).to.deep.equals({\n \"/v1/second/{userUid}/nature\": {\n post: {\n summary: \"Test route\",\n operationId: \"12345\",\n parameters: [\n {\n $ref: \"#/components/parameters/userUid\",\n },\n ],\n responses: {\n \"200\": {\n description: \"\",\n },\n },\n security: [{}],\n servers: [\n {\n url: \"https://api.stage.example.com\",\n description: \"stage\",\n },\n {\n url: \"https://api.example.com\",\n description: \"production\",\n },\n ],\n },\n },\n \"/v2/second/{userUid}/nature\": {\n post: {\n operationId: \"67920\",\n summary: \"Test route v2\",\n parameters: [\n {\n $ref: \"#/components/parameters/userUid\",\n },\n ],\n responses: {\n \"200\": {\n description: \"\",\n },\n },\n },\n },\n });\n });\n\n it(\"should import a file into a fs destination that does not yet exist\", async function () {\n const destinationPath = path.join(testTmpPath, \"routes-test-two.oas.json\");\n\n await importOpenApi({\n prompt: false,\n source: path.join(testAssetsPath, \"toimport.oas.json\"),\n destination: destinationPath,\n });\n\n const mergedContent = await fs.readFile(destinationPath, \"utf-8\");\n\n const jsonContent = JSON.parse(mergedContent);\n\n expect(jsonContent.info).to.deep.equals({\n version: \"v2\",\n title: \"Zuplo test API V2\",\n description: \"Test api v2\",\n contact: {\n name: \"Zuplo test\",\n url: \"www.zuplo.com\",\n },\n });\n\n expect(jsonContent.openapi).to.equal(\"3.1.0\");\n\n expect(jsonContent.components).to.deep.equals({\n parameters: {\n userUid: {\n name: \"userUid\",\n in: \"path\",\n description: \"Unique UUID of the user.\",\n required: true,\n schema: {\n type: \"string\",\n format: \"uuid\",\n },\n },\n },\n securitySchemes: {\n authorization: {\n type: \"http\",\n description: \"Firebase JWT auth token\",\n scheme: \"bearer\",\n },\n },\n });\n\n expect(jsonContent.servers).to.deep.equals([\n {\n url: \"https://api.stage.example.com\",\n description: \"Stage\",\n },\n {\n url: \"https://api.example.com\",\n description: \"Prod\",\n },\n ]);\n\n expect(jsonContent.security).to.deep.equals([{}]);\n\n expect(jsonContent.tags).to.deep.equals([]);\n\n expect(jsonContent.paths).to.deep.equals({\n \"/v2/second/{userUid}/nature\": {\n post: {\n summary: \"Test route v2\",\n operationId: \"67920\",\n parameters: [\n {\n $ref: \"#/components/parameters/userUid\",\n },\n ],\n responses: {\n \"200\": {\n description: \"\",\n },\n },\n },\n },\n });\n });\n});\n"]}
1
+ {"version":3,"file":"import-openapi.test.js","sourceRoot":"","sources":["../../src/__tests__/import-openapi.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,aAAa,EAA2B,MAAM,OAAO,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,MAAM,2BAA2B,GAAG;IAClC,IAAI,EAAE;QACJ,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,mBAAmB;QAC1B,WAAW,EAAE,aAAa;QAC1B,OAAO,EAAE;YACP,IAAI,EAAE,YAAY;YAClB,GAAG,EAAE,eAAe;SACrB;KACF;IACD,OAAO,EAAE,OAAO;IAChB,UAAU,EAAE;QACV,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,IAAI,EAAE,SAAS;gBACf,EAAE,EAAE,MAAM;gBACV,WAAW,EAAE,0BAA0B;gBACvC,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,MAAM;iBACf;aACF;SACF;QACD,eAAe,EAAE;YACf,aAAa,EAAE;gBACb,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,yBAAyB;gBACtC,MAAM,EAAE,QAAQ;aACjB;SACF;KACF;IACD,OAAO,EAAE;QACP;YACE,GAAG,EAAE,+BAA+B;YACpC,WAAW,EAAE,OAAO;SACrB;QACD;YACE,GAAG,EAAE,yBAAyB;YAC9B,WAAW,EAAE,MAAM;SACpB;KACF;IACD,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,IAAI,EAAE,EAAE;IACR,KAAK,EAAE;QACL,6BAA6B,EAAE;YAC7B,IAAI,EAAE;gBACJ,OAAO,EAAE,YAAY;gBACrB,WAAW,EAAE,OAAO;gBACpB,UAAU,EAAE;oBACV;wBACE,IAAI,EAAE,iCAAiC;qBACxC;iBACF;gBACD,SAAS,EAAE;oBACT,KAAK,EAAE;wBACL,WAAW,EAAE,EAAE;qBAChB;iBACF;gBACD,QAAQ,EAAE,CAAC,EAAE,CAAC;gBACd,OAAO,EAAE;oBACP;wBACE,GAAG,EAAE,+BAA+B;wBACpC,WAAW,EAAE,OAAO;qBACrB;oBACD;wBACE,GAAG,EAAE,yBAAyB;wBAC9B,WAAW,EAAE,YAAY;qBAC1B;iBACF;aACF;SACF;QACD,6BAA6B,EAAE;YAC7B,IAAI,EAAE;gBACJ,WAAW,EAAE,OAAO;gBACpB,OAAO,EAAE,eAAe;gBACxB,UAAU,EAAE;oBACV;wBACE,IAAI,EAAE,iCAAiC;qBACxC;iBACF;gBACD,SAAS,EAAE;oBACT,KAAK,EAAE;wBACL,WAAW,EAAE,EAAE;qBAChB;iBACF;aACF;SACF;KACF;CACF,CAAC;AAEF,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAC9B,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,WAAW,EACX,aAAa,CACd,CAAC;AAEF,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAC3B,SAAS,EACT,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,WAAW,EACX,UAAU,CACX,CAAC;AAEF,KAAK,UAAU,aAAa,CAAC,OAAe,EAAE,eAAuB;IACnE,IAAI,CAAC;QAEH,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAG1C,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAGzC,MAAM,EAAE,CAAC,SAAS,CAAC,eAAe,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QAErD,OAAO,CAAC,GAAG,CAAC,gCAAgC,eAAe,EAAE,CAAC,CAAC;IACjE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,0BAA0B,eAAe,GAAG,EAAE,KAAK,CAAC,CAAC;IACrE,CAAC;AACH,CAAC;AAED,IAAI,OAAqB,CAAC;AAC1B,QAAQ,CAAC,sBAAsB,EAAE,KAAK;IACpC,IAAI,SAAoB,CAAC;IACzB,UAAU,CAAC,KAAK;QACd,OAAO,GAAG,aAAa,EAAE,CAAC;QAE1B,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,CAAC,OAAO,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,KAAK;QACnD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAC/B,WAAW,EACX,QAAQ,EACR,0BAA0B,CAC3B,CAAC;QAEF,MAAM,aAAa,CACjB,IAAI,CAAC,SAAS,CAAC,2BAA2B,CAAC,EAC3C,eAAe,CAChB,CAAC;QAEF,MAAM,aAAa,CAAC;YAClB,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,mBAAmB,CAAC;YACtD,WAAW,EAAE,eAAe;SAC7B,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAElE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAE9C,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;YACvC,6BAA6B,EAAE;gBAC7B,IAAI,EAAE;oBACJ,OAAO,EAAE,YAAY;oBACrB,WAAW,EAAE,OAAO;oBACpB,UAAU,EAAE;wBACV;4BACE,IAAI,EAAE,iCAAiC;yBACxC;qBACF;oBACD,SAAS,EAAE;wBACT,KAAK,EAAE;4BACL,WAAW,EAAE,EAAE;yBAChB;qBACF;oBACD,QAAQ,EAAE,CAAC,EAAE,CAAC;oBACd,OAAO,EAAE;wBACP;4BACE,GAAG,EAAE,+BAA+B;4BACpC,WAAW,EAAE,OAAO;yBACrB;wBACD;4BACE,GAAG,EAAE,yBAAyB;4BAC9B,WAAW,EAAE,YAAY;yBAC1B;qBACF;iBACF;aACF;YACD,6BAA6B,EAAE;gBAC7B,IAAI,EAAE;oBACJ,WAAW,EAAE,OAAO;oBACpB,OAAO,EAAE,eAAe;oBACxB,UAAU,EAAE;wBACV;4BACE,IAAI,EAAE,iCAAiC;yBACxC;qBACF;oBACD,SAAS,EAAE;wBACT,KAAK,EAAE;4BACL,WAAW,EAAE,EAAE;yBAChB;qBACF;iBACF;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK;QAC5E,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,0BAA0B,CAAC,CAAC;QAE3E,MAAM,aAAa,CAAC;YAClB,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,mBAAmB,CAAC;YACtD,WAAW,EAAE,eAAe;SAC7B,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAElE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;QAE9C,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;YACtC,OAAO,EAAE,IAAI;YACb,KAAK,EAAE,mBAAmB;YAC1B,WAAW,EAAE,aAAa;YAC1B,OAAO,EAAE;gBACP,IAAI,EAAE,YAAY;gBAClB,GAAG,EAAE,eAAe;aACrB;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAE9C,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;YAC5C,UAAU,EAAE;gBACV,OAAO,EAAE;oBACP,IAAI,EAAE,SAAS;oBACf,EAAE,EAAE,MAAM;oBACV,WAAW,EAAE,0BAA0B;oBACvC,QAAQ,EAAE,IAAI;oBACd,MAAM,EAAE;wBACN,IAAI,EAAE,QAAQ;wBACd,MAAM,EAAE,MAAM;qBACf;iBACF;aACF;YACD,eAAe,EAAE;gBACf,aAAa,EAAE;oBACb,IAAI,EAAE,MAAM;oBACZ,WAAW,EAAE,yBAAyB;oBACtC,MAAM,EAAE,QAAQ;iBACjB;aACF;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;YACzC;gBACE,GAAG,EAAE,+BAA+B;gBACpC,WAAW,EAAE,OAAO;aACrB;YACD;gBACE,GAAG,EAAE,yBAAyB;gBAC9B,WAAW,EAAE,MAAM;aACpB;SACF,CAAC,CAAC;QAEH,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAElD,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAE5C,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC;YACvC,6BAA6B,EAAE;gBAC7B,IAAI,EAAE;oBACJ,OAAO,EAAE,eAAe;oBACxB,WAAW,EAAE,OAAO;oBACpB,UAAU,EAAE;wBACV;4BACE,IAAI,EAAE,iCAAiC;yBACxC;qBACF;oBACD,SAAS,EAAE;wBACT,KAAK,EAAE;4BACL,WAAW,EAAE,EAAE;yBAChB;qBACF;iBACF;aACF;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { afterEach, beforeEach, describe, it } from \"node:test\";\nimport { fileURLToPath } from \"node:url\";\nimport { expect } from \"chai\";\nimport { createSandbox, SinonSandbox, SinonStub } from \"sinon\";\nimport { importOpenApi } from \"../open-api/merge/handler.js\";\n\nconst baseRoutesFileOnImportTests = {\n info: {\n version: \"v2\",\n title: \"Zuplo test API V2\",\n description: \"Test api v2\",\n contact: {\n name: \"Zuplo test\",\n url: \"www.zuplo.com\",\n },\n },\n openapi: \"3.1.0\",\n components: {\n parameters: {\n userUid: {\n name: \"userUid\",\n in: \"path\",\n description: \"Unique UUID of the user.\",\n required: true,\n schema: {\n type: \"string\",\n format: \"uuid\",\n },\n },\n },\n securitySchemes: {\n authorization: {\n type: \"http\",\n description: \"Firebase JWT auth token\",\n scheme: \"bearer\",\n },\n },\n },\n servers: [\n {\n url: \"https://api.stage.example.com\",\n description: \"Stage\",\n },\n {\n url: \"https://api.example.com\",\n description: \"Prod\",\n },\n ],\n security: [{}],\n tags: [],\n paths: {\n \"/v1/second/{userUid}/nature\": {\n post: {\n summary: \"Test route\",\n operationId: \"12345\",\n parameters: [\n {\n $ref: \"#/components/parameters/userUid\",\n },\n ],\n responses: {\n \"200\": {\n description: \"\",\n },\n },\n security: [{}],\n servers: [\n {\n url: \"https://api.stage.example.com\",\n description: \"stage\",\n },\n {\n url: \"https://api.example.com\",\n description: \"production\",\n },\n ],\n },\n },\n \"/v2/second/{userUid}/nature\": {\n post: {\n operationId: \"67920\",\n summary: \"Test route v2\",\n parameters: [\n {\n $ref: \"#/components/parameters/userUid\",\n },\n ],\n responses: {\n \"200\": {\n description: \"\",\n },\n },\n },\n },\n },\n};\n\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\nconst testTmpPath = path.join(\n __dirname,\n \"..\",\n \"..\",\n \"src\",\n \"__tests__\",\n \"test-tmp\"\n);\n\nasync function createOASFile(content: string, destinationPath: string) {\n try {\n // Get the directory path of the file\n const dir = path.dirname(destinationPath);\n\n // Ensure that the directory exists (creates parent directories if necessary)\n await fs.mkdir(dir, { recursive: true });\n\n // Write the content to the file (creates the file if it doesn't exist)\n await fs.writeFile(destinationPath, content, \"utf8\");\n\n console.log(`File created successfully at ${destinationPath}`);\n } catch (error) {\n console.error(`Error creating file at ${destinationPath}:`, error);\n }\n}\n\nlet sandbox: SinonSandbox;\ndescribe(\"Import open api file\", async function () {\n let printExit: SinonStub;\n beforeEach(async function () {\n sandbox = createSandbox();\n // @NOTE - need to wrap this or else the cli code kills test run\n printExit = sandbox.stub(process, \"exit\");\n });\n\n afterEach(() => {\n sandbox.restore();\n });\n\n it(\"should merge two existing files correctly\", async function () {\n const destinationPath = path.join(\n testTmpPath,\n \"config\",\n \"routes-test-one.oas.json\"\n );\n // setup by creating the destination file first\n await createOASFile(\n JSON.stringify(baseRoutesFileOnImportTests),\n destinationPath\n );\n\n await importOpenApi({\n prompt: false,\n source: path.join(testAssetsPath, \"toimport.oas.json\"),\n destination: destinationPath,\n });\n\n const mergedContent = await fs.readFile(destinationPath, \"utf-8\");\n\n const jsonContent = JSON.parse(mergedContent);\n\n expect(jsonContent.paths).to.deep.equals({\n \"/v1/second/{userUid}/nature\": {\n post: {\n summary: \"Test route\",\n operationId: \"12345\",\n parameters: [\n {\n $ref: \"#/components/parameters/userUid\",\n },\n ],\n responses: {\n \"200\": {\n description: \"\",\n },\n },\n security: [{}],\n servers: [\n {\n url: \"https://api.stage.example.com\",\n description: \"stage\",\n },\n {\n url: \"https://api.example.com\",\n description: \"production\",\n },\n ],\n },\n },\n \"/v2/second/{userUid}/nature\": {\n post: {\n operationId: \"67920\",\n summary: \"Test route v2\",\n parameters: [\n {\n $ref: \"#/components/parameters/userUid\",\n },\n ],\n responses: {\n \"200\": {\n description: \"\",\n },\n },\n },\n },\n });\n });\n\n it(\"should import a file into a fs destination that does not yet exist\", async function () {\n const destinationPath = path.join(testTmpPath, \"routes-test-two.oas.json\");\n\n await importOpenApi({\n prompt: false,\n source: path.join(testAssetsPath, \"toimport.oas.json\"),\n destination: destinationPath,\n });\n\n const mergedContent = await fs.readFile(destinationPath, \"utf-8\");\n\n const jsonContent = JSON.parse(mergedContent);\n\n expect(jsonContent.info).to.deep.equals({\n version: \"v2\",\n title: \"Zuplo test API V2\",\n description: \"Test api v2\",\n contact: {\n name: \"Zuplo test\",\n url: \"www.zuplo.com\",\n },\n });\n\n expect(jsonContent.openapi).to.equal(\"3.1.0\");\n\n expect(jsonContent.components).to.deep.equals({\n parameters: {\n userUid: {\n name: \"userUid\",\n in: \"path\",\n description: \"Unique UUID of the user.\",\n required: true,\n schema: {\n type: \"string\",\n format: \"uuid\",\n },\n },\n },\n securitySchemes: {\n authorization: {\n type: \"http\",\n description: \"Firebase JWT auth token\",\n scheme: \"bearer\",\n },\n },\n });\n\n expect(jsonContent.servers).to.deep.equals([\n {\n url: \"https://api.stage.example.com\",\n description: \"Stage\",\n },\n {\n url: \"https://api.example.com\",\n description: \"Prod\",\n },\n ]);\n\n expect(jsonContent.security).to.deep.equals([{}]);\n\n expect(jsonContent.tags).to.deep.equals([]);\n\n expect(jsonContent.paths).to.deep.equals({\n \"/v2/second/{userUid}/nature\": {\n post: {\n summary: \"Test route v2\",\n operationId: \"67920\",\n parameters: [\n {\n $ref: \"#/components/parameters/userUid\",\n },\n ],\n responses: {\n \"200\": {\n description: \"\",\n },\n },\n },\n },\n });\n });\n});\n"]}
@@ -1,9 +1,9 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { convertDocument, detectFormatFromExtension, generateOutputPath, } from "@zuplo/openapi-tools";
3
4
  import chokidar from "chokidar";
4
5
  import { logger } from "../../common/logger.js";
5
6
  import { printDiagnosticsToConsole } from "../../common/output.js";
6
- import { convertDocument, detectFormat, generateOutputPath, } from "./convert-engine.js";
7
7
  async function performConversion(args) {
8
8
  const inputPath = path.resolve(args.input);
9
9
  const outputPath = args.output ? path.resolve(args.output) : undefined;
@@ -21,7 +21,7 @@ async function performConversion(args) {
21
21
  else {
22
22
  throw new Error("Output format must be specified using --format, --json, or --yaml");
23
23
  }
24
- const inputFormat = detectFormat(inputPath);
24
+ const inputFormat = detectFormatFromExtension(inputPath);
25
25
  if (!inputFormat) {
26
26
  throw new Error(`Unable to determine input format from extension: ${path.extname(inputPath)}`);
27
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/open-api/convert/handler.ts"],"names":[],"mappings":"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","sourcesContent":["/** biome-ignore-all lint/suspicious/noConsole: CLI output file */\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport chokidar from \"chokidar\";\nimport { logger } from \"../../common/logger.js\";\nimport { printDiagnosticsToConsole } from \"../../common/output.js\";\nimport {\n convertDocument,\n detectFormat,\n type FileFormat,\n generateOutputPath,\n} from \"./convert-engine.js\";\n\nexport interface Arguments {\n input: string;\n format?: \"json\" | \"yaml\";\n json?: boolean;\n yaml?: boolean;\n output?: string;\n watch?: boolean;\n}\n\n/**\n * Perform conversion once\n */\nasync function performConversion(args: Arguments): Promise<void> {\n const inputPath = path.resolve(args.input);\n const outputPath = args.output ? path.resolve(args.output) : undefined;\n const { format, json, yaml } = args;\n\n // Determine output format\n let outputFormat: FileFormat;\n if (format) {\n outputFormat = format;\n } else if (json) {\n outputFormat = \"json\";\n } else if (yaml) {\n outputFormat = \"yaml\";\n } else {\n throw new Error(\n \"Output format must be specified using --format, --json, or --yaml\"\n );\n }\n\n // Determine input format from extension\n const inputFormat = detectFormat(inputPath);\n if (!inputFormat) {\n throw new Error(\n `Unable to determine input format from extension: ${path.extname(inputPath)}`\n );\n }\n\n // Check if conversion is needed\n if (inputFormat === outputFormat) {\n if (!args.watch) {\n printDiagnosticsToConsole(\n `Input file is already in ${outputFormat.toUpperCase()} format. No conversion needed.`\n );\n }\n return;\n }\n\n if (!args.watch) {\n printDiagnosticsToConsole(\"OpenAPI Format Converter\");\n printDiagnosticsToConsole(\"========================\");\n printDiagnosticsToConsole(`Input file: ${inputPath}`);\n printDiagnosticsToConsole(`Input format: ${inputFormat.toUpperCase()}`);\n printDiagnosticsToConsole(`Output format: ${outputFormat.toUpperCase()}`);\n if (outputPath) {\n printDiagnosticsToConsole(`Output file: ${outputPath}`);\n }\n }\n\n try {\n // Load input file\n const inputContent = fs.readFileSync(inputPath, \"utf-8\");\n\n // Convert document\n const { content: outputContent } = convertDocument(\n inputContent,\n inputFormat,\n outputFormat\n );\n\n // Determine output path (use provided path or generate one)\n const finalOutputPath =\n outputPath || generateOutputPath(inputPath, outputFormat);\n\n // Create output directory if it doesn't exist\n const outputDir = path.dirname(finalOutputPath);\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n // Write output file\n fs.writeFileSync(finalOutputPath, outputContent, \"utf-8\");\n\n if (!args.watch) {\n printDiagnosticsToConsole(\n `\\n✓ Converted file written to: ${finalOutputPath}`\n );\n } else {\n printDiagnosticsToConsole(\n `✓ Converted file written to: ${finalOutputPath}`\n );\n }\n } catch (error) {\n logger.error(error, \"Error converting OpenAPI file\");\n printDiagnosticsToConsole(`Error: ${(error as Error).message}`);\n throw error;\n }\n}\n\n/**\n * Convert OpenAPI document between JSON and YAML formats\n */\nexport async function convertOpenAPI(args: Arguments): Promise<void> {\n // If watch mode is not enabled, just perform the conversion once\n if (!args.watch) {\n return performConversion(args);\n }\n\n const inputPath = path.resolve(args.input);\n\n // Validate input file exists\n if (!fs.existsSync(inputPath)) {\n throw new Error(`Input file not found: ${inputPath}`);\n }\n\n printDiagnosticsToConsole(\"OpenAPI Format Converter (Watch Mode)\");\n printDiagnosticsToConsole(\"======================================\");\n printDiagnosticsToConsole(`Input file: ${inputPath}`);\n printDiagnosticsToConsole(\"\\nStarting watch mode...\");\n printDiagnosticsToConsole(\"Press Ctrl+C to stop watching.\\n\");\n\n // Perform initial conversion\n try {\n await performConversion(args);\n printDiagnosticsToConsole(\"\\nWatching for changes...\");\n } catch (error) {\n logger.error(error, \"Initial conversion failed\");\n printDiagnosticsToConsole(`Error during initial conversion: ${error}`);\n printDiagnosticsToConsole(\"\\nWatching for changes...\");\n }\n\n // Set up file watcher\n const watcher = chokidar.watch(inputPath, {\n persistent: true,\n ignoreInitial: true,\n });\n\n watcher.on(\"change\", async () => {\n try {\n const relativePath = path.relative(process.cwd(), inputPath);\n printDiagnosticsToConsole(\n `\\nFile ${relativePath} changed, re-converting...`\n );\n await performConversion(args);\n printDiagnosticsToConsole(\"Re-conversion completed successfully.\\n\");\n } catch (error) {\n logger.error(error, \"Re-conversion failed\");\n printDiagnosticsToConsole(`Error during re-conversion: ${error}\\n`);\n }\n });\n\n watcher.on(\"error\", (error) => {\n logger.error(error, \"Watcher error\");\n printDiagnosticsToConsole(`Watcher error: ${error}`);\n });\n\n // Return a promise that never resolves to keep the process alive\n // The promise will only resolve when SIGINT/SIGTERM is received\n return new Promise<void>((resolve) => {\n // Handle graceful shutdown\n process.once(\"SIGINT\", async () => {\n printDiagnosticsToConsole(\"\\nStopping watch mode...\");\n await watcher.close();\n resolve();\n });\n\n process.once(\"SIGTERM\", async () => {\n printDiagnosticsToConsole(\"\\nStopping watch mode...\");\n await watcher.close();\n resolve();\n });\n });\n}\n"]}
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/open-api/convert/handler.ts"],"names":[],"mappings":"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","sourcesContent":["/** biome-ignore-all lint/suspicious/noConsole: CLI output file */\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {\n convertDocument,\n detectFormatFromExtension,\n type FileFormat,\n generateOutputPath,\n} from \"@zuplo/openapi-tools\";\nimport chokidar from \"chokidar\";\nimport { logger } from \"../../common/logger.js\";\nimport { printDiagnosticsToConsole } from \"../../common/output.js\";\n\nexport interface Arguments {\n input: string;\n format?: \"json\" | \"yaml\";\n json?: boolean;\n yaml?: boolean;\n output?: string;\n watch?: boolean;\n}\n\n/**\n * Perform conversion once\n */\nasync function performConversion(args: Arguments): Promise<void> {\n const inputPath = path.resolve(args.input);\n const outputPath = args.output ? path.resolve(args.output) : undefined;\n const { format, json, yaml } = args;\n\n // Determine output format\n let outputFormat: FileFormat;\n if (format) {\n outputFormat = format;\n } else if (json) {\n outputFormat = \"json\";\n } else if (yaml) {\n outputFormat = \"yaml\";\n } else {\n throw new Error(\n \"Output format must be specified using --format, --json, or --yaml\"\n );\n }\n\n // Determine input format from extension\n const inputFormat = detectFormatFromExtension(inputPath);\n if (!inputFormat) {\n throw new Error(\n `Unable to determine input format from extension: ${path.extname(inputPath)}`\n );\n }\n\n // Check if conversion is needed\n if (inputFormat === outputFormat) {\n if (!args.watch) {\n printDiagnosticsToConsole(\n `Input file is already in ${outputFormat.toUpperCase()} format. No conversion needed.`\n );\n }\n return;\n }\n\n if (!args.watch) {\n printDiagnosticsToConsole(\"OpenAPI Format Converter\");\n printDiagnosticsToConsole(\"========================\");\n printDiagnosticsToConsole(`Input file: ${inputPath}`);\n printDiagnosticsToConsole(`Input format: ${inputFormat.toUpperCase()}`);\n printDiagnosticsToConsole(`Output format: ${outputFormat.toUpperCase()}`);\n if (outputPath) {\n printDiagnosticsToConsole(`Output file: ${outputPath}`);\n }\n }\n\n try {\n // Load input file\n const inputContent = fs.readFileSync(inputPath, \"utf-8\");\n\n // Convert document\n const { content: outputContent } = convertDocument(\n inputContent,\n inputFormat,\n outputFormat\n );\n\n // Determine output path (use provided path or generate one)\n const finalOutputPath =\n outputPath || generateOutputPath(inputPath, outputFormat);\n\n // Create output directory if it doesn't exist\n const outputDir = path.dirname(finalOutputPath);\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n // Write output file\n fs.writeFileSync(finalOutputPath, outputContent, \"utf-8\");\n\n if (!args.watch) {\n printDiagnosticsToConsole(\n `\\n✓ Converted file written to: ${finalOutputPath}`\n );\n } else {\n printDiagnosticsToConsole(\n `✓ Converted file written to: ${finalOutputPath}`\n );\n }\n } catch (error) {\n logger.error(error, \"Error converting OpenAPI file\");\n printDiagnosticsToConsole(`Error: ${(error as Error).message}`);\n throw error;\n }\n}\n\n/**\n * Convert OpenAPI document between JSON and YAML formats\n */\nexport async function convertOpenAPI(args: Arguments): Promise<void> {\n // If watch mode is not enabled, just perform the conversion once\n if (!args.watch) {\n return performConversion(args);\n }\n\n const inputPath = path.resolve(args.input);\n\n // Validate input file exists\n if (!fs.existsSync(inputPath)) {\n throw new Error(`Input file not found: ${inputPath}`);\n }\n\n printDiagnosticsToConsole(\"OpenAPI Format Converter (Watch Mode)\");\n printDiagnosticsToConsole(\"======================================\");\n printDiagnosticsToConsole(`Input file: ${inputPath}`);\n printDiagnosticsToConsole(\"\\nStarting watch mode...\");\n printDiagnosticsToConsole(\"Press Ctrl+C to stop watching.\\n\");\n\n // Perform initial conversion\n try {\n await performConversion(args);\n printDiagnosticsToConsole(\"\\nWatching for changes...\");\n } catch (error) {\n logger.error(error, \"Initial conversion failed\");\n printDiagnosticsToConsole(`Error during initial conversion: ${error}`);\n printDiagnosticsToConsole(\"\\nWatching for changes...\");\n }\n\n // Set up file watcher\n const watcher = chokidar.watch(inputPath, {\n persistent: true,\n ignoreInitial: true,\n });\n\n watcher.on(\"change\", async () => {\n try {\n const relativePath = path.relative(process.cwd(), inputPath);\n printDiagnosticsToConsole(\n `\\nFile ${relativePath} changed, re-converting...`\n );\n await performConversion(args);\n printDiagnosticsToConsole(\"Re-conversion completed successfully.\\n\");\n } catch (error) {\n logger.error(error, \"Re-conversion failed\");\n printDiagnosticsToConsole(`Error during re-conversion: ${error}\\n`);\n }\n });\n\n watcher.on(\"error\", (error) => {\n logger.error(error, \"Watcher error\");\n printDiagnosticsToConsole(`Watcher error: ${error}`);\n });\n\n // Return a promise that never resolves to keep the process alive\n // The promise will only resolve when SIGINT/SIGTERM is received\n return new Promise<void>((resolve) => {\n // Handle graceful shutdown\n process.once(\"SIGINT\", async () => {\n printDiagnosticsToConsole(\"\\nStopping watch mode...\");\n await watcher.close();\n resolve();\n });\n\n process.once(\"SIGTERM\", async () => {\n printDiagnosticsToConsole(\"\\nStopping watch mode...\");\n await watcher.close();\n resolve();\n });\n });\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { type MergeMode } from "./merge-engine.js";
1
+ import { type MergeMode } from "@zuplo/openapi-tools";
2
2
  export interface Arguments {
3
3
  prompt?: boolean;
4
4
  source: string;
@@ -1 +1 @@
1
- {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/open-api/merge/handler.ts"],"names":[],"mappings":"AAeA,OAAO,EAML,KAAK,SAAS,EAGf,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA+JD,wBAAsB,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CA+ElE"}
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../../src/open-api/merge/handler.ts"],"names":[],"mappings":"AAKA,OAAO,EAML,KAAK,SAAS,EAIf,MAAM,sBAAsB,CAAC;AAU9B,MAAM,WAAW,SAAS;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAkKD,wBAAsB,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CA+ElE"}
@@ -3,12 +3,11 @@ import { mkdir, readFile, writeFile } from "node:fs/promises";
3
3
  import { tmpdir } from "node:os";
4
4
  import path from "node:path";
5
5
  import { confirm } from "@inquirer/prompts";
6
- import { mergeOpenApiDocuments } from "@zuplo/openapi-tools";
6
+ import { addOperationIdsAsNecessary, BASE_TEMPLATE, detectFormatFromContent, guessFileNameFromUrl, isUrl, mergeOpenApiDocuments, parseOpenApiFileFromString, } from "@zuplo/openapi-tools";
7
7
  import chokidar from "chokidar";
8
8
  import { format } from "prettier";
9
9
  import { logger } from "../../common/logger.js";
10
10
  import { printCriticalFailureToConsoleAndExit, printDiagnosticsToConsole, printResultToConsoleAndExitGracefully, } from "../../common/output.js";
11
- import { addOperationIdsAsNecessary, BASE_TEMPLATE, detectFormatFromContent, guessFileNameFromUrl, isUrl, parseOpenApiFile, } from "./merge-engine.js";
12
11
  async function performMerge(argv) {
13
12
  let normalizedFilePath;
14
13
  if (isUrl(argv.source)) {
@@ -49,16 +48,16 @@ async function performMerge(argv) {
49
48
  const rawOpenApiSpec = await readFile(normalizedFilePath);
50
49
  const extName = path.extname(normalizedFilePath);
51
50
  const fileContent = rawOpenApiSpec.toString();
52
- const parsedOpenApiSpec = await parseOpenApiFile(extName, fileContent);
51
+ const parsedOpenApiSpec = await parseOpenApiFileFromString(extName, fileContent);
53
52
  const destinationFilePath = path.resolve(argv.destination);
54
53
  let originalDocument;
55
54
  if (!existsSync(destinationFilePath)) {
56
- originalDocument = (await parseOpenApiFile(".json", BASE_TEMPLATE));
55
+ originalDocument = (await parseOpenApiFileFromString(".json", BASE_TEMPLATE));
57
56
  }
58
57
  else {
59
58
  const existingOpenApiSpec = await readFile(destinationFilePath);
60
59
  const existingFileContent = existingOpenApiSpec.toString();
61
- originalDocument = (await parseOpenApiFile(extName, existingFileContent));
60
+ originalDocument = (await parseOpenApiFileFromString(extName, existingFileContent));
62
61
  }
63
62
  const mergeMode = argv["merge-mode"] || "path-method";
64
63
  const prependPath = argv["prepend-path"];
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/open-api/merge/handler.ts"],"names":[],"mappings":"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","sourcesContent":["/** biome-ignore-all lint/suspicious/noConsole: CLI output file */\nimport { existsSync, writeFileSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { confirm } from \"@inquirer/prompts\";\nimport { mergeOpenApiDocuments } from \"@zuplo/openapi-tools\";\nimport chokidar from \"chokidar\";\nimport { format } from \"prettier\";\nimport { logger } from \"../../common/logger.js\";\nimport {\n printCriticalFailureToConsoleAndExit,\n printDiagnosticsToConsole,\n printResultToConsoleAndExitGracefully,\n} from \"../../common/output.js\";\nimport {\n addOperationIdsAsNecessary,\n BASE_TEMPLATE,\n detectFormatFromContent,\n guessFileNameFromUrl,\n isUrl,\n type MergeMode,\n parseOpenApiFile,\n type ZuploOpenApiDocument,\n} from \"./merge-engine.js\";\n\nexport interface Arguments {\n prompt?: boolean;\n source: string;\n destination: string;\n \"merge-mode\"?: MergeMode;\n \"server-paths\"?: boolean;\n \"prepend-path\"?: string;\n watch?: boolean;\n}\n\nasync function performMerge(argv: Arguments): Promise<void> {\n let normalizedFilePath: string;\n\n // Check if source is a URL\n if (isUrl(argv.source)) {\n const parsedUrl = new URL(argv.source);\n const tempDir = tmpdir();\n const guessedFileName = guessFileNameFromUrl(argv.source);\n normalizedFilePath = path.join(tempDir, guessedFileName);\n await mkdir(path.dirname(normalizedFilePath), { recursive: true });\n\n try {\n const response = await fetch(parsedUrl);\n if (!response.ok) {\n throw new Error(\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 const format = detectFormatFromContent(text);\n normalizedFilePath = `${normalizedFilePath}.${format === \"json\" ? \"json\" : \"yaml\"}`;\n await writeFile(normalizedFilePath, text, { flag: \"w+\" });\n } catch (err) {\n logger.error(err, \"Failed to parse the remote OpenAPI file\");\n throw new Error(\n \"Failed to parse the remote OpenAPI file as either JSON or YAML.\",\n { cause: err }\n );\n }\n } catch (err) {\n logger.error(err, \"Failed to download the remote OpenAPI file\");\n throw new Error(\"Failed to download the remote OpenAPI file.\", {\n cause: err,\n });\n }\n } else {\n // This is a normal file\n normalizedFilePath = path.resolve(argv.source);\n\n if (!existsSync(normalizedFilePath)) {\n throw new Error(\n `The file ${normalizedFilePath} to import does not exist.`\n );\n }\n }\n\n const rawOpenApiSpec = await readFile(normalizedFilePath);\n const extName = path.extname(normalizedFilePath);\n const fileContent = rawOpenApiSpec.toString();\n const parsedOpenApiSpec = await parseOpenApiFile(extName, fileContent);\n\n const destinationFilePath = path.resolve(argv.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 // Prepare merge options\n // If prepend-path is provided, disable server-paths to avoid conflict\n const mergeMode = argv[\"merge-mode\"] || \"path-method\";\n const prependPath = argv[\"prepend-path\"];\n const prependServerPath = prependPath ? false : argv[\"server-paths\"];\n\n const { created, merged, retained, mergedDocument } = mergeOpenApiDocuments(\n originalDocument,\n parsedOpenApiSpec,\n {\n mergeMode,\n prependServerPath,\n prependPath,\n }\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 ${created.size > 1 ? \"operations\" : \"operation\"}`\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} ${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} ${retained.size > 1 ? \"operations\" : \"operation\"}`\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 throw new Error(\"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 printDiagnosticsToConsole(\n `Import successful. File written to ${destinationFilePath}`\n );\n}\n\nexport async function importOpenApi(argv: Arguments): Promise<void> {\n // If watch mode is not enabled, just perform the merge once\n if (!argv.watch) {\n try {\n await performMerge(argv);\n await printResultToConsoleAndExitGracefully(\n `Import successful. File written to ${path.resolve(argv.destination)}`\n );\n } catch (error) {\n logger.error(error, \"Merge failed\");\n await printCriticalFailureToConsoleAndExit(`${(error as Error).message}`);\n }\n return;\n }\n\n // Check if source is a URL - watch mode doesn't support URLs\n if (isUrl(argv.source)) {\n throw new Error(\n \"Watch mode is not supported for URL sources. Please use a local file.\"\n );\n }\n\n const sourcePath = path.resolve(argv.source);\n\n if (!existsSync(sourcePath)) {\n throw new Error(`The file ${sourcePath} to import does not exist.`);\n }\n\n printDiagnosticsToConsole(`Starting watch mode for ${sourcePath}...`);\n printDiagnosticsToConsole(\"Press Ctrl+C to stop watching.\\n\");\n\n // Perform initial merge\n try {\n await performMerge(argv);\n printDiagnosticsToConsole(\"\\nWatching for changes...\");\n } catch (error) {\n logger.error(error, \"Initial merge failed\");\n printDiagnosticsToConsole(`Error during initial merge: ${error}`);\n printDiagnosticsToConsole(\"\\nWatching for changes...\");\n }\n\n // Set up file watcher\n const watcher = chokidar.watch(sourcePath, {\n persistent: true,\n ignoreInitial: true,\n });\n\n watcher.on(\"change\", async () => {\n try {\n printDiagnosticsToConsole(`\\nFile ${sourcePath} changed, re-merging...`);\n await performMerge(argv);\n printDiagnosticsToConsole(\"Re-merge completed successfully.\\n\");\n } catch (error) {\n logger.error(error, \"Re-merge failed\");\n printDiagnosticsToConsole(`Error during re-merge: ${error}\\n`);\n }\n });\n\n watcher.on(\"error\", (error) => {\n logger.error(error, \"Watcher error\");\n printDiagnosticsToConsole(`Watcher error: ${error}`);\n });\n\n // Return a promise that never resolves to keep the process alive\n // The promise will only resolve when SIGINT/SIGTERM is received\n return new Promise<void>((resolve) => {\n // Handle graceful shutdown\n process.once(\"SIGINT\", async () => {\n printDiagnosticsToConsole(\"\\nStopping watch mode...\");\n await watcher.close();\n resolve();\n });\n\n process.once(\"SIGTERM\", async () => {\n printDiagnosticsToConsole(\"\\nStopping watch mode...\");\n await watcher.close();\n resolve();\n });\n });\n}\n"]}
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/open-api/merge/handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, writeFileSync } from \"node:fs\";\nimport { mkdir, readFile, writeFile } from \"node:fs/promises\";\nimport { tmpdir } from \"node:os\";\nimport path from \"node:path\";\nimport { confirm } from \"@inquirer/prompts\";\nimport {\n addOperationIdsAsNecessary,\n BASE_TEMPLATE,\n detectFormatFromContent,\n guessFileNameFromUrl,\n isUrl,\n type MergeMode,\n mergeOpenApiDocuments,\n parseOpenApiFileFromString,\n type ZuploOpenApiDocument,\n} from \"@zuplo/openapi-tools\";\nimport chokidar from \"chokidar\";\nimport { format } from \"prettier\";\nimport { logger } from \"../../common/logger.js\";\nimport {\n printCriticalFailureToConsoleAndExit,\n printDiagnosticsToConsole,\n printResultToConsoleAndExitGracefully,\n} from \"../../common/output.js\";\n\nexport interface Arguments {\n prompt?: boolean;\n source: string;\n destination: string;\n \"merge-mode\"?: MergeMode;\n \"server-paths\"?: boolean;\n \"prepend-path\"?: string;\n watch?: boolean;\n}\n\nasync function performMerge(argv: Arguments): Promise<void> {\n let normalizedFilePath: string;\n\n // Check if source is a URL\n if (isUrl(argv.source)) {\n const parsedUrl = new URL(argv.source);\n const tempDir = tmpdir();\n const guessedFileName = guessFileNameFromUrl(argv.source);\n normalizedFilePath = path.join(tempDir, guessedFileName);\n await mkdir(path.dirname(normalizedFilePath), { recursive: true });\n\n try {\n const response = await fetch(parsedUrl);\n if (!response.ok) {\n throw new Error(\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 const format = detectFormatFromContent(text);\n normalizedFilePath = `${normalizedFilePath}.${format === \"json\" ? \"json\" : \"yaml\"}`;\n await writeFile(normalizedFilePath, text, { flag: \"w+\" });\n } catch (err) {\n logger.error(err, \"Failed to parse the remote OpenAPI file\");\n throw new Error(\n \"Failed to parse the remote OpenAPI file as either JSON or YAML.\",\n { cause: err }\n );\n }\n } catch (err) {\n logger.error(err, \"Failed to download the remote OpenAPI file\");\n throw new Error(\"Failed to download the remote OpenAPI file.\", {\n cause: err,\n });\n }\n } else {\n // This is a normal file\n normalizedFilePath = path.resolve(argv.source);\n\n if (!existsSync(normalizedFilePath)) {\n throw new Error(\n `The file ${normalizedFilePath} to import does not exist.`\n );\n }\n }\n\n const rawOpenApiSpec = await readFile(normalizedFilePath);\n const extName = path.extname(normalizedFilePath);\n const fileContent = rawOpenApiSpec.toString();\n const parsedOpenApiSpec = await parseOpenApiFileFromString(\n extName,\n fileContent\n );\n\n const destinationFilePath = path.resolve(argv.destination);\n\n let originalDocument: ZuploOpenApiDocument;\n if (!existsSync(destinationFilePath)) {\n // This is an initial import\n originalDocument = (await parseOpenApiFileFromString(\n \".json\",\n BASE_TEMPLATE\n )) as ZuploOpenApiDocument;\n } else {\n const existingOpenApiSpec = await readFile(destinationFilePath);\n const existingFileContent = existingOpenApiSpec.toString();\n originalDocument = (await parseOpenApiFileFromString(\n extName,\n existingFileContent\n )) as ZuploOpenApiDocument;\n }\n\n // Prepare merge options\n // If prepend-path is provided, disable server-paths to avoid conflict\n const mergeMode = argv[\"merge-mode\"] || \"path-method\";\n const prependPath = argv[\"prepend-path\"];\n const prependServerPath = prependPath ? false : argv[\"server-paths\"];\n\n const { created, merged, retained, mergedDocument } = mergeOpenApiDocuments(\n originalDocument,\n parsedOpenApiSpec,\n {\n mergeMode,\n prependServerPath,\n prependPath,\n }\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 ${created.size > 1 ? \"operations\" : \"operation\"}`\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} ${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} ${retained.size > 1 ? \"operations\" : \"operation\"}`\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 throw new Error(\"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 printDiagnosticsToConsole(\n `Import successful. File written to ${destinationFilePath}`\n );\n}\n\nexport async function importOpenApi(argv: Arguments): Promise<void> {\n // If watch mode is not enabled, just perform the merge once\n if (!argv.watch) {\n try {\n await performMerge(argv);\n await printResultToConsoleAndExitGracefully(\n `Import successful. File written to ${path.resolve(argv.destination)}`\n );\n } catch (error) {\n logger.error(error, \"Merge failed\");\n await printCriticalFailureToConsoleAndExit(`${(error as Error).message}`);\n }\n return;\n }\n\n // Check if source is a URL - watch mode doesn't support URLs\n if (isUrl(argv.source)) {\n throw new Error(\n \"Watch mode is not supported for URL sources. Please use a local file.\"\n );\n }\n\n const sourcePath = path.resolve(argv.source);\n\n if (!existsSync(sourcePath)) {\n throw new Error(`The file ${sourcePath} to import does not exist.`);\n }\n\n printDiagnosticsToConsole(`Starting watch mode for ${sourcePath}...`);\n printDiagnosticsToConsole(\"Press Ctrl+C to stop watching.\\n\");\n\n // Perform initial merge\n try {\n await performMerge(argv);\n printDiagnosticsToConsole(\"\\nWatching for changes...\");\n } catch (error) {\n logger.error(error, \"Initial merge failed\");\n printDiagnosticsToConsole(`Error during initial merge: ${error}`);\n printDiagnosticsToConsole(\"\\nWatching for changes...\");\n }\n\n // Set up file watcher\n const watcher = chokidar.watch(sourcePath, {\n persistent: true,\n ignoreInitial: true,\n });\n\n watcher.on(\"change\", async () => {\n try {\n printDiagnosticsToConsole(`\\nFile ${sourcePath} changed, re-merging...`);\n await performMerge(argv);\n printDiagnosticsToConsole(\"Re-merge completed successfully.\\n\");\n } catch (error) {\n logger.error(error, \"Re-merge failed\");\n printDiagnosticsToConsole(`Error during re-merge: ${error}\\n`);\n }\n });\n\n watcher.on(\"error\", (error) => {\n logger.error(error, \"Watcher error\");\n printDiagnosticsToConsole(`Watcher error: ${error}`);\n });\n\n // Return a promise that never resolves to keep the process alive\n // The promise will only resolve when SIGINT/SIGTERM is received\n return new Promise<void>((resolve) => {\n // Handle graceful shutdown\n process.once(\"SIGINT\", async () => {\n printDiagnosticsToConsole(\"\\nStopping watch mode...\");\n await watcher.close();\n resolve();\n });\n\n process.once(\"SIGTERM\", async () => {\n printDiagnosticsToConsole(\"\\nStopping watch mode...\");\n await watcher.close();\n resolve();\n });\n });\n}\n"]}
@@ -1,10 +1,9 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { applyOverlay as applyOverlayEngine, detectFormatFromExtension, parseFile, serializeContent, } from "@zuplo/openapi-tools";
3
4
  import chokidar from "chokidar";
4
- import { detectFormatFromExtension, parseFile, serializeContent, } from "../../common/file-format.js";
5
5
  import { logger } from "../../common/logger.js";
6
6
  import { printDiagnosticsToConsole } from "../../common/output.js";
7
- import { applyOverlay as applyOverlayEngine } from "./overlay-engine.js";
8
7
  function applyOverlayWithProgress(openapi, overlay) {
9
8
  let validatedOverlay;
10
9
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/open-api/overlay/handler.ts"],"names":[],"mappings":"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","sourcesContent":["/** biome-ignore-all lint/suspicious/noConsole: CLI output file */\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport chokidar from \"chokidar\";\nimport {\n detectFormatFromExtension,\n type FileFormat,\n parseFile,\n serializeContent,\n} from \"../../common/file-format.js\";\nimport { logger } from \"../../common/logger.js\";\nimport { printDiagnosticsToConsole } from \"../../common/output.js\";\nimport { applyOverlay as applyOverlayEngine } from \"./overlay-engine.js\";\n\nexport interface Arguments {\n overlay: string;\n input: string;\n output: string;\n format?: \"json\" | \"yaml\";\n json?: boolean;\n yaml?: boolean;\n watch?: boolean;\n}\n\n/**\n * Apply overlay to OpenAPI document with console output\n * Validates inputs and provides progress feedback\n */\nfunction applyOverlayWithProgress(\n openapi: unknown,\n overlay: unknown\n): Record<string, unknown> {\n // Apply overlay (includes validation)\n let validatedOverlay: ReturnType<typeof applyOverlayEngine>;\n\n try {\n validatedOverlay = applyOverlayEngine(openapi, overlay);\n } catch (error) {\n // Re-throw with better context for CLI users\n if (error instanceof Error) {\n printDiagnosticsToConsole(`\\n${error.message}`);\n }\n throw error;\n }\n\n const { result, stats } = validatedOverlay;\n\n // Show summary\n printDiagnosticsToConsole(`\\n=== Summary ===`);\n printDiagnosticsToConsole(\n `Applied: ${stats.applied} action${stats.applied !== 1 ? \"s\" : \"\"}`\n );\n printDiagnosticsToConsole(\n `Modified: ${stats.totalNodes} node${stats.totalNodes !== 1 ? \"s\" : \"\"}`\n );\n if (stats.skipped > 0) {\n printDiagnosticsToConsole(\n `Skipped: ${stats.skipped} action${stats.skipped !== 1 ? \"s\" : \"\"}`\n );\n }\n\n return result;\n}\n\n/**\n * Perform overlay application once\n */\nasync function performOverlay(args: Arguments): Promise<void> {\n const openapiPath = path.resolve(args.input);\n const overlayPath = path.resolve(args.overlay);\n const outputPath = path.resolve(args.output);\n\n // Validate input files exist\n if (!fs.existsSync(openapiPath)) {\n throw new Error(`OpenAPI file not found: ${openapiPath}`);\n }\n\n if (!fs.existsSync(overlayPath)) {\n throw new Error(`Overlay file not found: ${overlayPath}`);\n }\n\n if (!args.watch) {\n printDiagnosticsToConsole(\"OpenAPI Overlay Applicator\");\n printDiagnosticsToConsole(\"===========================\");\n printDiagnosticsToConsole(`OpenAPI file: ${openapiPath}`);\n printDiagnosticsToConsole(`Overlay file: ${overlayPath}`);\n printDiagnosticsToConsole(`Output file: ${outputPath}`);\n }\n\n try {\n // Load files with flexible parsing\n const openapiContent = fs.readFileSync(openapiPath, \"utf-8\");\n const overlayContent = fs.readFileSync(overlayPath, \"utf-8\");\n\n // Parse with automatic format detection\n let openapi: unknown;\n let overlay: unknown;\n\n try {\n const parsed = parseFile(openapiContent, openapiPath);\n openapi = parsed.document;\n } catch (error) {\n throw new Error(`Failed to parse OpenAPI file '${openapiPath}'`, {\n cause: error,\n });\n }\n\n try {\n const parsed = parseFile(overlayContent, overlayPath);\n overlay = parsed.document;\n } catch (error) {\n throw new Error(`Failed to parse overlay file '${overlayPath}'`, {\n cause: error,\n });\n }\n\n // Apply overlay with progress output\n // Validation happens inside applyOverlayWithProgress\n const result = applyOverlayWithProgress(openapi, overlay);\n\n // Determine output format\n let outputFormat: FileFormat;\n if (args.format) {\n outputFormat = args.format;\n } else if (args.json) {\n outputFormat = \"json\";\n } else if (args.yaml) {\n outputFormat = \"yaml\";\n } else {\n // Try to detect from output file extension\n const formatFromExt = detectFormatFromExtension(outputPath);\n outputFormat = formatFromExt || \"json\"; // Default to JSON if no extension\n }\n\n // Serialize output\n const outputContent = serializeContent(result, outputFormat);\n\n // Create output directory if it doesn't exist\n const outputDir = path.dirname(outputPath);\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n fs.writeFileSync(outputPath, outputContent, \"utf-8\");\n\n if (!args.watch) {\n printDiagnosticsToConsole(\n `\\n✓ Output written to: ${outputPath} (${outputFormat.toUpperCase()})`\n );\n } else {\n printDiagnosticsToConsole(\n `✓ Output written to: ${outputPath} (${outputFormat.toUpperCase()})`\n );\n }\n } catch (error) {\n logger.error(error, \"Error applying overlay\");\n printDiagnosticsToConsole(`Error: ${(error as Error).message}`);\n throw error;\n }\n}\n\n/**\n * Main handler function\n */\nexport async function applyOverlay(args: Arguments): Promise<void> {\n // If watch mode is not enabled, just perform the overlay once\n if (!args.watch) {\n return performOverlay(args);\n }\n\n const openapiPath = path.resolve(args.input);\n const overlayPath = path.resolve(args.overlay);\n const outputPath = path.resolve(args.output);\n\n // Validate input files exist\n if (!fs.existsSync(openapiPath)) {\n throw new Error(`OpenAPI file not found: ${openapiPath}`);\n }\n\n if (!fs.existsSync(overlayPath)) {\n throw new Error(`Overlay file not found: ${overlayPath}`);\n }\n\n printDiagnosticsToConsole(\"OpenAPI Overlay Applicator (Watch Mode)\");\n printDiagnosticsToConsole(\"========================================\");\n printDiagnosticsToConsole(`OpenAPI file: ${openapiPath}`);\n printDiagnosticsToConsole(`Overlay file: ${overlayPath}`);\n printDiagnosticsToConsole(`Output file: ${outputPath}`);\n printDiagnosticsToConsole(\"\\nStarting watch mode...\");\n printDiagnosticsToConsole(\"Press Ctrl+C to stop watching.\\n\");\n\n // Perform initial overlay\n try {\n await performOverlay(args);\n printDiagnosticsToConsole(\"\\nWatching for changes...\");\n } catch (error) {\n logger.error(error, \"Initial overlay application failed\");\n printDiagnosticsToConsole(`Error during initial overlay: ${error}`);\n printDiagnosticsToConsole(\"\\nWatching for changes...\");\n }\n\n // Set up file watcher for both input and overlay files\n const watcher = chokidar.watch([openapiPath, overlayPath], {\n persistent: true,\n ignoreInitial: true,\n });\n\n watcher.on(\"change\", async (changedPath) => {\n try {\n const relativePath = path.relative(process.cwd(), changedPath);\n printDiagnosticsToConsole(\n `\\nFile ${relativePath} changed, re-applying overlay...`\n );\n await performOverlay(args);\n printDiagnosticsToConsole(\"Re-apply completed successfully.\\n\");\n } catch (error) {\n logger.error(error, \"Re-apply failed\");\n printDiagnosticsToConsole(`Error during re-apply: ${error}\\n`);\n }\n });\n\n watcher.on(\"error\", (error) => {\n logger.error(error, \"Watcher error\");\n printDiagnosticsToConsole(`Watcher error: ${error}`);\n });\n\n // Return a promise that never resolves to keep the process alive\n // The promise will only resolve when SIGINT/SIGTERM is received\n return new Promise<void>((resolve) => {\n // Handle graceful shutdown\n process.once(\"SIGINT\", async () => {\n printDiagnosticsToConsole(\"\\nStopping watch mode...\");\n await watcher.close();\n resolve();\n });\n\n process.once(\"SIGTERM\", async () => {\n printDiagnosticsToConsole(\"\\nStopping watch mode...\");\n await watcher.close();\n resolve();\n });\n });\n}\n"]}
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/open-api/overlay/handler.ts"],"names":[],"mappings":"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","sourcesContent":["/** biome-ignore-all lint/suspicious/noConsole: CLI output file */\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport {\n applyOverlay as applyOverlayEngine,\n detectFormatFromExtension,\n type FileFormat,\n parseFile,\n serializeContent,\n} from \"@zuplo/openapi-tools\";\nimport chokidar from \"chokidar\";\nimport { logger } from \"../../common/logger.js\";\nimport { printDiagnosticsToConsole } from \"../../common/output.js\";\n\nexport interface Arguments {\n overlay: string;\n input: string;\n output: string;\n format?: \"json\" | \"yaml\";\n json?: boolean;\n yaml?: boolean;\n watch?: boolean;\n}\n\n/**\n * Apply overlay to OpenAPI document with console output\n * Validates inputs and provides progress feedback\n */\nfunction applyOverlayWithProgress(\n openapi: unknown,\n overlay: unknown\n): Record<string, unknown> {\n // Apply overlay (includes validation)\n let validatedOverlay: ReturnType<typeof applyOverlayEngine>;\n\n try {\n validatedOverlay = applyOverlayEngine(openapi, overlay);\n } catch (error) {\n // Re-throw with better context for CLI users\n if (error instanceof Error) {\n printDiagnosticsToConsole(`\\n${error.message}`);\n }\n throw error;\n }\n\n const { result, stats } = validatedOverlay;\n\n // Show summary\n printDiagnosticsToConsole(`\\n=== Summary ===`);\n printDiagnosticsToConsole(\n `Applied: ${stats.applied} action${stats.applied !== 1 ? \"s\" : \"\"}`\n );\n printDiagnosticsToConsole(\n `Modified: ${stats.totalNodes} node${stats.totalNodes !== 1 ? \"s\" : \"\"}`\n );\n if (stats.skipped > 0) {\n printDiagnosticsToConsole(\n `Skipped: ${stats.skipped} action${stats.skipped !== 1 ? \"s\" : \"\"}`\n );\n }\n\n return result;\n}\n\n/**\n * Perform overlay application once\n */\nasync function performOverlay(args: Arguments): Promise<void> {\n const openapiPath = path.resolve(args.input);\n const overlayPath = path.resolve(args.overlay);\n const outputPath = path.resolve(args.output);\n\n // Validate input files exist\n if (!fs.existsSync(openapiPath)) {\n throw new Error(`OpenAPI file not found: ${openapiPath}`);\n }\n\n if (!fs.existsSync(overlayPath)) {\n throw new Error(`Overlay file not found: ${overlayPath}`);\n }\n\n if (!args.watch) {\n printDiagnosticsToConsole(\"OpenAPI Overlay Applicator\");\n printDiagnosticsToConsole(\"===========================\");\n printDiagnosticsToConsole(`OpenAPI file: ${openapiPath}`);\n printDiagnosticsToConsole(`Overlay file: ${overlayPath}`);\n printDiagnosticsToConsole(`Output file: ${outputPath}`);\n }\n\n try {\n // Load files with flexible parsing\n const openapiContent = fs.readFileSync(openapiPath, \"utf-8\");\n const overlayContent = fs.readFileSync(overlayPath, \"utf-8\");\n\n // Parse with automatic format detection\n let openapi: unknown;\n let overlay: unknown;\n\n try {\n const parsed = parseFile(openapiContent, openapiPath);\n openapi = parsed.document;\n } catch (error) {\n throw new Error(`Failed to parse OpenAPI file '${openapiPath}'`, {\n cause: error,\n });\n }\n\n try {\n const parsed = parseFile(overlayContent, overlayPath);\n overlay = parsed.document;\n } catch (error) {\n throw new Error(`Failed to parse overlay file '${overlayPath}'`, {\n cause: error,\n });\n }\n\n // Apply overlay with progress output\n // Validation happens inside applyOverlayWithProgress\n const result = applyOverlayWithProgress(openapi, overlay);\n\n // Determine output format\n let outputFormat: FileFormat;\n if (args.format) {\n outputFormat = args.format;\n } else if (args.json) {\n outputFormat = \"json\";\n } else if (args.yaml) {\n outputFormat = \"yaml\";\n } else {\n // Try to detect from output file extension\n const formatFromExt = detectFormatFromExtension(outputPath);\n outputFormat = formatFromExt || \"json\"; // Default to JSON if no extension\n }\n\n // Serialize output\n const outputContent = serializeContent(result, outputFormat);\n\n // Create output directory if it doesn't exist\n const outputDir = path.dirname(outputPath);\n if (!fs.existsSync(outputDir)) {\n fs.mkdirSync(outputDir, { recursive: true });\n }\n\n fs.writeFileSync(outputPath, outputContent, \"utf-8\");\n\n if (!args.watch) {\n printDiagnosticsToConsole(\n `\\n✓ Output written to: ${outputPath} (${outputFormat.toUpperCase()})`\n );\n } else {\n printDiagnosticsToConsole(\n `✓ Output written to: ${outputPath} (${outputFormat.toUpperCase()})`\n );\n }\n } catch (error) {\n logger.error(error, \"Error applying overlay\");\n printDiagnosticsToConsole(`Error: ${(error as Error).message}`);\n throw error;\n }\n}\n\n/**\n * Main handler function\n */\nexport async function applyOverlay(args: Arguments): Promise<void> {\n // If watch mode is not enabled, just perform the overlay once\n if (!args.watch) {\n return performOverlay(args);\n }\n\n const openapiPath = path.resolve(args.input);\n const overlayPath = path.resolve(args.overlay);\n const outputPath = path.resolve(args.output);\n\n // Validate input files exist\n if (!fs.existsSync(openapiPath)) {\n throw new Error(`OpenAPI file not found: ${openapiPath}`);\n }\n\n if (!fs.existsSync(overlayPath)) {\n throw new Error(`Overlay file not found: ${overlayPath}`);\n }\n\n printDiagnosticsToConsole(\"OpenAPI Overlay Applicator (Watch Mode)\");\n printDiagnosticsToConsole(\"========================================\");\n printDiagnosticsToConsole(`OpenAPI file: ${openapiPath}`);\n printDiagnosticsToConsole(`Overlay file: ${overlayPath}`);\n printDiagnosticsToConsole(`Output file: ${outputPath}`);\n printDiagnosticsToConsole(\"\\nStarting watch mode...\");\n printDiagnosticsToConsole(\"Press Ctrl+C to stop watching.\\n\");\n\n // Perform initial overlay\n try {\n await performOverlay(args);\n printDiagnosticsToConsole(\"\\nWatching for changes...\");\n } catch (error) {\n logger.error(error, \"Initial overlay application failed\");\n printDiagnosticsToConsole(`Error during initial overlay: ${error}`);\n printDiagnosticsToConsole(\"\\nWatching for changes...\");\n }\n\n // Set up file watcher for both input and overlay files\n const watcher = chokidar.watch([openapiPath, overlayPath], {\n persistent: true,\n ignoreInitial: true,\n });\n\n watcher.on(\"change\", async (changedPath) => {\n try {\n const relativePath = path.relative(process.cwd(), changedPath);\n printDiagnosticsToConsole(\n `\\nFile ${relativePath} changed, re-applying overlay...`\n );\n await performOverlay(args);\n printDiagnosticsToConsole(\"Re-apply completed successfully.\\n\");\n } catch (error) {\n logger.error(error, \"Re-apply failed\");\n printDiagnosticsToConsole(`Error during re-apply: ${error}\\n`);\n }\n });\n\n watcher.on(\"error\", (error) => {\n logger.error(error, \"Watcher error\");\n printDiagnosticsToConsole(`Watcher error: ${error}`);\n });\n\n // Return a promise that never resolves to keep the process alive\n // The promise will only resolve when SIGINT/SIGTERM is received\n return new Promise<void>((resolve) => {\n // Handle graceful shutdown\n process.once(\"SIGINT\", async () => {\n printDiagnosticsToConsole(\"\\nStopping watch mode...\");\n await watcher.close();\n resolve();\n });\n\n process.once(\"SIGTERM\", async () => {\n printDiagnosticsToConsole(\"\\nStopping watch mode...\");\n await watcher.close();\n resolve();\n });\n });\n}\n"]}
@@ -1 +1 @@
1
- {"root":["../src/cli.ts","../src/internal.ts","../src/types.d.ts","../src/__tests__/archive-utils.test.ts","../src/__tests__/import-openapi-utils.test.ts","../src/__tests__/import-openapi.test.ts","../src/__tests__/oas-test-data.ts","../src/__tests__/outdated.test.ts","../src/__tests__/populate.test.ts","../src/__tests__/tsconfig-upgrader.test.ts","../src/__tests__/integration/delete.integration.test.ts","../src/__tests__/integration/deploy.integration.test.ts","../src/__tests__/integration/jest-mocks-setup.ts","../src/__tests__/integration/jest-setup.ts","../src/__tests__/integration/link.integration.test.ts","../src/__tests__/integration/list.integration.test.ts","../src/__tests__/integration/test-utils.ts","../src/__tests__/integration/tunnel.integration.test.ts","../src/__tests__/integration/variable.integration.test.ts","../src/build/handler.ts","../src/cmds/build.ts","../src/cmds/compile.ts","../src/cmds/delete.ts","../src/cmds/deploy.ts","../src/cmds/dev.ts","../src/cmds/docs.ts","../src/cmds/editor.ts","../src/cmds/init.ts","../src/cmds/link.ts","../src/cmds/list.ts","../src/cmds/login.ts","../src/cmds/test.ts","../src/cmds/mtls-certificates/create.ts","../src/cmds/mtls-certificates/delete.ts","../src/cmds/mtls-certificates/describe.ts","../src/cmds/mtls-certificates/disable.ts","../src/cmds/mtls-certificates/index.ts","../src/cmds/mtls-certificates/list.ts","../src/cmds/mtls-certificates/update.ts","../src/cmds/open-api/convert.ts","../src/cmds/open-api/index.ts","../src/cmds/open-api/merge.ts","../src/cmds/open-api/overlay.ts","../src/cmds/project/create.ts","../src/cmds/project/index.ts","../src/cmds/proxies/create.ts","../src/cmds/proxies/delete.ts","../src/cmds/proxies/describe.ts","../src/cmds/proxies/index.ts","../src/cmds/proxies/update.ts","../src/cmds/source/import-openapi.ts","../src/cmds/source/index.ts","../src/cmds/source/migrate.ts","../src/cmds/source/upgrade.ts","../src/cmds/tunnel/create.ts","../src/cmds/tunnel/delete.ts","../src/cmds/tunnel/describe.ts","../src/cmds/tunnel/index.ts","../src/cmds/tunnel/list.ts","../src/cmds/tunnel/rotate-token.ts","../src/cmds/tunnel/services/describe.ts","../src/cmds/tunnel/services/index.ts","../src/cmds/tunnel/services/update.ts","../src/cmds/variable/create.ts","../src/cmds/variable/index.ts","../src/cmds/variable/update.ts","../src/common/alias.ts","../src/common/args.ts","../src/common/constants.ts","../src/common/file-format.ts","../src/common/handler.ts","../src/common/logger.ts","../src/common/models.ts","../src/common/outdated.ts","../src/common/output.ts","../src/common/populate.ts","../src/common/runner.ts","../src/common/settings.ts","../src/common/worker-output.ts","../src/common/analytics/lib.ts","../src/common/api/lib.ts","../src/common/machine-id/lib.ts","../src/common/middleware/authentication.ts","../src/common/middleware/get-account-param.ts","../src/common/middleware/get-environment-param.ts","../src/common/middleware/get-project-param.ts","../src/common/middleware/logging.ts","../src/common/middleware/user-configuration.ts","../src/common/middleware/user-identification.ts","../src/common/middleware/validate-fleet.ts","../src/common/open-api/constants.ts","../src/common/open-api/index.ts","../src/common/open-api/validation.ts","../src/common/upgraders/lib.ts","../src/common/upgraders/package-json-upgrader.ts","../src/common/upgraders/tsconfig-upgrader.ts","../src/common/upgraders/vscode-settings-json-upgrader.ts","../src/common/utils/box.ts","../src/common/utils/branch.ts","../src/common/utils/ports.ts","../src/common/utils/prefixed-output.ts","../src/common/utils/pretty-print-environment-prompt.ts","../src/common/utils/stringify-config.test.ts","../src/common/utils/stringify-config.ts","../src/common/utils/types.ts","../src/common/utils/urls.ts","../src/common/validators/argument-validators.spec.ts","../src/common/validators/argument-validators.ts","../src/common/validators/file-system-validator.ts","../src/common/validators/lib.ts","../src/common/validators/project-name-validator.ts","../src/common/xdg/lib.ts","../src/compile/handler.ts","../src/delete/handler.ts","../src/delete/poll-deployment.ts","../src/deploy/archive.test.ts","../src/deploy/archive.ts","../src/deploy/environments.ts","../src/deploy/file-upload.ts","../src/deploy/handler.ts","../src/deploy/poll-deployment.ts","../src/dev/handler.ts","../src/docs/handler.ts","../src/editor/handler.ts","../src/editor/e2e/editor.spec.ts","../src/init/handler.ts","../src/link/handler.ts","../src/list/handler.ts","../src/login/login.ts","../src/login/tokens.ts","../src/mtls-certificates/models.ts","../src/mtls-certificates/create/handler.ts","../src/mtls-certificates/delete/handler.ts","../src/mtls-certificates/describe/handler.ts","../src/mtls-certificates/disable/handler.ts","../src/mtls-certificates/list/handler.ts","../src/mtls-certificates/update/handler.ts","../src/open-api/convert/convert-engine.spec.ts","../src/open-api/convert/convert-engine.ts","../src/open-api/convert/handler.spec.ts","../src/open-api/convert/handler.ts","../src/open-api/merge/ajv.ts","../src/open-api/merge/handler.spec.ts","../src/open-api/merge/handler.ts","../src/open-api/merge/interfaces.ts","../src/open-api/merge/merge-engine.spec.ts","../src/open-api/merge/merge-engine.ts","../src/open-api/merge/utils.ts","../src/open-api/overlay/handler.spec.ts","../src/open-api/overlay/handler.ts","../src/open-api/overlay/overlay-engine.spec.ts","../src/open-api/overlay/overlay-engine.ts","../src/project/create/handler.ts","../src/proxies/models.ts","../src/proxies/create/handler.ts","../src/proxies/delete/handler.ts","../src/proxies/describe/handler.ts","../src/proxies/update/handler.ts","../src/source/migrate/dev-portal/handler.ts","../src/source/migrate/dev-portal/types.ts","../src/source/update/handler.ts","../src/test/esbuild-config.ts","../src/test/handler.ts","../src/test/invoke-test.ts","../src/test/test-files.test.ts","../src/test/test-files.ts","../src/test/esbuild-plugins/node-test-prep-plugin.ts","../src/tunnel/models.ts","../src/tunnel/create/handler.ts","../src/tunnel/delete/handler.ts","../src/tunnel/delete/poll-teardown-operation.ts","../src/tunnel/describe/handler.ts","../src/tunnel/list/handler.ts","../src/tunnel/rotate-token/handler.ts","../src/tunnel/services/describe/handler.ts","../src/tunnel/services/update/handler.ts","../src/tunnel/services/update/poll-provisioning-operations.ts","../src/variable/models.ts","../src/variable/create/handler.ts","../src/variable/update/handler.ts"],"version":"5.8.2"}
1
+ {"root":["../src/cli.ts","../src/internal.ts","../src/types.d.ts","../src/__tests__/archive-utils.test.ts","../src/__tests__/import-openapi.test.ts","../src/__tests__/outdated.test.ts","../src/__tests__/populate.test.ts","../src/__tests__/tsconfig-upgrader.test.ts","../src/__tests__/integration/delete.integration.test.ts","../src/__tests__/integration/deploy.integration.test.ts","../src/__tests__/integration/jest-mocks-setup.ts","../src/__tests__/integration/jest-setup.ts","../src/__tests__/integration/link.integration.test.ts","../src/__tests__/integration/list.integration.test.ts","../src/__tests__/integration/test-utils.ts","../src/__tests__/integration/tunnel.integration.test.ts","../src/__tests__/integration/variable.integration.test.ts","../src/build/handler.ts","../src/cmds/build.ts","../src/cmds/compile.ts","../src/cmds/delete.ts","../src/cmds/deploy.ts","../src/cmds/dev.ts","../src/cmds/docs.ts","../src/cmds/editor.ts","../src/cmds/init.ts","../src/cmds/link.ts","../src/cmds/list.ts","../src/cmds/login.ts","../src/cmds/test.ts","../src/cmds/mtls-certificates/create.ts","../src/cmds/mtls-certificates/delete.ts","../src/cmds/mtls-certificates/describe.ts","../src/cmds/mtls-certificates/disable.ts","../src/cmds/mtls-certificates/index.ts","../src/cmds/mtls-certificates/list.ts","../src/cmds/mtls-certificates/update.ts","../src/cmds/open-api/convert.ts","../src/cmds/open-api/index.ts","../src/cmds/open-api/merge.ts","../src/cmds/open-api/overlay.ts","../src/cmds/project/create.ts","../src/cmds/project/index.ts","../src/cmds/proxies/create.ts","../src/cmds/proxies/delete.ts","../src/cmds/proxies/describe.ts","../src/cmds/proxies/index.ts","../src/cmds/proxies/update.ts","../src/cmds/source/import-openapi.ts","../src/cmds/source/index.ts","../src/cmds/source/migrate.ts","../src/cmds/source/upgrade.ts","../src/cmds/tunnel/create.ts","../src/cmds/tunnel/delete.ts","../src/cmds/tunnel/describe.ts","../src/cmds/tunnel/index.ts","../src/cmds/tunnel/list.ts","../src/cmds/tunnel/rotate-token.ts","../src/cmds/tunnel/services/describe.ts","../src/cmds/tunnel/services/index.ts","../src/cmds/tunnel/services/update.ts","../src/cmds/variable/create.ts","../src/cmds/variable/index.ts","../src/cmds/variable/update.ts","../src/common/alias.ts","../src/common/args.ts","../src/common/constants.ts","../src/common/handler.ts","../src/common/logger.ts","../src/common/models.ts","../src/common/outdated.ts","../src/common/output.ts","../src/common/populate.ts","../src/common/runner.ts","../src/common/settings.ts","../src/common/worker-output.ts","../src/common/analytics/lib.ts","../src/common/api/lib.ts","../src/common/machine-id/lib.ts","../src/common/middleware/authentication.ts","../src/common/middleware/get-account-param.ts","../src/common/middleware/get-environment-param.ts","../src/common/middleware/get-project-param.ts","../src/common/middleware/logging.ts","../src/common/middleware/user-configuration.ts","../src/common/middleware/user-identification.ts","../src/common/middleware/validate-fleet.ts","../src/common/upgraders/lib.ts","../src/common/upgraders/package-json-upgrader.ts","../src/common/upgraders/tsconfig-upgrader.ts","../src/common/upgraders/vscode-settings-json-upgrader.ts","../src/common/utils/box.ts","../src/common/utils/branch.ts","../src/common/utils/ports.ts","../src/common/utils/prefixed-output.ts","../src/common/utils/pretty-print-environment-prompt.ts","../src/common/utils/stringify-config.test.ts","../src/common/utils/stringify-config.ts","../src/common/utils/types.ts","../src/common/utils/urls.ts","../src/common/validators/argument-validators.spec.ts","../src/common/validators/argument-validators.ts","../src/common/validators/file-system-validator.ts","../src/common/validators/lib.ts","../src/common/validators/project-name-validator.ts","../src/common/xdg/lib.ts","../src/compile/handler.ts","../src/delete/handler.ts","../src/delete/poll-deployment.ts","../src/deploy/archive.test.ts","../src/deploy/archive.ts","../src/deploy/environments.ts","../src/deploy/file-upload.ts","../src/deploy/handler.ts","../src/deploy/poll-deployment.ts","../src/dev/handler.ts","../src/docs/handler.ts","../src/editor/handler.ts","../src/editor/e2e/editor.spec.ts","../src/init/handler.ts","../src/link/handler.ts","../src/list/handler.ts","../src/login/login.ts","../src/login/tokens.ts","../src/mtls-certificates/models.ts","../src/mtls-certificates/create/handler.ts","../src/mtls-certificates/delete/handler.ts","../src/mtls-certificates/describe/handler.ts","../src/mtls-certificates/disable/handler.ts","../src/mtls-certificates/list/handler.ts","../src/mtls-certificates/update/handler.ts","../src/open-api/convert/handler.spec.ts","../src/open-api/convert/handler.ts","../src/open-api/merge/handler.spec.ts","../src/open-api/merge/handler.ts","../src/open-api/overlay/handler.spec.ts","../src/open-api/overlay/handler.ts","../src/project/create/handler.ts","../src/proxies/models.ts","../src/proxies/create/handler.ts","../src/proxies/delete/handler.ts","../src/proxies/describe/handler.ts","../src/proxies/update/handler.ts","../src/source/migrate/dev-portal/handler.ts","../src/source/migrate/dev-portal/types.ts","../src/source/update/handler.ts","../src/test/esbuild-config.ts","../src/test/handler.ts","../src/test/invoke-test.ts","../src/test/test-files.test.ts","../src/test/test-files.ts","../src/test/esbuild-plugins/node-test-prep-plugin.ts","../src/tunnel/models.ts","../src/tunnel/create/handler.ts","../src/tunnel/delete/handler.ts","../src/tunnel/delete/poll-teardown-operation.ts","../src/tunnel/describe/handler.ts","../src/tunnel/list/handler.ts","../src/tunnel/rotate-token/handler.ts","../src/tunnel/services/describe/handler.ts","../src/tunnel/services/update/handler.ts","../src/tunnel/services/update/poll-provisioning-operations.ts","../src/variable/models.ts","../src/variable/create/handler.ts","../src/variable/update/handler.ts"],"version":"5.8.2"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuplo/cli",
3
- "version": "6.65.9",
3
+ "version": "6.66.3",
4
4
  "repository": "https://github.com/zuplo/zuplo",
5
5
  "author": "Zuplo, Inc.",
6
6
  "type": "module",
@@ -29,10 +29,10 @@
29
29
  "@opentelemetry/api": "1.9.0",
30
30
  "@sentry/node": "9.22.0",
31
31
  "@swc/core": "1.10.18",
32
- "@zuplo/core": "6.65.9",
32
+ "@zuplo/core": "6.66.3",
33
33
  "@zuplo/editor": "1.0.20821740935",
34
- "@zuplo/openapi-tools": "6.65.9",
35
- "@zuplo/runtime": "6.65.9",
34
+ "@zuplo/openapi-tools": "6.66.3",
35
+ "@zuplo/runtime": "6.66.3",
36
36
  "as-table": "1.0.55",
37
37
  "chalk": "5.4.1",
38
38
  "chokidar": "3.5.3",
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=import-openapi-utils.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"import-openapi-utils.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/import-openapi-utils.test.ts"],"names":[],"mappings":""}