keq 2.9.0 → 2.10.0

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 (151) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/esm/src/constant.d.ts +2 -0
  3. package/dist/esm/src/constant.js +2 -0
  4. package/dist/esm/src/core.d.ts +30 -0
  5. package/dist/esm/src/core.js +162 -53
  6. package/dist/esm/src/exception/abort.exception.d.ts +3 -0
  7. package/dist/esm/src/exception/abort.exception.js +6 -0
  8. package/dist/esm/src/index.d.ts +1 -0
  9. package/dist/esm/src/index.js +1 -0
  10. package/dist/esm/src/is/is-abort-signal.d.ts +1 -0
  11. package/dist/esm/src/is/is-abort-signal.js +8 -0
  12. package/dist/esm/src/middlewares/fetch-arguments-middleware.js +5 -1
  13. package/dist/esm/src/middlewares/retry-middleware.js +20 -3
  14. package/dist/esm/src/middlewares/timeout-middleware.js +3 -1
  15. package/dist/esm/src/types/keq-context.d.ts +10 -1
  16. package/dist/esm/src/types/keq-context.js +1 -1
  17. package/dist/umd/src/constant.d.ts +2 -0
  18. package/dist/umd/src/constant.js +3 -1
  19. package/dist/umd/src/core.d.ts +30 -0
  20. package/dist/umd/src/core.js +162 -53
  21. package/dist/umd/src/exception/abort.exception.d.ts +3 -0
  22. package/dist/umd/src/exception/abort.exception.js +20 -0
  23. package/dist/umd/src/index.d.ts +1 -0
  24. package/dist/umd/src/index.js +4 -2
  25. package/dist/umd/src/is/is-abort-signal.d.ts +1 -0
  26. package/dist/umd/src/is/is-abort-signal.js +22 -0
  27. package/dist/umd/src/middlewares/fetch-arguments-middleware.js +4 -0
  28. package/dist/umd/src/middlewares/retry-middleware.js +21 -4
  29. package/dist/umd/src/middlewares/timeout-middleware.js +4 -2
  30. package/dist/umd/src/types/keq-context.d.ts +10 -1
  31. package/package.json +10 -13
  32. package/.claude/settings.local.json +0 -26
  33. package/packages/cache/.turbo/turbo-build.log +0 -29
  34. package/packages/cache/dist/index.d.mts +0 -354
  35. package/packages/cache/dist/index.d.mts.map +0 -1
  36. package/packages/cache/dist/index.d.ts +0 -353
  37. package/packages/cache/dist/index.d.ts.map +0 -1
  38. package/packages/cache/dist/index.js +0 -1271
  39. package/packages/cache/dist/index.js.map +0 -1
  40. package/packages/cache/dist/index.mjs +0 -1237
  41. package/packages/cache/dist/index.mjs.map +0 -1
  42. package/packages/cli/.turbo/turbo-build.log +0 -91
  43. package/packages/cli/dist/cli.cjs +0 -1364
  44. package/packages/cli/dist/cli.cjs.map +0 -1
  45. package/packages/cli/dist/cli.d.cts +0 -1
  46. package/packages/cli/dist/cli.d.mts +0 -1
  47. package/packages/cli/dist/cli.mjs +0 -1359
  48. package/packages/cli/dist/cli.mjs.map +0 -1
  49. package/packages/cli/dist/compiler-0Kli6UCr.cjs +0 -738
  50. package/packages/cli/dist/compiler-0Kli6UCr.cjs.map +0 -1
  51. package/packages/cli/dist/compiler-C3AE8j54.mjs +0 -715
  52. package/packages/cli/dist/compiler-C3AE8j54.mjs.map +0 -1
  53. package/packages/cli/dist/index.cjs +0 -20
  54. package/packages/cli/dist/index.cjs.map +0 -1
  55. package/packages/cli/dist/index.d.cts +0 -17
  56. package/packages/cli/dist/index.d.cts.map +0 -1
  57. package/packages/cli/dist/index.d.mts +0 -17
  58. package/packages/cli/dist/index.d.mts.map +0 -1
  59. package/packages/cli/dist/index.mjs +0 -10
  60. package/packages/cli/dist/index.mjs.map +0 -1
  61. package/packages/cli/dist/init-BNhD2oCI.mjs +0 -168
  62. package/packages/cli/dist/init-BNhD2oCI.mjs.map +0 -1
  63. package/packages/cli/dist/init-DqxLcRSQ.cjs +0 -170
  64. package/packages/cli/dist/init-DqxLcRSQ.cjs.map +0 -1
  65. package/packages/cli/dist/logger-D7PyVZo3.cjs +0 -46
  66. package/packages/cli/dist/logger-D7PyVZo3.cjs.map +0 -1
  67. package/packages/cli/dist/logger-QLBHySQ3.mjs +0 -12
  68. package/packages/cli/dist/logger-QLBHySQ3.mjs.map +0 -1
  69. package/packages/cli/dist/micro-function.translator-BmJZzkKh.cjs +0 -16
  70. package/packages/cli/dist/micro-function.translator-BmJZzkKh.cjs.map +0 -1
  71. package/packages/cli/dist/micro-function.translator-CDfkj4Tt.mjs +0 -11
  72. package/packages/cli/dist/micro-function.translator-CDfkj4Tt.mjs.map +0 -1
  73. package/packages/cli/dist/mock-command-Bp1LxSls.mjs +0 -350
  74. package/packages/cli/dist/mock-command-Bp1LxSls.mjs.map +0 -1
  75. package/packages/cli/dist/mock-command-WZcfy5Iq.cjs +0 -353
  76. package/packages/cli/dist/mock-command-WZcfy5Iq.cjs.map +0 -1
  77. package/packages/cli/dist/plugins-CgMhaNZq.cjs +0 -3558
  78. package/packages/cli/dist/plugins-CgMhaNZq.cjs.map +0 -1
  79. package/packages/cli/dist/plugins-DCvJ8iHR.mjs +0 -3280
  80. package/packages/cli/dist/plugins-DCvJ8iHR.mjs.map +0 -1
  81. package/packages/cli/dist/plugins.cjs +0 -36
  82. package/packages/cli/dist/plugins.d.cts +0 -2
  83. package/packages/cli/dist/plugins.d.mts +0 -2
  84. package/packages/cli/dist/plugins.mjs +0 -2
  85. package/packages/cli/dist/runtime-config-BWQlPhiB.d.cts +0 -780
  86. package/packages/cli/dist/runtime-config-BWQlPhiB.d.cts.map +0 -1
  87. package/packages/cli/dist/runtime-config-CrzK-Ucf.d.mts +0 -780
  88. package/packages/cli/dist/runtime-config-CrzK-Ucf.d.mts.map +0 -1
  89. package/packages/cli/dist/translators.cjs +0 -14
  90. package/packages/cli/dist/translators.cjs.map +0 -1
  91. package/packages/cli/dist/translators.d.cts +0 -14
  92. package/packages/cli/dist/translators.d.cts.map +0 -1
  93. package/packages/cli/dist/translators.d.mts +0 -14
  94. package/packages/cli/dist/translators.d.mts.map +0 -1
  95. package/packages/cli/dist/translators.mjs +0 -12
  96. package/packages/cli/dist/translators.mjs.map +0 -1
  97. package/packages/cli/node_modules/.bin/eslint +0 -21
  98. package/packages/cli/node_modules/.bin/jiti +0 -21
  99. package/packages/cli/node_modules/.bin/js-yaml +0 -21
  100. package/packages/cli/node_modules/.bin/jsf +0 -21
  101. package/packages/cli/node_modules/.bin/jsonpath +0 -21
  102. package/packages/cli/node_modules/.bin/jsonpath-plus +0 -21
  103. package/packages/cli/node_modules/.bin/semver +0 -21
  104. package/packages/cli/node_modules/.bin/tsc +0 -21
  105. package/packages/cli/node_modules/.bin/tsserver +0 -21
  106. package/packages/exception/.turbo/turbo-build.log +0 -29
  107. package/packages/exception/dist/index.d.mts +0 -21
  108. package/packages/exception/dist/index.d.mts.map +0 -1
  109. package/packages/exception/dist/index.d.ts +0 -21
  110. package/packages/exception/dist/index.d.ts.map +0 -1
  111. package/packages/exception/dist/index.js +0 -104
  112. package/packages/exception/dist/index.js.map +0 -1
  113. package/packages/exception/dist/index.mjs +0 -99
  114. package/packages/exception/dist/index.mjs.map +0 -1
  115. package/packages/headers/.turbo/turbo-build.log +0 -29
  116. package/packages/headers/dist/index.d.mts +0 -46
  117. package/packages/headers/dist/index.d.mts.map +0 -1
  118. package/packages/headers/dist/index.d.ts +0 -46
  119. package/packages/headers/dist/index.d.ts.map +0 -1
  120. package/packages/headers/dist/index.js +0 -81
  121. package/packages/headers/dist/index.js.map +0 -1
  122. package/packages/headers/dist/index.mjs +0 -75
  123. package/packages/headers/dist/index.mjs.map +0 -1
  124. package/packages/keq/.turbo/turbo-build.log +0 -29
  125. package/packages/keq/dist/index.d.mts +0 -962
  126. package/packages/keq/dist/index.d.mts.map +0 -1
  127. package/packages/keq/dist/index.d.ts +0 -962
  128. package/packages/keq/dist/index.d.ts.map +0 -1
  129. package/packages/keq/dist/index.js +0 -1876
  130. package/packages/keq/dist/index.js.map +0 -1
  131. package/packages/keq/dist/index.mjs +0 -1814
  132. package/packages/keq/dist/index.mjs.map +0 -1
  133. package/packages/nestjs/.turbo/turbo-build.log +0 -29
  134. package/packages/nestjs/dist/index.d.mts +0 -52
  135. package/packages/nestjs/dist/index.d.mts.map +0 -1
  136. package/packages/nestjs/dist/index.d.ts +0 -52
  137. package/packages/nestjs/dist/index.d.ts.map +0 -1
  138. package/packages/nestjs/dist/index.js +0 -166
  139. package/packages/nestjs/dist/index.js.map +0 -1
  140. package/packages/nestjs/dist/index.mjs +0 -136
  141. package/packages/nestjs/dist/index.mjs.map +0 -1
  142. package/packages/test/.turbo/turbo-build.log +0 -6
  143. package/packages/url/.turbo/turbo-build.log +0 -29
  144. package/packages/url/dist/index.d.mts +0 -9
  145. package/packages/url/dist/index.d.mts.map +0 -1
  146. package/packages/url/dist/index.d.ts +0 -9
  147. package/packages/url/dist/index.d.ts.map +0 -1
  148. package/packages/url/dist/index.js +0 -43
  149. package/packages/url/dist/index.js.map +0 -1
  150. package/packages/url/dist/index.mjs +0 -40
  151. package/packages/url/dist/index.mjs.map +0 -1
@@ -1,3558 +0,0 @@
1
- const require_logger = require("./logger-D7PyVZo3.cjs");
2
- let tapable = require("tapable");
3
- let fs_extra = require("fs-extra");
4
- fs_extra = require_logger.__toESM(fs_extra, 1);
5
- let path = require("path");
6
- path = require_logger.__toESM(path, 1);
7
- let ramda = require("ramda");
8
- ramda = require_logger.__toESM(ramda, 1);
9
- let eslint = require("eslint");
10
- let child_process = require("child_process");
11
- let util = require("util");
12
- let change_case = require("change-case");
13
- change_case = require_logger.__toESM(change_case, 1);
14
- let jsonpath_plus = require("jsonpath-plus");
15
- let jsonpointer = require("jsonpointer");
16
- jsonpointer = require_logger.__toESM(jsonpointer, 1);
17
- let _scalar_openapi_parser = require("@scalar/openapi-parser");
18
- let ts_custom_error = require("ts-custom-error");
19
- let word_wrap = require("word-wrap");
20
- word_wrap = require_logger.__toESM(word_wrap, 1);
21
- let swagger_fix = require("swagger-fix");
22
- let fs_promises = require("fs/promises");
23
- fs_promises = require_logger.__toESM(fs_promises, 1);
24
- let js_yaml = require("js-yaml");
25
- js_yaml = require_logger.__toESM(js_yaml, 1);
26
- let url = require("url");
27
- let _opendoc_openapi_shaking = require("@opendoc/openapi-shaking");
28
- let inquirer_select_pro = require("inquirer-select-pro");
29
- let _listr2_prompt_adapter_inquirer = require("@listr2/prompt-adapter-inquirer");
30
- let ajv_dist_2020_js = require("ajv/dist/2020.js");
31
- ajv_dist_2020_js = require_logger.__toESM(ajv_dist_2020_js, 1);
32
- //#region src/constants/qs-array-format.ts
33
- let QsArrayFormat = /* @__PURE__ */ function(QsArrayFormat) {
34
- QsArrayFormat["brackets"] = "brackets";
35
- QsArrayFormat["indices"] = "indices";
36
- QsArrayFormat["repeat"] = "repeat";
37
- QsArrayFormat["comma"] = "comma";
38
- QsArrayFormat["space"] = "space";
39
- QsArrayFormat["pipe"] = "pipe";
40
- return QsArrayFormat;
41
- }({});
42
- //#endregion
43
- //#region src/constants/supported-methods.ts
44
- const SupportedMethods = [
45
- "get",
46
- "post",
47
- "put",
48
- "delete",
49
- "patch",
50
- "head",
51
- "options"
52
- ];
53
- //#endregion
54
- //#region src/models/plugin-metadata-storage.ts
55
- /**
56
- * A WeakMap-backed metadata storage for plugins.
57
- *
58
- * When a `key` is provided, the underlying WeakMap is stored in `globalThis` via
59
- * `Symbol.for(key)`, ensuring the same instance is shared across CJS and ESM module
60
- * boundaries. This is required for plugins that are imported by user config files
61
- * (e.g. via `@keq-request/cli/plugins`) and need to interoperate with the CLI's
62
- * internal plugins.
63
- *
64
- * When no `key` is provided, a plain `new WeakMap()` is used, which is sufficient
65
- * for plugins that always run within the same module system.
66
- */
67
- var PluginMetadataStorage = class {
68
- storage;
69
- constructor(key) {
70
- if (key !== void 0) {
71
- const storageKey = Symbol.for(key);
72
- const g = globalThis;
73
- if (!g[storageKey]) g[storageKey] = /* @__PURE__ */ new WeakMap();
74
- this.storage = g[storageKey];
75
- } else this.storage = /* @__PURE__ */ new WeakMap();
76
- }
77
- has(key) {
78
- return this.storage.has(key);
79
- }
80
- get(key) {
81
- return this.storage.get(key);
82
- }
83
- set(key, value) {
84
- this.storage.set(key, value);
85
- return this;
86
- }
87
- delete(key) {
88
- return this.storage.delete(key);
89
- }
90
- };
91
- //#endregion
92
- //#region src/plugins/eslint/constants/metadata-storage.ts
93
- const MetadataStorage$12 = new PluginMetadataStorage("@keq-request/cli:EslintPlugin:MetadataStorage");
94
- //#endregion
95
- //#region src/plugins/eslint/eslint.plugin.ts
96
- var EslintPlugin = class EslintPlugin {
97
- constructor(options = {}) {
98
- this.options = options;
99
- }
100
- apply(compiler) {
101
- if (!compiler.options.build) return;
102
- const metadata = EslintPlugin.register(compiler);
103
- if (metadata.applied) return;
104
- metadata.applied = true;
105
- if (this.options.disable && this.options.disable.length > 0) {
106
- const $rules = [...this.options.disable.map((rule) => `/* eslint-disable ${rule} */`)].join("\n");
107
- compiler.hooks.afterCompile.tap(EslintPlugin.name, () => {
108
- const artifacts = compiler.context.artifacts || [];
109
- for (const artifact of artifacts) artifact.anchor.append("file:start", $rules);
110
- });
111
- }
112
- compiler.hooks.afterPersist.tapPromise(EslintPlugin.name, async (task) => {
113
- const files = compiler.context.assets || [];
114
- if (files.length === 0) return;
115
- const results = await new eslint.ESLint({ fix: true }).lintFiles(files.map((file) => file.path));
116
- await eslint.ESLint.outputFixes(results);
117
- });
118
- }
119
- static register(compiler) {
120
- if (!MetadataStorage$12.has(compiler)) MetadataStorage$12.set(compiler, {
121
- applied: false,
122
- hooks: {}
123
- });
124
- return MetadataStorage$12.get(compiler);
125
- }
126
- static of(compiler) {
127
- return this.register(compiler);
128
- }
129
- };
130
- //#endregion
131
- //#region src/plugins/prettier/constants/metadata-storage.ts
132
- const MetadataStorage$11 = new PluginMetadataStorage("@keq-request/cli:PrettierPlugin:MetadataStorage");
133
- //#endregion
134
- //#region src/plugins/prettier/prettier.plugin.ts
135
- const execAsync = (0, util.promisify)(child_process.exec);
136
- var PrettierPlugin = class PrettierPlugin {
137
- apply(compiler) {
138
- if (!compiler.options.build) return;
139
- const metadata = PrettierPlugin.register(compiler);
140
- if (metadata.applied) return;
141
- metadata.applied = true;
142
- compiler.hooks.afterPersist.tapPromise(PrettierPlugin.name, async () => {
143
- const files = compiler.context.assets || [];
144
- if (files.length === 0) return;
145
- await execAsync(`prettier --write ${files.map((file) => file.path).join(" ")}`);
146
- });
147
- }
148
- static register(compiler) {
149
- if (!MetadataStorage$11.has(compiler)) MetadataStorage$11.set(compiler, {
150
- applied: false,
151
- hooks: {}
152
- });
153
- return MetadataStorage$11.get(compiler);
154
- }
155
- static of(compiler) {
156
- return this.register(compiler);
157
- }
158
- };
159
- //#endregion
160
- //#region src/utils/json-schema-utils/is-array.ts
161
- function isArray(schema) {
162
- return schema.type === "array";
163
- }
164
- //#endregion
165
- //#region src/utils/json-schema-utils/is-mixed.ts
166
- function isMixed(schema) {
167
- return Array.isArray(schema.type);
168
- }
169
- //#endregion
170
- //#region src/utils/json-schema-utils/is-non-array.ts
171
- function isNonArray(schema) {
172
- return typeof schema.type === "string" && schema.type !== "array";
173
- }
174
- //#endregion
175
- //#region src/utils/json-schema-utils/is-ref.ts
176
- function isRef(schema) {
177
- return "$ref" in schema;
178
- }
179
- //#endregion
180
- //#region src/utils/json-schema-utils/index.ts
181
- var JsonSchemaUtils = class {
182
- static isRef = isRef;
183
- static isArray = isArray;
184
- static isNonArray = isNonArray;
185
- static isMixed = isMixed;
186
- };
187
- //#endregion
188
- //#region src/plugins/generate-micro-function/constants/metadata-storage.ts
189
- const MetadataStorage$10 = new PluginMetadataStorage("@keq-request/cli:GenerateMicroFunctionPlugin:MetadataStorage");
190
- //#endregion
191
- //#region src/models/anchor.ts
192
- var AnchorBlock = class {
193
- constructor(artifact) {
194
- this.artifact = artifact;
195
- }
196
- /**
197
- * Append content to the end of the anchor block.
198
- */
199
- append(anchorName, content) {
200
- const lines = this.artifact.content.split("\n");
201
- const anchor = `@anchor:${anchorName}:end`;
202
- const anchorIndex = lines.findIndex((line) => line.includes(`/* ${anchor} */`));
203
- if (anchorIndex === -1) throw new Error(`"${anchor}" not found in artifact "${this.artifact.filepath}".`);
204
- lines.splice(anchorIndex, 0, content);
205
- this.artifact.content = lines.join("\n");
206
- }
207
- prepend(anchorName, content) {
208
- const lines = this.artifact.content.split("\n");
209
- const anchor = `@anchor:${anchorName}:start`;
210
- const anchorIndex = lines.findIndex((line) => line.includes(`/* ${anchor} */`));
211
- if (anchorIndex === -1) throw new Error(`"${anchor}" not found in artifact "${this.artifact.filepath}".`);
212
- lines.splice(anchorIndex + 1, 0, content);
213
- this.artifact.content = lines.join("\n");
214
- }
215
- replace(anchorName, content) {
216
- const lines = this.artifact.content.split("\n");
217
- const startIndex = lines.findIndex((line) => line.includes(`/* @anchor:${anchorName}:start */`));
218
- const endIndex = lines.findIndex((line) => line.includes(`/* @anchor:${anchorName}:end */`));
219
- if (startIndex === -1 || endIndex === -1 || endIndex <= startIndex) throw new Error(`"@anchor:${anchorName}:start" or "@anchor:${anchorName}:end" not found in artifact "${this.artifact.filepath}".`);
220
- lines.splice(startIndex + 1, endIndex - startIndex - 1, content);
221
- this.artifact.content = lines.join("\n");
222
- }
223
- };
224
- var Anchor = class {
225
- block;
226
- constructor(artifact) {
227
- this.artifact = artifact;
228
- this.block = new AnchorBlock(artifact);
229
- }
230
- append(anchorName, content) {
231
- const lines = this.artifact.content.split("\n");
232
- const anchor = `@anchor:${anchorName}`;
233
- const anchorIndex = lines.findIndex((line) => line.includes(`/* ${anchor} */`));
234
- if (anchorIndex === -1) throw new Error(`"${anchor}" not found in artifact "${this.artifact.filepath}".`);
235
- lines.splice(anchorIndex + 1, 0, content);
236
- this.artifact.content = lines.join("\n");
237
- }
238
- prepend(anchorName, content) {
239
- const lines = this.artifact.content.split("\n");
240
- const anchor = `@anchor:${anchorName}`;
241
- const anchorIndex = lines.findIndex((line) => line.includes(`/* ${anchor} */`));
242
- if (anchorIndex === -1) throw new Error(`"${anchor}" not found in artifact "${this.artifact.filepath}".`);
243
- lines.splice(anchorIndex, 0, content);
244
- this.artifact.content = lines.join("\n");
245
- }
246
- };
247
- //#endregion
248
- //#region src/models/artifact.ts
249
- const HeaderComment = [
250
- "// Code generated by @keq-request/cli. DO NOT EDIT.",
251
- "// Code generated by @keq-request/cli. DO NOT EDIT.",
252
- "// Code generated by @keq-request/cli. DO NOT EDIT.",
253
- "",
254
- ""
255
- ].join("\n");
256
- var Artifact = class {
257
- id;
258
- filepath;
259
- content;
260
- extensionName;
261
- anchor = new Anchor(this);
262
- constructor(options) {
263
- this.id = options.id;
264
- this.filepath = options.filepath;
265
- this.extensionName = options.extensionName || path.extname(options.filepath);
266
- this.content = options.content;
267
- }
268
- get dirname() {
269
- return path.dirname(this.filepath);
270
- }
271
- renderer() {
272
- return `${HeaderComment}${this.content}`;
273
- }
274
- };
275
- //#endregion
276
- //#region src/models/module-definition.ts
277
- var ModuleDefinition = class ModuleDefinition {
278
- name;
279
- address;
280
- constructor(name, address) {
281
- this.name = name;
282
- if (typeof address === "string") this.address = {
283
- url: address,
284
- headers: {},
285
- encoding: "utf8"
286
- };
287
- else this.address = address;
288
- }
289
- static unknown() {
290
- return new ModuleDefinition("", {
291
- url: "",
292
- headers: {},
293
- encoding: "utf8"
294
- });
295
- }
296
- };
297
- //#endregion
298
- //#region src/utils/is-keywords.ts
299
- const keywords = [
300
- "break",
301
- "case",
302
- "catch",
303
- "continue",
304
- "default",
305
- "delete",
306
- "do",
307
- "else",
308
- "finally",
309
- "for",
310
- "function",
311
- "if",
312
- "in",
313
- "instanceof",
314
- "new",
315
- "return",
316
- "switch",
317
- "this",
318
- "throw",
319
- "try",
320
- "typeof",
321
- "var",
322
- "void",
323
- "while",
324
- "with"
325
- ];
326
- function isKeywords(str) {
327
- return keywords.includes(str);
328
- }
329
- //#endregion
330
- //#region src/utils/is-reserved-word.ts
331
- const reservedWords = [
332
- "abstract",
333
- "boolean",
334
- "byte",
335
- "char",
336
- "class",
337
- "const",
338
- "debugger",
339
- "double",
340
- "enum",
341
- "export",
342
- "extends",
343
- "final",
344
- "float",
345
- "goto",
346
- "implements",
347
- "import",
348
- "int",
349
- "interface",
350
- "long",
351
- "native",
352
- "package",
353
- "private",
354
- "protected",
355
- "public",
356
- "short",
357
- "static",
358
- "super",
359
- "synchronized",
360
- "throws",
361
- "transient",
362
- "volatile"
363
- ];
364
- function isReservedWord(str) {
365
- return reservedWords.includes(str);
366
- }
367
- //#endregion
368
- //#region src/models/schema-definition.ts
369
- var SchemaDefinition = class SchemaDefinition {
370
- name;
371
- schema;
372
- module;
373
- document;
374
- get id() {
375
- return `${this.module.address.url}#/components/schemas/${this.name}`;
376
- }
377
- constructor(args) {
378
- this.module = args.module;
379
- this.name = args.name;
380
- this.schema = args.schema;
381
- this.document = args.document;
382
- }
383
- getDependencies() {
384
- return ramda.uniq((0, jsonpath_plus.JSONPath)({
385
- path: "$..*['$ref']",
386
- json: this.schema
387
- })).filter((ref) => typeof ref === "string" && !!ref.trim()).map((ref) => {
388
- const definition = this.document.dereference(ref);
389
- if (definition instanceof SchemaDefinition) return definition;
390
- return SchemaDefinition.unknown();
391
- }).filter((dep) => dep.id !== this.id);
392
- }
393
- static unknown() {
394
- return new SchemaDefinition({
395
- name: "",
396
- schema: {},
397
- module: ModuleDefinition.unknown(),
398
- document: ApiDocumentV3_1.unknown()
399
- });
400
- }
401
- static isUnknown(definition) {
402
- return definition.name === "";
403
- }
404
- };
405
- //#endregion
406
- //#region src/models/response-definition.ts
407
- var ResponseDefinition = class ResponseDefinition {
408
- name;
409
- response;
410
- module;
411
- document;
412
- get id() {
413
- return `${this.module.address.url}#/components/responses/${this.name}`;
414
- }
415
- constructor(args) {
416
- this.module = args.module;
417
- this.name = args.name;
418
- this.response = args.response;
419
- this.document = args.document;
420
- }
421
- getDependencies() {
422
- return ramda.uniq((0, jsonpath_plus.JSONPath)({
423
- path: "$.content..schema..$['$ref']",
424
- json: this.response
425
- })).filter((ref) => typeof ref === "string" && !!ref.trim()).map((ref) => {
426
- const definition = this.document.dereference(ref);
427
- if (definition instanceof SchemaDefinition) return definition;
428
- return SchemaDefinition.unknown();
429
- }).filter((dep) => dep.id !== this.id);
430
- }
431
- static unknown() {
432
- return new ResponseDefinition({
433
- name: "",
434
- response: { description: "" },
435
- module: ModuleDefinition.unknown(),
436
- document: ApiDocumentV3_1.unknown()
437
- });
438
- }
439
- static isUnknown(definition) {
440
- return definition.name === "";
441
- }
442
- };
443
- //#endregion
444
- //#region src/models/operation-definition.ts
445
- var OperationDefinition = class {
446
- module;
447
- operationId;
448
- method;
449
- pathname;
450
- operation;
451
- document;
452
- get id() {
453
- return `${this.module.address.url}#/paths/${this.pathname}/${this.method}`;
454
- }
455
- constructor(args) {
456
- this.module = args.module;
457
- this.method = args.method.toLowerCase();
458
- this.pathname = args.pathname;
459
- this.document = args.document;
460
- this.operationId = this.formatOperationId(args.method, args.pathname, args.operation);
461
- this.operation = {
462
- ...args.operation,
463
- operationId: this.operationId
464
- };
465
- }
466
- formatOperationId(method, pathname, operation) {
467
- const operationId = operation.operationId;
468
- if (operationId && operationId !== "index" && !isKeywords(operationId) && !isReservedWord(operationId)) return operationId;
469
- return `${method}_${pathname}`.replace(/\//g, "_").replace(/-/g, "_").replace(/:/g, "$$").replace(/{(.+)}/, "$$$1");
470
- }
471
- getDependencies() {
472
- return ramda.uniq([
473
- ...(0, jsonpath_plus.JSONPath)({
474
- path: "$.requestBody.content..schema..$ref",
475
- json: this.operation
476
- }),
477
- ...(0, jsonpath_plus.JSONPath)({
478
- path: "$.responses..content..schema..$ref",
479
- json: this.operation
480
- }),
481
- ...(0, jsonpath_plus.JSONPath)({
482
- path: "$.parameters..schema..$ref",
483
- json: this.operation
484
- })
485
- ]).filter((ref) => typeof ref === "string" && ref).map((ref) => {
486
- const definition = this.document.dereference(ref);
487
- if (definition instanceof SchemaDefinition) return definition;
488
- return SchemaDefinition.unknown();
489
- });
490
- }
491
- getResponseDependencies() {
492
- const responses = this.operation.responses || {};
493
- return ramda.uniqBy((dep) => dep.id, Object.values(responses).filter((response) => JsonSchemaUtils.isRef(response)).map((response) => {
494
- const definition = this.document.dereference(response.$ref);
495
- if (definition instanceof ResponseDefinition) return definition;
496
- return ResponseDefinition.unknown();
497
- }).filter((dep) => !ResponseDefinition.isUnknown(dep)));
498
- }
499
- };
500
- //#endregion
501
- //#region src/models/api-document_v3_1.ts
502
- var ApiDocumentV3_1 = class ApiDocumentV3_1 {
503
- module;
504
- specification;
505
- constructor(specification, module) {
506
- this.module = module;
507
- this.specification = specification;
508
- }
509
- get schemas() {
510
- const module = this.module;
511
- return Object.entries(this.specification.components?.schemas || {}).map(([name, schema]) => new SchemaDefinition({
512
- name,
513
- schema,
514
- module,
515
- document: this
516
- }));
517
- }
518
- get responses() {
519
- const module = this.module;
520
- return Object.entries(this.specification.components?.responses || {}).filter((entry) => {
521
- const [, response] = entry;
522
- return typeof response === "object" && !("$ref" in response);
523
- }).map(([name, response]) => new ResponseDefinition({
524
- name,
525
- response,
526
- module,
527
- document: this
528
- }));
529
- }
530
- get operations() {
531
- const module = this.module;
532
- return Object.entries(this.specification.paths || {}).flatMap(([pathname, pathItem]) => Object.entries(pathItem || {}).filter(([method]) => SupportedMethods.includes(method.toLowerCase())).map(([method, operation]) => new OperationDefinition({
533
- method,
534
- pathname,
535
- operation,
536
- module,
537
- document: this
538
- })));
539
- }
540
- isEmpty() {
541
- return ramda.isEmpty(this.specification.paths);
542
- }
543
- dereference($ref) {
544
- if ($ref.startsWith("#/")) {
545
- if ($ref.startsWith("#/components/responses/")) return this.responses.find((response) => response.id.endsWith($ref));
546
- return this.schemas.find((schema) => schema.id.endsWith($ref));
547
- }
548
- require_logger.logger.warn(`The $ref(${$ref}) is not defined in ${this.module.name} openapi/swagger.`);
549
- }
550
- isRefDefined($ref) {
551
- if ($ref.startsWith("#/")) {
552
- const path = $ref.replace("#/", "").split("/");
553
- return ramda.path(path, this.specification) !== void 0;
554
- }
555
- return false;
556
- }
557
- static unknown() {
558
- return new ApiDocumentV3_1({}, ModuleDefinition.unknown());
559
- }
560
- };
561
- //#endregion
562
- //#region src/models/asset.ts
563
- var Asset = class {
564
- path;
565
- constructor(path) {
566
- this.path = path;
567
- }
568
- };
569
- //#endregion
570
- //#region src/models/file-tracker.ts
571
- /**
572
- * Passive file change tracker based on mtime comparison.
573
- * Instead of actively watching filesystem events, it checks for changes on demand,
574
- * suitable for lazy reload of config files in long-lived processes.
575
- */
576
- var FileTracker = class {
577
- files = [];
578
- reloadPromise = null;
579
- async track(filepath) {
580
- let mtimeMs = 0;
581
- try {
582
- mtimeMs = (await fs_extra.default.stat(filepath)).mtimeMs;
583
- } catch {}
584
- this.files.push({
585
- filepath,
586
- mtimeMs
587
- });
588
- }
589
- async ensureFresh(reload) {
590
- if (!await this.isChanged()) return;
591
- if (this.reloadPromise) {
592
- await this.reloadPromise;
593
- return;
594
- }
595
- if (!await this.isChanged()) return;
596
- this.reloadPromise = reload().finally(() => {
597
- this.reloadPromise = null;
598
- });
599
- await this.reloadPromise;
600
- }
601
- async forceReload(reload) {
602
- if (this.reloadPromise) await this.reloadPromise;
603
- this.reloadPromise = reload().finally(() => {
604
- this.reloadPromise = null;
605
- });
606
- await this.reloadPromise;
607
- }
608
- async snapshot() {
609
- for (const file of this.files) try {
610
- file.mtimeMs = (await fs_extra.default.stat(file.filepath)).mtimeMs;
611
- } catch {
612
- file.mtimeMs = 0;
613
- }
614
- }
615
- async isChanged() {
616
- for (const file of this.files) try {
617
- if ((await fs_extra.default.stat(file.filepath)).mtimeMs !== file.mtimeMs) return true;
618
- } catch {
619
- if (file.mtimeMs !== 0) return true;
620
- }
621
- return false;
622
- }
623
- };
624
- //#endregion
625
- //#region src/transformers/json-schema/comment.renderer.ts
626
- var CommentRenderer$1 = class {
627
- constructor(schema) {
628
- this.schema = schema;
629
- }
630
- render() {
631
- const schema = this.schema;
632
- const lines = ["/**"];
633
- if (schema.description) {
634
- const description = schema.description.replace("*/", "*\\/").replace(/\t/g, " ").replace(/\r\n?/g, "\n");
635
- lines.push(...description.split("\n").map((line) => ` * ${line.trimEnd()}`));
636
- }
637
- if (schema.deprecated) lines.push(" * @deprecated");
638
- if (schema.readOnly) lines.push(" * @readonly");
639
- if (schema.format) lines.push(` * @format ${schema.format}`);
640
- lines.push(" */");
641
- if (lines.length === 2) return "";
642
- return lines.join("\n");
643
- }
644
- };
645
- //#endregion
646
- //#region src/utils/indent.ts
647
- function indent(space, text) {
648
- if (text === "") return "";
649
- const indentation = " ".repeat(space);
650
- return text.split("\n").map((line) => line ? `${indentation}${line}` : line).join("\n");
651
- }
652
- //#endregion
653
- //#region src/transformers/json-schema/reference.transformer.ts
654
- var ReferenceTransformer = class {
655
- static toDeclaration(schema, alias = ramda.identity) {
656
- if (!schema.$ref || !schema.$ref.startsWith("#")) return `unknown /* ${schema.$ref.replace("*/", "*\\/")} */`;
657
- const parts = schema.$ref.split("/");
658
- return alias(parts[parts.length - 1]) || "unknown";
659
- }
660
- /**
661
- * Render the case where the $ref target does not exist
662
- */
663
- static toNotFoundDeclaration(schema, hint) {
664
- const safeRef = schema.$ref.replace("*/", "*\\/");
665
- return `unknown /* ${hint ? `Cannot find $ref "${safeRef}". ${hint}` : `Cannot find $ref "${safeRef}"`} */`;
666
- }
667
- /**
668
- * Render the case where the $ref format is invalid
669
- */
670
- static toInvalidDeclaration(schema, hint) {
671
- const safeRef = schema.$ref.replace("*/", "*\\/");
672
- return `unknown /* ${hint ? `Invalid $ref "${safeRef}". ${hint}` : `Invalid $ref "${safeRef}"`} */`;
673
- }
674
- };
675
- //#endregion
676
- //#region src/transformers/json-schema/declaration.renderer.ts
677
- var DeclarationRenderer$1 = class {
678
- constructor(schema, options = {}) {
679
- this.schema = schema;
680
- this.options = options;
681
- }
682
- render() {
683
- return this.renderSchema(this.schema);
684
- }
685
- renderSchema(schema) {
686
- if (typeof schema === "boolean") return "unknown";
687
- if (JsonSchemaUtils.isRef(schema)) return this.renderReference(schema);
688
- if (JsonSchemaUtils.isMixed(schema)) return this.renderMixed(schema);
689
- if (JsonSchemaUtils.isArray(schema)) return this.renderArray(schema);
690
- if (schema.type === "object") return this.renderObject(schema);
691
- if (schema.enum) return this.renderEnum(schema);
692
- if (schema.oneOf) return this.renderOneOf(schema);
693
- if (schema.anyOf) return this.renderAnyOf(schema);
694
- if (schema.allOf) return this.renderAllOf(schema);
695
- if (schema.type === "string") return this.renderString(schema);
696
- if (schema.type === "number") return this.renderNumber(schema);
697
- if (schema.type === "boolean") return this.renderBoolean(schema);
698
- if (schema.type === "null") return this.renderNull(schema);
699
- if (schema.type === "integer") return this.renderInteger(schema);
700
- return "unknown";
701
- }
702
- renderMixed(schema) {
703
- if (Array.isArray(schema.type)) return schema.type.map((type) => ({
704
- ...schema,
705
- type
706
- })).map((schema) => this.renderSchema(schema)).join(" | ");
707
- return "unknown";
708
- }
709
- renderReference(schema) {
710
- if (!this.options.referenceTransformer) return ReferenceTransformer.toDeclaration(schema);
711
- return this.options.referenceTransformer(schema);
712
- }
713
- renderArray(schema) {
714
- if (schema.items && Array.isArray(schema.items)) return `[${schema.items.map((s) => this.renderSchema(s)).join(", ")}]`;
715
- if (schema.items && typeof schema.items === "object") return `${this.renderSchema(schema.items)}[]`;
716
- return "any[]";
717
- }
718
- renderObject(schema) {
719
- const hasProperties = schema.properties && !ramda.isEmpty(schema.properties);
720
- const apType = this.options.additionalPropertiesType ?? "unknown";
721
- if (!hasProperties) {
722
- if (schema.additionalProperties === false) return "Record<string, never>";
723
- if (typeof schema.additionalProperties === "object") return `Record<string, ${this.renderSchema(schema.additionalProperties)}>`;
724
- return `Record<string, ${apType}>`;
725
- }
726
- const $properties = Object.entries(schema.properties || {}).map(([propertyName, propertySchema]) => {
727
- let $comment = new CommentRenderer$1(propertySchema).render();
728
- if ($comment) $comment += "\n";
729
- const $key = `"${propertyName}"${schema.required?.includes(propertyName) ? "" : "?"}`;
730
- const $value = this.renderSchema(propertySchema);
731
- return indent(2, `${$comment}${$key}: ${$value}`);
732
- });
733
- if (schema.additionalProperties !== false) if (typeof schema.additionalProperties === "object") $properties.push(indent(2, `[key: string]: ${this.renderSchema(schema.additionalProperties)}`));
734
- else $properties.push(indent(2, `[key: string]: ${apType}`));
735
- return [
736
- "{",
737
- ...$properties,
738
- "}"
739
- ].join("\n");
740
- }
741
- renderOneOf(schema) {
742
- if (!schema.oneOf) return "unknown";
743
- return schema.oneOf.map((s) => this.renderSchema(s)).join(" | ");
744
- }
745
- renderAnyOf(schema) {
746
- if (!schema.anyOf) return "unknown";
747
- return schema.anyOf.map((s) => this.renderSchema(s)).join(" | ");
748
- }
749
- renderAllOf(schema) {
750
- if (!schema.allOf) return "unknown";
751
- return schema.allOf.map((s) => this.renderSchema(s)).join(" & ");
752
- }
753
- renderEnum(schema) {
754
- if (!schema.enum) return "unknown";
755
- return `(${schema.enum.map((v) => JSON.stringify(v)).join(" | ")})`;
756
- }
757
- renderString(schema) {
758
- if (schema.contentMediaType === "application/octet-stream") return "Blob | Buffer";
759
- if (schema.format === "binary") return "Blob | Buffer";
760
- return "string";
761
- }
762
- renderNumber(schema) {
763
- return "number";
764
- }
765
- renderBoolean(schema) {
766
- return "boolean";
767
- }
768
- renderNull(schema) {
769
- return "null";
770
- }
771
- renderInteger(schema) {
772
- return "number";
773
- }
774
- };
775
- //#endregion
776
- //#region src/transformers/json-schema/valibot.renderer.ts
777
- var ValibotRenderer = class {
778
- constructor(schema, options = {}) {
779
- this.schema = schema;
780
- this.options = options;
781
- }
782
- render() {
783
- return this.renderSchema(this.schema);
784
- }
785
- renderSchema(schema) {
786
- if (typeof schema === "boolean") return "v.unknown()";
787
- if (JsonSchemaUtils.isRef(schema)) return this.renderReference(schema);
788
- if (JsonSchemaUtils.isMixed(schema)) return this.renderMixed(schema);
789
- if (JsonSchemaUtils.isArray(schema)) return this.renderArray(schema);
790
- if (schema.type === "object") return this.renderObject(schema);
791
- if (schema.enum) return this.renderEnum(schema);
792
- if (schema.oneOf) return this.renderOneOf(schema);
793
- if (schema.anyOf) return this.renderAnyOf(schema);
794
- if (schema.allOf) return this.renderAllOf(schema);
795
- if (schema.type === "string") return this.renderString(schema);
796
- if (schema.type === "number") return this.renderNumber(schema);
797
- if (schema.type === "boolean") return this.renderBoolean(schema);
798
- if (schema.type === "null") return this.renderNull(schema);
799
- if (schema.type === "integer") return this.renderInteger(schema);
800
- return "v.unknown()";
801
- }
802
- renderMixed(schema) {
803
- if (Array.isArray(schema.type)) return `v.union([${schema.type.map((type) => ({
804
- ...schema,
805
- type
806
- })).map((schema) => this.renderSchema(schema)).join(", ")}])`;
807
- return "v.unknown()";
808
- }
809
- renderReference(schema) {
810
- if (!this.options.referenceTransformer) return ReferenceTransformer.toDeclaration(schema, (name) => `${name}Schema`);
811
- return this.options.referenceTransformer(schema);
812
- }
813
- renderArray(schema) {
814
- let result;
815
- if (schema.items && Array.isArray(schema.items)) result = `v.tuple([${schema.items.map((s) => this.renderSchema(s)).join(", ")}])`;
816
- else if (schema.items && typeof schema.items === "object") result = `v.array(${this.renderSchema(schema.items)})`;
817
- else result = "v.array(v.any())";
818
- const constraints = [];
819
- if (schema.minItems !== void 0) constraints.push(`v.minLength(${schema.minItems})`);
820
- if (schema.maxItems !== void 0) constraints.push(`v.maxLength(${schema.maxItems})`);
821
- if (constraints.length > 0) result = `v.pipe(${result}, ${constraints.join(", ")})`;
822
- return result;
823
- }
824
- renderObject(schema) {
825
- const hasProperties = schema.properties && !ramda.isEmpty(schema.properties);
826
- const apType = this.options.additionalPropertiesType ?? "unknown";
827
- if (!hasProperties) {
828
- if (schema.additionalProperties === false) return "v.object({})";
829
- if (typeof schema.additionalProperties === "object") return `v.record(v.string(), ${this.renderSchema(schema.additionalProperties)})`;
830
- return `v.record(v.string(), v.${apType}())`;
831
- }
832
- let result = [
833
- "v.object({",
834
- ...Object.entries(schema.properties || {}).map(([propertyName, propertySchema]) => {
835
- let $comment = new CommentRenderer$1(propertySchema).render();
836
- if ($comment) $comment += "\n";
837
- const $key = `"${propertyName}"`;
838
- let $value = this.renderSchema(propertySchema);
839
- if (!schema.required?.includes(propertyName)) $value = `v.optional(${$value})`;
840
- return indent(2, `${$comment}${$key}: ${$value},`);
841
- }),
842
- "})"
843
- ].join("\n");
844
- if (schema.additionalProperties !== false) if (typeof schema.additionalProperties === "object") {
845
- const $value = this.renderSchema(schema.additionalProperties);
846
- result = `v.intersect([${result}, v.record(v.string(), ${$value})])`;
847
- } else result = result.replace("v.object({", "v.looseObject({");
848
- return result;
849
- }
850
- renderOneOf(schema) {
851
- if (!schema.oneOf) return "v.unknown()";
852
- return `v.union([${schema.oneOf.map((s) => this.renderSchema(s)).join(", ")}])`;
853
- }
854
- renderAnyOf(schema) {
855
- if (!schema.anyOf) return "v.unknown()";
856
- return `v.union([${schema.anyOf.map((s) => this.renderSchema(s)).join(", ")}])`;
857
- }
858
- renderAllOf(schema) {
859
- if (!schema.allOf || schema.allOf.length === 0) return "v.unknown()";
860
- return `v.intersect([${schema.allOf.map((s) => this.renderSchema(s)).join(", ")}])`;
861
- }
862
- renderEnum(schema) {
863
- if (!schema.enum || schema.enum.length === 0) return "v.unknown()";
864
- if (schema.enum.length === 1) return `v.literal(${JSON.stringify(schema.enum[0])})`;
865
- if (schema.enum.every((v) => typeof v === "string")) return `v.picklist([${schema.enum.map((v) => JSON.stringify(v)).join(", ")}])`;
866
- return `v.union([${schema.enum.map((v) => `v.literal(${JSON.stringify(v)})`).join(", ")}])`;
867
- }
868
- renderString(schema) {
869
- if (schema.contentMediaType === "application/octet-stream") return "v.union([v.instance(Blob), v.instance(Buffer)])";
870
- if (schema.format === "binary") return "v.union([v.instance(Blob), v.instance(Buffer)])";
871
- let result = "v.string()";
872
- const constraints = [];
873
- if (schema.format === "email") constraints.push("v.email()");
874
- else if (schema.format === "uri" || schema.format === "url") constraints.push("v.url()");
875
- else if (schema.format === "uuid") constraints.push("v.uuid()");
876
- else if (schema.format === "date-time") constraints.push("v.isoDateTime()");
877
- else if (schema.format === "date") constraints.push("v.isoDate()");
878
- else if (schema.format === "time") constraints.push("v.isoTime()");
879
- if (schema.minLength !== void 0) constraints.push(`v.minLength(${schema.minLength})`);
880
- if (schema.maxLength !== void 0) constraints.push(`v.maxLength(${schema.maxLength})`);
881
- if (schema.pattern) {
882
- const escapedPattern = schema.pattern.replace(/\\/g, "\\\\");
883
- constraints.push(`v.regex(/${escapedPattern}/)`);
884
- }
885
- if (constraints.length > 0) result = `v.pipe(${result}, ${constraints.join(", ")})`;
886
- return result;
887
- }
888
- renderNumber(schema) {
889
- let result = "v.number()";
890
- const constraints = [];
891
- if (schema.minimum !== void 0) if (schema.exclusiveMinimum) constraints.push(`v.minValue(${schema.minimum + Number.EPSILON})`);
892
- else constraints.push(`v.minValue(${schema.minimum})`);
893
- if (schema.maximum !== void 0) if (schema.exclusiveMaximum) constraints.push(`v.maxValue(${schema.maximum - Number.EPSILON})`);
894
- else constraints.push(`v.maxValue(${schema.maximum})`);
895
- if (schema.multipleOf !== void 0) constraints.push(`v.multipleOf(${schema.multipleOf})`);
896
- if (constraints.length > 0) result = `v.pipe(${result}, ${constraints.join(", ")})`;
897
- return result;
898
- }
899
- renderBoolean(schema) {
900
- return "v.boolean()";
901
- }
902
- renderNull(schema) {
903
- return "v.null()";
904
- }
905
- renderInteger(schema) {
906
- let result = "v.number()";
907
- const constraints = ["v.integer()"];
908
- if (schema.minimum !== void 0) if (schema.exclusiveMinimum) constraints.push(`v.minValue(${schema.minimum + 1})`);
909
- else constraints.push(`v.minValue(${schema.minimum})`);
910
- if (schema.maximum !== void 0) if (schema.exclusiveMaximum) constraints.push(`v.maxValue(${schema.maximum - 1})`);
911
- else constraints.push(`v.maxValue(${schema.maximum})`);
912
- if (schema.multipleOf !== void 0) constraints.push(`v.multipleOf(${schema.multipleOf})`);
913
- result = `v.pipe(${result}, ${constraints.join(", ")})`;
914
- return result;
915
- }
916
- };
917
- //#endregion
918
- //#region src/transformers/json-schema/json-schema.transformer.ts
919
- var JsonSchemaTransformer = class {
920
- static toComment(schema) {
921
- return new CommentRenderer$1(schema).render();
922
- }
923
- static toDeclaration(schema, options) {
924
- return new DeclarationRenderer$1(schema, options).render();
925
- }
926
- static toValibot(schema, options) {
927
- return new ValibotRenderer(schema, options).render();
928
- }
929
- };
930
- //#endregion
931
- //#region src/transformers/schema-definition/schema-definition.transformer.ts
932
- var SchemaDefinitionTransformer = class {
933
- static toDeclaration(schemaDefinition, options) {
934
- const hint = `Referenced from schema definition "${schemaDefinition.name}".`;
935
- const referenceTransformer = (schema) => {
936
- if (!schema.$ref || !schema.$ref.startsWith("#")) return ReferenceTransformer.toInvalidDeclaration(schema, hint);
937
- if (!schemaDefinition.document.isRefDefined(schema.$ref)) return ReferenceTransformer.toNotFoundDeclaration(schema, hint);
938
- return ReferenceTransformer.toDeclaration(schema);
939
- };
940
- let $dependencies = schemaDefinition.getDependencies().filter((dep) => !SchemaDefinition.isUnknown(dep)).map((dep) => {
941
- const filepath = options.getDependentSchemaDefinitionFilepath(dep);
942
- return `import type { ${dep.name} } from "${filepath}"`;
943
- }).map((str) => str.replace(/ from "(\.\.?\/.+?)(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?"/, options.esm ? " from \"$1.js\"" : " from \"$1\"")).join("\n");
944
- if ($dependencies) $dependencies += "\n";
945
- let $comment = JsonSchemaTransformer.toComment(schemaDefinition.schema);
946
- if ($comment) $comment += "\n";
947
- if (typeof schemaDefinition.schema === "boolean") return [
948
- "/* @anchor:file:start */",
949
- "",
950
- $dependencies,
951
- $comment || void 0,
952
- `type ${schemaDefinition.name} = unknown`,
953
- "",
954
- "/* @anchor:file:end */"
955
- ].filter(ramda.isNotNil).join("\n");
956
- if (JsonSchemaUtils.isNonArray(schemaDefinition.schema) && schemaDefinition.schema.type === "object") {
957
- const $schema = JsonSchemaTransformer.toDeclaration(schemaDefinition.schema, {
958
- referenceTransformer,
959
- additionalPropertiesType: options.additionalPropertiesType
960
- });
961
- const $declaration = $schema.startsWith("{") ? `export interface ${schemaDefinition.name} ${$schema}` : `export type ${schemaDefinition.name} = ${$schema}`;
962
- return [
963
- "/* @anchor:file:start */",
964
- "",
965
- $dependencies,
966
- $comment || void 0,
967
- $declaration,
968
- "",
969
- "/* @anchor:file:end */"
970
- ].filter(ramda.isNotNil).join("\n");
971
- }
972
- return [
973
- "/* @anchor:file:start */",
974
- "",
975
- $dependencies,
976
- $comment || void 0,
977
- `export type ${schemaDefinition.name} = ${JsonSchemaTransformer.toDeclaration(schemaDefinition.schema, {
978
- referenceTransformer,
979
- additionalPropertiesType: options.additionalPropertiesType
980
- })}`,
981
- "",
982
- "/* @anchor:file:end */"
983
- ].filter(ramda.isNotNil).join("\n");
984
- }
985
- static toValibot(schemaDefinition, options) {
986
- const hint = `Referenced from schema definition "${schemaDefinition.name}".`;
987
- const referenceTransformer = (schema) => {
988
- if (!schema.$ref || !schema.$ref.startsWith("#")) return ReferenceTransformer.toInvalidDeclaration(schema, hint).replace(/^unknown/, "v.unknown()");
989
- if (!schemaDefinition.document.isRefDefined(schema.$ref)) return ReferenceTransformer.toNotFoundDeclaration(schema, hint).replace(/^unknown/, "v.unknown()");
990
- return `v.lazy(() => ${ReferenceTransformer.toDeclaration(schema, (name) => `${name}Schema`)})`;
991
- };
992
- const declarationReferenceTransformer = (schema) => {
993
- if (!schema.$ref || !schema.$ref.startsWith("#")) return ReferenceTransformer.toInvalidDeclaration(schema, hint);
994
- if (!schemaDefinition.document.isRefDefined(schema.$ref)) return ReferenceTransformer.toNotFoundDeclaration(schema, hint);
995
- return ReferenceTransformer.toDeclaration(schema);
996
- };
997
- let $dependencies = schemaDefinition.getDependencies().filter((dep) => !SchemaDefinition.isUnknown(dep)).map((dep) => {
998
- const filepath = options.getDependentSchemaDefinitionFilepath(dep);
999
- return `import { type ${dep.name}, ${dep.name}Schema } from "${filepath}"`;
1000
- }).map((str) => str.replace(/ from "(\.\.?\/.+?)(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?"/, options.esm ? " from \"$1.js\"" : " from \"$1\"")).join("\n");
1001
- if ($dependencies) $dependencies += "\n";
1002
- let $comment = JsonSchemaTransformer.toComment(schemaDefinition.schema);
1003
- if ($comment) $comment += "\n";
1004
- const $valibotImport = "import * as v from 'valibot'\n";
1005
- if (typeof schemaDefinition.schema === "boolean") return [
1006
- "/* @anchor:file:start */",
1007
- "",
1008
- $valibotImport,
1009
- $dependencies,
1010
- $comment || void 0,
1011
- `export const ${schemaDefinition.name}Schema = v.unknown()`,
1012
- `export type ${schemaDefinition.name} = v.InferOutput<typeof ${schemaDefinition.name}Schema>`,
1013
- "",
1014
- "/* @anchor:file:end */"
1015
- ].filter(ramda.isNotNil).join("\n");
1016
- const $schema = JsonSchemaTransformer.toValibot(schemaDefinition.schema, {
1017
- referenceTransformer,
1018
- additionalPropertiesType: options.additionalPropertiesType
1019
- });
1020
- const $typeSchema = JsonSchemaTransformer.toDeclaration(schemaDefinition.schema, {
1021
- referenceTransformer: declarationReferenceTransformer,
1022
- additionalPropertiesType: options.additionalPropertiesType
1023
- });
1024
- const $typeDeclaration = $typeSchema.startsWith("{") ? `export interface ${schemaDefinition.name} ${$typeSchema}` : `export type ${schemaDefinition.name} = ${$typeSchema}`;
1025
- return [
1026
- "/* @anchor:file:start */",
1027
- "",
1028
- $valibotImport,
1029
- $dependencies,
1030
- $comment || void 0,
1031
- $typeDeclaration,
1032
- `export const ${schemaDefinition.name}Schema: v.GenericSchema<${schemaDefinition.name}> = ${$schema}`,
1033
- "",
1034
- "/* @anchor:file:end */"
1035
- ].filter(ramda.isNotNil).join("\n");
1036
- }
1037
- };
1038
- //#endregion
1039
- //#region src/utils/import-alias-manager.ts
1040
- /**
1041
- * Manages import alias naming with collision detection for generated TypeScript files.
1042
- *
1043
- * When generating `import type { X as XSchema }` statements, the alias (e.g., `XSchema`)
1044
- * may collide with fixed names already present in the generated file (e.g., the file's own
1045
- * `export type` name). This class tracks all used names and automatically falls back to
1046
- * numbered suffixes (e.g., `XSchema$1`) when a collision is detected.
1047
- *
1048
- * Usage: call `register()` during import generation, then `resolve()` in referenceTransformer.
1049
- * `register()` must always be called before `resolve()` for the same dependency, because
1050
- * the first `register()` call determines the alias name.
1051
- */
1052
- var ImportAliasManager = class {
1053
- /** "category:originalName" → alias */
1054
- aliasMap = /* @__PURE__ */ new Map();
1055
- /** All alias names + reserved names currently in use */
1056
- usedNames = /* @__PURE__ */ new Set();
1057
- /**
1058
- * @param reservedNames - Fixed names in the generated file that aliases must not collide with.
1059
- * For example, the file's own export type name.
1060
- */
1061
- constructor(reservedNames = []) {
1062
- for (const name of reservedNames) this.usedNames.add(name);
1063
- }
1064
- /**
1065
- * Register a dependency and return its alias. Idempotent — calling with the same
1066
- * category + originalName always returns the same alias.
1067
- */
1068
- register(category, originalName) {
1069
- const key = `${category}:${originalName}`;
1070
- const existing = this.aliasMap.get(key);
1071
- if (existing) return existing;
1072
- let candidate = `${originalName}${category === "schema" ? "Schema" : "Response"}`;
1073
- if (this.usedNames.has(candidate)) {
1074
- let i = 1;
1075
- while (this.usedNames.has(`${candidate}$${i}`)) i++;
1076
- candidate = `${candidate}$${i}`;
1077
- }
1078
- this.aliasMap.set(key, candidate);
1079
- this.usedNames.add(candidate);
1080
- return candidate;
1081
- }
1082
- /**
1083
- * Look up alias for an already-registered dependency.
1084
- * Returns undefined if not yet registered.
1085
- */
1086
- resolve(category, originalName) {
1087
- return this.aliasMap.get(`${category}:${originalName}`);
1088
- }
1089
- };
1090
- //#endregion
1091
- //#region src/transformers/response-definition/response-definition.transformer.ts
1092
- var ResponseDefinitionTransformer = class ResponseDefinitionTransformer {
1093
- static toDeclaration(responseDefinition, options) {
1094
- const hint = `Referenced from response definition "${responseDefinition.name}".`;
1095
- const aliasManager = new ImportAliasManager([responseDefinition.name]);
1096
- let $dependencies = responseDefinition.getDependencies().filter((dep) => !SchemaDefinition.isUnknown(dep)).map((dep) => {
1097
- const filepath = options.getDependentSchemaDefinitionFilepath(dep);
1098
- return `import type { ${dep.name} as ${aliasManager.register("schema", dep.name)} } from "${filepath}"`;
1099
- }).map((str) => str.replace(/ from "(\.\.?\/.+?)(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?"/, options.esm ? " from \"$1.js\"" : " from \"$1\"")).join("\n");
1100
- if ($dependencies) $dependencies += "\n";
1101
- const referenceTransformer = (schema) => {
1102
- if (!schema.$ref || !schema.$ref.startsWith("#")) return ReferenceTransformer.toInvalidDeclaration(schema, hint);
1103
- if (!responseDefinition.document.isRefDefined(schema.$ref)) return ReferenceTransformer.toNotFoundDeclaration(schema, hint);
1104
- return ReferenceTransformer.toDeclaration(schema, (name) => aliasManager.resolve("schema", name) ?? `${name}Schema`);
1105
- };
1106
- const $type = ResponseDefinitionTransformer.renderContentType(responseDefinition.response, {
1107
- referenceTransformer,
1108
- additionalPropertiesType: options.additionalPropertiesType
1109
- });
1110
- return [
1111
- "/* @anchor:file:start */",
1112
- "",
1113
- $dependencies,
1114
- `export type ${responseDefinition.name} = ${$type}`,
1115
- "",
1116
- "/* @anchor:file:end */"
1117
- ].filter(ramda.isNotNil).join("\n");
1118
- }
1119
- static renderContentType(response, options) {
1120
- const content = response.content;
1121
- if (!content || ramda.isEmpty(content)) return "void";
1122
- return Object.entries(content).map(([mediaType, mediaTypeObject]) => {
1123
- if (mediaType.includes("text/event-stream")) return "ReadableStream<ServerSentEvent>";
1124
- if (mediaType.includes("multipart/form-data")) return "FormData";
1125
- if (!mediaTypeObject.schema) return "unknown";
1126
- return JsonSchemaTransformer.toDeclaration(mediaTypeObject.schema, options);
1127
- }).join(" | ") || "void";
1128
- }
1129
- };
1130
- //#endregion
1131
- //#region src/transformers/operation-definition/comment.renderer.ts
1132
- var CommentRenderer = class {
1133
- constructor(operationDefinition) {
1134
- this.operationDefinition = operationDefinition;
1135
- }
1136
- render() {
1137
- const operation = this.operationDefinition.operation;
1138
- if (!operation.summary && !operation.description) return "";
1139
- const lines = ["/**"];
1140
- if (operation.summary && typeof operation.summary === "string") {
1141
- const summary = ramda.trim(operation.summary).replace(/\t/g, " ").replace(/\r\n?/g, "\n");
1142
- lines.push(...summary.split("\n").map((line) => ` * ${line.trimEnd()}`));
1143
- lines.push(" *");
1144
- }
1145
- if (operation.description && typeof operation.description === "string") {
1146
- const descriptionLines = ramda.trim(operation.description).replace(/\t/g, " ").replace(/\r\n?/g, "\n").split("\n").map((line) => line.trimEnd());
1147
- lines.push(` * @description ${descriptionLines[0]}`);
1148
- lines.push(...descriptionLines.slice(1).map((line) => ` * ${line}`));
1149
- }
1150
- lines.push(" */");
1151
- return lines.join("\n");
1152
- }
1153
- };
1154
- //#endregion
1155
- //#region src/transformers/operation-definition/utils/type-name-factory.ts
1156
- function typeNameFactory(operationDefinition) {
1157
- const pascalCaseOperationId = change_case.pascalCase(operationDefinition.operationId);
1158
- return (name) => `${pascalCaseOperationId}${name}`;
1159
- }
1160
- //#endregion
1161
- //#region src/transformers/operation-definition/utils/rewrite-additional-properties-for-parameter.ts
1162
- const PARAMETER_AP_SCHEMAS = {
1163
- query: { oneOf: [
1164
- { type: "string" },
1165
- { type: "number" },
1166
- { type: "integer" },
1167
- { type: "null" }
1168
- ] },
1169
- path: { oneOf: [
1170
- { type: "string" },
1171
- { type: "number" },
1172
- { type: "integer" },
1173
- { type: "boolean" },
1174
- { type: "null" }
1175
- ] },
1176
- header: { oneOf: [
1177
- { type: "string" },
1178
- { type: "number" },
1179
- { type: "integer" }
1180
- ] }
1181
- };
1182
- /**
1183
- * Recursively rewrite `additionalProperties` in object schemas for parameter types.
1184
- * When additionalProperties is `true` or `undefined`, replace it with a keq-compatible schema
1185
- * based on the parameter location (query/path/header).
1186
- */
1187
- function rewriteAdditionalPropertiesForParameter(schema, parameterIn) {
1188
- if (JsonSchemaUtils.isRef(schema)) return schema;
1189
- if (typeof schema === "boolean") return schema;
1190
- const replacement = PARAMETER_AP_SCHEMAS[parameterIn];
1191
- if (!replacement) return schema;
1192
- const cloned = { ...schema };
1193
- if (cloned.type === "object" || cloned.properties) {
1194
- if (cloned.additionalProperties === true || cloned.additionalProperties === void 0) cloned.additionalProperties = replacement;
1195
- else if (typeof cloned.additionalProperties === "object" && !JsonSchemaUtils.isRef(cloned.additionalProperties)) cloned.additionalProperties = rewriteAdditionalPropertiesForParameter(cloned.additionalProperties, parameterIn);
1196
- }
1197
- if (cloned.properties) cloned.properties = Object.fromEntries(Object.entries(cloned.properties).map(([key, value]) => [key, rewriteAdditionalPropertiesForParameter(value, parameterIn)]));
1198
- if (cloned.items && typeof cloned.items === "object" && !Array.isArray(cloned.items)) cloned.items = rewriteAdditionalPropertiesForParameter(cloned.items, parameterIn);
1199
- for (const keyword of [
1200
- "allOf",
1201
- "oneOf",
1202
- "anyOf"
1203
- ]) if (cloned[keyword]) cloned[keyword] = cloned[keyword].map((s) => rewriteAdditionalPropertiesForParameter(s, parameterIn));
1204
- return cloned;
1205
- }
1206
- //#endregion
1207
- //#region src/utils/openapi-utils/dereference.ts
1208
- function dereference($ref, swagger) {
1209
- let value;
1210
- for (const key of $ref.split("/")) {
1211
- if (key === "#") value = swagger;
1212
- else value = value[key];
1213
- if (!value) break;
1214
- }
1215
- return value;
1216
- }
1217
- //#endregion
1218
- //#region src/utils/openapi-utils/is-ref-defined.ts
1219
- function isRefDefined($ref, swagger) {
1220
- if ($ref.startsWith("#/")) {
1221
- const path = $ref.replace("#/", "").split("/");
1222
- return ramda.path(path, swagger) !== void 0;
1223
- }
1224
- return false;
1225
- }
1226
- //#endregion
1227
- //#region src/utils/openapi-utils/remove-undefined-ref.ts
1228
- function removeUndefinedRef(swagger) {
1229
- const shadow = ramda.clone(swagger);
1230
- const matches = (0, jsonpath_plus.JSONPath)({
1231
- path: "$..*['$ref']^",
1232
- json: swagger,
1233
- resultType: "all"
1234
- });
1235
- for (const match of matches) if (match.value.$ref && !isRefDefined(match.value.$ref, swagger)) jsonpointer.default.set(shadow, match.pointer, ramda.omit(["$ref"], match.value));
1236
- return shadow;
1237
- }
1238
- //#endregion
1239
- //#region src/utils/openapi-utils/dereference-operation.ts
1240
- function dereferencePathObject(swagger) {
1241
- const matches = (0, jsonpath_plus.JSONPath)({
1242
- path: "$.paths.*.$ref^",
1243
- json: swagger,
1244
- resultType: "all"
1245
- });
1246
- for (const match of matches) {
1247
- const value = dereference(match.value.$ref, swagger);
1248
- jsonpointer.default.set(swagger, match.pointer, value);
1249
- }
1250
- }
1251
- function dereferenceRequestBody(swagger) {
1252
- const matches = (0, jsonpath_plus.JSONPath)({
1253
- path: "$.paths.*.*.requestBody.$ref^",
1254
- json: swagger,
1255
- resultType: "all"
1256
- });
1257
- for (const match of matches) {
1258
- const value = dereference(match.value.$ref, swagger);
1259
- jsonpointer.default.set(swagger, match.pointer, value);
1260
- }
1261
- }
1262
- function dereferenceResponses(swagger) {
1263
- const responseMatches = (0, jsonpath_plus.JSONPath)({
1264
- path: "$.paths.*.*.responses.*.$ref^",
1265
- json: swagger,
1266
- resultType: "all"
1267
- });
1268
- for (const match of responseMatches) if (match.value.$ref && !match.value.$ref.startsWith("#/components/responses/")) {
1269
- const value = dereference(match.value.$ref, swagger);
1270
- jsonpointer.default.set(swagger, match.pointer, value);
1271
- }
1272
- const headerMatches = (0, jsonpath_plus.JSONPath)({
1273
- path: "$.paths.*.*.responses.*.headers.*.$ref^",
1274
- json: swagger,
1275
- resultType: "all"
1276
- });
1277
- for (const match of headerMatches) {
1278
- const value = dereference(match.value.$ref, swagger);
1279
- jsonpointer.default.set(swagger, match.pointer, value);
1280
- }
1281
- }
1282
- function dereferenceParameters(swagger) {
1283
- const matches = (0, jsonpath_plus.JSONPath)({
1284
- path: "$.paths.*.*.parameters.*.$ref^",
1285
- json: swagger,
1286
- resultType: "all"
1287
- });
1288
- for (const match of matches) {
1289
- const value = dereference(match.value.$ref, swagger);
1290
- jsonpointer.default.set(swagger, match.pointer, value);
1291
- }
1292
- }
1293
- function dereferenceOperation(swagger) {
1294
- const shadow = ramda.clone(swagger);
1295
- dereferencePathObject(shadow);
1296
- dereferenceRequestBody(shadow);
1297
- dereferenceResponses(shadow);
1298
- dereferenceParameters(shadow);
1299
- return removeUndefinedRef(shadow);
1300
- }
1301
- //#endregion
1302
- //#region src/utils/openapi-utils/dereference-deep.ts
1303
- function dereferenceDeep($ref, swagger) {
1304
- const stack = [$ref];
1305
- let value;
1306
- while (true) {
1307
- const last = stack[stack.length - 1];
1308
- value = dereference(last, swagger);
1309
- if (JsonSchemaUtils.isRef(value)) if (!stack.includes(value.$ref)) {
1310
- stack.push(value.$ref);
1311
- continue;
1312
- } else throw new Error(`Circular reference detected: ${stack.join(" -> ")} -> ${value.$ref}`);
1313
- break;
1314
- }
1315
- return value;
1316
- }
1317
- //#endregion
1318
- //#region src/utils/openapi-utils/to-3_1.ts
1319
- function To3_1(openapi) {
1320
- const { specification } = (0, _scalar_openapi_parser.upgrade)(openapi);
1321
- return specification;
1322
- }
1323
- //#endregion
1324
- //#region src/utils/openapi-utils/map-operation.ts
1325
- function mapOperation(specification, mapper) {
1326
- const shadow = ramda.clone(specification);
1327
- for (const [pathname, pathItem] of Object.entries(shadow.paths || {})) for (const m in pathItem) {
1328
- const method = m.toLowerCase();
1329
- if (!SupportedMethods.includes(method)) continue;
1330
- if (typeof pathItem[m] !== "object" || Array.isArray(pathItem[m]) || pathItem[m] === null) continue;
1331
- const operation = pathItem[m];
1332
- pathItem[m] = mapper(method, pathname, operation);
1333
- }
1334
- return shadow;
1335
- }
1336
- //#endregion
1337
- //#region src/utils/openapi-utils/map-parameter.ts
1338
- function mapParameter(specification, mapper) {
1339
- return mapOperation(specification, (method, pathname, operation) => {
1340
- if (!operation.parameters) return operation;
1341
- operation.parameters = operation.parameters.map((parameter) => mapper(method, pathname, operation, parameter));
1342
- return operation;
1343
- });
1344
- }
1345
- //#endregion
1346
- //#region src/utils/openapi-utils/map-schema.ts
1347
- function walkSchema(schema, mapper) {
1348
- if (!schema) return schema;
1349
- if (typeof schema === "boolean") return schema;
1350
- if ("$ref" in schema) return schema;
1351
- let result = mapper(schema);
1352
- if (result.properties) {
1353
- const newProperties = {};
1354
- for (const [key, value] of Object.entries(result.properties)) newProperties[key] = walkSchema(value, mapper);
1355
- result = Object.assign({}, result, { properties: newProperties });
1356
- }
1357
- if (typeof result.additionalProperties === "object" && result.additionalProperties !== null && !("$ref" in result.additionalProperties)) result = Object.assign({}, result, { additionalProperties: walkSchema(result.additionalProperties, mapper) });
1358
- if ("items" in result && result.items && typeof result.items === "object" && !Array.isArray(result.items)) result = Object.assign({}, result, { items: walkSchema(result.items, mapper) });
1359
- for (const keyword of [
1360
- "allOf",
1361
- "oneOf",
1362
- "anyOf"
1363
- ]) if (result[keyword]) result = Object.assign({}, result, { [keyword]: result[keyword].map((s) => walkSchema(s, mapper)) });
1364
- return result;
1365
- }
1366
- function walkMediaTypeSchemas(content, mapper) {
1367
- if (!content) return;
1368
- for (const mediaType of Object.values(content)) if (mediaType.schema) mediaType.schema = walkSchema(mediaType.schema, mapper);
1369
- }
1370
- /**
1371
- * Recursively walk and transform every non-`$ref` schema in an OpenAPI 3.1 document.
1372
- *
1373
- * Returns a **deep clone** of the document — the original is never mutated.
1374
- * The `mapper` is called on each `SchemaObject` (skipping `$ref` and `boolean` schemas),
1375
- * and then `mapSchema` continues into the mapper's return value to process nested schemas
1376
- * (`properties`, `additionalProperties`, `items`, `allOf`/`oneOf`/`anyOf`).
1377
- *
1378
- * Traversal covers:
1379
- * - `components.schemas`
1380
- * - Inline schemas in operation parameters, request bodies, and responses
1381
- *
1382
- * @example
1383
- * // Set `additionalProperties: false` on every object schema that doesn't define it
1384
- * const patched = mapSchema(doc, (schema) => {
1385
- * if ((schema.type === 'object' || schema.properties) && schema.additionalProperties === undefined) {
1386
- * return Object.assign({}, schema, { additionalProperties: false })
1387
- * }
1388
- * return schema
1389
- * })
1390
- *
1391
- * @example
1392
- * // Add a `description` fallback to all string schemas
1393
- * const annotated = mapSchema(doc, (schema) => {
1394
- * if (schema.type === 'string' && !schema.description) {
1395
- * return Object.assign({}, schema, { description: 'No description provided' })
1396
- * }
1397
- * return schema
1398
- * })
1399
- */
1400
- function mapSchema(specification, mapper) {
1401
- const shadow = ramda.clone(specification);
1402
- if (shadow.components?.schemas) for (const [name, schema] of Object.entries(shadow.components.schemas)) shadow.components.schemas[name] = walkSchema(schema, mapper);
1403
- for (const [, pathItem] of Object.entries(shadow.paths || {})) for (const m in pathItem) {
1404
- const method = m.toLowerCase();
1405
- if (!SupportedMethods.includes(method)) continue;
1406
- if (typeof pathItem[m] !== "object" || Array.isArray(pathItem[m]) || pathItem[m] === null) continue;
1407
- const operation = pathItem[m];
1408
- if (operation.parameters) for (const param of operation.parameters) {
1409
- if ("$ref" in param) continue;
1410
- if (param.schema) param.schema = walkSchema(param.schema, mapper);
1411
- }
1412
- if (operation.requestBody && !("$ref" in operation.requestBody)) walkMediaTypeSchemas(operation.requestBody.content, mapper);
1413
- if (operation.responses) for (const response of Object.values(operation.responses)) {
1414
- if ("$ref" in response) continue;
1415
- walkMediaTypeSchemas(response.content, mapper);
1416
- }
1417
- }
1418
- return shadow;
1419
- }
1420
- //#endregion
1421
- //#region src/utils/openapi-utils/index.ts
1422
- var OpenapiUtils = class {
1423
- static isRefDefined = isRefDefined;
1424
- static dereference = dereference;
1425
- static dereferenceDeep = dereferenceDeep;
1426
- static removeUndefinedRef = removeUndefinedRef;
1427
- static dereferenceOperation = dereferenceOperation;
1428
- static mapOperation = mapOperation;
1429
- static mapParameter = mapParameter;
1430
- static mapSchema = mapSchema;
1431
- static to3_1 = To3_1;
1432
- };
1433
- //#endregion
1434
- //#region src/transformers/operation-definition/declaration.renderer.ts
1435
- const alias = (name) => `${name}Schema`;
1436
- const responseAlias = (name) => `${name}Response`;
1437
- var DeclarationRenderer = class {
1438
- typeName;
1439
- constructor(operationDefinition, options) {
1440
- this.operationDefinition = operationDefinition;
1441
- this.options = options;
1442
- this.typeName = typeNameFactory(operationDefinition);
1443
- }
1444
- renderResponseBodies(operation, options) {
1445
- if (!operation.responses || ramda.isEmpty(operation.responses)) return `export interface ${this.typeName("ResponseBodies")} {}`;
1446
- const $responses = Object.entries(operation.responses).map(([statusCode, response]) => {
1447
- if (JsonSchemaUtils.isRef(response)) return indent(2, `${statusCode}: ${responseAlias(response.$ref.split("/").pop() || "")}`);
1448
- return indent(2, `${statusCode}: ${Object.entries(response.content || {}).map(([mediaType, mediaTypeObject]) => [mediaType, mediaTypeObject.schema]).map(([mediaType, schema]) => {
1449
- if (mediaType.includes("text/event-stream")) return "ReadableStream<ServerSentEvent>";
1450
- if (mediaType.includes("multipart/form-data")) return "FormData";
1451
- if (!schema) return "unknown";
1452
- return JsonSchemaTransformer.toDeclaration(schema, options);
1453
- }).join(" | ") || "void"}`);
1454
- }).join("\n");
1455
- return [
1456
- `export interface ${this.typeName("ResponseBodies")} {`,
1457
- $responses,
1458
- "}"
1459
- ].join("\n");
1460
- }
1461
- renderRequestBodies(operation, options) {
1462
- let $requestBodies = `export interface ${this.typeName("RequestBodies")} {}`;
1463
- if (operation.requestBody && !JsonSchemaUtils.isRef(operation.requestBody)) {
1464
- const $mediaTypes = Object.entries(operation.requestBody.content || {}).map(([mediaType, mediaTypeObject]) => [mediaType, mediaTypeObject.schema]).map(([mediaType, schema]) => {
1465
- if (!schema) return `${JSON.stringify(mediaType)}: unknown`;
1466
- return `${JSON.stringify(mediaType)}: ${JsonSchemaTransformer.toDeclaration(schema, options)}`;
1467
- }).map((pair) => indent(2, pair));
1468
- $requestBodies = [
1469
- `export interface ${this.typeName("RequestBodies")} {`,
1470
- ...$mediaTypes,
1471
- "}"
1472
- ].join("\n");
1473
- }
1474
- return $requestBodies;
1475
- }
1476
- renderParameterBodies(operationDefinition, options) {
1477
- const { operation } = operationDefinition;
1478
- let parameterBodies = "";
1479
- if (operation.requestBody && !JsonSchemaUtils.isRef(operation.requestBody)) {
1480
- const $mediaTypes = Object.entries(operation.requestBody.content || {}).map(([mediaType, mediaTypeObject]) => [mediaType, mediaTypeObject.schema]).map(([mediaType, schemaOrRef]) => {
1481
- if (!schemaOrRef) return `${JSON.stringify(mediaType)}: unknown`;
1482
- const schema = JsonSchemaUtils.isRef(schemaOrRef) ? OpenapiUtils.dereferenceDeep(schemaOrRef.$ref, operationDefinition.document.specification) : schemaOrRef;
1483
- if (schema.type === "object" || schema.properties) return `${JSON.stringify(mediaType)}: ${JsonSchemaTransformer.toDeclaration(schemaOrRef, options)} & { [key: string]: any }`;
1484
- return `${JSON.stringify(mediaType)}: { [key: string]: any }`;
1485
- }).map((pair) => indent(2, pair));
1486
- parameterBodies = [
1487
- `interface ${this.typeName("ParameterBodies")} {`,
1488
- ...$mediaTypes,
1489
- "}",
1490
- ""
1491
- ].join("\n");
1492
- }
1493
- return parameterBodies;
1494
- }
1495
- renderRequestParameters(operation, options) {
1496
- const mediaTypes = operation.requestBody && !JsonSchemaUtils.isRef(operation.requestBody) ? Object.keys(operation.requestBody.content || {}) : [];
1497
- const base = `${this.typeName("RequestQuery")} & ${this.typeName("RouteParameters")} & ${this.typeName("RequestHeaders")}`;
1498
- if (mediaTypes.length === 1) return `export type ${this.typeName("RequestParameters")} = ${base} & ${this.typeName("RequestBodies")}[${JSON.stringify(mediaTypes[0])}]`;
1499
- if (mediaTypes.length > 1) {
1500
- const unions = mediaTypes.map((mediaType) => `(${base} & ${this.typeName("RequestBodies")}[${JSON.stringify(mediaType)}] & { "content-type": ${JSON.stringify(mediaType)} })`).join("\n| ");
1501
- return `export type ${this.typeName("RequestParameters")} = ${unions}`;
1502
- }
1503
- return `export type ${this.typeName("RequestParameters")} = ${base}`;
1504
- }
1505
- rendererParameters(name, parameters, options) {
1506
- if (parameters.length === 0) return `export type ${name} = {}`;
1507
- const $parameters = parameters.map((parameter) => {
1508
- const parameterName = `"${parameter.name}"`;
1509
- const $key = parameter.required ? parameterName : `${parameterName}?`;
1510
- const schema = parameter.schema ? rewriteAdditionalPropertiesForParameter(parameter.schema, parameter.in) : { type: "any" };
1511
- return indent(2, `${$key}: ${JsonSchemaTransformer.toDeclaration(schema, options)}`);
1512
- }).join("\n");
1513
- return [
1514
- `export type ${name} = {`,
1515
- $parameters,
1516
- "}"
1517
- ].filter(Boolean).join("\n");
1518
- }
1519
- renderDependencies() {
1520
- const $schemaDefinitions = this.operationDefinition.getDependencies().filter((schemaDefinition) => !SchemaDefinition.isUnknown(schemaDefinition)).map((schemaDefinition) => {
1521
- const filepath = this.options.getDependentSchemaDefinitionFilepath(schemaDefinition);
1522
- const schemaName = schemaDefinition.name;
1523
- return `import type { ${schemaName} as ${alias(schemaName)} } from "${filepath}"`;
1524
- }).map((str) => str.replace(/ from "(\.\.?\/.+?)(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?"/, this.options.esm ? " from \"$1.js\"" : " from \"$1\""));
1525
- const $responseDefinitions = this.operationDefinition.getResponseDependencies().filter((responseDefinition) => !ResponseDefinition.isUnknown(responseDefinition)).map((responseDefinition) => {
1526
- const filepath = this.options.getDependentResponseDefinitionFilepath(responseDefinition);
1527
- const responseName = responseDefinition.name;
1528
- return `import type { ${responseName} as ${responseAlias(responseName)} } from "${filepath}"`;
1529
- }).map((str) => str.replace(/ from "(\.\.?\/.+?)(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?"/, this.options.esm ? " from \"$1.js\"" : " from \"$1\""));
1530
- return [
1531
- "import type { KeqOperation, KeqPathParameterInit, KeqQueryInit, ServerSentEvent } from \"keq\"",
1532
- ...$schemaDefinitions,
1533
- ...$responseDefinitions
1534
- ].join("\n");
1535
- }
1536
- render() {
1537
- const { operation } = this.operationDefinition;
1538
- if (!operation.responses) return "";
1539
- const hint = `Referenced from operation "${this.operationDefinition.method.toUpperCase()} ${this.operationDefinition.pathname}".`;
1540
- const jsonSchemaDeclarationRendererOptions = {
1541
- referenceTransformer: (schema) => {
1542
- if (schema.$ref && schema.$ref.startsWith("#") && !this.operationDefinition.document.isRefDefined(schema.$ref)) return ReferenceTransformer.toNotFoundDeclaration(schema, hint);
1543
- return ReferenceTransformer.toDeclaration(schema, alias);
1544
- },
1545
- additionalPropertiesType: this.options.additionalPropertiesType
1546
- };
1547
- const $dependencies = this.renderDependencies();
1548
- const $responseBodies = this.renderResponseBodies(operation, jsonSchemaDeclarationRendererOptions);
1549
- const $requestBodies = this.renderRequestBodies(operation, jsonSchemaDeclarationRendererOptions);
1550
- const $parameterBodies = this.renderParameterBodies(this.operationDefinition, jsonSchemaDeclarationRendererOptions);
1551
- const $requestParameters = this.renderRequestParameters(operation, jsonSchemaDeclarationRendererOptions);
1552
- return [
1553
- "/* @anchor:file:start */",
1554
- "",
1555
- $dependencies,
1556
- "",
1557
- $responseBodies,
1558
- "",
1559
- $requestBodies,
1560
- "",
1561
- this.rendererParameters(`${this.typeName("RequestQuery")}`, operation.parameters?.filter((p) => !JsonSchemaUtils.isRef(p) && p.in === "query") || [], jsonSchemaDeclarationRendererOptions),
1562
- "",
1563
- this.rendererParameters(`${this.typeName("RouteParameters")}`, operation.parameters?.filter((p) => !JsonSchemaUtils.isRef(p) && p.in === "path") || [], jsonSchemaDeclarationRendererOptions),
1564
- "",
1565
- this.rendererParameters(`${this.typeName("RequestHeaders")}`, operation.parameters?.filter((p) => !JsonSchemaUtils.isRef(p) && p.in === "header") || [], jsonSchemaDeclarationRendererOptions),
1566
- "",
1567
- $parameterBodies || void 0,
1568
- $requestParameters,
1569
- "",
1570
- `export interface ${this.typeName("Operation")}<STATUS extends keyof ${this.typeName("ResponseBodies")}, CONTENT_TYPE extends ${$parameterBodies ? `keyof ${this.typeName("ParameterBodies")}` : "string"} > extends KeqOperation {`,
1571
- ` requestParams: ${this.typeName("RouteParameters")} & { [key: string]: KeqPathParameterInit }`,
1572
- ` requestQuery: ${this.typeName("RequestQuery")} & { [key: string]: KeqQueryInit }`,
1573
- ` requestHeaders: ${this.typeName("RequestHeaders")} & { [key: string]: string | number }`,
1574
- ` requestBody: ${$parameterBodies ? `${this.typeName("ParameterBodies")}[CONTENT_TYPE] | ` : "object | "}BodyInit`,
1575
- ` responseBody: ${this.typeName("ResponseBodies")}[STATUS]`,
1576
- "}",
1577
- "",
1578
- "/* @anchor:file:end */"
1579
- ].filter(ramda.isNotNil).join("\n");
1580
- }
1581
- };
1582
- //#endregion
1583
- //#region src/utils/to-safe-identifier.ts
1584
- /**
1585
- * Check if a string is a valid JavaScript/TypeScript identifier.
1586
- */
1587
- function isValidIdentifier(str) {
1588
- return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(str);
1589
- }
1590
- /**
1591
- * Convert a string to a valid JavaScript/TypeScript identifier.
1592
- * If the string is already a valid identifier, return it as-is.
1593
- * Otherwise, convert it to camelCase and ensure it starts with a valid character.
1594
- */
1595
- function toSafeIdentifier(str) {
1596
- if (isValidIdentifier(str)) return str;
1597
- const camelCased = change_case.camelCase(str);
1598
- if (!camelCased) return `_${str.replace(/[^a-zA-Z0-9_$]/g, "_")}`;
1599
- if (/^[0-9]/.test(camelCased)) return `_${camelCased}`;
1600
- if (!isValidIdentifier(camelCased)) return `_${camelCased.replace(/[^a-zA-Z0-9_$]/g, "_")}`;
1601
- return camelCased;
1602
- }
1603
- //#endregion
1604
- //#region src/exception.ts
1605
- var Exception = class extends ts_custom_error.CustomError {
1606
- constructor(module, message) {
1607
- const moduleName = typeof module === "string" ? module : module.name;
1608
- const msg = (0, word_wrap.default)(message, {
1609
- width: 60,
1610
- indent: " "
1611
- });
1612
- super(`${moduleName} module failed to compile:\n${msg}`);
1613
- Object.defineProperty(this, "name", { value: "KeqCLI_Exception" });
1614
- }
1615
- };
1616
- //#endregion
1617
- //#region src/transformers/operation-definition/typescript-snippet.ts
1618
- var OperationDefinitionSnippet = class {
1619
- typeName;
1620
- constructor(operationDefinition, options) {
1621
- this.operationDefinition = operationDefinition;
1622
- this.options = options;
1623
- this.typeName = typeNameFactory(operationDefinition);
1624
- }
1625
- getQsParameters(parameter) {
1626
- let arrayFormat;
1627
- let allowDots;
1628
- let indices;
1629
- const style = parameter.style || "form";
1630
- const explode = parameter.explode ?? true;
1631
- if ("x-qs-array-format" in parameter) arrayFormat = parameter["x-qs-array-format"];
1632
- else if (style === "deepObject") arrayFormat = "brackets";
1633
- else if (explode) arrayFormat = "repeat";
1634
- else if (style === "form") arrayFormat = "comma";
1635
- else if (style === "spaceDelimited") arrayFormat = "space";
1636
- else if (style === "pipeDelimited") arrayFormat = "pipe";
1637
- if ("x-qs-allow-dots" in parameter) allowDots = Boolean(parameter["x-qs-allow-dots"]);
1638
- if ("x-qs-indices" in parameter) indices = Boolean(parameter["x-qs-indices"]);
1639
- if (arrayFormat || allowDots !== void 0 || indices !== void 0) return {
1640
- ...arrayFormat ? { arrayFormat } : {},
1641
- ...allowDots !== void 0 ? { allowDots } : {},
1642
- ...indices !== void 0 ? { indices } : {}
1643
- };
1644
- }
1645
- renderRequestHeaders() {
1646
- const { operation } = this.operationDefinition;
1647
- return (operation.parameters || []).filter((p) => !JsonSchemaUtils.isRef(p)).filter((p) => p.in === "header").map((p) => `if (args && ${JSON.stringify(p.name)} in args) req.header(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}])`).join("\n");
1648
- }
1649
- renderRequestQuery() {
1650
- const { operation } = this.operationDefinition;
1651
- return (operation.parameters || []).filter((p) => !JsonSchemaUtils.isRef(p)).filter((p) => p.in === "query").map((p) => {
1652
- const option = this.getQsParameters(p);
1653
- const $option = !option || ramda.isEmpty(option) ? "" : `, ${JSON.stringify(option)}`;
1654
- return `if (args && ${JSON.stringify(p.name)} in args) req.query(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}]${$option})`;
1655
- }).join("\n");
1656
- }
1657
- renderRequestPathParameters() {
1658
- const { operation } = this.operationDefinition;
1659
- return (operation.parameters || []).filter((p) => !JsonSchemaUtils.isRef(p)).filter((p) => p.in === "path").map((p) => `if (args && ${JSON.stringify(p.name)} in args) req.params(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}])`).join("\n");
1660
- }
1661
- getRequestMediaTypes() {
1662
- const { operation } = this.operationDefinition;
1663
- const requestBodyContent = operation.requestBody?.content || {};
1664
- return Object.keys(requestBodyContent);
1665
- }
1666
- renderMediaType() {
1667
- const mediaTypes = this.getRequestMediaTypes();
1668
- if (mediaTypes.length === 1 && !mediaTypes[0].endsWith("/*")) return `req.type("${mediaTypes[0]}")\n`;
1669
- else if (mediaTypes.some((mediaType) => mediaType === "*/*")) {} else if (mediaTypes.some((mediaType) => mediaType.endsWith("/*"))) return "if(args?.[\"content-type\"]) req.type(args[\"content-type\"])\n";
1670
- else if (mediaTypes.length > 1) return "if(args?.[\"content-type\"]) req.type(args[\"content-type\"])\n";
1671
- return "";
1672
- }
1673
- requestBodyFormDataPropertyRenderer(propertyName, propertySchema, mediaType) {
1674
- try {
1675
- const $propertyName = JSON.stringify(propertyName);
1676
- const schema = JsonSchemaUtils.isRef(propertySchema) ? OpenapiUtils.dereferenceDeep(propertySchema.$ref, this.operationDefinition.document.specification) : propertySchema;
1677
- if (schema.type === "string" && schema.format === "binary" || schema.contentMediaType === "application/octet-stream") return `if (args && ${$propertyName} in args && args[${$propertyName}]) req.attach(${$propertyName}, args[${$propertyName}])`;
1678
- else if (schema.type === "string" || schema.type === "array" && schema.items && schema.items.type === "string") return `if (args && ${$propertyName} in args && args[${$propertyName}] !== undefined) req.field(${$propertyName}, args[${$propertyName}])`;
1679
- else if (schema.type === "number" || schema.type === "integer") return `if (args && ${$propertyName} in args && args[${$propertyName}] !== undefined) req.field(${$propertyName}, String(args[${$propertyName}]))`;
1680
- return `if (args && ${$propertyName} in args && args[${$propertyName}] !== undefined) req.field(${$propertyName}, String(args[${$propertyName}]) /* type is non-string in schema; triggers type coercion here */)`;
1681
- } catch (err) {
1682
- return this.renderErrorComment(err, mediaType);
1683
- }
1684
- }
1685
- requestBodyPropertyRenderer(propertyName, propertySchema, mediaType) {
1686
- if (mediaType === "application/json") {
1687
- const $propertyName = JSON.stringify(propertyName);
1688
- return `if (args && ${$propertyName} in args) req.send({ ${$propertyName}: args[${$propertyName}] })`;
1689
- } else if (mediaType === "multipart/form-data") return this.requestBodyFormDataPropertyRenderer(propertyName, propertySchema, mediaType);
1690
- else throw new Error(`Unsupported media type: ${mediaType}`);
1691
- }
1692
- renderRequestBody() {
1693
- const { operation } = this.operationDefinition;
1694
- const requestBodyContent = operation.requestBody?.content || {};
1695
- return Object.entries(requestBodyContent).map(([mediaType, mediaTypeObject]) => {
1696
- if (!mediaTypeObject.schema) return;
1697
- try {
1698
- const schema = JsonSchemaUtils.isRef(mediaTypeObject.schema) ? OpenapiUtils.dereferenceDeep(mediaTypeObject.schema.$ref, this.operationDefinition.document.specification) : mediaTypeObject.schema;
1699
- if (schema.type !== "object") return;
1700
- const properties = schema.properties || {};
1701
- return Object.entries(properties).map(([propertyName, propertySchema]) => this.requestBodyPropertyRenderer(propertyName, propertySchema, mediaType)).join("\n");
1702
- } catch (err) {
1703
- return this.renderErrorComment(err, mediaType);
1704
- }
1705
- }).filter(ramda.isNotNil).join("\n");
1706
- }
1707
- renderErrorComment(err, mediaType) {
1708
- const $err = String(err).split("\n").map(((line) => ` * ${line}`)).join("\n");
1709
- return [
1710
- "/**",
1711
- ` * Unable to dereference schema for media type ${mediaType}`,
1712
- $err,
1713
- " */"
1714
- ].join("\n");
1715
- }
1716
- };
1717
- //#endregion
1718
- //#region src/transformers/operation-definition/micro-function.renderer.ts
1719
- var OperationDefinitionMicroFunctionRenderer = class {
1720
- helper;
1721
- typeName;
1722
- constructor(operationDefinition, options) {
1723
- this.operationDefinition = operationDefinition;
1724
- this.options = options;
1725
- this.typeName = typeNameFactory(operationDefinition);
1726
- this.helper = new OperationDefinitionSnippet(operationDefinition, options);
1727
- }
1728
- get operationId() {
1729
- return toSafeIdentifier(this.operationDefinition.operationId);
1730
- }
1731
- render() {
1732
- const { operation, method, pathname } = this.operationDefinition;
1733
- if (!operation.responses) return "";
1734
- const operationId = this.operationId;
1735
- const $dependencies = this.renderDependencies();
1736
- const $comment = new CommentRenderer(this.operationDefinition).render();
1737
- const $method = method.toLowerCase();
1738
- const $queryParameters = this.helper.renderRequestQuery();
1739
- const $headerParameters = this.helper.renderRequestHeaders();
1740
- const $pathParameters = this.helper.renderRequestPathParameters();
1741
- const $mediaType = this.helper.renderMediaType();
1742
- const $requestBody = this.helper.renderRequestBody();
1743
- const $operationDeclaration = this.renderOperationDeclaration();
1744
- return [
1745
- "/* @anchor:file:start */",
1746
- "",
1747
- $dependencies,
1748
- "",
1749
- `const method = "${method}"`,
1750
- `const pathname = "${pathname}"`,
1751
- "",
1752
- $comment || void 0,
1753
- `export ${$operationDeclaration} {`,
1754
- ` const req = request.${$method}<${this.typeName("ResponseBodies")}[STATUS]>("${pathname}")`,
1755
- "",
1756
- $mediaType ? indent(2, $mediaType) : void 0,
1757
- " /* @anchor:query:start */",
1758
- $queryParameters ? indent(2, $queryParameters) : void 0,
1759
- " /* @anchor:query:end */",
1760
- "",
1761
- " /* @anchor:headers:start */",
1762
- $headerParameters ? indent(2, $headerParameters) : void 0,
1763
- " /* @anchor:headers:end */",
1764
- "",
1765
- " /* @anchor:path-parameters:start */",
1766
- $pathParameters ? indent(2, $pathParameters) : void 0,
1767
- " /* @anchor:path-parameters:end */",
1768
- "",
1769
- " /* @anchor:body:start */",
1770
- $requestBody ? indent(2, $requestBody) : void 0,
1771
- " /* @anchor:body:end */",
1772
- "",
1773
- " /* @anchor:operation-return */",
1774
- ` return req as ReturnType<typeof ${operationId}<STATUS${$operationDeclaration.includes("CONTENT_TYPE") ? ", CONTENT_TYPE" : ""}>>`,
1775
- "}",
1776
- "",
1777
- `${operationId}.pathname = pathname`,
1778
- `${operationId}.method = method`,
1779
- "/* @anchor:file:end */"
1780
- ].filter(ramda.isNotNil).join("\n");
1781
- }
1782
- renderDependencies() {
1783
- const declarationFilepath = this.options.getOperationDefinitionDeclarationFilepath(this.operationDefinition);
1784
- return [
1785
- "import { Keq } from \"keq\"",
1786
- `import { request } from "${this.options.getRequestFilepath()}"`,
1787
- `import type { ${this.typeName("Operation")}, ${this.typeName("ResponseBodies")}, ${this.typeName("RequestParameters")} } from "${declarationFilepath}"`,
1788
- `export type { ${this.typeName("RequestQuery")}, ${this.typeName("RequestHeaders")}, ${this.typeName("RequestBodies")} } from "${declarationFilepath}"`
1789
- ].map((str) => str.replace(/ from "(\.\.?\/.+?)(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?"/, this.options.esm ? " from \"$1.js\"" : " from \"$1\"")).join("\n");
1790
- }
1791
- renderOperationDeclaration() {
1792
- const operationId = this.operationId;
1793
- const mediaTypes = this.helper.getRequestMediaTypes();
1794
- if (mediaTypes.length === 0) return `function ${operationId}<STATUS extends keyof ${this.typeName("ResponseBodies")}, CONTENT_TYPE extends never = never>(args?: ${this.typeName("RequestParameters")}): Keq<${this.typeName("Operation")}<STATUS, CONTENT_TYPE>>`;
1795
- else if (mediaTypes.length === 1) return `function ${operationId}<STATUS extends keyof ${this.typeName("ResponseBodies")}, CONTENT_TYPE extends ${JSON.stringify(mediaTypes[0])} = ${JSON.stringify(mediaTypes[0])}>(args?: ${this.typeName("RequestParameters")}): Keq<${this.typeName("Operation")}<STATUS, CONTENT_TYPE>>`;
1796
- else if (mediaTypes.length > 1) return `function ${operationId}<STATUS extends keyof ${this.typeName("ResponseBodies")}, CONTENT_TYPE extends ${this.typeName("RequestParameters")}["content-type"]>(args?: Extract<${this.typeName("RequestParameters")}, { "content-type": CONTENT_TYPE }>): Keq<${this.typeName("Operation")}<STATUS, CONTENT_TYPE>>`;
1797
- throw new Exception(this.operationDefinition.module, "[operationDeclarationRenderer] Unreachable");
1798
- }
1799
- };
1800
- //#endregion
1801
- //#region src/transformers/operation-definition/nestjs-method.renderer.ts
1802
- var OperationDefinitionNestjsMethodRenderer = class {
1803
- helper;
1804
- typeName;
1805
- constructor(operationDefinition, options) {
1806
- this.operationDefinition = operationDefinition;
1807
- this.options = options;
1808
- this.typeName = typeNameFactory(operationDefinition);
1809
- this.helper = new OperationDefinitionSnippet(operationDefinition, options);
1810
- }
1811
- get operationId() {
1812
- return toSafeIdentifier(this.operationDefinition.operationId);
1813
- }
1814
- render() {
1815
- const pathname = this.operationDefinition.pathname;
1816
- const $comment = new CommentRenderer(this.operationDefinition).render();
1817
- const $method = this.operationDefinition.method.toLowerCase();
1818
- const $mediaType = this.helper.renderMediaType();
1819
- const $operationDeclaration = this.renderOperationDeclaration(this.operationDefinition);
1820
- const $queryParameters = this.helper.renderRequestQuery();
1821
- const $headerParameters = this.helper.renderRequestHeaders();
1822
- const $pathParameters = this.helper.renderRequestPathParameters();
1823
- const $requestBody = this.helper.renderRequestBody();
1824
- return [
1825
- $comment,
1826
- `${$operationDeclaration} {`,
1827
- ` const req = this.request.${$method}<${this.typeName("ResponseBodies")}[STATUS]>(${JSON.stringify(pathname)})`,
1828
- "",
1829
- $mediaType ? indent(2, $mediaType) : void 0,
1830
- "",
1831
- " /* @anchor:query:start */",
1832
- $queryParameters ? indent(2, $queryParameters) : void 0,
1833
- " /* @anchor:query:end */",
1834
- "",
1835
- " /* @anchor:headers:start */",
1836
- $headerParameters ? indent(2, $headerParameters) : void 0,
1837
- " /* @anchor:headers:end */",
1838
- "",
1839
- " /* @anchor:path-parameters:start */",
1840
- $pathParameters ? indent(2, $pathParameters) : void 0,
1841
- " /* @anchor:path-parameters:end */",
1842
- "",
1843
- " /* @anchor:body:start */",
1844
- $requestBody ? indent(2, $requestBody) : void 0,
1845
- " /* @anchor:body:end */",
1846
- "",
1847
- " return req",
1848
- "}"
1849
- ].filter(ramda.isNotNil).join("\n");
1850
- }
1851
- renderOperationDeclaration(operationDefinition) {
1852
- const operationId = this.operationId;
1853
- const typeName = typeNameFactory(operationDefinition);
1854
- const mediaTypes = this.helper.getRequestMediaTypes();
1855
- if (mediaTypes.length === 0) return `${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends never = never>(args?: ${typeName("RequestParameters")}): Keq<${typeName("Operation")}<STATUS, CONTENT_TYPE>>`;
1856
- else if (mediaTypes.length === 1) return `${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends ${JSON.stringify(mediaTypes[0])} = ${JSON.stringify(mediaTypes[0])}>(args?: ${typeName("RequestParameters")}): Keq<${typeName("Operation")}<STATUS, CONTENT_TYPE>>`;
1857
- else if (mediaTypes.length > 1) return `${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends ${typeName("RequestParameters")}["content-type"]>(args?: Extract<${typeName("RequestParameters")}, { "content-type": CONTENT_TYPE }>): Keq<${typeName("Operation")}<STATUS, CONTENT_TYPE>>`;
1858
- throw new Exception(operationDefinition.module, "[operationDeclarationRenderer] Unreachable");
1859
- }
1860
- };
1861
- //#endregion
1862
- //#region src/transformers/operation-definition/operation-definition.transformer.ts
1863
- var OperationDefinitionTransformer = class {
1864
- static toDeclaration(operationDefinition, options) {
1865
- return new DeclarationRenderer(operationDefinition, options).render();
1866
- }
1867
- static toMicroFunction(operationDefinition, options) {
1868
- return new OperationDefinitionMicroFunctionRenderer(operationDefinition, options).render();
1869
- }
1870
- static toNestjsMethod(operationDefinition, options) {
1871
- return new OperationDefinitionNestjsMethodRenderer(operationDefinition, options).render();
1872
- }
1873
- static toComment(operationDefinition) {
1874
- return new CommentRenderer(operationDefinition).render();
1875
- }
1876
- };
1877
- //#endregion
1878
- //#region src/transformers/entrypoint/entrypoint.transformer.ts
1879
- var EntrypointTransformer = class {
1880
- static toTypescript(exports, options) {
1881
- return [
1882
- "/* @anchor:file:start */",
1883
- "",
1884
- ...exports.map((exportArtifact) => {
1885
- const relativePath = path.relative(options.dirpath, exportArtifact.filepath).replace(/(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?$/, options.esm ? ".js" : "");
1886
- return relativePath.startsWith(".") ? `export * from '${relativePath}'` : `export * from './${relativePath}'`;
1887
- }),
1888
- "",
1889
- "/* @anchor:file:end */"
1890
- ].join("\n");
1891
- }
1892
- };
1893
- //#endregion
1894
- //#region src/transformers/api-document/nestjs-client.renderer.ts
1895
- var NestjsClientRenderer = class {
1896
- constructor(document, options) {
1897
- this.document = document;
1898
- this.options = options;
1899
- }
1900
- renderDependencies() {
1901
- return [
1902
- "import { Injectable, Logger } from \"@nestjs/common\"",
1903
- "import { Keq, KeqRequest } from \"keq\"",
1904
- ...this.document.operations.map((operationDefinition) => {
1905
- const filepath = this.options.getOperationDefinitionDeclarationFilepath(operationDefinition);
1906
- const typeName = typeNameFactory(operationDefinition);
1907
- return `import type { ${typeName("Operation")}, ${typeName("ResponseBodies")}, ${typeName("RequestParameters")} } from "${filepath}"`;
1908
- }).map((str) => str.replace(/ from "(\.\.?\/.+?)(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?"/, this.options.esm ? " from \"$1.js\"" : " from \"$1\""))
1909
- ].join("\n");
1910
- }
1911
- render() {
1912
- const moduleName = change_case.pascalCase(this.document.module.name);
1913
- const $dependencies = this.renderDependencies();
1914
- const $operations = this.document.operations.map((operation) => OperationDefinitionTransformer.toNestjsMethod(operation, { esm: this.options.esm })).join("\n\n");
1915
- return [
1916
- "/* @anchor:file:start */",
1917
- "",
1918
- $dependencies,
1919
- "",
1920
- "@Injectable()",
1921
- `export class ${moduleName}Client {`,
1922
- ` private readonly logger = new Logger(${moduleName}Client.name)`,
1923
- "",
1924
- " constructor(",
1925
- " // @anchor:client-constructor-parameters:start",
1926
- " private readonly request: KeqRequest,",
1927
- " // @anchor:client-constructor-parameters:end",
1928
- " ) {}",
1929
- "",
1930
- indent(2, $operations),
1931
- "}",
1932
- "",
1933
- "/* @anchor:file:end */"
1934
- ].filter(ramda.isNotNil).join("\n");
1935
- }
1936
- };
1937
- //#endregion
1938
- //#region src/transformers/api-document/nestjs-module.renderer.ts
1939
- var NestjsModuleRenderer = class {
1940
- constructor(document, options) {
1941
- this.document = document;
1942
- this.options = options;
1943
- }
1944
- render() {
1945
- const moduleName = change_case.pascalCase(this.document.module.name);
1946
- return [
1947
- "/* @anchor:file:start */",
1948
- "import { Module, ConfigurableModuleBuilder, Provider } from \"@nestjs/common\"",
1949
- "import { KeqRequest } from \"keq\"",
1950
- "import { KeqModule, type KeqModuleOptions } from \"@keq-request/nestjs\"",
1951
- `import { ${moduleName}Client } from "${this.options.getNestjsClientFilepath(this.document).replace(/(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?$/, this.options.esm ? ".js" : "")}"`,
1952
- "",
1953
- "",
1954
- `export interface ${moduleName}ModuleOptions extends KeqModuleOptions {`,
1955
- " /**",
1956
- " * Whether to register the module globally.",
1957
- " * @default false",
1958
- " */",
1959
- " isGlobal?: boolean",
1960
- "}",
1961
- "",
1962
- `const KEQ_REQUEST_TOKEN = Symbol("${moduleName}KeqRequest")`,
1963
- "",
1964
- `const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } = new ConfigurableModuleBuilder<${moduleName}ModuleOptions>()`,
1965
- " .setExtras({ isGlobal: false }, (definition, extras) => ({",
1966
- " ...definition,",
1967
- " global: extras.isGlobal,",
1968
- " }))",
1969
- " .build()",
1970
- "",
1971
- "const REQUEST_PROVIDER: Provider = {",
1972
- " provide: KEQ_REQUEST_TOKEN,",
1973
- ` useFactory: (options: ${moduleName}ModuleOptions, globalRequest?: KeqRequest) => {`,
1974
- "",
1975
- " if (!options.isolate && !globalRequest) {",
1976
- ` console.warn("${moduleName}Module: No global KeqRequest found, creating an isolated instance. Import KeqModule globally or set { isolate: true } to suppress this warning.")`,
1977
- " }",
1978
- "",
1979
- " const request = (!options.isolate && globalRequest)",
1980
- " ? globalRequest.fork()",
1981
- " : new KeqRequest()",
1982
- "",
1983
- " if (options.middlewares) {",
1984
- " for (const middleware of options.middlewares) {",
1985
- " request.use(middleware)",
1986
- " }",
1987
- " }",
1988
- "",
1989
- " return request",
1990
- " },",
1991
- " inject: [",
1992
- " MODULE_OPTIONS_TOKEN,",
1993
- " { token: KeqRequest, optional: true },",
1994
- " ],",
1995
- "}",
1996
- "",
1997
- "const CLIENT_PROVIDER: Provider = {",
1998
- ` provide: ${moduleName}Client,`,
1999
- ` useFactory: (request: KeqRequest) => new ${moduleName}Client(request),`,
2000
- " inject: [KEQ_REQUEST_TOKEN],",
2001
- "}",
2002
- "",
2003
- "/**",
2004
- ` * NestJS module that provides the {@link ${moduleName}Client} for dependency injection.`,
2005
- " *",
2006
- " * This module requires a `KeqRequest` instance, which can be provided in two ways:",
2007
- " *",
2008
- " * **Option 1: Use the global `KeqModule` (recommended)**",
2009
- " *",
2010
- " * Import `KeqModule` globally, then register this module.",
2011
- " * The module will fork from the global KeqRequest and inherit its middlewares.",
2012
- " *",
2013
- " * ```typescript",
2014
- " * // app.module.ts",
2015
- " * import { KeqModule } from '@keq-request/nestjs'",
2016
- " * ",
2017
- " * @Module({",
2018
- " * imports: [",
2019
- " * KeqModule,",
2020
- ` * ${moduleName}Module.register({`,
2021
- " * isGlobal: true, // optional, default false",
2022
- " * middlewares: [], // module-level middlewares",
2023
- " * }),",
2024
- " * ],",
2025
- " * })",
2026
- " * export class AppModule {}",
2027
- " * ```",
2028
- " *",
2029
- " * **Option 2: Provide an isolated `KeqRequest` instance**",
2030
- " *",
2031
- " * ```typescript",
2032
- " * @Module({",
2033
- " * imports: [",
2034
- ` * ${moduleName}Module.register({`,
2035
- " * isolate: true, // no inherited middlewares",
2036
- " * }),",
2037
- " * ],",
2038
- " * })",
2039
- " * export class SomeFeatureModule {}",
2040
- " * ```",
2041
- " *",
2042
- " * Then inject `" + moduleName + "Client` in your services:",
2043
- " *",
2044
- " * ```typescript",
2045
- " * @Injectable()",
2046
- " * export class SomeService {",
2047
- ` * constructor(private readonly client: ${moduleName}Client) {}`,
2048
- " * }",
2049
- " * ```",
2050
- " */",
2051
- "@Module({",
2052
- " imports: [KeqModule],",
2053
- " providers: [REQUEST_PROVIDER, CLIENT_PROVIDER],",
2054
- ` exports: [${moduleName}Client],`,
2055
- "})",
2056
- `export class ${moduleName}Module extends ConfigurableModuleClass {`,
2057
- ` static readonly KEQ_REQUEST = KEQ_REQUEST_TOKEN`,
2058
- "}",
2059
- "",
2060
- "/* @anchor:file:end */"
2061
- ].join("\n");
2062
- }
2063
- };
2064
- //#endregion
2065
- //#region src/transformers/api-document/api-document.transformer.ts
2066
- var ApiDocumentTransformer = class {
2067
- static toNestjsModule(document, options) {
2068
- return new NestjsModuleRenderer(document, options).render();
2069
- }
2070
- static toNestjsClient(document, options) {
2071
- return new NestjsClientRenderer(document, options).render();
2072
- }
2073
- };
2074
- //#endregion
2075
- //#region src/plugins/generate-declaration/constants/metadata-storage.ts
2076
- const MetadataStorage$9 = new PluginMetadataStorage("@keq-request/cli:GenerateDeclarationPlugin:MetadataStorage");
2077
- //#endregion
2078
- //#region src/plugins/generate-declaration/generators/schema-declaration/schema.generator.ts
2079
- const SCHEMA_GENERATOR = "schemaGenerator";
2080
- var SchemaDeclarationGenerator = class SchemaDeclarationGenerator {
2081
- async compile(compiler, task) {
2082
- const context = compiler.context;
2083
- const metadata = MetadataStorage$9.get(compiler);
2084
- const rc = context.rc;
2085
- const schemaDefinitions = context.documents.flatMap((document) => document.schemas);
2086
- const artifactMap = new Map(await Promise.all(schemaDefinitions.map(async (schemaDefinition) => [schemaDefinition, await metadata.hooks.afterSchemaDeclarationArtifactGenerated.promise(this.generateSchemaDefinitionsArtifact(schemaDefinition, rc), schemaDefinition, task)])));
2087
- if (!rc.rendering.entrypoint) return [...artifactMap.values()];
2088
- const entrypoints = ramda.collectBy((schemaDefinition) => schemaDefinition.module.name, schemaDefinitions).map((schemaDefinitions) => [schemaDefinitions[0].module, schemaDefinitions.map((schemaDefinition) => artifactMap.get(schemaDefinition)).filter((artifact) => Boolean(artifact))]).map(([moduleDefinition, artifacts]) => this.generateEntrypointArtifact(moduleDefinition, artifacts, rc));
2089
- return [...artifactMap.values(), ...entrypoints];
2090
- }
2091
- generateSchemaDefinitionsArtifact(schemaDefinition, rc) {
2092
- const filepath = SchemaDeclarationGenerator.getSchemaDefinitionArtifactFilepath(schemaDefinition, rc.rendering.fileNamingStyle);
2093
- const dirpath = path.dirname(filepath);
2094
- return new Artifact({
2095
- id: SchemaDeclarationGenerator.getSchemaDefinitionArtifactId(schemaDefinition),
2096
- filepath,
2097
- content: SchemaDefinitionTransformer.toDeclaration(schemaDefinition, {
2098
- esm: rc.rendering.esm,
2099
- additionalPropertiesType: rc.rendering.additionalPropertiesType,
2100
- getDependentSchemaDefinitionFilepath(dependentSchemaDefinition) {
2101
- const relativePath = path.relative(dirpath, SchemaDeclarationGenerator.getSchemaDefinitionArtifactFilepath(dependentSchemaDefinition, rc.rendering.fileNamingStyle));
2102
- return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2103
- }
2104
- }),
2105
- extensionName: ".schema.ts"
2106
- });
2107
- }
2108
- generateEntrypointArtifact(moduleDefinition, exports, rc) {
2109
- const filepath = SchemaDeclarationGenerator.getEntrypointArtifactFilepath(moduleDefinition, rc.rendering.fileNamingStyle);
2110
- const dirpath = path.dirname(filepath);
2111
- return new Artifact({
2112
- id: SchemaDeclarationGenerator.getEntrypointArtifactId(moduleDefinition),
2113
- filepath,
2114
- content: EntrypointTransformer.toTypescript(exports, { dirpath })
2115
- });
2116
- }
2117
- static getEntrypointArtifactFilepath(moduleDefinition, fileNamingStyle) {
2118
- return [
2119
- ".",
2120
- change_case[fileNamingStyle](moduleDefinition.name),
2121
- "types",
2122
- "components",
2123
- "schemas",
2124
- "index.ts"
2125
- ].join("/");
2126
- }
2127
- static getEntrypointArtifactId(moduleDefinition) {
2128
- return `${moduleDefinition.address.url}/components/schemas/entrypoint?generator=${SCHEMA_GENERATOR}`;
2129
- }
2130
- static getSchemaDefinitionArtifactFilepath(schemaDefinition, fileNamingStyle) {
2131
- const filename = `${change_case[fileNamingStyle](schemaDefinition.name)}.schema.ts`;
2132
- return [
2133
- ".",
2134
- change_case[fileNamingStyle](schemaDefinition.module.name),
2135
- "types",
2136
- "components",
2137
- "schemas",
2138
- filename
2139
- ].join("/");
2140
- }
2141
- static getSchemaDefinitionArtifactId(schemaDefinition) {
2142
- return `${schemaDefinition.id}?generator=${SCHEMA_GENERATOR}`;
2143
- }
2144
- };
2145
- //#endregion
2146
- //#region src/plugins/generate-declaration/generators/response-declaration/response.generator.ts
2147
- const RESPONSE_GENERATOR = "responseGenerator";
2148
- var ResponseDeclarationGenerator = class ResponseDeclarationGenerator {
2149
- async compile(compiler, task) {
2150
- const context = compiler.context;
2151
- const metadata = MetadataStorage$9.get(compiler);
2152
- const rc = context.rc;
2153
- const responseDefinitions = context.documents.flatMap((document) => document.responses);
2154
- if (responseDefinitions.length === 0) return [];
2155
- const artifactMap = new Map(await Promise.all(responseDefinitions.map(async (responseDefinition) => [responseDefinition, await metadata.hooks.afterResponseDeclarationArtifactGenerated.promise(this.generateResponseDefinitionArtifact(responseDefinition, rc), responseDefinition, task)])));
2156
- if (!rc.rendering.entrypoint) return [...artifactMap.values()];
2157
- const entrypoints = ramda.collectBy((responseDefinition) => responseDefinition.module.name, responseDefinitions).map((responseDefinitions) => [responseDefinitions[0].module, responseDefinitions.map((responseDefinition) => artifactMap.get(responseDefinition)).filter((artifact) => Boolean(artifact))]).map(([moduleDefinition, artifacts]) => this.generateEntrypointArtifact(moduleDefinition, artifacts, rc));
2158
- return [...artifactMap.values(), ...entrypoints];
2159
- }
2160
- generateResponseDefinitionArtifact(responseDefinition, rc) {
2161
- const filepath = ResponseDeclarationGenerator.getResponseDefinitionArtifactFilepath(responseDefinition, rc.rendering.fileNamingStyle);
2162
- const dirpath = path.dirname(filepath);
2163
- return new Artifact({
2164
- id: ResponseDeclarationGenerator.getResponseDefinitionArtifactId(responseDefinition),
2165
- filepath,
2166
- content: ResponseDefinitionTransformer.toDeclaration(responseDefinition, {
2167
- esm: rc.rendering.esm,
2168
- additionalPropertiesType: rc.rendering.additionalPropertiesType,
2169
- getDependentSchemaDefinitionFilepath(dependentSchemaDefinition) {
2170
- const relativePath = path.relative(dirpath, SchemaDeclarationGenerator.getSchemaDefinitionArtifactFilepath(dependentSchemaDefinition, rc.rendering.fileNamingStyle));
2171
- return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2172
- }
2173
- }),
2174
- extensionName: ".response.ts"
2175
- });
2176
- }
2177
- generateEntrypointArtifact(moduleDefinition, exports, rc) {
2178
- const filepath = ResponseDeclarationGenerator.getEntrypointArtifactFilepath(moduleDefinition, rc.rendering.fileNamingStyle);
2179
- const dirpath = path.dirname(filepath);
2180
- return new Artifact({
2181
- id: ResponseDeclarationGenerator.getEntrypointArtifactId(moduleDefinition),
2182
- filepath,
2183
- content: EntrypointTransformer.toTypescript(exports, { dirpath })
2184
- });
2185
- }
2186
- static getEntrypointArtifactFilepath(moduleDefinition, fileNamingStyle) {
2187
- return [
2188
- ".",
2189
- change_case[fileNamingStyle](moduleDefinition.name),
2190
- "types",
2191
- "components",
2192
- "responses",
2193
- "index.ts"
2194
- ].join("/");
2195
- }
2196
- static getEntrypointArtifactId(moduleDefinition) {
2197
- return `${moduleDefinition.address.url}/components/responses/entrypoint?generator=${RESPONSE_GENERATOR}`;
2198
- }
2199
- static getResponseDefinitionArtifactFilepath(responseDefinition, fileNamingStyle) {
2200
- const filename = `${change_case[fileNamingStyle](responseDefinition.name)}.response.ts`;
2201
- return [
2202
- ".",
2203
- change_case[fileNamingStyle](responseDefinition.module.name),
2204
- "types",
2205
- "components",
2206
- "responses",
2207
- filename
2208
- ].join("/");
2209
- }
2210
- static getResponseDefinitionArtifactId(responseDefinition) {
2211
- return `${responseDefinition.id}?generator=${RESPONSE_GENERATOR}`;
2212
- }
2213
- };
2214
- //#endregion
2215
- //#region src/plugins/generate-declaration/generators/operation-declaration/operation.generator.ts
2216
- const OPERATION_GENERATOR = "operationDeclarationGenerator";
2217
- var OperationDeclarationGenerator = class OperationDeclarationGenerator {
2218
- async compile(compiler, task) {
2219
- const context = compiler.context;
2220
- const metadata = MetadataStorage$9.get(compiler);
2221
- const rc = context.rc;
2222
- const operationDefinitions = context.documents.flatMap((document) => document.operations);
2223
- const artifactMap = new Map(await Promise.all(operationDefinitions.map(async (operationDefinition) => [operationDefinition, await metadata.hooks.afterOperationDeclarationArtifactGenerated.promise(this.generateOperationDefinitionArtifact(operationDefinition, rc), operationDefinition, task)])));
2224
- return Array.from(artifactMap.values());
2225
- }
2226
- generateOperationDefinitionArtifact(operationDefinition, rc) {
2227
- const filepath = OperationDeclarationGenerator.getOperationDefinitionArtifactFilepath(operationDefinition, rc.rendering.fileNamingStyle);
2228
- const dirpath = path.dirname(filepath);
2229
- return new Artifact({
2230
- id: OperationDeclarationGenerator.getOperationDefinitionArtifactId(operationDefinition),
2231
- filepath,
2232
- content: OperationDefinitionTransformer.toDeclaration(operationDefinition, {
2233
- esm: rc.rendering.esm,
2234
- additionalPropertiesType: rc.rendering.additionalPropertiesType,
2235
- getDependentSchemaDefinitionFilepath(dependentSchemaDefinition) {
2236
- const relativePath = path.relative(dirpath, SchemaDeclarationGenerator.getSchemaDefinitionArtifactFilepath(dependentSchemaDefinition, rc.rendering.fileNamingStyle));
2237
- return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2238
- },
2239
- getDependentResponseDefinitionFilepath(dependentResponseDefinition) {
2240
- const relativePath = path.relative(dirpath, ResponseDeclarationGenerator.getResponseDefinitionArtifactFilepath(dependentResponseDefinition, rc.rendering.fileNamingStyle));
2241
- return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2242
- }
2243
- }),
2244
- extensionName: ".type.ts"
2245
- });
2246
- }
2247
- generateEntrypointArtifact(moduleDefinition, exports, rc) {
2248
- const filepath = OperationDeclarationGenerator.getEntrypointArtifactFilepath(moduleDefinition, rc.rendering.fileNamingStyle);
2249
- const dirpath = path.dirname(filepath);
2250
- return new Artifact({
2251
- id: OperationDeclarationGenerator.getEntrypointArtifactId(moduleDefinition),
2252
- filepath,
2253
- content: EntrypointTransformer.toTypescript(exports, { dirpath })
2254
- });
2255
- }
2256
- static getOperationDefinitionArtifactFilepath(operationDefinition, fileNamingStyle) {
2257
- const filename = `${change_case[fileNamingStyle](operationDefinition.operationId)}.type.ts`;
2258
- return [
2259
- ".",
2260
- change_case[fileNamingStyle](operationDefinition.module.name),
2261
- "types",
2262
- "operations",
2263
- filename
2264
- ].join("/");
2265
- }
2266
- static getOperationDefinitionArtifactId(operationDefinition) {
2267
- return `${operationDefinition.id}?generator=${OPERATION_GENERATOR}`;
2268
- }
2269
- static getEntrypointArtifactFilepath(moduleDefinition, fileNamingStyle) {
2270
- return [
2271
- ".",
2272
- change_case[fileNamingStyle](moduleDefinition.name),
2273
- "types",
2274
- "operations",
2275
- "index.ts"
2276
- ].join("/");
2277
- }
2278
- static getEntrypointArtifactId(moduleDefinition) {
2279
- return `${moduleDefinition.address.url}/paths/entrypoint?generator=${OPERATION_GENERATOR}`;
2280
- }
2281
- };
2282
- //#endregion
2283
- //#region src/plugins/generate-declaration/generate-declaration.plugin.ts
2284
- const DECLARATION_GENERATOR = "declarationGenerator";
2285
- var GenerateDeclarationPlugin = class GenerateDeclarationPlugin {
2286
- name = DECLARATION_GENERATOR;
2287
- operationGenerator = new OperationDeclarationGenerator();
2288
- schemaGenerator = new SchemaDeclarationGenerator();
2289
- responseGenerator = new ResponseDeclarationGenerator();
2290
- constructor() {}
2291
- apply(compiler) {
2292
- const metadata = GenerateDeclarationPlugin.register(compiler);
2293
- if (metadata.applied) return;
2294
- metadata.applied = true;
2295
- compiler.hooks.compile.tapPromise(GenerateDeclarationPlugin.name, async (task) => {
2296
- compiler.context.artifacts?.push(...await this.schemaGenerator.compile(compiler, task), ...await this.responseGenerator.compile(compiler, task), ...await this.operationGenerator.compile(compiler, task));
2297
- });
2298
- }
2299
- static register(compiler) {
2300
- if (!MetadataStorage$9.has(compiler)) MetadataStorage$9.set(compiler, {
2301
- applied: false,
2302
- hooks: {
2303
- afterEntrypointArtifactGenerated: new tapable.AsyncSeriesWaterfallHook(["artifact", "task"]),
2304
- afterSchemaDeclarationArtifactGenerated: new tapable.AsyncSeriesWaterfallHook([
2305
- "artifact",
2306
- "schemaDefinition",
2307
- "task"
2308
- ]),
2309
- afterResponseDeclarationArtifactGenerated: new tapable.AsyncSeriesWaterfallHook([
2310
- "artifact",
2311
- "responseDefinition",
2312
- "task"
2313
- ]),
2314
- afterOperationDeclarationArtifactGenerated: new tapable.AsyncSeriesWaterfallHook([
2315
- "artifact",
2316
- "operationDefinition",
2317
- "task"
2318
- ])
2319
- }
2320
- });
2321
- return MetadataStorage$9.get(compiler);
2322
- }
2323
- static of(compiler) {
2324
- return this.register(compiler);
2325
- }
2326
- };
2327
- //#endregion
2328
- //#region src/plugins/generate-micro-function/generators/request/request.generator.ts
2329
- const MICRO_FUNCTION_REQUEST_GENERATOR = "microFunctionRequestGenerator";
2330
- var RequestGenerator = class RequestGenerator {
2331
- generateRequestArtifact(moduleName, fileNamingStyle) {
2332
- const content = [
2333
- "/* @anchor:file:start */",
2334
- "",
2335
- "import { KeqRequest } from \"keq\"",
2336
- "",
2337
- "/* @anchor:request-declaration */",
2338
- "export const request = new KeqRequest()",
2339
- "",
2340
- "/* @anchor:file:end */"
2341
- ].join("\n");
2342
- return new Artifact({
2343
- id: RequestGenerator.getRequestArtifactId(moduleName),
2344
- filepath: RequestGenerator.getRequestArtifactFilepath(moduleName, fileNamingStyle),
2345
- content
2346
- });
2347
- }
2348
- async compile(compiler, task) {
2349
- const context = compiler.context;
2350
- const rc = context.rc;
2351
- const documents = context.documents;
2352
- return [...new Set(documents.flatMap((doc) => doc.operations.map((op) => op.module.name)))].map((moduleName) => this.generateRequestArtifact(moduleName, rc.rendering.fileNamingStyle));
2353
- }
2354
- static getRequestArtifactFilepath(moduleName, fileNamingStyle) {
2355
- return `./${change_case[fileNamingStyle](moduleName)}/request.ts`;
2356
- }
2357
- static getRequestArtifactId(moduleName) {
2358
- return `request?module=${moduleName}&generator=${MICRO_FUNCTION_REQUEST_GENERATOR}`;
2359
- }
2360
- };
2361
- //#endregion
2362
- //#region src/plugins/generate-micro-function/generators/micro_function/micro-function.generator.ts
2363
- const MICRO_FUNCTION_GENERATOR = "microFunctionGenerator";
2364
- var MicroFunctionGenerator = class MicroFunctionGenerator {
2365
- async compile(compiler, task) {
2366
- const metadata = MetadataStorage$10.get(compiler);
2367
- const context = compiler.context;
2368
- const rc = context.rc;
2369
- const operationDefinitions = context.documents.flatMap((document) => document.operations);
2370
- const artifactMap = new Map(await Promise.all(operationDefinitions.map(async (operationDefinition) => [operationDefinition, await metadata.hooks.afterMicroFunctionArtifactGenerated.promise(this.generateOperationDefinitionArtifact(operationDefinition, rc), operationDefinition, task)])));
2371
- if (!rc.rendering.entrypoint) return [...artifactMap.values()];
2372
- return [...await Promise.all(ramda.collectBy((operationDefinition) => operationDefinition.module.name, operationDefinitions).map((operationDefinitions) => [operationDefinitions[0].module, operationDefinitions.map((operationDefinition) => artifactMap.get(operationDefinition)).filter((artifact) => Boolean(artifact))]).map(async ([moduleDefinition, artifacts]) => await metadata.hooks.afterEntrypointArtifactGenerated.promise(this.generateEntrypointArtifact(moduleDefinition, artifacts, rc), task))), ...artifactMap.values()];
2373
- }
2374
- generateOperationDefinitionArtifact(operationDefinition, rc) {
2375
- const filepath = MicroFunctionGenerator.getOperationDefinitionArtifactFilepath(operationDefinition, rc.rendering.fileNamingStyle);
2376
- const dirpath = path.dirname(filepath);
2377
- return new Artifact({
2378
- id: MicroFunctionGenerator.getOperationDefinitionArtifactId(operationDefinition),
2379
- filepath,
2380
- content: OperationDefinitionTransformer.toMicroFunction(operationDefinition, {
2381
- esm: rc.rendering.esm,
2382
- getOperationDefinitionDeclarationFilepath(operationDefinition) {
2383
- const relativePath = path.relative(dirpath, OperationDeclarationGenerator.getOperationDefinitionArtifactFilepath(operationDefinition, rc.rendering.fileNamingStyle));
2384
- return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2385
- },
2386
- getRequestFilepath() {
2387
- const relativePath = path.relative(dirpath, RequestGenerator.getRequestArtifactFilepath(operationDefinition.module.name, rc.rendering.fileNamingStyle));
2388
- return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2389
- }
2390
- }),
2391
- extensionName: ".type.ts"
2392
- });
2393
- }
2394
- generateEntrypointArtifact(moduleDefinition, exports, rc) {
2395
- const filepath = MicroFunctionGenerator.getEntrypointArtifactFilepath(moduleDefinition, rc.rendering.fileNamingStyle);
2396
- const dirpath = filepath.substring(0, filepath.lastIndexOf("/"));
2397
- return new Artifact({
2398
- id: MicroFunctionGenerator.getEntrypointArtifactId(moduleDefinition),
2399
- filepath,
2400
- content: EntrypointTransformer.toTypescript(exports, { dirpath })
2401
- });
2402
- }
2403
- static getOperationDefinitionArtifactFilepath(operationDefinition, fileNamingStyle) {
2404
- const filename = `${change_case[fileNamingStyle](operationDefinition.operationId)}.fn.ts`;
2405
- return [
2406
- ".",
2407
- change_case[fileNamingStyle](operationDefinition.module.name),
2408
- "operations",
2409
- filename
2410
- ].join("/");
2411
- }
2412
- static getOperationDefinitionArtifactId(operationDefinition) {
2413
- return `${operationDefinition.id}?generator=${MICRO_FUNCTION_GENERATOR}`;
2414
- }
2415
- static getEntrypointArtifactFilepath(moduleDefinition, fileNamingStyle) {
2416
- return [
2417
- ".",
2418
- change_case[fileNamingStyle](moduleDefinition.name),
2419
- "operations",
2420
- "index.ts"
2421
- ].join("/");
2422
- }
2423
- static getEntrypointArtifactId(moduleDefinition) {
2424
- return `${moduleDefinition.address}/paths/entrypoint?generator=${MICRO_FUNCTION_GENERATOR}`;
2425
- }
2426
- };
2427
- //#endregion
2428
- //#region src/plugins/generate-micro-function/generate-micro-function.plugin.ts
2429
- var GenerateMicroFunctionPlugin = class GenerateMicroFunctionPlugin {
2430
- microFunctionGenerator = new MicroFunctionGenerator();
2431
- requestGenerator = new RequestGenerator();
2432
- apply(compiler) {
2433
- const metadata = GenerateMicroFunctionPlugin.register(compiler);
2434
- if (metadata.applied) return;
2435
- metadata.applied = true;
2436
- compiler.hooks.compile.tapPromise(GenerateMicroFunctionPlugin.name, async (task) => {
2437
- const artifacts = [...await this.requestGenerator.compile(compiler, task), ...await this.microFunctionGenerator.compile(compiler, task)];
2438
- compiler.context.artifacts.push(...artifacts);
2439
- });
2440
- }
2441
- static register(compiler) {
2442
- if (!MetadataStorage$10.has(compiler)) MetadataStorage$10.set(compiler, {
2443
- applied: false,
2444
- hooks: {
2445
- afterEntrypointArtifactGenerated: new tapable.AsyncSeriesWaterfallHook(["artifact", "task"]),
2446
- afterMicroFunctionArtifactGenerated: new tapable.AsyncSeriesWaterfallHook([
2447
- "artifact",
2448
- "operationDefinition",
2449
- "task"
2450
- ])
2451
- }
2452
- });
2453
- return MetadataStorage$10.get(compiler);
2454
- }
2455
- static of(compiler) {
2456
- return this.register(compiler);
2457
- }
2458
- };
2459
- //#endregion
2460
- //#region src/plugins/body-fallback/constants/metadata-storage.ts
2461
- const MetadataStorage$8 = new PluginMetadataStorage("@keq-request/cli:BodyFallbackPlugin:MetadataStorage");
2462
- //#endregion
2463
- //#region src/plugins/body-fallback/index.ts
2464
- var BodyFallbackPlugin = class BodyFallbackPlugin {
2465
- apply(compiler) {
2466
- const metadata = BodyFallbackPlugin.register(compiler);
2467
- if (metadata.applied) return;
2468
- metadata.applied = true;
2469
- compiler.hooks.setup.tap(BodyFallbackPlugin.name, () => {
2470
- const generateMicroFunctionPluginMetadata = GenerateMicroFunctionPlugin.of(compiler);
2471
- if (!generateMicroFunctionPluginMetadata) throw new Error("BodyFallbackPlugin requires GenerateMicroFunctionPlugin to be applied first.");
2472
- generateMicroFunctionPluginMetadata.hooks.afterMicroFunctionArtifactGenerated.tap(BodyFallbackPlugin.name, (artifact, operationDefinition) => {
2473
- const keys = (operationDefinition.operation.parameters?.filter((p) => !JsonSchemaUtils.isRef(p)) || []).map((p) => p.name).filter(ramda.isNotNil);
2474
- const $acc = !keys.length ? " acc[key] = args[key]" : [
2475
- ` if (![${keys.map((k) => JSON.stringify(k)).join(", ")}].includes(key)) {`,
2476
- " acc[key] = args[key]",
2477
- " }"
2478
- ].join("\n");
2479
- artifact.anchor.block.replace("body", [
2480
- " if (typeof args === \"object\" && args !== null && !Array.isArray(args)) {",
2481
- " const requestBody = Object.keys(args)",
2482
- " .reduce((acc, key) => {",
2483
- $acc,
2484
- " return acc",
2485
- " }, {} as Record<string, unknown>)",
2486
- "",
2487
- " if (Object.keys(requestBody).length > 0) {",
2488
- " req.send(requestBody)",
2489
- " }",
2490
- " }"
2491
- ].filter(ramda.isNotNil).join("\n"));
2492
- return artifact;
2493
- });
2494
- });
2495
- }
2496
- static register(compiler) {
2497
- if (!MetadataStorage$8.has(compiler)) MetadataStorage$8.set(compiler, {
2498
- applied: false,
2499
- hooks: {}
2500
- });
2501
- return MetadataStorage$8.get(compiler);
2502
- }
2503
- static of(compiler) {
2504
- return this.register(compiler);
2505
- }
2506
- };
2507
- //#endregion
2508
- //#region src/plugins/use-valibot/constants/metadata-storage.ts
2509
- const MetadataStorage$7 = new PluginMetadataStorage("@keq-request/cli:UseValibotPlugin:MetadataStorage");
2510
- //#endregion
2511
- //#region src/plugins/use-valibot/use-valibot.plugin.ts
2512
- const USE_VALIBOT = "useValibot";
2513
- var UseValibotPlugin = class UseValibotPlugin {
2514
- name = USE_VALIBOT;
2515
- constructor() {}
2516
- apply(compiler) {
2517
- const metadata = UseValibotPlugin.register(compiler);
2518
- if (metadata.applied) return;
2519
- metadata.applied = true;
2520
- const declarationMetadata = GenerateDeclarationPlugin.of(compiler);
2521
- if (!declarationMetadata) throw new Error("UseValibotPlugin requires GenerateDeclarationPlugin to be registered first");
2522
- declarationMetadata.hooks.afterSchemaDeclarationArtifactGenerated.tap(UseValibotPlugin.name, (artifact, schemaDefinition) => {
2523
- const rc = compiler.context.rc;
2524
- const filepath = artifact.filepath;
2525
- const dirpath = path.dirname(filepath);
2526
- const valibotContent = SchemaDefinitionTransformer.toValibot(schemaDefinition, {
2527
- esm: rc.rendering.esm,
2528
- additionalPropertiesType: rc.rendering.additionalPropertiesType,
2529
- getDependentSchemaDefinitionFilepath(dependentSchemaDefinition) {
2530
- const relativePath = path.relative(dirpath, SchemaDeclarationGenerator.getSchemaDefinitionArtifactFilepath(dependentSchemaDefinition, rc.rendering.fileNamingStyle));
2531
- return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2532
- }
2533
- });
2534
- return new Artifact({
2535
- ...artifact,
2536
- content: valibotContent
2537
- });
2538
- });
2539
- }
2540
- static register(compiler) {
2541
- if (!MetadataStorage$7.has(compiler)) MetadataStorage$7.set(compiler, { applied: false });
2542
- return MetadataStorage$7.get(compiler);
2543
- }
2544
- static of(compiler) {
2545
- return this.register(compiler);
2546
- }
2547
- };
2548
- //#endregion
2549
- //#region src/plugins/generate-nestjs-module/constants/metadata-storage.ts
2550
- const MetadataStorage$6 = new PluginMetadataStorage("@keq-request/cli:GenerateNestjsModulePlugin:MetadataStorage");
2551
- //#endregion
2552
- //#region src/plugins/generate-nestjs-module/generators/nestjs-module.generator.ts
2553
- const NESTJS_MODULE_GENERATOR = "nestjs-module-generator";
2554
- var NestjsModuleGenerator = class NestjsModuleGenerator {
2555
- generateNestjsModuleArtifact(document, rc) {
2556
- const filepath = NestjsModuleGenerator.getNestjsModuleArtifactFilepath(document, rc.rendering.fileNamingStyle);
2557
- const dirname = path.dirname(filepath);
2558
- return new Artifact({
2559
- id: NestjsModuleGenerator.getNestjsModuleArtifactId(document),
2560
- filepath,
2561
- content: ApiDocumentTransformer.toNestjsModule(document, {
2562
- esm: rc.rendering.esm,
2563
- getNestjsClientFilepath(document) {
2564
- const relativePath = path.relative(dirname, NestjsModuleGenerator.getNestjsClientArtifactFilepath(document, rc.rendering.fileNamingStyle));
2565
- return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2566
- }
2567
- })
2568
- });
2569
- }
2570
- generateNestjsClientArtifact(document, rc) {
2571
- const filepath = NestjsModuleGenerator.getNestjsClientArtifactFilepath(document, rc.rendering.fileNamingStyle);
2572
- const dirpath = path.dirname(filepath);
2573
- return new Artifact({
2574
- id: NestjsModuleGenerator.getNestjsClientArtifactId(document),
2575
- filepath,
2576
- content: ApiDocumentTransformer.toNestjsClient(document, {
2577
- esm: rc.rendering.esm,
2578
- getOperationDefinitionDeclarationFilepath(operationDefinition) {
2579
- const relativePath = path.relative(dirpath, OperationDeclarationGenerator.getOperationDefinitionArtifactFilepath(operationDefinition, rc.rendering.fileNamingStyle));
2580
- return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2581
- }
2582
- })
2583
- });
2584
- }
2585
- async compile(compiler, task) {
2586
- const metadata = MetadataStorage$6.get(compiler);
2587
- const rc = compiler.context.rc;
2588
- const documents = compiler.context.documents;
2589
- const nestjsModuleArtifacts = await Promise.all(documents.map((document) => metadata.hooks.afterNestjsModuleArtifactGenerated.promise(this.generateNestjsModuleArtifact(document, rc), document, task)));
2590
- const nestjsClientArtifacts = await Promise.all(documents.map((document) => metadata.hooks.afterNestjsModuleArtifactGenerated.promise(this.generateNestjsClientArtifact(document, rc), document, task)));
2591
- return [...nestjsModuleArtifacts, ...nestjsClientArtifacts];
2592
- }
2593
- static getNestjsModuleArtifactFilepath(document, fileNamingStyle) {
2594
- const filename = `${change_case[fileNamingStyle](document.module.name)}.module.ts`;
2595
- return [
2596
- ".",
2597
- change_case[fileNamingStyle](document.module.name),
2598
- filename
2599
- ].join("/");
2600
- }
2601
- static getNestjsModuleArtifactId(document) {
2602
- return `${document.module.address}?generate=${NESTJS_MODULE_GENERATOR}`;
2603
- }
2604
- static getNestjsClientArtifactFilepath(document, fileNamingStyle) {
2605
- const filename = `${change_case[fileNamingStyle](document.module.name)}.client.ts`;
2606
- return [
2607
- ".",
2608
- change_case[fileNamingStyle](document.module.name),
2609
- filename
2610
- ].join("/");
2611
- }
2612
- static getNestjsClientArtifactId(document) {
2613
- return `${document.module.address}?generate=${NESTJS_MODULE_GENERATOR}-client`;
2614
- }
2615
- };
2616
- //#endregion
2617
- //#region src/plugins/generate-nestjs-module/generate-nestjs-module.ts
2618
- var GenerateNestjsModulePlugin = class GenerateNestjsModulePlugin {
2619
- nestjsModuleGenerator = new NestjsModuleGenerator();
2620
- apply(compiler) {
2621
- const metadata = GenerateNestjsModulePlugin.register(compiler);
2622
- if (metadata.applied) return;
2623
- metadata.applied = true;
2624
- compiler.hooks.compile.tapPromise(GenerateNestjsModulePlugin.name, async (task) => {
2625
- const artifacts = await this.nestjsModuleGenerator.compile(compiler, task);
2626
- compiler.context.artifacts.push(...artifacts);
2627
- });
2628
- }
2629
- static register(compiler) {
2630
- if (!MetadataStorage$6.has(compiler)) MetadataStorage$6.set(compiler, {
2631
- applied: false,
2632
- hooks: { afterNestjsModuleArtifactGenerated: new tapable.AsyncSeriesWaterfallHook([
2633
- "artifact",
2634
- "document",
2635
- "task"
2636
- ]) }
2637
- });
2638
- return MetadataStorage$6.get(compiler);
2639
- }
2640
- static of(compiler) {
2641
- return MetadataStorage$6.get(compiler);
2642
- }
2643
- };
2644
- //#endregion
2645
- //#region src/plugins/chinese-to-pinyin/constants/metadata-storage.ts
2646
- const MetadataStorage$5 = new PluginMetadataStorage("@keq-request/cli:ChineseToPinyinPlugin:MetadataStorage");
2647
- //#endregion
2648
- //#region src/plugins/chinese-to-pinyin/chinese-to-pinyin.plugin.ts
2649
- var ChineseToPinyinPlugin = class ChineseToPinyinPlugin {
2650
- apply(compiler) {
2651
- const metadata = ChineseToPinyinPlugin.register(compiler);
2652
- if (metadata.applied) return;
2653
- metadata.applied = true;
2654
- compiler.hooks.afterDownload.tap(ChineseToPinyinPlugin.name, (task) => {
2655
- const documents = compiler.context.documents;
2656
- compiler.context.documents = documents.map((doc) => {
2657
- return new ApiDocumentV3_1((0, swagger_fix.fixSwagger)(doc.specification), doc.module);
2658
- });
2659
- });
2660
- }
2661
- static register(compiler) {
2662
- if (!MetadataStorage$5.has(compiler)) MetadataStorage$5.set(compiler, {
2663
- applied: false,
2664
- hooks: {}
2665
- });
2666
- return MetadataStorage$5.get(compiler);
2667
- }
2668
- static of(compiler) {
2669
- return this.register(compiler);
2670
- }
2671
- };
2672
- //#endregion
2673
- //#region src/plugins/download-http-file/constants/metadata-storage.ts
2674
- const MetadataStorage$4 = new PluginMetadataStorage("@keq-request/cli:DownloadHttpFilePlugin:MetadataStorage");
2675
- //#endregion
2676
- //#region src/plugins/download-http-file/download-http-file.plugin.ts
2677
- var DownloadHttpFilePlugin = class DownloadHttpFilePlugin {
2678
- apply(compiler) {
2679
- const metadata = DownloadHttpFilePlugin.register(compiler);
2680
- if (metadata.applied) return;
2681
- metadata.applied = true;
2682
- compiler.hooks.download.tapPromise(DownloadHttpFilePlugin.name, async (address, task) => {
2683
- const { url } = address;
2684
- if (!url.startsWith("http://") && !url.startsWith("https://")) return void 0;
2685
- const content = await this.download(address);
2686
- const spec = this.deserialize(content);
2687
- return JSON.stringify(spec);
2688
- });
2689
- }
2690
- async download(address) {
2691
- const { url, headers } = address;
2692
- try {
2693
- const res = await fetch(url, { headers });
2694
- if (res.status >= 400) {
2695
- const body = await res.text().catch(() => "");
2696
- const detail = body ? `\n Response Body: ${body}` : "";
2697
- throw new Error(`failed with status code ${res.status}${detail}`);
2698
- }
2699
- return await res.text();
2700
- } catch (e) {
2701
- if (e instanceof Error) e.message = `Unable get the openapi/swagger file from ${url}: ${e.message}`;
2702
- throw e;
2703
- }
2704
- }
2705
- deserialize(content) {
2706
- const json = JSON.parse(content);
2707
- return OpenapiUtils.to3_1(json);
2708
- }
2709
- static register(compiler) {
2710
- if (!MetadataStorage$4.has(compiler)) MetadataStorage$4.set(compiler, {
2711
- applied: false,
2712
- hooks: {}
2713
- });
2714
- return MetadataStorage$4.get(compiler);
2715
- }
2716
- static of(compiler) {
2717
- return this.register(compiler);
2718
- }
2719
- };
2720
- //#endregion
2721
- //#region src/plugins/download-local-file/constants/metadata-storage.ts
2722
- const MetadataStorage$3 = new PluginMetadataStorage("@keq-request/cli:DownloadLocalFilePlugin:MetadataStorage");
2723
- //#endregion
2724
- //#region src/plugins/download-local-file/download-local-file.plugin.ts
2725
- var DownloadLocalFilePlugin = class DownloadLocalFilePlugin {
2726
- apply(compiler) {
2727
- const metadata = DownloadLocalFilePlugin.register(compiler);
2728
- if (metadata.applied) return;
2729
- metadata.applied = true;
2730
- compiler.hooks.download.tapPromise(DownloadLocalFilePlugin.name, async (address, task) => {
2731
- const { url: url$1, encoding } = address;
2732
- if (!url$1.startsWith("file://")) return void 0;
2733
- const filepath = (0, url.fileURLToPath)(url$1);
2734
- const fileExt = path.extname(filepath);
2735
- const content = await fs_promises.readFile(filepath, encoding);
2736
- const str = typeof content === "string" ? content : content.toString(encoding);
2737
- if ([".yml", ".yaml"].includes(fileExt)) {
2738
- const value = js_yaml.load(str);
2739
- return JSON.stringify(OpenapiUtils.to3_1(value));
2740
- } else if (fileExt === ".json") return JSON.stringify(OpenapiUtils.to3_1(JSON.parse(str)));
2741
- });
2742
- }
2743
- static register(compiler) {
2744
- if (!MetadataStorage$3.has(compiler)) MetadataStorage$3.set(compiler, {
2745
- applied: false,
2746
- hooks: {}
2747
- });
2748
- return MetadataStorage$3.get(compiler);
2749
- }
2750
- static of(compiler) {
2751
- return this.register(compiler);
2752
- }
2753
- };
2754
- //#endregion
2755
- //#region src/plugins/shaking/constants/metadata-storage.ts
2756
- const MetadataStorage$2 = new PluginMetadataStorage("@keq-request/cli:ShakingPlugin:MetadataStorage");
2757
- //#endregion
2758
- //#region src/plugins/shaking/shaking.plugin.ts
2759
- var ShakingPlugin = class ShakingPlugin {
2760
- apply(compiler) {
2761
- const metadata = ShakingPlugin.register(compiler);
2762
- if (metadata.applied) return;
2763
- metadata.applied = true;
2764
- compiler.hooks.beforeCompile.tap(ShakingPlugin.name, (task) => {
2765
- const matcher = compiler.context.matcher;
2766
- const documents = compiler.context.documents;
2767
- compiler.context.documents = documents.map((document) => this.shaking(compiler, document)).filter((document) => !document.isEmpty()).filter((document) => !matcher.isModuleDenied(document.module));
2768
- });
2769
- }
2770
- shaking(compiler, document) {
2771
- const rc = compiler.context.rc;
2772
- const matcher = compiler.context.matcher;
2773
- const isAccepted = (pathname, method, operation) => {
2774
- if (!SupportedMethods.includes(method)) return false;
2775
- return !matcher.isOperationDenied(new OperationDefinition({
2776
- method,
2777
- pathname,
2778
- operation,
2779
- module: document.module,
2780
- document
2781
- }));
2782
- };
2783
- return new ApiDocumentV3_1((0, _opendoc_openapi_shaking.openapiShakingSync)(document.specification, isAccepted, { tolerant: rc.tolerant }), new ModuleDefinition(document.module.name, {
2784
- url: `memory://${document.module.name}.v3_1.sharked.json`,
2785
- headers: {},
2786
- encoding: "utf8"
2787
- }));
2788
- }
2789
- static register(compiler) {
2790
- if (!MetadataStorage$2.has(compiler)) MetadataStorage$2.set(compiler, {
2791
- applied: false,
2792
- hooks: {}
2793
- });
2794
- return MetadataStorage$2.get(compiler);
2795
- }
2796
- static of(compiler) {
2797
- return this.register(compiler);
2798
- }
2799
- };
2800
- //#endregion
2801
- //#region src/plugins/terminal-select/utils/select-operation-definitions.ts
2802
- async function selectOperationDefinitions(task, operationDefinitions) {
2803
- return await task.prompt(_listr2_prompt_adapter_inquirer.ListrInquirerPromptAdapter).run(inquirer_select_pro.select, {
2804
- message: "Select Pathname",
2805
- defaultValue: [],
2806
- options: (input) => {
2807
- const items = operationDefinitions.map((op) => ({
2808
- name: `${op.module.name} ${op.method.toUpperCase()} ${op.pathname}`,
2809
- value: op
2810
- }));
2811
- if (!input) return items;
2812
- const keys = input.trim().toLowerCase().split(/\s+/);
2813
- return items.filter((i) => {
2814
- const name = i.name.toLowerCase();
2815
- return keys.every((q) => name.includes(q));
2816
- });
2817
- }
2818
- });
2819
- }
2820
- //#endregion
2821
- //#region src/plugins/terminal-select/constants/metadata-storage.ts
2822
- const MetadataStorage$1 = new PluginMetadataStorage("@keq-request/cli:TerminalSelectPlugin:MetadataStorage");
2823
- //#endregion
2824
- //#region src/plugins/terminal-select/terminal-select.plugin.ts
2825
- var TerminalSelectPlugin = class TerminalSelectPlugin {
2826
- constructor(options) {
2827
- this.options = options;
2828
- }
2829
- apply(compiler) {
2830
- const metadata = TerminalSelectPlugin.register(compiler);
2831
- if (metadata.applied) return;
2832
- metadata.applied = true;
2833
- compiler.hooks.afterDownload.tapPromise(TerminalSelectPlugin.name, async (task) => {
2834
- const context = compiler.context;
2835
- const matcher = context.matcher;
2836
- const selectedOperationDefinitions = await selectOperationDefinitions(task, context.documents.flatMap((document) => document.operations));
2837
- for (const op of selectedOperationDefinitions) matcher.append({
2838
- persist: !!this.options.persist,
2839
- deny: this.options.mode === "deny",
2840
- moduleName: op.module.name,
2841
- operationMethod: op.method,
2842
- operationPathname: op.pathname
2843
- });
2844
- });
2845
- }
2846
- static register(compiler) {
2847
- if (!MetadataStorage$1.has(compiler)) MetadataStorage$1.set(compiler, {
2848
- applied: false,
2849
- hooks: {}
2850
- });
2851
- return MetadataStorage$1.get(compiler);
2852
- }
2853
- static of(compiler) {
2854
- return this.register(compiler);
2855
- }
2856
- };
2857
- //#endregion
2858
- //#region src/plugins/clean/clean.plugin.ts
2859
- var CleanPlugin = class CleanPlugin {
2860
- apply(compiler) {
2861
- compiler.hooks.beforePersist.tapPromise(CleanPlugin.name, async () => {
2862
- const rc = compiler.context.rc;
2863
- if (!rc) throw new Error("Please run setup task first.");
2864
- const outdir = rc.outdir;
2865
- await fs_extra.default.emptyDir(outdir);
2866
- });
2867
- }
2868
- };
2869
- //#endregion
2870
- //#region src/plugins/initialize/initialize.plugin.ts
2871
- var InitializePlugin = class InitializePlugin {
2872
- constructor(options) {
2873
- this.options = options;
2874
- }
2875
- apply(compiler) {
2876
- compiler.hooks.setup.tap(InitializePlugin.name, (task) => {
2877
- const plugins = [new DownloadHttpFilePlugin(), new DownloadLocalFilePlugin()];
2878
- if (this.options.build) plugins.push(new ShakingPlugin());
2879
- if (this.options.interactive) plugins.push(new TerminalSelectPlugin(typeof this.options.interactive === "object" ? this.options.interactive : { mode: "allow" }));
2880
- const rc = compiler.context.rc;
2881
- plugins.push(...ramda.unnest((rc.translators || []).map((translator) => {
2882
- return translator.apply();
2883
- })));
2884
- if (this.options.fresh) plugins.push(new CleanPlugin());
2885
- if (rc.plugins && rc.plugins.length) plugins.push(...rc.plugins);
2886
- for (const plugin of plugins) plugin.apply(compiler);
2887
- });
2888
- }
2889
- };
2890
- //#endregion
2891
- //#region src/plugins/overwrite-operation-id/overwrite-operation-id.plugin.ts
2892
- var OverwriteOperationIdPlugin = class OverwriteOperationIdPlugin {
2893
- constructor(factory) {
2894
- this.factory = factory;
2895
- }
2896
- apply(compiler) {
2897
- compiler.hooks.afterDownload.tap(OverwriteOperationIdPlugin.name, () => {
2898
- const documents = compiler.context.documents;
2899
- const factory = this.factory;
2900
- compiler.context.documents = documents.map((document) => {
2901
- return new ApiDocumentV3_1(OpenapiUtils.mapOperation(document.specification, (method, pathname, operation) => {
2902
- const operationId = factory({
2903
- method,
2904
- pathname,
2905
- operation,
2906
- module: document.module
2907
- });
2908
- if (typeof operationId === "string") {
2909
- if (operationId.length === 0) throw new Exception(document.module, `The generated operationId for [${method.toUpperCase()} ${pathname}] is an empty string.`);
2910
- operation.operationId = operationId;
2911
- return operation;
2912
- }
2913
- return operation;
2914
- }), document.module);
2915
- });
2916
- });
2917
- }
2918
- };
2919
- //#endregion
2920
- //#region src/plugins/overwrite-schema-name/overwrite-schema-name.plugin.ts
2921
- var OverwriteSchemaNamePlugin = class OverwriteSchemaNamePlugin {
2922
- constructor(factory) {
2923
- this.factory = factory;
2924
- }
2925
- apply(compiler) {
2926
- compiler.hooks.beforeValidate.tap(OverwriteSchemaNamePlugin.name, (spec, moduleDefinition) => {
2927
- const schemas = spec.components?.schemas;
2928
- if (!schemas) return;
2929
- const renameMap = /* @__PURE__ */ new Map();
2930
- for (const name of Object.keys(schemas)) {
2931
- const newName = this.factory({
2932
- name,
2933
- module: moduleDefinition
2934
- });
2935
- if (typeof newName === "string" && newName !== name) renameMap.set(name, newName);
2936
- }
2937
- if (renameMap.size === 0) return;
2938
- for (const [oldName, newName] of renameMap) {
2939
- schemas[newName] = schemas[oldName];
2940
- delete schemas[oldName];
2941
- }
2942
- const refMap = /* @__PURE__ */ new Map();
2943
- for (const [oldName, newName] of renameMap) refMap.set(`#/components/schemas/${oldName}`, `#/components/schemas/${newName}`);
2944
- const matches = (0, jsonpath_plus.JSONPath)({
2945
- path: "$..*['$ref']^",
2946
- json: spec,
2947
- resultType: "all"
2948
- });
2949
- for (const match of matches) {
2950
- const ref = match.value.$ref;
2951
- if (typeof ref === "string" && refMap.has(ref)) match.value.$ref = refMap.get(ref);
2952
- }
2953
- });
2954
- }
2955
- };
2956
- //#endregion
2957
- //#region src/plugins/overwrite-query-options/overwrite-query-options.plugin.ts
2958
- const QsArrayFormatUnion = Object.values(QsArrayFormat);
2959
- var OverwriteQueryOptionsPlugin = class OverwriteQueryOptionsPlugin {
2960
- constructor(factory) {
2961
- this.factory = factory;
2962
- }
2963
- apply(compiler) {
2964
- compiler.hooks.afterDownload.tap(OverwriteQueryOptionsPlugin.name, (task) => {
2965
- const documents = compiler.context.documents;
2966
- const factory = this.factory;
2967
- compiler.context.documents = documents.map((document) => {
2968
- return new ApiDocumentV3_1(OpenapiUtils.mapParameter(document.specification, (method, pathname, operation, parameter) => {
2969
- const qsOptions = typeof factory === "function" ? factory({
2970
- parameter,
2971
- operation,
2972
- pathname,
2973
- method,
2974
- module: document.module
2975
- }) : factory;
2976
- if (!qsOptions) return parameter;
2977
- if (qsOptions.arrayFormat) {
2978
- if (!QsArrayFormatUnion.includes(qsOptions.arrayFormat)) throw new Exception(document.module, `The 'arrayFormat' value '${qsOptions.arrayFormat}' for the query parameter '${parameter.name}' in [${method.toUpperCase()} ${pathname}] is invalid.`);
2979
- parameter["x-qs-array-format"] = qsOptions.arrayFormat;
2980
- }
2981
- if (qsOptions.allowDots !== void 0) {
2982
- if (typeof qsOptions.allowDots !== "boolean") throw new Exception(document.module, `The 'allowDots' value for the query parameter '${parameter.name}' in [${method.toUpperCase()} ${pathname}] must be a boolean.`);
2983
- parameter["x-qs-allow-dots"] = Boolean(qsOptions.allowDots);
2984
- }
2985
- if (qsOptions.indices !== void 0) {
2986
- if (typeof qsOptions.indices !== "boolean") throw new Exception(document.module, `The 'indices' value for the query parameter '${parameter.name}' in [${method.toUpperCase()} ${pathname}] must be a boolean.`);
2987
- parameter["x-qs-indices"] = Boolean(qsOptions.indices);
2988
- }
2989
- return parameter;
2990
- }), document.module);
2991
- });
2992
- });
2993
- }
2994
- };
2995
- //#endregion
2996
- //#region src/plugins/overwrite-additional-properties/constants/metadata-storage.ts
2997
- const MetadataStorage = new PluginMetadataStorage("@keq-request/cli:OverwriteAdditionalPropertiesPlugin:MetadataStorage");
2998
- //#endregion
2999
- //#region src/plugins/overwrite-additional-properties/overwrite-additional-properties.plugin.ts
3000
- var OverwriteAdditionalPropertiesPlugin = class OverwriteAdditionalPropertiesPlugin {
3001
- constructor(options = {}) {
3002
- this.options = options;
3003
- }
3004
- apply(compiler) {
3005
- const metadata = OverwriteAdditionalPropertiesPlugin.register(compiler);
3006
- if (metadata.applied) return;
3007
- metadata.applied = true;
3008
- const { disallowIfNotPresent = false } = this.options;
3009
- if (!disallowIfNotPresent) return;
3010
- compiler.hooks.afterDownload.tap(OverwriteAdditionalPropertiesPlugin.name, () => {
3011
- const documents = compiler.context.documents;
3012
- compiler.context.documents = documents.map((document) => {
3013
- return new ApiDocumentV3_1(OpenapiUtils.mapSchema(document.specification, (schema) => {
3014
- if (schema.type !== "object" && !schema.properties) return schema;
3015
- if (schema.additionalProperties === void 0) return Object.assign({}, schema, { additionalProperties: false });
3016
- return schema;
3017
- }), document.module);
3018
- });
3019
- });
3020
- }
3021
- static register(compiler) {
3022
- if (!MetadataStorage.has(compiler)) MetadataStorage.set(compiler, { applied: false });
3023
- return MetadataStorage.get(compiler);
3024
- }
3025
- static of(compiler) {
3026
- return this.register(compiler);
3027
- }
3028
- };
3029
- //#endregion
3030
- //#region src/plugins/lint-schema/lint-schema.plugin.ts
3031
- var LintSchemaPlugin = class LintSchemaPlugin {
3032
- constructor(options = {}) {
3033
- this.options = options;
3034
- }
3035
- apply(compiler) {
3036
- compiler.hooks.beforeCompile.tap(LintSchemaPlugin.name, () => {
3037
- const documents = compiler.context.documents;
3038
- const validate = new ajv_dist_2020_js.default({
3039
- allErrors: true,
3040
- strict: false
3041
- }).getSchema("https://json-schema.org/draft/2020-12/schema");
3042
- if (!validate) {
3043
- require_logger.logger.warn("Failed to load JSON Schema Draft 2020-12 meta-schema for validation");
3044
- return;
3045
- }
3046
- let hasErrors = false;
3047
- for (const document of documents) {
3048
- const spec = document.specification;
3049
- const moduleName = document.module.name;
3050
- if (spec.components?.schemas) for (const [name, schema] of Object.entries(spec.components.schemas)) {
3051
- if (typeof schema === "boolean" || "$ref" in schema) continue;
3052
- if (!validate(schema) && validate.errors) {
3053
- hasErrors = true;
3054
- for (const error of validate.errors) require_logger.logger.warn(`[${moduleName}] components.schemas.${name}${error.instancePath}: ${error.message}`);
3055
- }
3056
- }
3057
- for (const [path, pathItem] of Object.entries(spec.paths || {})) {
3058
- if (!pathItem) continue;
3059
- for (const method of SupportedMethods) {
3060
- const operation = pathItem[method];
3061
- if (!operation) continue;
3062
- const operationId = operation.operationId || `${method.toUpperCase()} ${path}`;
3063
- if (operation.parameters) for (const param of operation.parameters) {
3064
- if ("$ref" in param || !param.schema) continue;
3065
- if (typeof param.schema === "boolean" || "$ref" in param.schema) continue;
3066
- if (!validate(param.schema) && validate.errors) {
3067
- hasErrors = true;
3068
- for (const error of validate.errors) require_logger.logger.warn(`[${moduleName}] ${operationId} parameter "${param.name}" schema${error.instancePath}: ${error.message}`);
3069
- }
3070
- }
3071
- if (operation.requestBody && !("$ref" in operation.requestBody)) {
3072
- const content = operation.requestBody.content || {};
3073
- for (const [mediaType, mediaTypeObj] of Object.entries(content)) {
3074
- if (!mediaTypeObj.schema || typeof mediaTypeObj.schema === "boolean" || "$ref" in mediaTypeObj.schema) continue;
3075
- if (!validate(mediaTypeObj.schema) && validate.errors) {
3076
- hasErrors = true;
3077
- for (const error of validate.errors) require_logger.logger.warn(`[${moduleName}] ${operationId} requestBody ${mediaType} schema${error.instancePath}: ${error.message}`);
3078
- }
3079
- }
3080
- }
3081
- if (operation.responses) for (const [statusCode, response] of Object.entries(operation.responses)) {
3082
- if ("$ref" in response) continue;
3083
- const content = response.content || {};
3084
- for (const [mediaType, mediaTypeObj] of Object.entries(content)) {
3085
- if (!mediaTypeObj.schema || typeof mediaTypeObj.schema === "boolean" || "$ref" in mediaTypeObj.schema) continue;
3086
- if (!validate(mediaTypeObj.schema) && validate.errors) {
3087
- hasErrors = true;
3088
- for (const error of validate.errors) require_logger.logger.warn(`[${moduleName}] ${operationId} response ${statusCode} ${mediaType} schema${error.instancePath}: ${error.message}`);
3089
- }
3090
- }
3091
- }
3092
- }
3093
- }
3094
- }
3095
- if (this.options.strict && hasErrors) throw new Error("Schema validation failed. Fix the errors above or set LintSchemaPlugin strict option to false.");
3096
- this.lintDuplicateOperationId(compiler, documents);
3097
- });
3098
- }
3099
- /**
3100
- * Detect duplicate operationId across all operations within each API document.
3101
- *
3102
- * In tolerant mode, duplicates are auto-resolved by appending `__{method}_{pathname}` suffix
3103
- * and the patched document replaces the original in the compiler context.
3104
- * In strict mode (tolerant=false), an Exception is thrown immediately.
3105
- */
3106
- lintDuplicateOperationId(compiler, documents) {
3107
- for (let i = 0; i < documents.length; i++) {
3108
- const document = documents[i];
3109
- const spec = document.specification;
3110
- const moduleName = document.module.name;
3111
- const operationIdMap = /* @__PURE__ */ new Map();
3112
- for (const [pathname, pathItem] of Object.entries(spec.paths || {})) {
3113
- if (!pathItem) continue;
3114
- for (const method of SupportedMethods) {
3115
- const operation = pathItem[method];
3116
- if (!operation?.operationId) continue;
3117
- const list = operationIdMap.get(operation.operationId) || [];
3118
- list.push({
3119
- method,
3120
- pathname
3121
- });
3122
- operationIdMap.set(operation.operationId, list);
3123
- }
3124
- }
3125
- const duplicates = [...operationIdMap.entries()].filter(([, ops]) => ops.length > 1);
3126
- if (duplicates.length === 0) continue;
3127
- if (!compiler.options.tolerant) {
3128
- const messages = duplicates.map(([id, ops]) => ` - operationId "${id}" is used by: ${ops.map((o) => `[${o.method.toUpperCase()} ${o.pathname}]`).join(", ")}`);
3129
- throw new Exception(document.module, `Duplicate operationId found:\n${messages.join("\n")}`);
3130
- }
3131
- const duplicateIds = new Set(duplicates.map(([id]) => id));
3132
- for (const [id, ops] of duplicates) require_logger.logger.warn(`[${moduleName}] Duplicate operationId "${id}" found in: ${ops.map((o) => `[${o.method.toUpperCase()} ${o.pathname}]`).join(", ")}`);
3133
- const newSpec = OpenapiUtils.mapOperation(spec, (method, pathname, operation) => {
3134
- if (operation.operationId && duplicateIds.has(operation.operationId)) {
3135
- const sanitized = pathname.replace(/\//g, "_").replace(/-/g, "_").replace(/:/g, "$$").replace(/{(.+)}/, "$$$1");
3136
- const newId = `${operation.operationId}__${method}${sanitized}`;
3137
- require_logger.logger.warn(`[${moduleName}] Renamed: "${operation.operationId}" -> "${newId}" for [${method.toUpperCase()} ${pathname}]`);
3138
- operation.operationId = newId;
3139
- }
3140
- return operation;
3141
- });
3142
- compiler.context.documents[i] = new ApiDocumentV3_1(newSpec, document.module);
3143
- }
3144
- }
3145
- };
3146
- //#endregion
3147
- //#region src/plugins/springdoc-compat/springdoc-compat.plugin.ts
3148
- function flattenExtensions(obj) {
3149
- if (typeof obj !== "object" || obj === null) return;
3150
- if (Array.isArray(obj)) {
3151
- for (const item of obj) flattenExtensions(item);
3152
- return;
3153
- }
3154
- const record = obj;
3155
- if ("extensions" in record && typeof record.extensions === "object" && record.extensions !== null) {
3156
- const extensions = record.extensions;
3157
- for (const [key, value] of Object.entries(extensions)) if (!(key in record)) record[key] = value;
3158
- delete record.extensions;
3159
- }
3160
- for (const value of Object.values(record)) flattenExtensions(value);
3161
- }
3162
- /**
3163
- * Springdoc (Java/Spring Boot) 生成的 OpenAPI 文档兼容插件。
3164
- *
3165
- * Springdoc 输出的文档存在若干不符合 OpenAPI 规范的结构,此插件在验证前进行修正。
3166
- * 当前处理:
3167
- * - 将嵌套的 `extensions` 对象展平为同级 x-* 属性
3168
- */
3169
- var SpringdocCompatPlugin = class SpringdocCompatPlugin {
3170
- apply(compiler) {
3171
- compiler.hooks.beforeValidate.tap(SpringdocCompatPlugin.name, (spec) => {
3172
- flattenExtensions(spec);
3173
- });
3174
- }
3175
- };
3176
- //#endregion
3177
- //#region src/plugins/mock/mock.plugin.ts
3178
- function resolveRef(root, ref) {
3179
- if (!ref.startsWith("#/")) return void 0;
3180
- const parts = ref.slice(2).split("/");
3181
- let current = root;
3182
- for (const part of parts) {
3183
- if (typeof current !== "object" || current === null) return void 0;
3184
- current = current[part];
3185
- }
3186
- return typeof current === "object" && current !== null ? current : void 0;
3187
- }
3188
- function resolveSchemaNode(root, node) {
3189
- if ("$ref" in node && typeof node["$ref"] === "string") return resolveRef(root, node["$ref"]);
3190
- return node;
3191
- }
3192
- function hasExplicitValue(node) {
3193
- return "example" in node || "examples" in node || "enum" in node || "const" in node || "x-faker" in node;
3194
- }
3195
- function matchesCondition(node, when) {
3196
- if (when.type) {
3197
- if (!(Array.isArray(when.type) ? when.type : [when.type]).includes(node.type)) return false;
3198
- }
3199
- if (when.format && node.format !== when.format) return false;
3200
- return true;
3201
- }
3202
- function applyAction(node, then) {
3203
- if ("example" in then) node.example = then.example;
3204
- else if ("faker" in then) node["x-faker"] = then.args ? { [then.faker]: then.args } : then.faker;
3205
- else if ("default" in then) node.default = then.default;
3206
- }
3207
- function extractPropertyTarget(given) {
3208
- const match = given.match(/\.properties\.([^.[]+)$/);
3209
- return match ? match[1] : void 0;
3210
- }
3211
- function extractSchemaEntryPath(given) {
3212
- const idx = given.lastIndexOf(".properties.");
3213
- if (idx === -1) return void 0;
3214
- return given.slice(0, idx);
3215
- }
3216
- function walkSchemaProperties(schema, root, visitor, visited = /* @__PURE__ */ new Set()) {
3217
- const resolved = resolveSchemaNode(root, schema);
3218
- if (!resolved) return;
3219
- if (visited.has(resolved)) return;
3220
- visited.add(resolved);
3221
- if (resolved.properties && typeof resolved.properties === "object") for (const [name, propValue] of Object.entries(resolved.properties)) {
3222
- if (typeof propValue !== "object" || propValue === null) continue;
3223
- const propSchema = propValue;
3224
- visitor(name, propSchema);
3225
- walkSchemaProperties(propSchema, root, visitor, visited);
3226
- }
3227
- if (resolved.items && typeof resolved.items === "object") walkSchemaProperties(resolved.items, root, visitor, visited);
3228
- for (const key of [
3229
- "allOf",
3230
- "oneOf",
3231
- "anyOf"
3232
- ]) {
3233
- const arr = resolved[key];
3234
- if (Array.isArray(arr)) {
3235
- for (const sub of arr) if (typeof sub === "object" && sub !== null) walkSchemaProperties(sub, root, visitor, visited);
3236
- }
3237
- }
3238
- }
3239
- var MockPlugin = class MockPlugin {
3240
- rules;
3241
- constructor(options) {
3242
- this.rules = options.rules;
3243
- }
3244
- apply(compiler) {
3245
- compiler.hooks.beforeValidate.tap(MockPlugin.name, (spec) => {
3246
- for (const rule of this.rules) this.applyRule(spec, rule);
3247
- });
3248
- }
3249
- applyRule(spec, rule) {
3250
- const propertyTarget = extractPropertyTarget(rule.given);
3251
- if (!propertyTarget) {
3252
- const matches = (0, jsonpath_plus.JSONPath)({
3253
- path: rule.given,
3254
- json: spec,
3255
- resultType: "all"
3256
- });
3257
- for (const match of matches) {
3258
- const node = match.value;
3259
- if (typeof node !== "object" || node === null) continue;
3260
- const schema = node;
3261
- if (hasExplicitValue(schema)) continue;
3262
- if (rule.when && !matchesCondition(schema, rule.when)) continue;
3263
- applyAction(schema, rule.then);
3264
- }
3265
- return;
3266
- }
3267
- const schemaEntryPath = extractSchemaEntryPath(rule.given);
3268
- if (!schemaEntryPath) return;
3269
- const entries = (0, jsonpath_plus.JSONPath)({
3270
- path: schemaEntryPath,
3271
- json: spec,
3272
- resultType: "all"
3273
- });
3274
- for (const entry of entries) {
3275
- if (typeof entry.value !== "object" || entry.value === null) continue;
3276
- const schemaEntry = entry.value;
3277
- walkSchemaProperties(schemaEntry, spec, (propName, propSchema) => {
3278
- if (propName !== propertyTarget) return;
3279
- if (hasExplicitValue(propSchema)) return;
3280
- if (rule.when && !matchesCondition(propSchema, rule.when)) return;
3281
- applyAction(propSchema, rule.then);
3282
- });
3283
- }
3284
- }
3285
- };
3286
- //#endregion
3287
- Object.defineProperty(exports, "ApiDocumentV3_1", {
3288
- enumerable: true,
3289
- get: function() {
3290
- return ApiDocumentV3_1;
3291
- }
3292
- });
3293
- Object.defineProperty(exports, "Artifact", {
3294
- enumerable: true,
3295
- get: function() {
3296
- return Artifact;
3297
- }
3298
- });
3299
- Object.defineProperty(exports, "Asset", {
3300
- enumerable: true,
3301
- get: function() {
3302
- return Asset;
3303
- }
3304
- });
3305
- Object.defineProperty(exports, "BodyFallbackPlugin", {
3306
- enumerable: true,
3307
- get: function() {
3308
- return BodyFallbackPlugin;
3309
- }
3310
- });
3311
- Object.defineProperty(exports, "ChineseToPinyinPlugin", {
3312
- enumerable: true,
3313
- get: function() {
3314
- return ChineseToPinyinPlugin;
3315
- }
3316
- });
3317
- Object.defineProperty(exports, "CleanPlugin", {
3318
- enumerable: true,
3319
- get: function() {
3320
- return CleanPlugin;
3321
- }
3322
- });
3323
- Object.defineProperty(exports, "DECLARATION_GENERATOR", {
3324
- enumerable: true,
3325
- get: function() {
3326
- return DECLARATION_GENERATOR;
3327
- }
3328
- });
3329
- Object.defineProperty(exports, "DownloadHttpFilePlugin", {
3330
- enumerable: true,
3331
- get: function() {
3332
- return DownloadHttpFilePlugin;
3333
- }
3334
- });
3335
- Object.defineProperty(exports, "DownloadLocalFilePlugin", {
3336
- enumerable: true,
3337
- get: function() {
3338
- return DownloadLocalFilePlugin;
3339
- }
3340
- });
3341
- Object.defineProperty(exports, "EslintPlugin", {
3342
- enumerable: true,
3343
- get: function() {
3344
- return EslintPlugin;
3345
- }
3346
- });
3347
- Object.defineProperty(exports, "Exception", {
3348
- enumerable: true,
3349
- get: function() {
3350
- return Exception;
3351
- }
3352
- });
3353
- Object.defineProperty(exports, "FileTracker", {
3354
- enumerable: true,
3355
- get: function() {
3356
- return FileTracker;
3357
- }
3358
- });
3359
- Object.defineProperty(exports, "GenerateDeclarationPlugin", {
3360
- enumerable: true,
3361
- get: function() {
3362
- return GenerateDeclarationPlugin;
3363
- }
3364
- });
3365
- Object.defineProperty(exports, "GenerateMicroFunctionPlugin", {
3366
- enumerable: true,
3367
- get: function() {
3368
- return GenerateMicroFunctionPlugin;
3369
- }
3370
- });
3371
- Object.defineProperty(exports, "GenerateNestjsModulePlugin", {
3372
- enumerable: true,
3373
- get: function() {
3374
- return GenerateNestjsModulePlugin;
3375
- }
3376
- });
3377
- Object.defineProperty(exports, "InitializePlugin", {
3378
- enumerable: true,
3379
- get: function() {
3380
- return InitializePlugin;
3381
- }
3382
- });
3383
- Object.defineProperty(exports, "LintSchemaPlugin", {
3384
- enumerable: true,
3385
- get: function() {
3386
- return LintSchemaPlugin;
3387
- }
3388
- });
3389
- Object.defineProperty(exports, "MICRO_FUNCTION_GENERATOR", {
3390
- enumerable: true,
3391
- get: function() {
3392
- return MICRO_FUNCTION_GENERATOR;
3393
- }
3394
- });
3395
- Object.defineProperty(exports, "MICRO_FUNCTION_REQUEST_GENERATOR", {
3396
- enumerable: true,
3397
- get: function() {
3398
- return MICRO_FUNCTION_REQUEST_GENERATOR;
3399
- }
3400
- });
3401
- Object.defineProperty(exports, "MicroFunctionGenerator", {
3402
- enumerable: true,
3403
- get: function() {
3404
- return MicroFunctionGenerator;
3405
- }
3406
- });
3407
- Object.defineProperty(exports, "MockPlugin", {
3408
- enumerable: true,
3409
- get: function() {
3410
- return MockPlugin;
3411
- }
3412
- });
3413
- Object.defineProperty(exports, "ModuleDefinition", {
3414
- enumerable: true,
3415
- get: function() {
3416
- return ModuleDefinition;
3417
- }
3418
- });
3419
- Object.defineProperty(exports, "NestjsModuleGenerator", {
3420
- enumerable: true,
3421
- get: function() {
3422
- return NestjsModuleGenerator;
3423
- }
3424
- });
3425
- Object.defineProperty(exports, "OPERATION_GENERATOR", {
3426
- enumerable: true,
3427
- get: function() {
3428
- return OPERATION_GENERATOR;
3429
- }
3430
- });
3431
- Object.defineProperty(exports, "OpenapiUtils", {
3432
- enumerable: true,
3433
- get: function() {
3434
- return OpenapiUtils;
3435
- }
3436
- });
3437
- Object.defineProperty(exports, "OperationDeclarationGenerator", {
3438
- enumerable: true,
3439
- get: function() {
3440
- return OperationDeclarationGenerator;
3441
- }
3442
- });
3443
- Object.defineProperty(exports, "OperationDefinition", {
3444
- enumerable: true,
3445
- get: function() {
3446
- return OperationDefinition;
3447
- }
3448
- });
3449
- Object.defineProperty(exports, "OverwriteAdditionalPropertiesPlugin", {
3450
- enumerable: true,
3451
- get: function() {
3452
- return OverwriteAdditionalPropertiesPlugin;
3453
- }
3454
- });
3455
- Object.defineProperty(exports, "OverwriteOperationIdPlugin", {
3456
- enumerable: true,
3457
- get: function() {
3458
- return OverwriteOperationIdPlugin;
3459
- }
3460
- });
3461
- Object.defineProperty(exports, "OverwriteQueryOptionsPlugin", {
3462
- enumerable: true,
3463
- get: function() {
3464
- return OverwriteQueryOptionsPlugin;
3465
- }
3466
- });
3467
- Object.defineProperty(exports, "OverwriteSchemaNamePlugin", {
3468
- enumerable: true,
3469
- get: function() {
3470
- return OverwriteSchemaNamePlugin;
3471
- }
3472
- });
3473
- Object.defineProperty(exports, "PrettierPlugin", {
3474
- enumerable: true,
3475
- get: function() {
3476
- return PrettierPlugin;
3477
- }
3478
- });
3479
- Object.defineProperty(exports, "QsArrayFormat", {
3480
- enumerable: true,
3481
- get: function() {
3482
- return QsArrayFormat;
3483
- }
3484
- });
3485
- Object.defineProperty(exports, "RESPONSE_GENERATOR", {
3486
- enumerable: true,
3487
- get: function() {
3488
- return RESPONSE_GENERATOR;
3489
- }
3490
- });
3491
- Object.defineProperty(exports, "RequestGenerator", {
3492
- enumerable: true,
3493
- get: function() {
3494
- return RequestGenerator;
3495
- }
3496
- });
3497
- Object.defineProperty(exports, "ResponseDeclarationGenerator", {
3498
- enumerable: true,
3499
- get: function() {
3500
- return ResponseDeclarationGenerator;
3501
- }
3502
- });
3503
- Object.defineProperty(exports, "SCHEMA_GENERATOR", {
3504
- enumerable: true,
3505
- get: function() {
3506
- return SCHEMA_GENERATOR;
3507
- }
3508
- });
3509
- Object.defineProperty(exports, "SchemaDeclarationGenerator", {
3510
- enumerable: true,
3511
- get: function() {
3512
- return SchemaDeclarationGenerator;
3513
- }
3514
- });
3515
- Object.defineProperty(exports, "SchemaDefinition", {
3516
- enumerable: true,
3517
- get: function() {
3518
- return SchemaDefinition;
3519
- }
3520
- });
3521
- Object.defineProperty(exports, "ShakingPlugin", {
3522
- enumerable: true,
3523
- get: function() {
3524
- return ShakingPlugin;
3525
- }
3526
- });
3527
- Object.defineProperty(exports, "SpringdocCompatPlugin", {
3528
- enumerable: true,
3529
- get: function() {
3530
- return SpringdocCompatPlugin;
3531
- }
3532
- });
3533
- Object.defineProperty(exports, "SupportedMethods", {
3534
- enumerable: true,
3535
- get: function() {
3536
- return SupportedMethods;
3537
- }
3538
- });
3539
- Object.defineProperty(exports, "TerminalSelectPlugin", {
3540
- enumerable: true,
3541
- get: function() {
3542
- return TerminalSelectPlugin;
3543
- }
3544
- });
3545
- Object.defineProperty(exports, "USE_VALIBOT", {
3546
- enumerable: true,
3547
- get: function() {
3548
- return USE_VALIBOT;
3549
- }
3550
- });
3551
- Object.defineProperty(exports, "UseValibotPlugin", {
3552
- enumerable: true,
3553
- get: function() {
3554
- return UseValibotPlugin;
3555
- }
3556
- });
3557
-
3558
- //# sourceMappingURL=plugins-CgMhaNZq.cjs.map