@keq-request/cli 5.0.0-alpha.27 → 5.0.0-alpha.29

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 (109) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cli.cjs +1060 -1112
  3. package/dist/cli.cjs.map +1 -1
  4. package/dist/cli.js +1180 -1232
  5. package/dist/cli.js.map +1 -1
  6. package/dist/compiler/compiler.d.ts.map +1 -1
  7. package/dist/compiler/tasks/setup/index.d.ts.map +1 -1
  8. package/dist/compiler/tasks/setup/utils/index.d.ts +0 -1
  9. package/dist/compiler/tasks/setup/utils/index.d.ts.map +1 -1
  10. package/dist/compiler/tasks/setup/utils/parse-runtime-config.d.ts +3 -0
  11. package/dist/compiler/tasks/setup/utils/parse-runtime-config.d.ts.map +1 -0
  12. package/dist/compiler/types/compiler-context.d.ts +1 -1
  13. package/dist/compiler/types/compiler-context.d.ts.map +1 -1
  14. package/dist/compiler/types/compiler-hooks.d.ts +2 -1
  15. package/dist/compiler/types/compiler-hooks.d.ts.map +1 -1
  16. package/dist/define-config.d.ts +3 -0
  17. package/dist/define-config.d.ts.map +1 -0
  18. package/dist/index.cjs +1130 -1184
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +1041 -1094
  23. package/dist/index.js.map +1 -1
  24. package/dist/models/module-definition.d.ts +3 -2
  25. package/dist/models/module-definition.d.ts.map +1 -1
  26. package/dist/plugins/body-fallback/constants/index.d.ts +2 -0
  27. package/dist/plugins/body-fallback/constants/index.d.ts.map +1 -0
  28. package/dist/plugins/body-fallback/constants/metadata-storage.d.ts +6 -0
  29. package/dist/plugins/body-fallback/constants/metadata-storage.d.ts.map +1 -0
  30. package/dist/plugins/body-fallback/index.d.ts +3 -0
  31. package/dist/plugins/body-fallback/index.d.ts.map +1 -1
  32. package/dist/plugins/chinese-to-pinyin/chinese-to-pinyin.plugin.d.ts +3 -0
  33. package/dist/plugins/chinese-to-pinyin/chinese-to-pinyin.plugin.d.ts.map +1 -1
  34. package/dist/plugins/chinese-to-pinyin/constants/index.d.ts +2 -0
  35. package/dist/plugins/chinese-to-pinyin/constants/index.d.ts.map +1 -0
  36. package/dist/plugins/chinese-to-pinyin/constants/metadata-storage.d.ts +6 -0
  37. package/dist/plugins/chinese-to-pinyin/constants/metadata-storage.d.ts.map +1 -0
  38. package/dist/plugins/download-http-file/constants/index.d.ts +2 -0
  39. package/dist/plugins/download-http-file/constants/index.d.ts.map +1 -0
  40. package/dist/plugins/download-http-file/constants/metadata-storage.d.ts +6 -0
  41. package/dist/plugins/download-http-file/constants/metadata-storage.d.ts.map +1 -0
  42. package/dist/plugins/download-http-file/download-http-file.plugin.d.ts +5 -2
  43. package/dist/plugins/download-http-file/download-http-file.plugin.d.ts.map +1 -1
  44. package/dist/plugins/download-local-file/constants/index.d.ts +2 -0
  45. package/dist/plugins/download-local-file/constants/index.d.ts.map +1 -0
  46. package/dist/plugins/download-local-file/constants/metadata-storage.d.ts +6 -0
  47. package/dist/plugins/download-local-file/constants/metadata-storage.d.ts.map +1 -0
  48. package/dist/plugins/download-local-file/download-local-file.plugin.d.ts +3 -0
  49. package/dist/plugins/download-local-file/download-local-file.plugin.d.ts.map +1 -1
  50. package/dist/plugins/eslint/constants/index.d.ts +2 -0
  51. package/dist/plugins/eslint/constants/index.d.ts.map +1 -0
  52. package/dist/plugins/eslint/constants/metadata-storage.d.ts +6 -0
  53. package/dist/plugins/eslint/constants/metadata-storage.d.ts.map +1 -0
  54. package/dist/plugins/eslint/eslint.plugin.d.ts +18 -0
  55. package/dist/plugins/eslint/eslint.plugin.d.ts.map +1 -0
  56. package/dist/plugins/eslint/index.d.ts +1 -14
  57. package/dist/plugins/eslint/index.d.ts.map +1 -1
  58. package/dist/plugins/generate-declaration/generate-declaration.plugin.d.ts.map +1 -1
  59. package/dist/plugins/generate-declaration/generators/schema-declaration/schema.generator.d.ts.map +1 -1
  60. package/dist/plugins/generate-micro-function/generate-micro-function.plugin.d.ts.map +1 -1
  61. package/dist/plugins/generate-nestjs-module/generate-nestjs-module.d.ts.map +1 -1
  62. package/dist/plugins/initialize/initialize.plugin.d.ts.map +1 -1
  63. package/dist/plugins/prettier/constants/index.d.ts +2 -0
  64. package/dist/plugins/prettier/constants/index.d.ts.map +1 -0
  65. package/dist/plugins/prettier/constants/metadata-storage.d.ts +6 -0
  66. package/dist/plugins/prettier/constants/metadata-storage.d.ts.map +1 -0
  67. package/dist/plugins/prettier/prettier.plugin.d.ts +3 -0
  68. package/dist/plugins/prettier/prettier.plugin.d.ts.map +1 -1
  69. package/dist/plugins/shaking/constants/index.d.ts +2 -0
  70. package/dist/plugins/shaking/constants/index.d.ts.map +1 -0
  71. package/dist/plugins/shaking/constants/metadata-storage.d.ts +6 -0
  72. package/dist/plugins/shaking/constants/metadata-storage.d.ts.map +1 -0
  73. package/dist/plugins/shaking/shaking.plugin.d.ts +3 -0
  74. package/dist/plugins/shaking/shaking.plugin.d.ts.map +1 -1
  75. package/dist/plugins/terminal-select/constants/index.d.ts +2 -0
  76. package/dist/plugins/terminal-select/constants/index.d.ts.map +1 -0
  77. package/dist/plugins/terminal-select/constants/metadata-storage.d.ts +6 -0
  78. package/dist/plugins/terminal-select/constants/metadata-storage.d.ts.map +1 -0
  79. package/dist/plugins/terminal-select/terminal-select.plugin.d.ts +3 -0
  80. package/dist/plugins/terminal-select/terminal-select.plugin.d.ts.map +1 -1
  81. package/dist/plugins.cjs +208 -47
  82. package/dist/plugins.cjs.map +1 -1
  83. package/dist/plugins.js +208 -47
  84. package/dist/plugins.js.map +1 -1
  85. package/dist/translators/index.d.ts +3 -0
  86. package/dist/translators/index.d.ts.map +1 -0
  87. package/dist/translators/micro-function.translator.d.ts +5 -0
  88. package/dist/translators/micro-function.translator.d.ts.map +1 -0
  89. package/dist/translators/nestjs.translator.d.ts +5 -0
  90. package/dist/translators/nestjs.translator.d.ts.map +1 -0
  91. package/dist/translators.cjs +2061 -0
  92. package/dist/translators.cjs.map +1 -0
  93. package/dist/translators.js +2023 -0
  94. package/dist/translators.js.map +1 -0
  95. package/dist/types/address.d.ts +8 -0
  96. package/dist/types/address.d.ts.map +1 -0
  97. package/dist/types/index.d.ts +3 -1
  98. package/dist/types/index.d.ts.map +1 -1
  99. package/dist/types/runtime-config.d.ts +39 -8
  100. package/dist/types/runtime-config.d.ts.map +1 -1
  101. package/dist/types/translator.d.ts +5 -0
  102. package/dist/types/translator.d.ts.map +1 -0
  103. package/dist/utils/is-valid-url.d.ts +16 -0
  104. package/dist/utils/is-valid-url.d.ts.map +1 -0
  105. package/package.json +8 -3
  106. package/dist/compiler/tasks/setup/utils/validate-modules.d.ts +0 -2
  107. package/dist/compiler/tasks/setup/utils/validate-modules.d.ts.map +0 -1
  108. package/dist/define-keq-config.d.ts +0 -3
  109. package/dist/define-keq-config.d.ts.map +0 -1
package/dist/cli.js CHANGED
@@ -28,9 +28,8 @@ import { Listr } from "listr2";
28
28
  import { AsyncParallelHook, AsyncSeriesBailHook, AsyncSeriesHook, SyncHook } from "tapable";
29
29
 
30
30
  // src/compiler/tasks/setup/index.ts
31
- import fs3 from "fs-extra";
32
- import path2 from "path";
33
- import { Value } from "@sinclair/typebox/value";
31
+ import fs4 from "fs-extra";
32
+ import path10 from "path";
34
33
  import { cosmiconfig } from "cosmiconfig";
35
34
 
36
35
  // src/utils/ignore-matcher.ts
@@ -124,8 +123,51 @@ var IgnoreMatcher = class _IgnoreMatcher {
124
123
  }
125
124
  };
126
125
 
127
- // src/types/runtime-config.ts
126
+ // src/compiler/tasks/setup/utils/find-nearest-package-json.ts
127
+ import fs2 from "fs";
128
+ import path from "path";
129
+ function findNearestPackageJson(startDir = process.cwd()) {
130
+ let dir = startDir;
131
+ while (true) {
132
+ const pkgPath = path.join(dir, "package.json");
133
+ if (fs2.existsSync(pkgPath)) {
134
+ const json = JSON.parse(fs2.readFileSync(pkgPath, "utf8"));
135
+ return { json, path: pkgPath };
136
+ }
137
+ const parent = path.dirname(dir);
138
+ if (parent === dir) break;
139
+ dir = parent;
140
+ }
141
+ return null;
142
+ }
143
+
144
+ // src/compiler/tasks/setup/utils/get-project-module-system.ts
145
+ function getProjectModuleSystem(pkgInfo) {
146
+ if (!pkgInfo?.json) return "cjs";
147
+ const { json } = pkgInfo;
148
+ if (json.type === "module") return "esm";
149
+ return "cjs";
150
+ }
151
+
152
+ // src/compiler/tasks/setup/utils/parse-runtime-config.ts
153
+ import { Value } from "@sinclair/typebox/value";
154
+
155
+ // src/types/address.ts
128
156
  import { Type } from "@sinclair/typebox";
157
+ var Address = Type.Object({
158
+ url: Type.String(),
159
+ headers: Type.Optional(Type.Record(Type.String(), Type.String(), { default: {} })),
160
+ encoding: Type.Optional(
161
+ Type.Union([
162
+ Type.Literal("utf8"),
163
+ Type.Literal("ascii")
164
+ ], { default: "utf8" })
165
+ )
166
+ });
167
+
168
+ // src/types/runtime-config.ts
169
+ import * as R2 from "ramda";
170
+ import { Type as Type2 } from "@sinclair/typebox";
129
171
 
130
172
  // src/constants/file-naming-style.ts
131
173
  var FileNamingStyle = /* @__PURE__ */ ((FileNamingStyle2) => {
@@ -143,168 +185,173 @@ var FileNamingStyle = /* @__PURE__ */ ((FileNamingStyle2) => {
143
185
  return FileNamingStyle2;
144
186
  })(FileNamingStyle || {});
145
187
 
188
+ // src/utils/is-valid-url.ts
189
+ var URL_REGEX = /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\/(?:[^\s@]+@)?[^\s/:?#]*(?::\d+)?(?:\/[^\s?#]*)?(?:\?[^\s#]*)?(?:#[^\s]*)?$/;
190
+ function isValidURL(url) {
191
+ return URL_REGEX.test(url);
192
+ }
193
+
146
194
  // src/types/runtime-config.ts
147
- var RuntimeConfig = Type.Object({
148
- mode: Type.Optional(
149
- Type.Union([
150
- Type.Literal("micro-function"),
151
- Type.Literal("nestjs-module"),
152
- Type.Literal("none")
153
- ], { default: "micro-function" })
154
- ),
195
+ var Modules = Type2.Transform(
196
+ Type2.Record(
197
+ Type2.String(),
198
+ Type2.Union([Type2.String(), Address])
199
+ )
200
+ ).Decode((value) => {
201
+ const keys2 = Object.keys(value);
202
+ for (const key of keys2) {
203
+ if (!/^[A-Za-z_][A-Za-z0-9_$]*$/.test(key)) {
204
+ throw new Error(`Module name "${key}" is not valid. It must start with a letter or underscore, and can only contain letters, numbers, and underscores.`);
205
+ }
206
+ }
207
+ const keysGroupByLowerCase = R2.groupBy(R2.toLower, keys2);
208
+ for (const groupKey in keysGroupByLowerCase) {
209
+ const keys3 = keysGroupByLowerCase[groupKey] || [];
210
+ if (keys3.length > 1) {
211
+ throw new Error(`Module names ${keys3.map((name) => `"${name}"`).join(", ")} are case-insensitively duplicated.`);
212
+ }
213
+ }
214
+ for (const key in value) {
215
+ const url = typeof value[key] === "string" ? value[key] : value[key].url;
216
+ if (isValidURL(url)) continue;
217
+ throw new Error(`The ${JSON.stringify(url)} of module "${key}" is not a valid URL.`);
218
+ }
219
+ return R2.map(
220
+ (item) => typeof item !== "string" ? item : { url: item, headers: {}, encoding: "utf8" },
221
+ value
222
+ );
223
+ }).Encode((value) => value);
224
+ var RawConfig = Type2.Object({
155
225
  /**
156
226
  * Whether to generate ES Module code
157
227
  *
158
228
  * If not specified, the module system will be inferred from the nearest package.json "type" field
159
229
  * or defaults to "cjs" if no package.json is found.
160
230
  */
161
- esm: Type.Optional(Type.Boolean({ default: false })),
231
+ esm: Type2.Optional(Type2.Boolean({ default: false })),
162
232
  /**
163
233
  * Output directory for generated files
164
234
  */
165
- outdir: Type.String({ default: `${process.cwd()}/api` }),
235
+ outdir: Type2.String({ default: `${process.cwd()}/api` }),
166
236
  /**
167
237
  * File naming style for generated files
168
238
  */
169
- fileNamingStyle: Type.Enum(FileNamingStyle, { default: "snakeCase" /* snakeCase */ }),
170
- modules: Type.Record(Type.String(), Type.String()),
171
- debug: Type.Optional(Type.Boolean({ default: false })),
239
+ fileNamingStyle: Type2.Enum(FileNamingStyle, { default: "snakeCase" /* snakeCase */ }),
240
+ /**
241
+ * OpenAPI/Swagger document sources
242
+ *
243
+ * A map of module names to their document URLs or Address objects.
244
+ * The module name must be a valid JavaScript identifier.
245
+ */
246
+ modules: Modules,
247
+ /**
248
+ * Enable debug mode to output detailed logs during compilation
249
+ */
250
+ debug: Type2.Optional(Type2.Boolean({ default: false })),
172
251
  /**
173
252
  * Whether to tolerate wrong openapi/swagger structure
174
253
  */
175
- tolerant: Type.Optional(Type.Boolean({ default: false })),
176
- plugins: Type.Optional(Type.Array(Type.Any(), { default: [] }))
254
+ tolerant: Type2.Optional(Type2.Boolean({ default: false })),
255
+ /**
256
+ * Translators to transform generated code
257
+ *
258
+ * Used to customize the code generation process for different frameworks or patterns.
259
+ * Can be a single translator or an array of translators.
260
+ */
261
+ translators: Type2.Optional(
262
+ Type2.Transform(
263
+ Type2.Union([
264
+ Type2.Unsafe(Type2.Any()),
265
+ Type2.Array(Type2.Unsafe(Type2.Any()))
266
+ ], { default: [] })
267
+ ).Decode((value) => {
268
+ if (value === void 0) return [];
269
+ if (Array.isArray(value)) return value;
270
+ return [value];
271
+ }).Encode((value) => value)
272
+ ),
273
+ /**
274
+ * Plugins to extend code generation functionality
275
+ *
276
+ * An array of plugin instances that can hook into various stages of the compilation process,
277
+ * such as code transformation, formatting, linting, or custom file generation.
278
+ */
279
+ plugins: Type2.Optional(Type2.Array(Type2.Unsafe(Type2.Any()), { default: [] }))
177
280
  });
178
281
 
179
- // src/compiler/tasks/setup/utils/validate-modules.ts
180
- import * as R2 from "ramda";
181
- import validator from "validator";
182
- function validateModules(modules) {
183
- const keys2 = Object.keys(modules);
184
- for (const key of keys2) {
185
- if (!/^[A-Za-z_][A-Za-z0-9_$]*$/.test(key)) {
186
- throw new Error(`Module name "${key}" is not valid. It must start with a letter or underscore, and can only contain letters, numbers, and underscores.`);
187
- }
188
- }
189
- const keysGroupByLowerCase = R2.groupBy(R2.toLower, keys2);
190
- for (const groupKey in keysGroupByLowerCase) {
191
- const keys3 = keysGroupByLowerCase[groupKey] || [];
192
- if (keys3.length > 1) {
193
- throw new Error(`Module names ${keys3.map((name) => `"${name}"`).join(", ")} are case-insensitively duplicated.`);
282
+ // src/compiler/tasks/setup/utils/parse-runtime-config.ts
283
+ function parseRuntimeConfig(data) {
284
+ try {
285
+ const originalPlugins = typeof data === "object" && data !== null && "plugins" in data ? data.plugins : void 0;
286
+ const originTranslators = typeof data === "object" && data !== null && "translators" in data ? data.translators : void 0;
287
+ const parsed = Value.Parse(RawConfig, data);
288
+ if (originalPlugins !== void 0) {
289
+ parsed.plugins = originalPlugins;
194
290
  }
195
- }
196
- for (const key in modules) {
197
- const address = modules[key];
198
- if (validator.isURL(address, { require_host: true, require_protocol: true, protocols: ["http", "https"] })) {
199
- continue;
291
+ if (originTranslators !== void 0) {
292
+ parsed.translators = originTranslators;
200
293
  }
201
- if (/^(\/|\.\/|\.\.\/)/.test(address)) {
202
- continue;
294
+ return parsed;
295
+ } catch (error) {
296
+ if (error instanceof Error) {
297
+ error.message = `Invalid Config: ${error.message}`;
203
298
  }
204
- throw new Error(`Module address "${address}" of module "${key}" is not valid. It must be a URL or a local path.`);
299
+ throw error;
205
300
  }
206
301
  }
207
302
 
208
- // src/compiler/tasks/setup/utils/find-nearest-package-json.ts
209
- import fs2 from "fs";
210
- import path from "path";
211
- function findNearestPackageJson(startDir = process.cwd()) {
212
- let dir = startDir;
213
- while (true) {
214
- const pkgPath = path.join(dir, "package.json");
215
- if (fs2.existsSync(pkgPath)) {
216
- const json = JSON.parse(fs2.readFileSync(pkgPath, "utf8"));
217
- return { json, path: pkgPath };
218
- }
219
- const parent = path.dirname(dir);
220
- if (parent === dir) break;
221
- dir = parent;
222
- }
223
- return null;
303
+ // src/plugins/eslint/eslint.plugin.ts
304
+ import { ESLint } from "eslint";
305
+
306
+ // src/plugins/prettier/prettier.plugin.ts
307
+ import { exec } from "child_process";
308
+ import { promisify } from "util";
309
+ var execAsync = promisify(exec);
310
+
311
+ // src/plugins/body-fallback/index.ts
312
+ import * as R21 from "ramda";
313
+
314
+ // src/utils/json-schema-utils/is-array.ts
315
+ function isArray(schema) {
316
+ return schema.type === "array";
224
317
  }
225
318
 
226
- // src/compiler/tasks/setup/utils/get-project-module-system.ts
227
- function getProjectModuleSystem(pkgInfo) {
228
- if (!pkgInfo?.json) return "cjs";
229
- const { json } = pkgInfo;
230
- if (json.type === "module") return "esm";
231
- return "cjs";
319
+ // src/utils/json-schema-utils/is-mixed.ts
320
+ function isMixed(schema) {
321
+ return Array.isArray(schema.type);
232
322
  }
233
323
 
234
- // src/compiler/tasks/setup/index.ts
235
- var explore = cosmiconfig("keq");
236
- function main(compiler, options) {
237
- return {
238
- task: async (context, task) => {
239
- const result = options?.config ? await explore.load(options.config) : await explore.search();
240
- if (!result || "isEmpty" in result && result.isEmpty) {
241
- throw new Error("Cannot find config file.");
242
- }
243
- if (!Value.Check(RuntimeConfig, result.config)) {
244
- const errors = [...Value.Errors(RuntimeConfig, result.config)];
245
- const message = errors.map(({ path: path13, message: message2 }) => `${path13}: ${message2}`).join("\n");
246
- throw new Error(`Invalid Config: ${message}`);
247
- }
248
- const rc = Value.Default(RuntimeConfig, result.config);
249
- validateModules(rc.modules);
250
- if (options?.debug) {
251
- await fs3.ensureDir(".keq");
252
- rc.debug = true;
253
- }
254
- rc.tolerant = Boolean(rc.tolerant);
255
- const packageJsonInfo = findNearestPackageJson();
256
- if (packageJsonInfo) {
257
- const moduleSystem = getProjectModuleSystem(packageJsonInfo);
258
- rc.esm = moduleSystem === "esm";
259
- }
260
- context.rc = rc;
261
- let matcher = new IgnoreMatcher([]);
262
- if (result.filepath) {
263
- const ignoreFilepath = path2.resolve(path2.dirname(result.filepath), ".keqignore");
264
- if (await fs3.exists(ignoreFilepath)) {
265
- matcher = await IgnoreMatcher.read(ignoreFilepath);
266
- }
267
- }
268
- const ignoreRules = options.ignore === false ? [] : options.ignore?.rules || [];
269
- for (const rule of ignoreRules) {
270
- matcher.append({
271
- persist: !!rule.persist,
272
- ignore: rule.ignore,
273
- moduleName: rule.moduleName,
274
- operationMethod: rule.operationMethod,
275
- operationPathname: rule.operationPathname
276
- });
277
- }
278
- context.matcher = matcher;
279
- await compiler.hooks.setup.promise(task);
280
- }
281
- };
324
+ // src/utils/json-schema-utils/is-non-array.ts
325
+ function isNonArray(schema) {
326
+ return typeof schema.type === "string" && schema.type !== "array";
282
327
  }
283
- function createSetupTask(compiler, options) {
284
- return {
285
- title: "Setup",
286
- enabled: options?.enabled,
287
- skip: options?.skip,
288
- task: (context, task) => task.newListr(
289
- [
290
- main(compiler, options),
291
- {
292
- task: (context2, task2) => compiler.hooks.afterSetup.promise(task2)
293
- }
294
- ],
295
- {
296
- concurrent: false
297
- }
298
- )
299
- };
328
+
329
+ // src/utils/json-schema-utils/is-ref.ts
330
+ function isRef(schema) {
331
+ return "$ref" in schema;
300
332
  }
301
333
 
302
- // src/compiler/tasks/download/index.ts
303
- import { PRESET_TIMER } from "listr2";
304
- import { validate } from "@scalar/openapi-parser";
334
+ // src/utils/json-schema-utils/index.ts
335
+ var JsonSchemaUtils = class {
336
+ static isRef = isRef;
337
+ static isArray = isArray;
338
+ static isNonArray = isNonArray;
339
+ static isMixed = isMixed;
340
+ };
341
+
342
+ // src/plugins/generate-micro-function/generate-micro-function.plugin.ts
343
+ import { AsyncSeriesWaterfallHook as AsyncSeriesWaterfallHook2 } from "tapable";
344
+
345
+ // src/plugins/generate-micro-function/constants/metadata-storage.ts
346
+ var MetadataStorage3 = /* @__PURE__ */ new WeakMap();
347
+
348
+ // src/plugins/generate-micro-function/generators/micro_function/micro-function.generator.ts
349
+ import * as R20 from "ramda";
350
+ import * as path8 from "path";
351
+ import * as changeCase6 from "change-case";
305
352
 
306
353
  // src/models/artifact.ts
307
- import * as path3 from "path";
354
+ import * as path2 from "path";
308
355
 
309
356
  // src/models/anchor.ts
310
357
  var AnchorBlock = class {
@@ -390,11 +437,11 @@ var Artifact = class {
390
437
  constructor(options) {
391
438
  this.id = options.id;
392
439
  this.filepath = options.filepath;
393
- this.extensionName = options.extensionName || path3.extname(options.filepath);
440
+ this.extensionName = options.extensionName || path2.extname(options.filepath);
394
441
  this.content = options.content;
395
442
  }
396
443
  get dirname() {
397
- return path3.dirname(this.filepath);
444
+ return path2.dirname(this.filepath);
398
445
  }
399
446
  renderer() {
400
447
  return `${HeaderComment}${this.content}`;
@@ -410,10 +457,14 @@ var ModuleDefinition = class _ModuleDefinition {
410
457
  address;
411
458
  constructor(name, address) {
412
459
  this.name = name;
413
- this.address = address;
460
+ if (typeof address === "string") {
461
+ this.address = { url: address, headers: {}, encoding: "utf8" };
462
+ } else {
463
+ this.address = address;
464
+ }
414
465
  }
415
466
  static unknown() {
416
- return new _ModuleDefinition("", "");
467
+ return new _ModuleDefinition("", { url: "", headers: {}, encoding: "utf8" });
417
468
  }
418
469
  };
419
470
 
@@ -625,8 +676,8 @@ var ApiDocumentV3_1 = class _ApiDocumentV3_1 {
625
676
  }
626
677
  isRefDefined($ref) {
627
678
  if ($ref.startsWith("#/")) {
628
- const path13 = $ref.replace("#/", "").split("/");
629
- return R5.path(path13, this.specification) !== void 0;
679
+ const path12 = $ref.replace("#/", "").split("/");
680
+ return R5.path(path12, this.specification) !== void 0;
630
681
  }
631
682
  return false;
632
683
  }
@@ -638,61 +689,296 @@ var ApiDocumentV3_1 = class _ApiDocumentV3_1 {
638
689
  // src/models/asset.ts
639
690
  var Asset = class {
640
691
  path;
641
- constructor(path13) {
642
- this.path = path13;
692
+ constructor(path12) {
693
+ this.path = path12;
643
694
  }
644
695
  };
645
696
 
646
- // src/exception.ts
647
- import { CustomError } from "ts-custom-error";
648
- import wrap from "word-wrap";
649
- var Exception = class extends CustomError {
650
- constructor(module, message) {
651
- const moduleName = typeof module === "string" ? module : module.name;
652
- const msg = wrap(message, { width: 60, indent: " " });
653
- super(`${moduleName} module failed to compile:
654
- ${msg}`);
655
- Object.defineProperty(this, "name", { value: "KeqCLI_Exception" });
656
- }
657
- };
697
+ // src/plugins/generate-declaration/generate-declaration.plugin.ts
698
+ import { AsyncSeriesWaterfallHook } from "tapable";
658
699
 
659
- // src/utils/openapi-utils/dereference.ts
660
- function dereference($ref, swagger) {
661
- let value;
662
- for (const key of $ref.split("/")) {
663
- if (key === "#") {
664
- value = swagger;
665
- } else {
666
- value = value[key];
700
+ // src/plugins/generate-declaration/generators/operation-declaration/operation.generator.ts
701
+ import * as path7 from "path";
702
+ import * as changeCase5 from "change-case";
703
+
704
+ // src/transformers/json-schema/comment.renderer.ts
705
+ var CommentRenderer = class {
706
+ constructor(schema) {
707
+ this.schema = schema;
708
+ }
709
+ render() {
710
+ const schema = this.schema;
711
+ const lines = ["/**"];
712
+ if (schema.description) {
713
+ const description = schema.description.replace("*/", "*\\/");
714
+ lines.push(...description.split("\n").map((line) => ` * ${line}`));
667
715
  }
668
- if (!value) break;
716
+ if (schema.deprecated) {
717
+ lines.push(" * @deprecated");
718
+ }
719
+ if (schema.readOnly) {
720
+ lines.push(" * @readonly");
721
+ }
722
+ if (schema.format) {
723
+ lines.push(` * @format ${schema.format}`);
724
+ }
725
+ lines.push(" */");
726
+ if (lines.length === 2) return "";
727
+ return lines.join("\n");
669
728
  }
670
- return value;
671
- }
729
+ };
672
730
 
673
- // src/utils/openapi-utils/dereference-operation.ts
731
+ // src/transformers/json-schema/declaration.renderer.ts
732
+ import * as R7 from "ramda";
733
+
734
+ // src/utils/indent.ts
735
+ function indent(space, text) {
736
+ if (text === "") return "";
737
+ const indentation = " ".repeat(space);
738
+ return text.split("\n").map((line) => line ? `${indentation}${line}` : line).join("\n");
739
+ }
740
+
741
+ // src/transformers/json-schema/reference.transformer.ts
742
+ import * as R6 from "ramda";
743
+ var ReferenceTransformer = class {
744
+ static toDeclaration(schema, alias2 = R6.identity) {
745
+ if (!schema.$ref || !schema.$ref.startsWith("#")) return `unknown /* ${schema.$ref.replace("*/", "*\\/")} */`;
746
+ const parts = schema.$ref.split("/");
747
+ return alias2(parts[parts.length - 1]) || "unknown";
748
+ }
749
+ };
750
+
751
+ // src/transformers/json-schema/declaration.renderer.ts
752
+ var DeclarationRenderer = class {
753
+ constructor(schema, options = {}) {
754
+ this.schema = schema;
755
+ this.options = options;
756
+ }
757
+ render() {
758
+ return this.renderSchema(this.schema);
759
+ }
760
+ renderSchema(schema) {
761
+ if (typeof schema === "boolean") return "unknown";
762
+ if (JsonSchemaUtils.isRef(schema)) return this.renderReference(schema);
763
+ if (JsonSchemaUtils.isMixed(schema)) return this.renderMixed(schema);
764
+ if (JsonSchemaUtils.isArray(schema)) return this.renderArray(schema);
765
+ if (schema.type === "object") return this.renderObject(schema);
766
+ if (schema.enum) return this.renderEnum(schema);
767
+ if (schema.oneOf) return this.renderOneOf(schema);
768
+ if (schema.anyOf) return this.renderAnyOf(schema);
769
+ if (schema.allOf) return this.renderAllOf(schema);
770
+ if (schema.type === "string") return this.renderString(schema);
771
+ if (schema.type === "number") return this.renderNumber(schema);
772
+ if (schema.type === "boolean") return this.renderBoolean(schema);
773
+ if (schema.type === "null") return this.renderNull(schema);
774
+ if (schema.type === "integer") return this.renderInteger(schema);
775
+ return "unknown";
776
+ }
777
+ renderMixed(schema) {
778
+ if (Array.isArray(schema.type)) {
779
+ schema.type.map((type) => ({ ...schema, type })).map((schema2) => this.renderSchema(schema2)).join(" | ");
780
+ }
781
+ return "unknown";
782
+ }
783
+ renderReference(schema) {
784
+ if (!this.options.referenceTransformer) {
785
+ return ReferenceTransformer.toDeclaration(schema);
786
+ }
787
+ return this.options.referenceTransformer(schema);
788
+ }
789
+ renderArray(schema) {
790
+ if (schema.items && Array.isArray(schema.items)) {
791
+ const items = schema.items.map((s) => this.renderSchema(s)).join(", ");
792
+ return `[${items}]`;
793
+ }
794
+ if (schema.items && typeof schema.items === "object") {
795
+ return `${this.renderSchema(schema.items)}[]`;
796
+ }
797
+ return "any[]";
798
+ }
799
+ renderObject(schema) {
800
+ if ((!schema.properties || R7.isEmpty(schema.properties)) && (!schema.additionalProperties || R7.isEmpty(schema.additionalProperties))) {
801
+ return "object";
802
+ }
803
+ const $properties = Object.entries(schema.properties || {}).map(([propertyName, propertySchema]) => {
804
+ let $comment = new CommentRenderer(propertySchema).render();
805
+ if ($comment) $comment += "\n";
806
+ const $key = `"${propertyName}"${schema.required?.includes(propertyName) ? "" : "?"}`;
807
+ const $value = this.renderSchema(propertySchema);
808
+ return indent(2, `${$comment}${$key}: ${$value}`);
809
+ });
810
+ if (schema.additionalProperties) {
811
+ const $value = schema.additionalProperties === true ? "any" : this.renderSchema(schema.additionalProperties);
812
+ $properties.push(indent(2, `[key: string]: ${$value}`));
813
+ }
814
+ return [
815
+ "{",
816
+ ...$properties,
817
+ "}"
818
+ ].join("\n");
819
+ }
820
+ renderOneOf(schema) {
821
+ if (!schema.oneOf) return "unknown";
822
+ return schema.oneOf.map((s) => this.renderSchema(s)).join(" | ");
823
+ }
824
+ renderAnyOf(schema) {
825
+ if (!schema.anyOf) return "unknown";
826
+ return schema.anyOf.map((s) => this.renderSchema(s)).join(" | ");
827
+ }
828
+ renderAllOf(schema) {
829
+ if (!schema.allOf) return "unknown";
830
+ return schema.allOf.map((s) => this.renderSchema(s)).join(" & ");
831
+ }
832
+ renderEnum(schema) {
833
+ if (!schema.enum) return "unknown";
834
+ return schema.enum.map((v) => JSON.stringify(v)).join(" | ");
835
+ }
836
+ renderString(schema) {
837
+ if (schema.contentMediaType === "application/octet-stream") return "Blob | Buffer";
838
+ if (schema.format === "binary") return "Blob | Buffer";
839
+ return "string";
840
+ }
841
+ renderNumber(schema) {
842
+ return "number";
843
+ }
844
+ renderBoolean(schema) {
845
+ return "boolean";
846
+ }
847
+ renderNull(schema) {
848
+ return "null";
849
+ }
850
+ renderInteger(schema) {
851
+ return "number";
852
+ }
853
+ };
854
+
855
+ // src/transformers/json-schema/json-schema.transformer.ts
856
+ var JsonSchemaTransformer = class {
857
+ static toComment(schema) {
858
+ return new CommentRenderer(schema).render();
859
+ }
860
+ static toDeclaration(schema, options) {
861
+ return new DeclarationRenderer(schema, options).render();
862
+ }
863
+ };
864
+
865
+ // src/transformers/schema-definition/schema-definition.transformer.ts
674
866
  import * as R8 from "ramda";
867
+ var SchemaDefinitionTransformer = class {
868
+ static toDeclaration(schemaDefinition, options) {
869
+ const dependencies = schemaDefinition.getDependencies();
870
+ let $dependencies = dependencies.filter((dep) => !SchemaDefinition.isUnknown(dep)).map((dep) => {
871
+ const filepath = options.getDependentSchemaDefinitionFilepath(dep);
872
+ return `import type { ${dep.name} } from "${filepath}"`;
873
+ }).map((str) => str.replace(/ from "(\.\.?\/.+?)(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?"/, options.esm ? ' from "$1.js"' : ' from "$1"')).join("\n");
874
+ if ($dependencies) $dependencies += "\n";
875
+ let $comment = JsonSchemaTransformer.toComment(schemaDefinition.schema);
876
+ if ($comment) $comment += "\n";
877
+ if (typeof schemaDefinition.schema === "boolean") {
878
+ return [
879
+ "/* @anchor:file:start */",
880
+ "",
881
+ $dependencies,
882
+ $comment || void 0,
883
+ `type ${schemaDefinition.name} = unknown`,
884
+ "",
885
+ "/* @anchor:file:end */"
886
+ ].filter(R8.isNotNil).join("\n");
887
+ }
888
+ if (JsonSchemaUtils.isNonArray(schemaDefinition.schema) && schemaDefinition.schema.type === "object") {
889
+ const $schema = JsonSchemaTransformer.toDeclaration(schemaDefinition.schema);
890
+ const $declaration = $schema.startsWith("{") ? `export interface ${schemaDefinition.name} ${$schema}` : `export type ${schemaDefinition.name} = ${$schema}`;
891
+ return [
892
+ "/* @anchor:file:start */",
893
+ "",
894
+ $dependencies,
895
+ $comment || void 0,
896
+ $declaration,
897
+ "",
898
+ "/* @anchor:file:end */"
899
+ ].filter(R8.isNotNil).join("\n");
900
+ }
901
+ return [
902
+ "/* @anchor:file:start */",
903
+ "",
904
+ $dependencies,
905
+ $comment || void 0,
906
+ `export type ${schemaDefinition.name} = ${JsonSchemaTransformer.toDeclaration(schemaDefinition.schema)}`,
907
+ "",
908
+ "/* @anchor:file:end */"
909
+ ].filter(R8.isNotNil).join("\n");
910
+ }
911
+ };
912
+
913
+ // src/transformers/operation-definition/comment.renderer.ts
914
+ import * as R9 from "ramda";
915
+ var CommentRenderer2 = class {
916
+ constructor(operationDefinition) {
917
+ this.operationDefinition = operationDefinition;
918
+ }
919
+ render() {
920
+ const operation = this.operationDefinition.operation;
921
+ if (!operation.summary && !operation.description) return "";
922
+ const lines = ["/**"];
923
+ if (operation.summary && typeof operation.summary === "string") {
924
+ lines.push(` * ${R9.trim(operation.summary)}`);
925
+ lines.push(" *");
926
+ }
927
+ if (operation.description && typeof operation.description === "string") {
928
+ lines.push(` * @description ${R9.trim(operation.description)}`);
929
+ }
930
+ lines.push(" */");
931
+ return lines.join("\n");
932
+ }
933
+ };
934
+
935
+ // src/transformers/operation-definition/declaration.renderer.ts
936
+ import * as R14 from "ramda";
937
+
938
+ // src/transformers/operation-definition/utils/type-name-factory.ts
939
+ import * as changeCase from "change-case";
940
+ function typeNameFactory(operationDefinition) {
941
+ const pascalCaseOperationId = changeCase.pascalCase(operationDefinition.operationId);
942
+ return (name) => `${pascalCaseOperationId}${name}`;
943
+ }
944
+
945
+ // src/utils/openapi-utils/dereference.ts
946
+ function dereference($ref, swagger) {
947
+ let value;
948
+ for (const key of $ref.split("/")) {
949
+ if (key === "#") {
950
+ value = swagger;
951
+ } else {
952
+ value = value[key];
953
+ }
954
+ if (!value) break;
955
+ }
956
+ return value;
957
+ }
958
+
959
+ // src/utils/openapi-utils/dereference-operation.ts
960
+ import * as R12 from "ramda";
675
961
  import jsonpointer2 from "jsonpointer";
676
962
  import { JSONPath as JSONPath4 } from "jsonpath-plus";
677
963
 
678
964
  // src/utils/openapi-utils/remove-undefined-ref.ts
679
- import * as R7 from "ramda";
965
+ import * as R11 from "ramda";
680
966
  import jsonpointer from "jsonpointer";
681
967
  import { JSONPath as JSONPath3 } from "jsonpath-plus";
682
968
 
683
969
  // src/utils/openapi-utils/is-ref-defined.ts
684
- import * as R6 from "ramda";
970
+ import * as R10 from "ramda";
685
971
  function isRefDefined($ref, swagger) {
686
972
  if ($ref.startsWith("#/")) {
687
- const path13 = $ref.replace("#/", "").split("/");
688
- return R6.path(path13, swagger) !== void 0;
973
+ const path12 = $ref.replace("#/", "").split("/");
974
+ return R10.path(path12, swagger) !== void 0;
689
975
  }
690
976
  return false;
691
977
  }
692
978
 
693
979
  // src/utils/openapi-utils/remove-undefined-ref.ts
694
980
  function removeUndefinedRef(swagger) {
695
- const shadow = R7.clone(swagger);
981
+ const shadow = R11.clone(swagger);
696
982
  const matches = JSONPath3({
697
983
  path: "$..*['$ref']^",
698
984
  json: swagger,
@@ -700,7 +986,7 @@ function removeUndefinedRef(swagger) {
700
986
  });
701
987
  for (const match of matches) {
702
988
  if (match.value.$ref && !isRefDefined(match.value.$ref, swagger)) {
703
- jsonpointer.set(shadow, match.pointer, R7.omit(["$ref"], match.value));
989
+ jsonpointer.set(shadow, match.pointer, R11.omit(["$ref"], match.value));
704
990
  }
705
991
  }
706
992
  return shadow;
@@ -759,7 +1045,7 @@ function dereferenceParameters(swagger) {
759
1045
  }
760
1046
  }
761
1047
  function dereferenceOperation(swagger) {
762
- const shadow = R8.clone(swagger);
1048
+ const shadow = R12.clone(swagger);
763
1049
  dereferencePathObject(shadow);
764
1050
  dereferenceRequestBody(shadow);
765
1051
  dereferenceResponses(shadow);
@@ -767,34 +1053,6 @@ function dereferenceOperation(swagger) {
767
1053
  return removeUndefinedRef(shadow);
768
1054
  }
769
1055
 
770
- // src/utils/json-schema-utils/is-array.ts
771
- function isArray(schema) {
772
- return schema.type === "array";
773
- }
774
-
775
- // src/utils/json-schema-utils/is-mixed.ts
776
- function isMixed(schema) {
777
- return Array.isArray(schema.type);
778
- }
779
-
780
- // src/utils/json-schema-utils/is-non-array.ts
781
- function isNonArray(schema) {
782
- return typeof schema.type === "string" && schema.type !== "array";
783
- }
784
-
785
- // src/utils/json-schema-utils/is-ref.ts
786
- function isRef(schema) {
787
- return "$ref" in schema;
788
- }
789
-
790
- // src/utils/json-schema-utils/index.ts
791
- var JsonSchemaUtils = class {
792
- static isRef = isRef;
793
- static isArray = isArray;
794
- static isNonArray = isNonArray;
795
- static isMixed = isMixed;
796
- };
797
-
798
1056
  // src/utils/openapi-utils/dereference-deep.ts
799
1057
  function dereferenceDeep($ref, swagger) {
800
1058
  const stack = [$ref];
@@ -823,9 +1081,9 @@ function To3_1(openapi) {
823
1081
  }
824
1082
 
825
1083
  // src/utils/openapi-utils/map-operation.ts
826
- import * as R9 from "ramda";
1084
+ import * as R13 from "ramda";
827
1085
  function mapOperation(specification, mapper) {
828
- const shadow = R9.clone(specification);
1086
+ const shadow = R13.clone(specification);
829
1087
  for (const [pathname, pathItem] of Object.entries(shadow.paths || {})) {
830
1088
  for (const m in pathItem) {
831
1089
  const method = m.toLowerCase();
@@ -860,628 +1118,87 @@ var OpenapiUtils = class {
860
1118
  static to3_1 = To3_1;
861
1119
  };
862
1120
 
863
- // src/compiler/tasks/download/index.ts
864
- function main2(compiler, options) {
865
- return {
866
- task: (context, task) => {
867
- if (!context.rc || !context.matcher) {
868
- throw new Error("Please run setup task first.");
1121
+ // src/transformers/operation-definition/declaration.renderer.ts
1122
+ var alias = (name) => `${name}Schema`;
1123
+ var DeclarationRenderer2 = class {
1124
+ constructor(operationDefinition, options) {
1125
+ this.operationDefinition = operationDefinition;
1126
+ this.options = options;
1127
+ this.typeName = typeNameFactory(operationDefinition);
1128
+ }
1129
+ typeName;
1130
+ renderResponseBodies(operation, options) {
1131
+ if (!operation.responses || R14.isEmpty(operation.responses)) {
1132
+ return `export interface ${this.typeName("ResponseBodies")} {}`;
1133
+ }
1134
+ const $responses = Object.entries(operation.responses).map(([statusCode, response]) => {
1135
+ if (!JsonSchemaUtils.isRef(response)) {
1136
+ const $value = Object.entries(response.content || {}).map(([mediaType, mediaTypeObject]) => [mediaType, mediaTypeObject.schema]).map(([mediaType, schema]) => {
1137
+ if (mediaType.includes("text/event-stream")) return "ReadableStream<ServerSentEvent>";
1138
+ if (mediaType.includes("multipart/form-data")) return "FormData";
1139
+ if (!schema) return "unknown";
1140
+ return JsonSchemaTransformer.toDeclaration(schema, options);
1141
+ }).join(" | ");
1142
+ return indent(2, `${statusCode}: ${$value || "void"}`);
869
1143
  }
870
- const rc = context.rc;
871
- const matcher = context.matcher;
872
- context.documents = [];
873
- return task.newListr(
874
- Object.entries(rc.modules).map(([moduleName, address]) => new ModuleDefinition(moduleName, address)).map((moduleDefinition) => ({
875
- title: moduleDefinition.name,
876
- task: async (ctx, task2) => {
877
- if (options?.skipIgnoredModules && matcher.isModuleIgnored(moduleDefinition)) {
878
- task2.skip(`(${moduleDefinition.name}) is ignored`);
879
- return;
880
- }
881
- task2.output = `Downloaded from ${moduleDefinition.address}`;
882
- const content = await compiler.hooks.download.promise(moduleDefinition.address, moduleDefinition, task2);
883
- if (!content) {
884
- throw new Exception(moduleDefinition, `Cannot download document from ${moduleDefinition.address}`);
885
- }
886
- const spec = JSON.parse(content);
887
- const { valid, errors } = await validate(spec);
888
- if (!valid) {
889
- const message = `${moduleDefinition.name} module openapi/swagger file does not conform to the openapi specifications or have grammatical errors, which may cause unexpected errors:
890
- ${errors?.map((e) => ` - ${e.message}`).join("\n")}`;
891
- task2.output = message;
892
- }
893
- OpenapiUtils.dereferenceOperation(spec);
894
- const document = new ApiDocumentV3_1(
895
- spec,
896
- moduleDefinition
897
- );
898
- ctx.documents?.push(document);
899
- }
900
- })),
901
- {
902
- concurrent: true,
903
- exitOnError: false,
904
- collectErrors: "minimal",
905
- rendererOptions: {
906
- collapseSubtasks: false,
907
- // collapseSkips: false,
908
- suffixSkips: true,
909
- timer: PRESET_TIMER
910
- }
911
- }
912
- );
1144
+ }).join("\n");
1145
+ return [
1146
+ `export interface ${this.typeName("ResponseBodies")} {`,
1147
+ $responses,
1148
+ "}"
1149
+ ].join("\n");
1150
+ }
1151
+ renderRequestBodies(operation, options) {
1152
+ let $requestBodies = `export interface ${this.typeName("RequestBodies")} {}`;
1153
+ if (operation.requestBody && !JsonSchemaUtils.isRef(operation.requestBody)) {
1154
+ const $mediaTypes = Object.entries(operation.requestBody.content || {}).map(([mediaType, mediaTypeObject]) => [mediaType, mediaTypeObject.schema]).map(([mediaType, schema]) => {
1155
+ if (!schema) return `${JSON.stringify(mediaType)}: unknown`;
1156
+ return `${JSON.stringify(mediaType)}: ${JsonSchemaTransformer.toDeclaration(schema, options)}`;
1157
+ }).map((pair) => indent(2, pair));
1158
+ $requestBodies = [
1159
+ `export interface ${this.typeName("RequestBodies")} {`,
1160
+ ...$mediaTypes,
1161
+ "}"
1162
+ ].join("\n");
913
1163
  }
914
- };
915
- }
916
- function createDownloadTask(compiler, options) {
917
- return {
918
- title: "Download",
919
- enabled: options?.enabled,
920
- skip: options?.skip,
921
- task: (_, task) => task.newListr(
922
- [
923
- main2(compiler, options),
924
- {
925
- task: (context, task2) => compiler.hooks.afterDownload.promise(task2)
1164
+ return $requestBodies;
1165
+ }
1166
+ renderParameterBodies(operationDefinition, options) {
1167
+ const { operation } = operationDefinition;
1168
+ let parameterBodies = "";
1169
+ if (operation.requestBody && !JsonSchemaUtils.isRef(operation.requestBody)) {
1170
+ const $mediaTypes = Object.entries(operation.requestBody.content || {}).map(([mediaType, mediaTypeObject]) => [mediaType, mediaTypeObject.schema]).map(([mediaType, schemaOrRef]) => {
1171
+ if (!schemaOrRef) return `${JSON.stringify(mediaType)}: unknown`;
1172
+ const schema = JsonSchemaUtils.isRef(schemaOrRef) ? OpenapiUtils.dereferenceDeep(schemaOrRef.$ref, operationDefinition.document.specification) : schemaOrRef;
1173
+ if (schema.type === "object" || schema.properties) {
1174
+ return `${JSON.stringify(mediaType)}: ${JsonSchemaTransformer.toDeclaration(schemaOrRef, options)} & { [key: string]: any }`;
926
1175
  }
927
- ],
928
- {
929
- concurrent: false
930
- }
931
- )
932
- };
933
- }
934
-
935
- // src/compiler/tasks/persist/index.ts
936
- import * as path6 from "path";
937
- import fs4 from "fs-extra";
938
- function createPersistArtifactTask() {
939
- return {
940
- title: "Write files",
941
- task: async (context, task) => {
942
- if (!context.rc) throw new Error("Please run setup task first.");
943
- if (!context.artifacts || context.artifacts.length === 0) {
944
- task.skip("No compiled artifacts to persist.");
945
- return;
946
- }
947
- const rc = context.rc;
948
- const artifacts = context.artifacts;
949
- const total = artifacts.length;
950
- let completed = 0;
951
- const files = await Promise.all(artifacts.map(async (artifact) => {
952
- const realpath = `./${path6.join(rc.outdir, artifact.filepath)}`;
953
- await fs4.ensureFile(realpath);
954
- await fs4.writeFile(realpath, artifact.renderer());
955
- completed += 1;
956
- task.output = `Persisted ${completed}/${total} files`;
957
- return new Asset(path6.resolve(realpath));
958
- }));
959
- context.assets = files;
1176
+ return `${JSON.stringify(mediaType)}: { [key: string]: any }`;
1177
+ }).map((pair) => indent(2, pair));
1178
+ parameterBodies = [
1179
+ `interface ${this.typeName("ParameterBodies")} {`,
1180
+ ...$mediaTypes,
1181
+ "}",
1182
+ ""
1183
+ ].join("\n");
960
1184
  }
961
- };
962
- }
963
- function createPersistIgnoreTask() {
964
- return {
965
- title: "Update .keqignore",
966
- task: async (context, task) => {
967
- if (!context.matcher) throw new Error("Please run setup task first.");
968
- const matcher = context.matcher;
969
- await matcher.write(".keqignore");
1185
+ return parameterBodies;
1186
+ }
1187
+ renderRequestParameters(operation, options) {
1188
+ const mediaTypes = operation.requestBody && !JsonSchemaUtils.isRef(operation.requestBody) ? Object.keys(operation.requestBody.content || {}) : [];
1189
+ const base = `${this.typeName("RequestQuery")} & ${this.typeName("RouteParameters")} & ${this.typeName("RequestHeaders")}`;
1190
+ if (mediaTypes.length === 1) {
1191
+ return `export type ${this.typeName("RequestParameters")} = ${base} & ${this.typeName("RequestBodies")}[${JSON.stringify(mediaTypes[0])}]`;
970
1192
  }
971
- };
972
- }
973
- function main3() {
974
- return {
975
- task: (context, task) => task.newListr(
976
- [
977
- createPersistArtifactTask(),
978
- createPersistIgnoreTask()
979
- ],
980
- {
981
- concurrent: true,
982
- rendererOptions: {
983
- collapseSubtasks: true
984
- }
985
- }
986
- )
987
- };
988
- }
989
- function createPersistTask(compiler, options) {
990
- return {
991
- title: "Persist",
992
- enabled: options?.enabled,
993
- skip: options?.skip,
994
- task: (context, task) => task.newListr(
995
- [
996
- main3(),
997
- {
998
- task: (context2, task2) => compiler.hooks.afterPersist.promise(task2)
999
- }
1000
- ],
1001
- {
1002
- concurrent: false
1003
- }
1004
- )
1005
- };
1006
- }
1007
-
1008
- // src/compiler/tasks/compile/index.ts
1009
- function main4(compiler) {
1010
- return {
1011
- task: async (context, task) => {
1012
- if (!context.rc) throw new Error("Please run setup task first.");
1013
- if (!context.documents) throw new Error("Please run shaking task first.");
1014
- context.artifacts = [];
1015
- await compiler.hooks.compile.promise(task);
1193
+ if (mediaTypes.length > 1) {
1194
+ const unions = mediaTypes.map((mediaType) => `(${base} & ${this.typeName("RequestBodies")}[${JSON.stringify(mediaType)}] & { "content-type": ${JSON.stringify(mediaType)} })`).join("\n| ");
1195
+ return `export type ${this.typeName("RequestParameters")} = ${unions}`;
1016
1196
  }
1017
- };
1018
- }
1019
- function createCompileTask(compiler, options) {
1020
- return {
1021
- title: "Compile",
1022
- enabled: options?.enabled,
1023
- skip: options?.skip,
1024
- task: (context, task) => task.newListr(
1025
- [
1026
- {
1027
- task: (context2, task2) => compiler.hooks.beforeCompile.promise(task2)
1028
- },
1029
- main4(compiler),
1030
- {
1031
- task: (context2, task2) => compiler.hooks.afterCompile.promise(task2)
1032
- }
1033
- ],
1034
- {
1035
- concurrent: false
1036
- }
1037
- )
1038
- };
1039
- }
1040
-
1041
- // src/compiler/intercepter/print-information.ts
1042
- function proxyTaskWrapper(pluginName, task) {
1043
- return new Proxy(task, {
1044
- set(target, prop2, value) {
1045
- if (prop2 !== "output") {
1046
- return Reflect.set(target, prop2, value);
1047
- }
1048
- target.output = `[Plugin: ${pluginName}] ${value}`;
1049
- return true;
1050
- }
1051
- });
1052
- }
1053
- function printInformation(taskIndex) {
1054
- return {
1055
- register: (tap) => {
1056
- const fn = tap.fn;
1057
- if (tap.type === "promise") {
1058
- tap.fn = (...args) => {
1059
- const task = args[taskIndex];
1060
- const proxyTask = proxyTaskWrapper(tap.name, task);
1061
- args[taskIndex] = proxyTask;
1062
- proxyTask.output = "Processing...";
1063
- return fn(...args);
1064
- };
1065
- }
1066
- if (tap.type === "sync") {
1067
- tap.fn = (...args) => {
1068
- const task = args[taskIndex];
1069
- const proxyTask = proxyTaskWrapper(tap.name, task);
1070
- args[taskIndex] = proxyTask;
1071
- proxyTask.output = "Processing...";
1072
- return fn(...args);
1073
- };
1074
- }
1075
- if (tap.type === "async") {
1076
- tap.fn = (...args) => {
1077
- const task = args[taskIndex];
1078
- const proxyTask = proxyTaskWrapper(tap.name, task);
1079
- args[taskIndex] = proxyTask;
1080
- proxyTask.output = "Processing...";
1081
- return fn(...args);
1082
- };
1083
- }
1084
- return tap;
1085
- }
1086
- };
1087
- }
1088
-
1089
- // src/compiler/intercepter/perfect-error-message.ts
1090
- import * as R10 from "ramda";
1091
- function perfectErrorMessage() {
1092
- return {
1093
- register: (tap) => {
1094
- const fn = tap.fn;
1095
- function prefix(err) {
1096
- if (err instanceof Error) {
1097
- err.message = `[Plugin: ${tap.name}] ${err.message}`;
1098
- }
1099
- }
1100
- if (tap.type === "promise") {
1101
- tap.fn = async (...args) => {
1102
- try {
1103
- return await fn(...args);
1104
- } catch (err) {
1105
- prefix(err);
1106
- throw err;
1107
- }
1108
- };
1109
- }
1110
- if (tap.type === "sync") {
1111
- tap.fn = (...args) => {
1112
- try {
1113
- return fn(...args);
1114
- } catch (err) {
1115
- prefix(err);
1116
- throw err;
1117
- }
1118
- };
1119
- }
1120
- if (tap.type === "async") {
1121
- tap.fn = (...args) => {
1122
- const callback = R10.last(args);
1123
- return fn(...R10.init(args), (err, result) => {
1124
- prefix(err);
1125
- return callback(err, result);
1126
- });
1127
- };
1128
- }
1129
- return tap;
1130
- }
1131
- };
1132
- }
1133
-
1134
- // src/plugins/eslint/index.ts
1135
- import { ESLint } from "eslint";
1136
-
1137
- // src/plugins/prettier/prettier.plugin.ts
1138
- import { exec } from "child_process";
1139
- import { promisify } from "util";
1140
- var execAsync = promisify(exec);
1141
-
1142
- // src/plugins/body-fallback/index.ts
1143
- import * as R22 from "ramda";
1144
-
1145
- // src/plugins/generate-micro-function/generate-micro-function.plugin.ts
1146
- import { AsyncSeriesWaterfallHook as AsyncSeriesWaterfallHook2 } from "tapable";
1147
-
1148
- // src/plugins/generate-micro-function/constants/metadata-storage.ts
1149
- var MetadataStorage = /* @__PURE__ */ new WeakMap();
1150
-
1151
- // src/plugins/generate-micro-function/generators/micro_function/micro-function.generator.ts
1152
- import * as R21 from "ramda";
1153
- import * as path10 from "path";
1154
- import * as changeCase6 from "change-case";
1155
-
1156
- // src/plugins/generate-declaration/generate-declaration.plugin.ts
1157
- import { AsyncSeriesWaterfallHook } from "tapable";
1158
-
1159
- // src/plugins/generate-declaration/generators/operation-declaration/operation.generator.ts
1160
- import * as path9 from "path";
1161
- import * as changeCase5 from "change-case";
1162
-
1163
- // src/transformers/json-schema/comment.renderer.ts
1164
- var CommentRenderer = class {
1165
- constructor(schema) {
1166
- this.schema = schema;
1167
- }
1168
- render() {
1169
- const schema = this.schema;
1170
- const lines = ["/**"];
1171
- if (schema.description) {
1172
- const description = schema.description.replace("*/", "*\\/");
1173
- lines.push(...description.split("\n").map((line) => ` * ${line}`));
1174
- }
1175
- if (schema.deprecated) {
1176
- lines.push(" * @deprecated");
1177
- }
1178
- if (schema.readOnly) {
1179
- lines.push(" * @readonly");
1180
- }
1181
- if (schema.format) {
1182
- lines.push(` * @format ${schema.format}`);
1183
- }
1184
- lines.push(" */");
1185
- if (lines.length === 2) return "";
1186
- return lines.join("\n");
1187
- }
1188
- };
1189
-
1190
- // src/transformers/json-schema/declaration.renderer.ts
1191
- import * as R12 from "ramda";
1192
-
1193
- // src/utils/indent.ts
1194
- function indent(space, text) {
1195
- if (text === "") return "";
1196
- const indentation = " ".repeat(space);
1197
- return text.split("\n").map((line) => line ? `${indentation}${line}` : line).join("\n");
1198
- }
1199
-
1200
- // src/transformers/json-schema/reference.transformer.ts
1201
- import * as R11 from "ramda";
1202
- var ReferenceTransformer = class {
1203
- static toDeclaration(schema, alias2 = R11.identity) {
1204
- if (!schema.$ref || !schema.$ref.startsWith("#")) return `unknown /* ${schema.$ref.replace("*/", "*\\/")} */`;
1205
- const parts = schema.$ref.split("/");
1206
- return alias2(parts[parts.length - 1]) || "unknown";
1207
- }
1208
- };
1209
-
1210
- // src/transformers/json-schema/declaration.renderer.ts
1211
- var DeclarationRenderer = class {
1212
- constructor(schema, options = {}) {
1213
- this.schema = schema;
1214
- this.options = options;
1215
- }
1216
- render() {
1217
- return this.renderSchema(this.schema);
1218
- }
1219
- renderSchema(schema) {
1220
- if (typeof schema === "boolean") return "unknown";
1221
- if (JsonSchemaUtils.isRef(schema)) return this.renderReference(schema);
1222
- if (JsonSchemaUtils.isMixed(schema)) return this.renderMixed(schema);
1223
- if (JsonSchemaUtils.isArray(schema)) return this.renderArray(schema);
1224
- if (schema.type === "object") return this.renderObject(schema);
1225
- if (schema.enum) return this.renderEnum(schema);
1226
- if (schema.oneOf) return this.renderOneOf(schema);
1227
- if (schema.anyOf) return this.renderAnyOf(schema);
1228
- if (schema.allOf) return this.renderAllOf(schema);
1229
- if (schema.type === "string") return this.renderString(schema);
1230
- if (schema.type === "number") return this.renderNumber(schema);
1231
- if (schema.type === "boolean") return this.renderBoolean(schema);
1232
- if (schema.type === "null") return this.renderNull(schema);
1233
- if (schema.type === "integer") return this.renderInteger(schema);
1234
- return "unknown";
1235
- }
1236
- renderMixed(schema) {
1237
- if (Array.isArray(schema.type)) {
1238
- schema.type.map((type) => ({ ...schema, type })).map((schema2) => this.renderSchema(schema2)).join(" | ");
1239
- }
1240
- return "unknown";
1241
- }
1242
- renderReference(schema) {
1243
- if (!this.options.referenceTransformer) {
1244
- return ReferenceTransformer.toDeclaration(schema);
1245
- }
1246
- return this.options.referenceTransformer(schema);
1247
- }
1248
- renderArray(schema) {
1249
- if (schema.items && Array.isArray(schema.items)) {
1250
- const items = schema.items.map((s) => this.renderSchema(s)).join(", ");
1251
- return `[${items}]`;
1252
- }
1253
- if (schema.items && typeof schema.items === "object") {
1254
- return `${this.renderSchema(schema.items)}[]`;
1255
- }
1256
- return "any[]";
1257
- }
1258
- renderObject(schema) {
1259
- if ((!schema.properties || R12.isEmpty(schema.properties)) && (!schema.additionalProperties || R12.isEmpty(schema.additionalProperties))) {
1260
- return "object";
1261
- }
1262
- const $properties = Object.entries(schema.properties || {}).map(([propertyName, propertySchema]) => {
1263
- let $comment = new CommentRenderer(propertySchema).render();
1264
- if ($comment) $comment += "\n";
1265
- const $key = `"${propertyName}"${schema.required?.includes(propertyName) ? "" : "?"}`;
1266
- const $value = this.renderSchema(propertySchema);
1267
- return indent(2, `${$comment}${$key}: ${$value}`);
1268
- });
1269
- if (schema.additionalProperties) {
1270
- const $value = schema.additionalProperties === true ? "any" : this.renderSchema(schema.additionalProperties);
1271
- $properties.push(indent(2, `[key: string]: ${$value}`));
1272
- }
1273
- return [
1274
- "{",
1275
- ...$properties,
1276
- "}"
1277
- ].join("\n");
1278
- }
1279
- renderOneOf(schema) {
1280
- if (!schema.oneOf) return "unknown";
1281
- return schema.oneOf.map((s) => this.renderSchema(s)).join(" | ");
1282
- }
1283
- renderAnyOf(schema) {
1284
- if (!schema.anyOf) return "unknown";
1285
- return schema.anyOf.map((s) => this.renderSchema(s)).join(" | ");
1286
- }
1287
- renderAllOf(schema) {
1288
- if (!schema.allOf) return "unknown";
1289
- return schema.allOf.map((s) => this.renderSchema(s)).join(" & ");
1290
- }
1291
- renderEnum(schema) {
1292
- if (!schema.enum) return "unknown";
1293
- return schema.enum.map((v) => JSON.stringify(v)).join(" | ");
1294
- }
1295
- renderString(schema) {
1296
- if (schema.contentMediaType === "application/octet-stream") return "Blob | Buffer";
1297
- if (schema.format === "binary") return "Blob | Buffer";
1298
- return "string";
1299
- }
1300
- renderNumber(schema) {
1301
- return "number";
1302
- }
1303
- renderBoolean(schema) {
1304
- return "boolean";
1305
- }
1306
- renderNull(schema) {
1307
- return "null";
1308
- }
1309
- renderInteger(schema) {
1310
- return "number";
1311
- }
1312
- };
1313
-
1314
- // src/transformers/json-schema/json-schema.transformer.ts
1315
- var JsonSchemaTransformer = class {
1316
- static toComment(schema) {
1317
- return new CommentRenderer(schema).render();
1318
- }
1319
- static toDeclaration(schema, options) {
1320
- return new DeclarationRenderer(schema, options).render();
1321
- }
1322
- };
1323
-
1324
- // src/transformers/schema-definition/schema-definition.transformer.ts
1325
- import * as R13 from "ramda";
1326
- var SchemaDefinitionTransformer = class {
1327
- static toDeclaration(schemaDefinition, options) {
1328
- const dependencies = schemaDefinition.getDependencies();
1329
- let $dependencies = dependencies.filter((dep) => !SchemaDefinition.isUnknown(dep)).map((dep) => {
1330
- const filepath = options.getDependentSchemaDefinitionFilepath(dep);
1331
- return `import type { ${dep.name} } from "${filepath}"`;
1332
- }).map((str) => str.replace(/ from "(\.\.?\/.+?)(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?"/, options.esm ? ' from "$1.js"' : ' from "$1"')).join("\n");
1333
- if ($dependencies) $dependencies += "\n";
1334
- let $comment = JsonSchemaTransformer.toComment(schemaDefinition.schema);
1335
- if ($comment) $comment += "\n";
1336
- if (typeof schemaDefinition.schema === "boolean") {
1337
- return [
1338
- "/* @anchor:file:start */",
1339
- "",
1340
- $dependencies,
1341
- $comment || void 0,
1342
- `type ${schemaDefinition.name} = unknown`,
1343
- "",
1344
- "/* @anchor:file:end */"
1345
- ].filter(R13.isNotNil).join("\n");
1346
- }
1347
- if (JsonSchemaUtils.isNonArray(schemaDefinition.schema) && schemaDefinition.schema.type === "object") {
1348
- const $schema = JsonSchemaTransformer.toDeclaration(schemaDefinition.schema);
1349
- const $declaration = $schema.startsWith("{") ? `export interface ${schemaDefinition.name} ${$schema}` : `export type ${schemaDefinition.name} = ${$schema}`;
1350
- return [
1351
- "/* @anchor:file:start */",
1352
- "",
1353
- $dependencies,
1354
- $comment || void 0,
1355
- $declaration,
1356
- "",
1357
- "/* @anchor:file:end */"
1358
- ].filter(R13.isNotNil).join("\n");
1359
- }
1360
- return [
1361
- "/* @anchor:file:start */",
1362
- "",
1363
- $dependencies,
1364
- $comment || void 0,
1365
- `export type ${schemaDefinition.name} = ${JsonSchemaTransformer.toDeclaration(schemaDefinition.schema)}`,
1366
- "",
1367
- "/* @anchor:file:end */"
1368
- ].filter(R13.isNotNil).join("\n");
1369
- }
1370
- };
1371
-
1372
- // src/transformers/operation-definition/comment.renderer.ts
1373
- import * as R14 from "ramda";
1374
- var CommentRenderer2 = class {
1375
- constructor(operationDefinition) {
1376
- this.operationDefinition = operationDefinition;
1377
- }
1378
- render() {
1379
- const operation = this.operationDefinition.operation;
1380
- if (!operation.summary && !operation.description) return "";
1381
- const lines = ["/**"];
1382
- if (operation.summary && typeof operation.summary === "string") {
1383
- lines.push(` * ${R14.trim(operation.summary)}`);
1384
- lines.push(" *");
1385
- }
1386
- if (operation.description && typeof operation.description === "string") {
1387
- lines.push(` * @description ${R14.trim(operation.description)}`);
1388
- }
1389
- lines.push(" */");
1390
- return lines.join("\n");
1391
- }
1392
- };
1393
-
1394
- // src/transformers/operation-definition/declaration.renderer.ts
1395
- import * as R15 from "ramda";
1396
-
1397
- // src/transformers/operation-definition/utils/type-name-factory.ts
1398
- import * as changeCase from "change-case";
1399
- function typeNameFactory(operationDefinition) {
1400
- const pascalCaseOperationId = changeCase.pascalCase(operationDefinition.operationId);
1401
- return (name) => `${pascalCaseOperationId}${name}`;
1402
- }
1403
-
1404
- // src/transformers/operation-definition/declaration.renderer.ts
1405
- var alias = (name) => `${name}Schema`;
1406
- var DeclarationRenderer2 = class {
1407
- constructor(operationDefinition, options) {
1408
- this.operationDefinition = operationDefinition;
1409
- this.options = options;
1410
- this.typeName = typeNameFactory(operationDefinition);
1411
- }
1412
- typeName;
1413
- renderResponseBodies(operation, options) {
1414
- if (!operation.responses || R15.isEmpty(operation.responses)) {
1415
- return `export interface ${this.typeName("ResponseBodies")} {}`;
1416
- }
1417
- const $responses = Object.entries(operation.responses).map(([statusCode, response]) => {
1418
- if (!JsonSchemaUtils.isRef(response)) {
1419
- const $value = Object.entries(response.content || {}).map(([mediaType, mediaTypeObject]) => [mediaType, mediaTypeObject.schema]).map(([mediaType, schema]) => {
1420
- if (mediaType.includes("text/event-stream")) return "ReadableStream<ServerSentEvent>";
1421
- if (mediaType.includes("multipart/form-data")) return "FormData";
1422
- if (!schema) return "unknown";
1423
- return JsonSchemaTransformer.toDeclaration(schema, options);
1424
- }).join(" | ");
1425
- return indent(2, `${statusCode}: ${$value || "void"}`);
1426
- }
1427
- }).join("\n");
1428
- return [
1429
- `export interface ${this.typeName("ResponseBodies")} {`,
1430
- $responses,
1431
- "}"
1432
- ].join("\n");
1433
- }
1434
- renderRequestBodies(operation, options) {
1435
- let $requestBodies = `export interface ${this.typeName("RequestBodies")} {}`;
1436
- if (operation.requestBody && !JsonSchemaUtils.isRef(operation.requestBody)) {
1437
- const $mediaTypes = Object.entries(operation.requestBody.content || {}).map(([mediaType, mediaTypeObject]) => [mediaType, mediaTypeObject.schema]).map(([mediaType, schema]) => {
1438
- if (!schema) return `${JSON.stringify(mediaType)}: unknown`;
1439
- return `${JSON.stringify(mediaType)}: ${JsonSchemaTransformer.toDeclaration(schema, options)}`;
1440
- }).map((pair) => indent(2, pair));
1441
- $requestBodies = [
1442
- `export interface ${this.typeName("RequestBodies")} {`,
1443
- ...$mediaTypes,
1444
- "}"
1445
- ].join("\n");
1446
- }
1447
- return $requestBodies;
1448
- }
1449
- renderParameterBodies(operationDefinition, options) {
1450
- const { operation } = operationDefinition;
1451
- let parameterBodies = "";
1452
- if (operation.requestBody && !JsonSchemaUtils.isRef(operation.requestBody)) {
1453
- const $mediaTypes = Object.entries(operation.requestBody.content || {}).map(([mediaType, mediaTypeObject]) => [mediaType, mediaTypeObject.schema]).map(([mediaType, schemaOrRef]) => {
1454
- if (!schemaOrRef) return `${JSON.stringify(mediaType)}: unknown`;
1455
- const schema = JsonSchemaUtils.isRef(schemaOrRef) ? OpenapiUtils.dereferenceDeep(schemaOrRef.$ref, operationDefinition.document.specification) : schemaOrRef;
1456
- if (schema.type === "object" || schema.properties) {
1457
- return `${JSON.stringify(mediaType)}: ${JsonSchemaTransformer.toDeclaration(schemaOrRef, options)} & { [key: string]: any }`;
1458
- }
1459
- return `${JSON.stringify(mediaType)}: { [key: string]: any }`;
1460
- }).map((pair) => indent(2, pair));
1461
- parameterBodies = [
1462
- `interface ${this.typeName("ParameterBodies")} {`,
1463
- ...$mediaTypes,
1464
- "}",
1465
- ""
1466
- ].join("\n");
1467
- }
1468
- return parameterBodies;
1469
- }
1470
- renderRequestParameters(operation, options) {
1471
- const mediaTypes = operation.requestBody && !JsonSchemaUtils.isRef(operation.requestBody) ? Object.keys(operation.requestBody.content || {}) : [];
1472
- const base = `${this.typeName("RequestQuery")} & ${this.typeName("RouteParameters")} & ${this.typeName("RequestHeaders")}`;
1473
- if (mediaTypes.length === 1) {
1474
- return `export type ${this.typeName("RequestParameters")} = ${base} & ${this.typeName("RequestBodies")}[${JSON.stringify(mediaTypes[0])}]`;
1475
- }
1476
- if (mediaTypes.length > 1) {
1477
- const unions = mediaTypes.map((mediaType) => `(${base} & ${this.typeName("RequestBodies")}[${JSON.stringify(mediaType)}] & { "content-type": ${JSON.stringify(mediaType)} })`).join("\n| ");
1478
- return `export type ${this.typeName("RequestParameters")} = ${unions}`;
1479
- }
1480
- return `export type ${this.typeName("RequestParameters")} = ${base}`;
1481
- }
1482
- rendererParameters(name, parameters, options) {
1483
- if (parameters.length === 0) {
1484
- return `export type ${name} = {}`;
1197
+ return `export type ${this.typeName("RequestParameters")} = ${base}`;
1198
+ }
1199
+ rendererParameters(name, parameters, options) {
1200
+ if (parameters.length === 0) {
1201
+ return `export type ${name} = {}`;
1485
1202
  }
1486
1203
  const $parameters = parameters.map((parameter) => {
1487
1204
  const parameterName = `"${parameter.name}"`;
@@ -1562,15 +1279,28 @@ var DeclarationRenderer2 = class {
1562
1279
  "}",
1563
1280
  "",
1564
1281
  "/* @anchor:file:end */"
1565
- ].filter(R15.isNotNil).join("\n");
1282
+ ].filter(R14.isNotNil).join("\n");
1566
1283
  }
1567
1284
  };
1568
1285
 
1569
1286
  // src/transformers/operation-definition/micro-function.renderer.ts
1570
- import * as R17 from "ramda";
1287
+ import * as R16 from "ramda";
1288
+
1289
+ // src/exception.ts
1290
+ import { CustomError } from "ts-custom-error";
1291
+ import wrap from "word-wrap";
1292
+ var Exception = class extends CustomError {
1293
+ constructor(module, message) {
1294
+ const moduleName = typeof module === "string" ? module : module.name;
1295
+ const msg = wrap(message, { width: 60, indent: " " });
1296
+ super(`${moduleName} module failed to compile:
1297
+ ${msg}`);
1298
+ Object.defineProperty(this, "name", { value: "KeqCLI_Exception" });
1299
+ }
1300
+ };
1571
1301
 
1572
1302
  // src/transformers/operation-definition/typescript-snippet.ts
1573
- import * as R16 from "ramda";
1303
+ import * as R15 from "ramda";
1574
1304
 
1575
1305
  // src/constants/qs-array-format.ts
1576
1306
  var QsArrayFormat = /* @__PURE__ */ ((QsArrayFormat2) => {
@@ -1640,7 +1370,7 @@ var OperationDefinitionSnippet = class {
1640
1370
  const { operation } = this.operationDefinition;
1641
1371
  const $query = (operation.parameters || []).filter((p) => !JsonSchemaUtils.isRef(p)).filter((p) => p.in === "query").map((p) => {
1642
1372
  const option = this.getQsParameters(p);
1643
- const $option = !option || R16.isEmpty(option) ? "" : `, ${JSON.stringify(option)}`;
1373
+ const $option = !option || R15.isEmpty(option) ? "" : `, ${JSON.stringify(option)}`;
1644
1374
  return `if (args && ${JSON.stringify(p.name)} in args) req.query(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}]${$option})`;
1645
1375
  }).join("\n");
1646
1376
  return $query;
@@ -1710,7 +1440,7 @@ var OperationDefinitionSnippet = class {
1710
1440
  } catch (err) {
1711
1441
  return this.renderErrorComment(err, mediaType);
1712
1442
  }
1713
- }).filter(R16.isNotNil).join("\n");
1443
+ }).filter(R15.isNotNil).join("\n");
1714
1444
  return $requestBody;
1715
1445
  }
1716
1446
  renderErrorComment(err, mediaType) {
@@ -1785,7 +1515,7 @@ var OperationDefinitionMicroFunctionRenderer = class {
1785
1515
  `${operationId}.pathname = pathname`,
1786
1516
  `${operationId}.method = method`,
1787
1517
  "/* @anchor:file:end */"
1788
- ].filter(R17.isNotNil).join("\n");
1518
+ ].filter(R16.isNotNil).join("\n");
1789
1519
  }
1790
1520
  renderDependencies() {
1791
1521
  const declarationFilepath = this.options.getOperationDefinitionDeclarationFilepath(this.operationDefinition);
@@ -1812,7 +1542,7 @@ var OperationDefinitionMicroFunctionRenderer = class {
1812
1542
  };
1813
1543
 
1814
1544
  // src/transformers/operation-definition/nestjs-method.renderer.ts
1815
- import * as R18 from "ramda";
1545
+ import * as R17 from "ramda";
1816
1546
  var OperationDefinitionNestjsMethodRenderer = class {
1817
1547
  constructor(operationDefinition, options) {
1818
1548
  this.operationDefinition = operationDefinition;
@@ -1865,7 +1595,7 @@ var OperationDefinitionNestjsMethodRenderer = class {
1865
1595
  "",
1866
1596
  " return req",
1867
1597
  "}"
1868
- ].filter(R18.isNotNil).join("\n");
1598
+ ].filter(R17.isNotNil).join("\n");
1869
1599
  }
1870
1600
  renderOperationDeclaration(operationDefinition) {
1871
1601
  const { operationId } = operationDefinition;
@@ -1899,11 +1629,11 @@ var OperationDefinitionTransformer = class {
1899
1629
  };
1900
1630
 
1901
1631
  // src/transformers/entrypoint/entrypoint.transformer.ts
1902
- import * as path7 from "path";
1632
+ import * as path5 from "path";
1903
1633
  var EntrypointTransformer = class {
1904
1634
  static toTypescript(exports, options) {
1905
1635
  const $exports = exports.map((exportArtifact) => {
1906
- const relativePath = path7.relative(
1636
+ const relativePath = path5.relative(
1907
1637
  options.dirpath,
1908
1638
  exportArtifact.filepath
1909
1639
  ).replace(/(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?$/, options.esm ? ".js" : "");
@@ -1920,128 +1650,26 @@ var EntrypointTransformer = class {
1920
1650
  };
1921
1651
 
1922
1652
  // src/transformers/api-document/nestjs-client.renderer.ts
1923
- import * as R19 from "ramda";
1653
+ import * as R18 from "ramda";
1924
1654
  import * as changeCase2 from "change-case";
1925
- var NestjsClientRenderer = class {
1926
- constructor(document, options) {
1927
- this.document = document;
1928
- this.options = options;
1929
- }
1930
- renderDependencies() {
1931
- const $operations = this.document.operations.map((operationDefinition) => {
1932
- const filepath = this.options.getOperationDefinitionDeclarationFilepath(operationDefinition);
1933
- const typeName = typeNameFactory(operationDefinition);
1934
- return `import type { ${typeName("Operation")}, ${typeName("ResponseBodies")}, ${typeName("RequestParameters")} } from "${filepath}"`;
1935
- }).map((str) => str.replace(/ from "(\.\.?\/.+?)(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?"/, this.options.esm ? ' from "$1.js"' : ' from "$1"'));
1936
- return [
1937
- 'import { Injectable, Logger } from "@nestjs/common"',
1938
- 'import { Keq, KeqRequest } from "keq"',
1939
- ...$operations
1940
- ].join("\n");
1941
- }
1942
- render() {
1943
- const moduleName = changeCase2.pascalCase(this.document.module.name);
1944
- const $dependencies = this.renderDependencies();
1945
- const $operations = this.document.operations.map((operation) => OperationDefinitionTransformer.toNestjsMethod(operation, {
1946
- esm: this.options.esm
1947
- })).join("\n\n");
1948
- return [
1949
- "/* @anchor:file:start */",
1950
- "",
1951
- $dependencies,
1952
- "",
1953
- "@Injectable()",
1954
- `export class ${moduleName}Client {`,
1955
- ` private readonly logger = new Logger(${moduleName}Client.name)`,
1956
- "",
1957
- " constructor(",
1958
- " // @anchor:client-constructor-parameters:start",
1959
- " private readonly request: KeqRequest,",
1960
- " // @anchor:client-constructor-parameters:end",
1961
- " ) {}",
1962
- "",
1963
- indent(2, $operations),
1964
- "}",
1965
- "",
1966
- "/* @anchor:file:end */"
1967
- ].filter(R19.isNotNil).join("\n");
1968
- }
1969
- };
1970
1655
 
1971
1656
  // src/transformers/api-document/nestjs-module.renderer.ts
1972
1657
  import * as changeCase3 from "change-case";
1973
- var NestjsModuleRenderer = class {
1974
- constructor(document, options) {
1975
- this.document = document;
1976
- this.options = options;
1977
- }
1978
- render() {
1979
- const moduleName = changeCase3.pascalCase(this.document.module.name);
1980
- const clientFilepath = this.options.getNestjsClientFilepath(this.document).replace(/(\.ts|\.mts|\.cts|\.js|\.cjs|\.mjs)?$/, this.options.esm ? ".js" : "");
1981
- return [
1982
- "/* @anchor:file:start */",
1983
- 'import { Module, Inject, ConfigurableModuleBuilder, Global } from "@nestjs/common"',
1984
- 'import { KeqRequest } from "keq"',
1985
- 'import { KeqModuleOptions } from "@keq-request/nestjs"',
1986
- `import { ${moduleName}Client } from "${clientFilepath}"`,
1987
- "",
1988
- "",
1989
- "const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE, ASYNC_OPTIONS_TYPE } = new ConfigurableModuleBuilder<KeqModuleOptions>().build()",
1990
- "",
1991
- "@Global()",
1992
- "@Module({",
1993
- " imports: [],",
1994
- " controllers: [],",
1995
- ` providers: [${moduleName}Client],`,
1996
- ` exports: [${moduleName}Client],`,
1997
- "})",
1998
- `export class ${moduleName}Module extends ConfigurableModuleClass {`,
1999
- "",
2000
- " constructor(",
2001
- " @Inject(MODULE_OPTIONS_TOKEN) private readonly options: KeqModuleOptions,",
2002
- " private readonly request: KeqRequest,",
2003
- " ) {",
2004
- " super()",
2005
- " }",
2006
- "",
2007
- " onModuleInit() {",
2008
- " if (this.options.middlewares) {",
2009
- " for (const middleware of this.options.middlewares) {",
2010
- " this.request.use(middleware)",
2011
- " }",
2012
- " }",
2013
- " }",
2014
- "}",
2015
- "",
2016
- "/* @anchor:file:end */"
2017
- ].join("\n");
2018
- }
2019
- };
2020
-
2021
- // src/transformers/api-document/api-document.transformer.ts
2022
- var ApiDocumentTransformer = class {
2023
- static toNestjsModule(document, options) {
2024
- return new NestjsModuleRenderer(document, options).render();
2025
- }
2026
- static toNestjsClient(document, options) {
2027
- return new NestjsClientRenderer(document, options).render();
2028
- }
2029
- };
2030
1658
 
2031
1659
  // src/plugins/generate-declaration/generators/schema-declaration/schema.generator.ts
2032
- import * as R20 from "ramda";
2033
- import * as path8 from "path";
1660
+ import * as R19 from "ramda";
1661
+ import * as path6 from "path";
2034
1662
  import * as changeCase4 from "change-case";
2035
1663
 
2036
1664
  // src/plugins/generate-declaration/constants/metadata-storage.ts
2037
- var MetadataStorage2 = /* @__PURE__ */ new WeakMap();
1665
+ var MetadataStorage4 = /* @__PURE__ */ new WeakMap();
2038
1666
 
2039
1667
  // src/plugins/generate-declaration/generators/schema-declaration/schema.generator.ts
2040
1668
  var SCHEMA_GENERATOR = "schemaGenerator";
2041
1669
  var SchemaDeclarationGenerator = class _SchemaDeclarationGenerator {
2042
1670
  async compile(compiler, task) {
2043
1671
  const context = compiler.context;
2044
- const metadata = MetadataStorage2.get(compiler);
1672
+ const metadata = MetadataStorage4.get(compiler);
2045
1673
  const rc = context.rc;
2046
1674
  const documents = context.documents;
2047
1675
  const schemaDefinitions = documents.flatMap((document) => document.schemas);
@@ -2057,7 +1685,7 @@ var SchemaDeclarationGenerator = class _SchemaDeclarationGenerator {
2057
1685
  ])
2058
1686
  )
2059
1687
  );
2060
- const entrypoints = R20.collectBy(
1688
+ const entrypoints = R19.collectBy(
2061
1689
  (schemaDefinition) => schemaDefinition.module.name,
2062
1690
  schemaDefinitions
2063
1691
  ).map((schemaDefinitions2) => [
@@ -2072,7 +1700,7 @@ var SchemaDeclarationGenerator = class _SchemaDeclarationGenerator {
2072
1700
  }
2073
1701
  generateSchemaDefinitionsArtifact(schemaDefinition, rc) {
2074
1702
  const filepath = _SchemaDeclarationGenerator.getSchemaDefinitionArtifactFilepath(schemaDefinition, rc.fileNamingStyle);
2075
- const dirpath = path8.dirname(filepath);
1703
+ const dirpath = path6.dirname(filepath);
2076
1704
  const artifact = new Artifact({
2077
1705
  id: _SchemaDeclarationGenerator.getSchemaDefinitionArtifactId(schemaDefinition),
2078
1706
  filepath,
@@ -2081,7 +1709,7 @@ var SchemaDeclarationGenerator = class _SchemaDeclarationGenerator {
2081
1709
  {
2082
1710
  esm: rc.esm,
2083
1711
  getDependentSchemaDefinitionFilepath(dependentSchemaDefinition) {
2084
- const relativePath = path8.relative(
1712
+ const relativePath = path6.relative(
2085
1713
  dirpath,
2086
1714
  _SchemaDeclarationGenerator.getSchemaDefinitionArtifactFilepath(dependentSchemaDefinition, rc.fileNamingStyle)
2087
1715
  );
@@ -2095,7 +1723,7 @@ var SchemaDeclarationGenerator = class _SchemaDeclarationGenerator {
2095
1723
  }
2096
1724
  generateEntrypointArtifact(moduleDefinition, exports, rc) {
2097
1725
  const filepath = _SchemaDeclarationGenerator.getEntrypointArtifactFilepath(moduleDefinition, rc.fileNamingStyle);
2098
- const dirpath = path8.dirname(filepath);
1726
+ const dirpath = path6.dirname(filepath);
2099
1727
  const artifact = new Artifact({
2100
1728
  id: _SchemaDeclarationGenerator.getEntrypointArtifactId(moduleDefinition),
2101
1729
  filepath,
@@ -2114,7 +1742,7 @@ var SchemaDeclarationGenerator = class _SchemaDeclarationGenerator {
2114
1742
  ].join("/");
2115
1743
  }
2116
1744
  static getEntrypointArtifactId(moduleDefinition) {
2117
- return `${moduleDefinition.address}/components/schemas/entrypoint?generator=${SCHEMA_GENERATOR}`;
1745
+ return `${moduleDefinition.address.url}/components/schemas/entrypoint?generator=${SCHEMA_GENERATOR}`;
2118
1746
  }
2119
1747
  static getSchemaDefinitionArtifactFilepath(schemaDefinition, fileNamingStyle) {
2120
1748
  const filename = `${changeCase4[fileNamingStyle](schemaDefinition.name)}.schema.ts`;
@@ -2137,7 +1765,7 @@ var OPERATION_GENERATOR = "operationDeclarationGenerator";
2137
1765
  var OperationDeclarationGenerator = class _OperationDeclarationGenerator {
2138
1766
  async compile(compiler, task) {
2139
1767
  const context = compiler.context;
2140
- const metadata = MetadataStorage2.get(compiler);
1768
+ const metadata = MetadataStorage4.get(compiler);
2141
1769
  const rc = context.rc;
2142
1770
  const documents = context.documents;
2143
1771
  const operationDefinitions = documents.flatMap((document) => document.operations);
@@ -2157,7 +1785,7 @@ var OperationDeclarationGenerator = class _OperationDeclarationGenerator {
2157
1785
  }
2158
1786
  generateOperationDefinitionArtifact(operationDefinition, rc) {
2159
1787
  const filepath = _OperationDeclarationGenerator.getOperationDefinitionArtifactFilepath(operationDefinition, rc.fileNamingStyle);
2160
- const dirpath = path9.dirname(filepath);
1788
+ const dirpath = path7.dirname(filepath);
2161
1789
  const artifact = new Artifact({
2162
1790
  id: _OperationDeclarationGenerator.getOperationDefinitionArtifactId(operationDefinition),
2163
1791
  filepath,
@@ -2166,7 +1794,7 @@ var OperationDeclarationGenerator = class _OperationDeclarationGenerator {
2166
1794
  {
2167
1795
  esm: rc.esm,
2168
1796
  getDependentSchemaDefinitionFilepath(dependentSchemaDefinition) {
2169
- const relativePath = path9.relative(
1797
+ const relativePath = path7.relative(
2170
1798
  dirpath,
2171
1799
  SchemaDeclarationGenerator.getSchemaDefinitionArtifactFilepath(dependentSchemaDefinition, rc.fileNamingStyle)
2172
1800
  );
@@ -2180,7 +1808,7 @@ var OperationDeclarationGenerator = class _OperationDeclarationGenerator {
2180
1808
  }
2181
1809
  generateEntrypointArtifact(moduleDefinition, exports, rc) {
2182
1810
  const filepath = _OperationDeclarationGenerator.getEntrypointArtifactFilepath(moduleDefinition, rc.fileNamingStyle);
2183
- const dirpath = path9.dirname(filepath);
1811
+ const dirpath = path7.dirname(filepath);
2184
1812
  const artifact = new Artifact({
2185
1813
  id: _OperationDeclarationGenerator.getEntrypointArtifactId(moduleDefinition),
2186
1814
  filepath,
@@ -2212,7 +1840,7 @@ var OperationDeclarationGenerator = class _OperationDeclarationGenerator {
2212
1840
  ].join("/");
2213
1841
  }
2214
1842
  static getEntrypointArtifactId(moduleDefinition) {
2215
- return `${moduleDefinition.address}/paths/entrypoint?generator=${OPERATION_GENERATOR}`;
1843
+ return `${moduleDefinition.address.url}/paths/entrypoint?generator=${OPERATION_GENERATOR}`;
2216
1844
  }
2217
1845
  };
2218
1846
 
@@ -2225,6 +1853,7 @@ var GenerateDeclarationPlugin = class _GenerateDeclarationPlugin {
2225
1853
  constructor() {
2226
1854
  }
2227
1855
  apply(compiler) {
1856
+ if (MetadataStorage4.has(compiler)) return;
2228
1857
  _GenerateDeclarationPlugin.register(compiler);
2229
1858
  compiler.hooks.compile.tapPromise(_GenerateDeclarationPlugin.name, async (task) => {
2230
1859
  compiler.context.artifacts?.push(
@@ -2234,8 +1863,8 @@ var GenerateDeclarationPlugin = class _GenerateDeclarationPlugin {
2234
1863
  });
2235
1864
  }
2236
1865
  static register(compiler) {
2237
- if (!MetadataStorage2.has(compiler)) {
2238
- MetadataStorage2.set(compiler, {
1866
+ if (!MetadataStorage4.has(compiler)) {
1867
+ MetadataStorage4.set(compiler, {
2239
1868
  hooks: {
2240
1869
  afterEntrypointArtifactGenerated: new AsyncSeriesWaterfallHook(["artifact", "task"]),
2241
1870
  afterSchemaDeclarationArtifactGenerated: new AsyncSeriesWaterfallHook(["artifact", "schemaDefinition", "task"]),
@@ -2243,7 +1872,7 @@ var GenerateDeclarationPlugin = class _GenerateDeclarationPlugin {
2243
1872
  }
2244
1873
  });
2245
1874
  }
2246
- return MetadataStorage2.get(compiler);
1875
+ return MetadataStorage4.get(compiler);
2247
1876
  }
2248
1877
  static of(compiler) {
2249
1878
  return this.register(compiler);
@@ -2288,7 +1917,7 @@ var RequestGenerator = class _RequestGenerator {
2288
1917
  var MICRO_FUNCTION_GENERATOR = "microFunctionGenerator";
2289
1918
  var MicroFunctionGenerator = class _MicroFunctionGenerator {
2290
1919
  async compile(compiler, task) {
2291
- const metadata = MetadataStorage.get(compiler);
1920
+ const metadata = MetadataStorage3.get(compiler);
2292
1921
  const context = compiler.context;
2293
1922
  const rc = context.rc;
2294
1923
  const documents = context.documents;
@@ -2306,7 +1935,7 @@ var MicroFunctionGenerator = class _MicroFunctionGenerator {
2306
1935
  )
2307
1936
  );
2308
1937
  const entrypoints = await Promise.all(
2309
- R21.collectBy(
1938
+ R20.collectBy(
2310
1939
  (operationDefinition) => operationDefinition.module.name,
2311
1940
  operationDefinitions
2312
1941
  ).map((operationDefinitions2) => [
@@ -2325,21 +1954,21 @@ var MicroFunctionGenerator = class _MicroFunctionGenerator {
2325
1954
  }
2326
1955
  generateOperationDefinitionArtifact(operationDefinition, rc) {
2327
1956
  const filepath = _MicroFunctionGenerator.getOperationDefinitionArtifactFilepath(operationDefinition, rc.fileNamingStyle);
2328
- const dirpath = path10.dirname(filepath);
1957
+ const dirpath = path8.dirname(filepath);
2329
1958
  const artifact = new Artifact({
2330
1959
  id: _MicroFunctionGenerator.getOperationDefinitionArtifactId(operationDefinition),
2331
1960
  filepath,
2332
1961
  content: OperationDefinitionTransformer.toMicroFunction(operationDefinition, {
2333
1962
  esm: rc.esm,
2334
1963
  getOperationDefinitionDeclarationFilepath(operationDefinition2) {
2335
- const relativePath = path10.relative(
1964
+ const relativePath = path8.relative(
2336
1965
  dirpath,
2337
1966
  OperationDeclarationGenerator.getOperationDefinitionArtifactFilepath(operationDefinition2, rc.fileNamingStyle)
2338
1967
  );
2339
1968
  return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2340
1969
  },
2341
1970
  getRequestFilepath() {
2342
- const relativePath = path10.relative(
1971
+ const relativePath = path8.relative(
2343
1972
  dirpath,
2344
1973
  RequestGenerator.getRequestArtifactFilepath()
2345
1974
  );
@@ -2391,6 +2020,7 @@ var GenerateMicroFunctionPlugin = class _GenerateMicroFunctionPlugin {
2391
2020
  microFunctionGenerator = new MicroFunctionGenerator();
2392
2021
  requestGenerator = new RequestGenerator();
2393
2022
  apply(compiler) {
2023
+ if (MetadataStorage3.has(compiler)) return;
2394
2024
  _GenerateMicroFunctionPlugin.register(compiler);
2395
2025
  compiler.hooks.compile.tapPromise(_GenerateMicroFunctionPlugin.name, async (task) => {
2396
2026
  const artifacts = [
@@ -2401,15 +2031,15 @@ var GenerateMicroFunctionPlugin = class _GenerateMicroFunctionPlugin {
2401
2031
  });
2402
2032
  }
2403
2033
  static register(compiler) {
2404
- if (!MetadataStorage.has(compiler)) {
2405
- MetadataStorage.set(compiler, {
2034
+ if (!MetadataStorage3.has(compiler)) {
2035
+ MetadataStorage3.set(compiler, {
2406
2036
  hooks: {
2407
2037
  afterEntrypointArtifactGenerated: new AsyncSeriesWaterfallHook2(["artifact", "task"]),
2408
2038
  afterMicroFunctionArtifactGenerated: new AsyncSeriesWaterfallHook2(["artifact", "operationDefinition", "task"])
2409
2039
  }
2410
2040
  });
2411
2041
  }
2412
- return MetadataStorage.get(compiler);
2042
+ return MetadataStorage3.get(compiler);
2413
2043
  }
2414
2044
  static of(compiler) {
2415
2045
  return this.register(compiler);
@@ -2419,328 +2049,646 @@ var GenerateMicroFunctionPlugin = class _GenerateMicroFunctionPlugin {
2419
2049
  // src/plugins/generate-nestjs-module/generate-nestjs-module.ts
2420
2050
  import { AsyncSeriesWaterfallHook as AsyncSeriesWaterfallHook3 } from "tapable";
2421
2051
 
2422
- // src/plugins/generate-nestjs-module/constants/metadata-storage.ts
2423
- var MetadataStorage3 = /* @__PURE__ */ new WeakMap();
2424
-
2425
2052
  // src/plugins/generate-nestjs-module/generators/nestjs-module.generator.ts
2426
- import * as path11 from "path";
2427
2053
  import * as changeCase7 from "change-case";
2428
- var NESTJS_MODULE_GENERATOR = "nestjs-module-generator";
2429
- var NestjsModuleGenerator = class _NestjsModuleGenerator {
2430
- generateNestjsModuleArtifact(document, rc) {
2431
- const filepath = _NestjsModuleGenerator.getNestjsModuleArtifactFilepath(document, rc.fileNamingStyle);
2432
- const dirname6 = path11.dirname(filepath);
2433
- const artifact = new Artifact({
2434
- id: _NestjsModuleGenerator.getNestjsModuleArtifactId(document),
2435
- filepath,
2436
- content: ApiDocumentTransformer.toNestjsModule(document, {
2437
- esm: rc.esm,
2438
- getNestjsClientFilepath(document2) {
2439
- const relativePath = path11.relative(
2440
- dirname6,
2441
- _NestjsModuleGenerator.getNestjsClientArtifactFilepath(document2, rc.fileNamingStyle)
2442
- );
2443
- return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2444
- }
2445
- })
2054
+
2055
+ // src/plugins/chinese-to-pinyin/chinese-to-pinyin.plugin.ts
2056
+ import { fixSwagger } from "swagger-fix";
2057
+
2058
+ // src/plugins/download-http-file/constants/metadata-storage.ts
2059
+ var MetadataStorage8 = /* @__PURE__ */ new WeakMap();
2060
+
2061
+ // src/plugins/download-http-file/download-http-file.plugin.ts
2062
+ var DownloadHttpFilePlugin = class _DownloadHttpFilePlugin {
2063
+ apply(compiler) {
2064
+ if (MetadataStorage8.has(compiler)) return;
2065
+ _DownloadHttpFilePlugin.register(compiler);
2066
+ compiler.hooks.download.tapPromise(_DownloadHttpFilePlugin.name, async (address, task) => {
2067
+ const { url } = address;
2068
+ if (!url.startsWith("http://") && !url.startsWith("https://")) return void 0;
2069
+ const content = await this.download(address);
2070
+ const spec = this.deserialize(content);
2071
+ return JSON.stringify(spec);
2446
2072
  });
2447
- return artifact;
2448
2073
  }
2449
- generateNestjsClientArtifact(document, rc) {
2450
- const filepath = _NestjsModuleGenerator.getNestjsClientArtifactFilepath(document, rc.fileNamingStyle);
2451
- const dirpath = path11.dirname(filepath);
2452
- const artifact = new Artifact({
2453
- id: _NestjsModuleGenerator.getNestjsClientArtifactId(document),
2454
- filepath,
2455
- content: ApiDocumentTransformer.toNestjsClient(document, {
2456
- esm: rc.esm,
2457
- getOperationDefinitionDeclarationFilepath(operationDefinition) {
2458
- const relativePath = path11.relative(
2459
- dirpath,
2460
- OperationDeclarationGenerator.getOperationDefinitionArtifactFilepath(operationDefinition, rc.fileNamingStyle)
2461
- );
2462
- return relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
2463
- }
2464
- })
2074
+ async download(address) {
2075
+ const { url, headers } = address;
2076
+ try {
2077
+ const res = await fetch(url, { headers });
2078
+ if (res.status >= 400) throw new Error(`failed with status code ${res.status}`);
2079
+ return await res.text();
2080
+ } catch (e) {
2081
+ if (e instanceof Error) {
2082
+ e.message = `Unable get the openapi/swagger file from ${url}: ${e.message}`;
2083
+ }
2084
+ throw e;
2085
+ }
2086
+ }
2087
+ deserialize(content) {
2088
+ const json = JSON.parse(content);
2089
+ const spec = OpenapiUtils.to3_1(json);
2090
+ return spec;
2091
+ }
2092
+ static register(compiler) {
2093
+ if (!MetadataStorage8.has(compiler)) {
2094
+ MetadataStorage8.set(compiler, {
2095
+ hooks: {}
2096
+ });
2097
+ }
2098
+ return MetadataStorage8.get(compiler);
2099
+ }
2100
+ static of(compiler) {
2101
+ return this.register(compiler);
2102
+ }
2103
+ };
2104
+
2105
+ // src/plugins/download-local-file/download-local-file.plugin.ts
2106
+ import * as path9 from "path";
2107
+ import * as fs3 from "fs/promises";
2108
+ import * as yaml from "js-yaml";
2109
+ import { fileURLToPath } from "url";
2110
+
2111
+ // src/plugins/download-local-file/constants/metadata-storage.ts
2112
+ var MetadataStorage9 = /* @__PURE__ */ new WeakMap();
2113
+
2114
+ // src/plugins/download-local-file/download-local-file.plugin.ts
2115
+ var DownloadLocalFilePlugin = class _DownloadLocalFilePlugin {
2116
+ apply(compiler) {
2117
+ if (MetadataStorage9.has(compiler)) return;
2118
+ _DownloadLocalFilePlugin.register(compiler);
2119
+ compiler.hooks.download.tapPromise(_DownloadLocalFilePlugin.name, async (address, task) => {
2120
+ const { url, encoding } = address;
2121
+ if (!url.startsWith("file://")) return void 0;
2122
+ const filepath = fileURLToPath(url);
2123
+ const fileExt = path9.extname(filepath);
2124
+ const content = await fs3.readFile(filepath, encoding);
2125
+ const str = typeof content === "string" ? content : content.toString(encoding);
2126
+ if ([".yml", ".yaml"].includes(fileExt)) {
2127
+ const value = yaml.load(str);
2128
+ return JSON.stringify(OpenapiUtils.to3_1(value));
2129
+ } else if (fileExt === ".json") {
2130
+ return JSON.stringify(OpenapiUtils.to3_1(JSON.parse(str)));
2131
+ }
2465
2132
  });
2466
- return artifact;
2467
2133
  }
2468
- async compile(compiler, task) {
2469
- const metadata = MetadataStorage3.get(compiler);
2134
+ static register(compiler) {
2135
+ if (!MetadataStorage9.has(compiler)) {
2136
+ MetadataStorage9.set(compiler, {
2137
+ hooks: {}
2138
+ });
2139
+ }
2140
+ return MetadataStorage9.get(compiler);
2141
+ }
2142
+ static of(compiler) {
2143
+ return this.register(compiler);
2144
+ }
2145
+ };
2146
+
2147
+ // src/plugins/shaking/shaking.plugin.ts
2148
+ import { openapiShakingSync } from "@opendoc/openapi-shaking";
2149
+
2150
+ // src/plugins/shaking/constants/metadata-storage.ts
2151
+ var MetadataStorage10 = /* @__PURE__ */ new WeakMap();
2152
+
2153
+ // src/plugins/shaking/shaking.plugin.ts
2154
+ var ShakingPlugin = class _ShakingPlugin {
2155
+ apply(compiler) {
2156
+ if (MetadataStorage10.has(compiler)) return;
2157
+ _ShakingPlugin.register(compiler);
2158
+ compiler.hooks.beforeCompile.tap(_ShakingPlugin.name, (task) => {
2159
+ const matcher = compiler.context.matcher;
2160
+ const documents = compiler.context.documents;
2161
+ compiler.context.documents = documents.map((document) => this.shaking(compiler, document)).filter((document) => !document.isEmpty()).filter((document) => !matcher.isModuleIgnored(document.module));
2162
+ });
2163
+ }
2164
+ shaking(compiler, document) {
2470
2165
  const rc = compiler.context.rc;
2471
- const documents = compiler.context.documents;
2472
- const nestjsModuleArtifacts = await Promise.all(
2473
- documents.map((document) => metadata.hooks.afterNestjsModuleArtifactGenerated.promise(
2474
- this.generateNestjsModuleArtifact(document, rc),
2475
- document,
2476
- task
2477
- ))
2166
+ const matcher = compiler.context.matcher;
2167
+ const isAccepted = (pathname, method, operation) => {
2168
+ if (!SupportedMethods.includes(method)) return false;
2169
+ return !matcher.isOperationIgnored(new OperationDefinition({
2170
+ method,
2171
+ pathname,
2172
+ operation,
2173
+ module: document.module,
2174
+ document
2175
+ }));
2176
+ };
2177
+ const sharkedSwagger = openapiShakingSync(
2178
+ document.specification,
2179
+ isAccepted,
2180
+ { tolerant: rc.tolerant }
2478
2181
  );
2479
- const nestjsClientArtifacts = await Promise.all(
2480
- documents.map((document) => metadata.hooks.afterNestjsModuleArtifactGenerated.promise(
2481
- this.generateNestjsClientArtifact(document, rc),
2482
- document,
2483
- task
2484
- ))
2182
+ return new ApiDocumentV3_1(
2183
+ sharkedSwagger,
2184
+ new ModuleDefinition(
2185
+ document.module.name,
2186
+ {
2187
+ url: `memory://${document.module.name}.v3_1.sharked.json`,
2188
+ headers: {},
2189
+ encoding: "utf8"
2190
+ }
2191
+ )
2485
2192
  );
2486
- return [...nestjsModuleArtifacts, ...nestjsClientArtifacts];
2487
- }
2488
- static getNestjsModuleArtifactFilepath(document, fileNamingStyle) {
2489
- const filename = `${changeCase7[fileNamingStyle](document.module.name)}.module.ts`;
2490
- const filepath = [
2491
- ".",
2492
- changeCase7[fileNamingStyle](document.module.name),
2493
- filename
2494
- ];
2495
- return filepath.join("/");
2496
2193
  }
2497
- static getNestjsModuleArtifactId(document) {
2498
- return `${document.module.address}?generate=${NESTJS_MODULE_GENERATOR}`;
2499
- }
2500
- static getNestjsClientArtifactFilepath(document, fileNamingStyle) {
2501
- const filename = `${changeCase7[fileNamingStyle](document.module.name)}.client.ts`;
2502
- const filepath = [
2503
- ".",
2504
- changeCase7[fileNamingStyle](document.module.name),
2505
- filename
2506
- ];
2507
- return filepath.join("/");
2194
+ static register(compiler) {
2195
+ if (!MetadataStorage10.has(compiler)) {
2196
+ MetadataStorage10.set(compiler, {
2197
+ hooks: {}
2198
+ });
2199
+ }
2200
+ return MetadataStorage10.get(compiler);
2508
2201
  }
2509
- static getNestjsClientArtifactId(document) {
2510
- return `${document.module.address}?generate=${NESTJS_MODULE_GENERATOR}-client`;
2202
+ static of(compiler) {
2203
+ return this.register(compiler);
2511
2204
  }
2512
2205
  };
2513
2206
 
2514
- // src/plugins/generate-nestjs-module/generate-nestjs-module.ts
2515
- var GenerateNestjsModulePlugin = class _GenerateNestjsModulePlugin {
2516
- nestjsModuleGenerator = new NestjsModuleGenerator();
2207
+ // src/plugins/terminal-select/utils/select-operation-definitions.ts
2208
+ import { select } from "inquirer-select-pro";
2209
+ import { ListrInquirerPromptAdapter } from "@listr2/prompt-adapter-inquirer";
2210
+ async function selectOperationDefinitions(task, operationDefinitions) {
2211
+ const selectedOperationDefinitions = await task.prompt(ListrInquirerPromptAdapter).run(
2212
+ select,
2213
+ {
2214
+ message: "Select Pathname",
2215
+ defaultValue: [],
2216
+ options: (input) => {
2217
+ const items = operationDefinitions.map((op) => ({ name: `${op.module.name} ${op.method.toUpperCase()} ${op.pathname}`, value: op }));
2218
+ if (!input) return items;
2219
+ const keys2 = input.trim().toLowerCase().split(/\s+/);
2220
+ return items.filter((i) => {
2221
+ const name = i.name.toLowerCase();
2222
+ return keys2.every((q) => name.includes(q));
2223
+ });
2224
+ }
2225
+ }
2226
+ );
2227
+ return selectedOperationDefinitions;
2228
+ }
2229
+
2230
+ // src/plugins/terminal-select/constants/metadata-storage.ts
2231
+ var MetadataStorage11 = /* @__PURE__ */ new WeakMap();
2232
+
2233
+ // src/plugins/terminal-select/terminal-select.plugin.ts
2234
+ var TerminalSelectPlugin = class _TerminalSelectPlugin {
2235
+ constructor(options) {
2236
+ this.options = options;
2237
+ }
2517
2238
  apply(compiler) {
2518
- _GenerateNestjsModulePlugin.register(compiler);
2519
- compiler.hooks.compile.tapPromise(_GenerateNestjsModulePlugin.name, async (task) => {
2520
- const artifacts = await this.nestjsModuleGenerator.compile(compiler, task);
2521
- compiler.context.artifacts.push(...artifacts);
2239
+ if (MetadataStorage11.has(compiler)) return;
2240
+ _TerminalSelectPlugin.register(compiler);
2241
+ compiler.hooks.afterDownload.tapPromise(_TerminalSelectPlugin.name, async (task) => {
2242
+ const context = compiler.context;
2243
+ const matcher = context.matcher;
2244
+ const documents = context.documents;
2245
+ const operationDefinitions = documents.flatMap((document) => document.operations);
2246
+ const selectedOperationDefinitions = await selectOperationDefinitions(task, operationDefinitions);
2247
+ if (this.options.clear) {
2248
+ matcher.append({
2249
+ persist: false,
2250
+ ignore: true,
2251
+ moduleName: "*",
2252
+ operationMethod: "*",
2253
+ operationPathname: "*"
2254
+ });
2255
+ }
2256
+ for (const op of selectedOperationDefinitions) {
2257
+ matcher.append({
2258
+ persist: !!this.options.persist,
2259
+ ignore: this.options.mode === "add",
2260
+ moduleName: op.module.name,
2261
+ operationMethod: op.method,
2262
+ operationPathname: op.pathname
2263
+ });
2264
+ }
2522
2265
  });
2523
2266
  }
2524
- static register(compiler) {
2525
- if (!MetadataStorage3.has(compiler)) {
2526
- MetadataStorage3.set(compiler, {
2527
- hooks: {
2528
- afterNestjsModuleArtifactGenerated: new AsyncSeriesWaterfallHook3(["artifact", "document", "task"])
2529
- }
2267
+ static register(compiler) {
2268
+ if (!MetadataStorage11.has(compiler)) {
2269
+ MetadataStorage11.set(compiler, {
2270
+ hooks: {}
2530
2271
  });
2531
2272
  }
2532
- return MetadataStorage3.get(compiler);
2273
+ return MetadataStorage11.get(compiler);
2533
2274
  }
2534
2275
  static of(compiler) {
2535
- return MetadataStorage3.get(compiler);
2276
+ return this.register(compiler);
2536
2277
  }
2537
2278
  };
2538
2279
 
2539
- // src/plugins/chinese-to-pinyin/chinese-to-pinyin.plugin.ts
2540
- import { fixSwagger } from "swagger-fix";
2541
-
2542
- // src/plugins/download-http-file/download-http-file.plugin.ts
2543
- import * as validUrl from "valid-url";
2544
- var DownloadHttpFilePlugin = class _DownloadHttpFilePlugin {
2545
- apply(compiler) {
2546
- compiler.hooks.download.tapPromise(_DownloadHttpFilePlugin.name, async (address, task) => {
2547
- if (!validUrl.isUri(address)) return void 0;
2548
- const content = await this.download(address);
2549
- const spec = this.deserialize(content);
2550
- return JSON.stringify(spec);
2551
- });
2280
+ // src/plugins/initialize/initialize.plugin.ts
2281
+ import * as R22 from "ramda";
2282
+ var InitializePlugin = class _InitializePlugin {
2283
+ constructor(options) {
2284
+ this.options = options;
2552
2285
  }
2553
- async download(address) {
2554
- try {
2555
- const res = await fetch(address);
2556
- if (res.status >= 400) throw new Error(`failed with status code ${res.status}`);
2557
- return await res.text();
2558
- } catch (e) {
2559
- if (e instanceof Error) {
2560
- e.message = `Unable get the openapi/swagger file from ${address}: ${e.message}`;
2286
+ apply(compiler) {
2287
+ compiler.hooks.setup.tap(_InitializePlugin.name, (task) => {
2288
+ const plugins = [
2289
+ new DownloadHttpFilePlugin(),
2290
+ new DownloadLocalFilePlugin()
2291
+ ];
2292
+ if (this.options.build) {
2293
+ plugins.push(new ShakingPlugin());
2561
2294
  }
2562
- throw e;
2295
+ if (this.options.interactive) {
2296
+ plugins.push(
2297
+ new TerminalSelectPlugin(
2298
+ typeof this.options.interactive === "object" ? this.options.interactive : { mode: "except" }
2299
+ )
2300
+ );
2301
+ }
2302
+ const rc = compiler.context.rc;
2303
+ plugins.push(
2304
+ ...R22.unnest(
2305
+ (rc.translators || []).map((translator) => {
2306
+ const plugins2 = translator.apply();
2307
+ return plugins2;
2308
+ })
2309
+ )
2310
+ );
2311
+ if (rc.plugins && rc.plugins.length) {
2312
+ plugins.push(...rc.plugins);
2313
+ }
2314
+ for (const plugin of plugins) {
2315
+ plugin.apply(compiler);
2316
+ }
2317
+ });
2318
+ if (this.options.includes && this.options.includes.length) {
2319
+ const modulesIncludes = this.options.includes;
2320
+ compiler.hooks.afterSetup.tap(_InitializePlugin.name, (task) => {
2321
+ const rc = compiler.context.rc;
2322
+ const matcher = compiler.context.matcher;
2323
+ const notExistModules = modulesIncludes.filter((moduleName) => !(moduleName in rc.modules));
2324
+ if (notExistModules.length) {
2325
+ throw new Error(`Cannot find module(s) ${notExistModules.join(", ")} in config file.`);
2326
+ }
2327
+ const ignoredModules = R22.difference(R22.keys(rc.modules), modulesIncludes);
2328
+ for (const moduleName of ignoredModules) {
2329
+ matcher.append({
2330
+ persist: false,
2331
+ ignore: true,
2332
+ moduleName,
2333
+ operationMethod: "*",
2334
+ operationPathname: "*"
2335
+ });
2336
+ }
2337
+ });
2563
2338
  }
2564
2339
  }
2565
- deserialize(content) {
2566
- const json = JSON.parse(content);
2567
- const spec = OpenapiUtils.to3_1(json);
2568
- return spec;
2340
+ };
2341
+
2342
+ // src/plugins/overwrite-query-options/overwrite-query-options.plugin.ts
2343
+ var QsArrayFormatUnion = Object.values(QsArrayFormat);
2344
+
2345
+ // src/translators/micro-function.translator.ts
2346
+ var MicroFunctionTranslator = class {
2347
+ apply() {
2348
+ return [
2349
+ new GenerateDeclarationPlugin(),
2350
+ new GenerateMicroFunctionPlugin()
2351
+ ];
2569
2352
  }
2570
2353
  };
2571
2354
 
2572
- // src/plugins/download-local-file/download-local-file.plugin.ts
2573
- import * as path12 from "path";
2574
- import * as fs5 from "fs/promises";
2575
- import * as yaml from "js-yaml";
2576
- var DownloadLocalFilePlugin = class _DownloadLocalFilePlugin {
2577
- apply(compiler) {
2578
- compiler.hooks.download.tapPromise(_DownloadLocalFilePlugin.name, async (address, task) => {
2579
- if (!address.startsWith("./") && !address.startsWith("/") && !address.startsWith("../")) return void 0;
2580
- const fileExt = path12.extname(address);
2581
- const content = await fs5.readFile(address, "utf8");
2582
- if ([".yml", ".yaml"].includes(fileExt)) {
2583
- const value = yaml.load(content);
2584
- return JSON.stringify(OpenapiUtils.to3_1(value));
2585
- } else if (fileExt === ".json") {
2586
- return JSON.stringify(OpenapiUtils.to3_1(JSON.parse(content)));
2355
+ // src/compiler/tasks/setup/index.ts
2356
+ var explore = cosmiconfig("keq");
2357
+ function main(compiler, options) {
2358
+ return {
2359
+ task: async (context, task) => {
2360
+ const result = options?.config ? await explore.load(options.config) : await explore.search();
2361
+ if (!result || "isEmpty" in result && result.isEmpty) {
2362
+ throw new Error("Cannot find config file.");
2363
+ }
2364
+ const rc = parseRuntimeConfig(result.config);
2365
+ if (options?.debug) {
2366
+ await fs4.ensureDir(".keq");
2367
+ rc.debug = true;
2368
+ }
2369
+ rc.tolerant = Boolean(rc.tolerant);
2370
+ if (!rc.translators || !rc.translators.length) {
2371
+ rc.translators = [new MicroFunctionTranslator()];
2372
+ }
2373
+ const packageJsonInfo = findNearestPackageJson();
2374
+ if (packageJsonInfo) {
2375
+ const moduleSystem = getProjectModuleSystem(packageJsonInfo);
2376
+ rc.esm = moduleSystem === "esm";
2377
+ }
2378
+ context.rc = rc;
2379
+ let matcher = new IgnoreMatcher([]);
2380
+ if (result.filepath) {
2381
+ const ignoreFilepath = path10.resolve(path10.dirname(result.filepath), ".keqignore");
2382
+ if (await fs4.exists(ignoreFilepath)) {
2383
+ matcher = await IgnoreMatcher.read(ignoreFilepath);
2384
+ }
2385
+ }
2386
+ const ignoreRules = options.ignore === false ? [] : options.ignore?.rules || [];
2387
+ for (const rule of ignoreRules) {
2388
+ matcher.append({
2389
+ persist: !!rule.persist,
2390
+ ignore: rule.ignore,
2391
+ moduleName: rule.moduleName,
2392
+ operationMethod: rule.operationMethod,
2393
+ operationPathname: rule.operationPathname
2394
+ });
2395
+ }
2396
+ context.matcher = matcher;
2397
+ await compiler.hooks.setup.promise(task);
2398
+ }
2399
+ };
2400
+ }
2401
+ function createSetupTask(compiler, options) {
2402
+ return {
2403
+ title: "Setup",
2404
+ enabled: options?.enabled,
2405
+ skip: options?.skip,
2406
+ task: (context, task) => task.newListr(
2407
+ [
2408
+ main(compiler, options),
2409
+ {
2410
+ task: (context2, task2) => compiler.hooks.afterSetup.promise(task2)
2411
+ }
2412
+ ],
2413
+ {
2414
+ concurrent: false
2415
+ }
2416
+ )
2417
+ };
2418
+ }
2419
+
2420
+ // src/compiler/tasks/download/index.ts
2421
+ import { PRESET_TIMER } from "listr2";
2422
+ import { validate } from "@scalar/openapi-parser";
2423
+ function main2(compiler, options) {
2424
+ return {
2425
+ task: (context, task) => {
2426
+ if (!context.rc || !context.matcher) {
2427
+ throw new Error("Please run setup task first.");
2428
+ }
2429
+ const rc = context.rc;
2430
+ const matcher = context.matcher;
2431
+ context.documents = [];
2432
+ return task.newListr(
2433
+ Object.entries(rc.modules).map(([moduleName, address]) => new ModuleDefinition(moduleName, address)).map((moduleDefinition) => ({
2434
+ title: moduleDefinition.name,
2435
+ task: async (ctx, task2) => {
2436
+ if (options?.skipIgnoredModules && matcher.isModuleIgnored(moduleDefinition)) {
2437
+ task2.skip(`(${moduleDefinition.name}) is ignored`);
2438
+ return;
2439
+ }
2440
+ task2.output = `Downloaded from ${moduleDefinition.address.url}`;
2441
+ const content = await compiler.hooks.download.promise(moduleDefinition.address, moduleDefinition, task2);
2442
+ if (!content) {
2443
+ throw new Exception(moduleDefinition, `Cannot download document from ${moduleDefinition.address.url}`);
2444
+ }
2445
+ const spec = JSON.parse(content);
2446
+ const { valid, errors } = await validate(spec);
2447
+ if (!valid) {
2448
+ const message = `${moduleDefinition.name} module openapi/swagger file does not conform to the openapi specifications or have grammatical errors, which may cause unexpected errors:
2449
+ ${errors?.map((e) => ` - ${e.message}`).join("\n")}`;
2450
+ task2.output = message;
2451
+ }
2452
+ OpenapiUtils.dereferenceOperation(spec);
2453
+ const document = new ApiDocumentV3_1(
2454
+ spec,
2455
+ moduleDefinition
2456
+ );
2457
+ ctx.documents?.push(document);
2458
+ }
2459
+ })),
2460
+ {
2461
+ concurrent: true,
2462
+ exitOnError: false,
2463
+ collectErrors: "minimal",
2464
+ rendererOptions: {
2465
+ collapseSubtasks: false,
2466
+ // collapseSkips: false,
2467
+ suffixSkips: true,
2468
+ timer: PRESET_TIMER
2469
+ }
2470
+ }
2471
+ );
2472
+ }
2473
+ };
2474
+ }
2475
+ function createDownloadTask(compiler, options) {
2476
+ return {
2477
+ title: "Download",
2478
+ enabled: options?.enabled,
2479
+ skip: options?.skip,
2480
+ task: (_, task) => task.newListr(
2481
+ [
2482
+ main2(compiler, options),
2483
+ {
2484
+ task: (context, task2) => compiler.hooks.afterDownload.promise(task2)
2485
+ }
2486
+ ],
2487
+ {
2488
+ concurrent: false
2489
+ }
2490
+ )
2491
+ };
2492
+ }
2493
+
2494
+ // src/compiler/tasks/persist/index.ts
2495
+ import * as path11 from "path";
2496
+ import fs5 from "fs-extra";
2497
+ function createPersistArtifactTask() {
2498
+ return {
2499
+ title: "Write files",
2500
+ task: async (context, task) => {
2501
+ if (!context.rc) throw new Error("Please run setup task first.");
2502
+ if (!context.artifacts || context.artifacts.length === 0) {
2503
+ task.skip("No compiled artifacts to persist.");
2504
+ return;
2505
+ }
2506
+ const rc = context.rc;
2507
+ const artifacts = context.artifacts;
2508
+ const total = artifacts.length;
2509
+ let completed = 0;
2510
+ const files = await Promise.all(artifacts.map(async (artifact) => {
2511
+ const realpath = `./${path11.join(rc.outdir, artifact.filepath)}`;
2512
+ await fs5.ensureFile(realpath);
2513
+ await fs5.writeFile(realpath, artifact.renderer());
2514
+ completed += 1;
2515
+ task.output = `Persisted ${completed}/${total} files`;
2516
+ return new Asset(path11.resolve(realpath));
2517
+ }));
2518
+ context.assets = files;
2519
+ }
2520
+ };
2521
+ }
2522
+ function createPersistIgnoreTask() {
2523
+ return {
2524
+ title: "Update .keqignore",
2525
+ task: async (context, task) => {
2526
+ if (!context.matcher) throw new Error("Please run setup task first.");
2527
+ const matcher = context.matcher;
2528
+ await matcher.write(".keqignore");
2529
+ }
2530
+ };
2531
+ }
2532
+ function main3() {
2533
+ return {
2534
+ task: (context, task) => task.newListr(
2535
+ [
2536
+ createPersistArtifactTask(),
2537
+ createPersistIgnoreTask()
2538
+ ],
2539
+ {
2540
+ concurrent: true,
2541
+ rendererOptions: {
2542
+ collapseSubtasks: true
2543
+ }
2544
+ }
2545
+ )
2546
+ };
2547
+ }
2548
+ function createPersistTask(compiler, options) {
2549
+ return {
2550
+ title: "Persist",
2551
+ enabled: options?.enabled,
2552
+ skip: options?.skip,
2553
+ task: (context, task) => task.newListr(
2554
+ [
2555
+ main3(),
2556
+ {
2557
+ task: (context2, task2) => compiler.hooks.afterPersist.promise(task2)
2558
+ }
2559
+ ],
2560
+ {
2561
+ concurrent: false
2587
2562
  }
2588
- });
2589
- }
2590
- };
2563
+ )
2564
+ };
2565
+ }
2591
2566
 
2592
- // src/plugins/shaking/shaking.plugin.ts
2593
- import { openapiShakingSync } from "@opendoc/openapi-shaking";
2594
- var ShakingPlugin = class _ShakingPlugin {
2595
- apply(compiler) {
2596
- compiler.hooks.beforeCompile.tap(_ShakingPlugin.name, (task) => {
2597
- const matcher = compiler.context.matcher;
2598
- const documents = compiler.context.documents;
2599
- compiler.context.documents = documents.map((document) => this.shaking(compiler, document)).filter((document) => !document.isEmpty()).filter((document) => !matcher.isModuleIgnored(document.module));
2600
- });
2601
- }
2602
- shaking(compiler, document) {
2603
- const rc = compiler.context.rc;
2604
- const matcher = compiler.context.matcher;
2605
- const isAccepted = (pathname, method, operation) => {
2606
- if (!SupportedMethods.includes(method)) return false;
2607
- return !matcher.isOperationIgnored(new OperationDefinition({
2608
- method,
2609
- pathname,
2610
- operation,
2611
- module: document.module,
2612
- document
2613
- }));
2614
- };
2615
- const sharkedSwagger = openapiShakingSync(
2616
- document.specification,
2617
- isAccepted,
2618
- { tolerant: rc.tolerant }
2619
- );
2620
- return new ApiDocumentV3_1(
2621
- sharkedSwagger,
2622
- new ModuleDefinition(
2623
- document.module.name,
2624
- `file://${document.module.name}.v3_1.sharked.json`
2625
- )
2626
- );
2627
- }
2628
- };
2567
+ // src/compiler/tasks/compile/index.ts
2568
+ function main4(compiler) {
2569
+ return {
2570
+ task: async (context, task) => {
2571
+ if (!context.rc) throw new Error("Please run setup task first.");
2572
+ if (!context.documents) throw new Error("Please run shaking task first.");
2573
+ context.artifacts = [];
2574
+ await compiler.hooks.compile.promise(task);
2575
+ }
2576
+ };
2577
+ }
2578
+ function createCompileTask(compiler, options) {
2579
+ return {
2580
+ title: "Compile",
2581
+ enabled: options?.enabled,
2582
+ skip: options?.skip,
2583
+ task: (context, task) => task.newListr(
2584
+ [
2585
+ {
2586
+ task: (context2, task2) => compiler.hooks.beforeCompile.promise(task2)
2587
+ },
2588
+ main4(compiler),
2589
+ {
2590
+ task: (context2, task2) => compiler.hooks.afterCompile.promise(task2)
2591
+ }
2592
+ ],
2593
+ {
2594
+ concurrent: false
2595
+ }
2596
+ )
2597
+ };
2598
+ }
2629
2599
 
2630
- // src/plugins/terminal-select/utils/select-operation-definitions.ts
2631
- import { select } from "inquirer-select-pro";
2632
- import { ListrInquirerPromptAdapter } from "@listr2/prompt-adapter-inquirer";
2633
- async function selectOperationDefinitions(task, operationDefinitions) {
2634
- const selectedOperationDefinitions = await task.prompt(ListrInquirerPromptAdapter).run(
2635
- select,
2636
- {
2637
- message: "Select Pathname",
2638
- defaultValue: [],
2639
- options: (input) => {
2640
- const items = operationDefinitions.map((op) => ({ name: `${op.module.name} ${op.method.toUpperCase()} ${op.pathname}`, value: op }));
2641
- if (!input) return items;
2642
- const keys2 = input.trim().toLowerCase().split(/\s+/);
2643
- return items.filter((i) => {
2644
- const name = i.name.toLowerCase();
2645
- return keys2.every((q) => name.includes(q));
2646
- });
2600
+ // src/compiler/intercepter/print-information.ts
2601
+ function proxyTaskWrapper(pluginName, task) {
2602
+ return new Proxy(task, {
2603
+ set(target, prop2, value) {
2604
+ if (prop2 !== "output") {
2605
+ return Reflect.set(target, prop2, value);
2647
2606
  }
2607
+ target.output = `[Plugin: ${pluginName}] ${value}`;
2608
+ return true;
2648
2609
  }
2649
- );
2650
- return selectedOperationDefinitions;
2610
+ });
2651
2611
  }
2652
-
2653
- // src/plugins/terminal-select/terminal-select.plugin.ts
2654
- var TerminalSelectPlugin = class _TerminalSelectPlugin {
2655
- constructor(options) {
2656
- this.options = options;
2657
- }
2658
- apply(compiler) {
2659
- compiler.hooks.afterDownload.tapPromise(_TerminalSelectPlugin.name, async (task) => {
2660
- const context = compiler.context;
2661
- const matcher = context.matcher;
2662
- const documents = context.documents;
2663
- const operationDefinitions = documents.flatMap((document) => document.operations);
2664
- const selectedOperationDefinitions = await selectOperationDefinitions(task, operationDefinitions);
2665
- if (this.options.clear) {
2666
- matcher.append({
2667
- persist: false,
2668
- ignore: true,
2669
- moduleName: "*",
2670
- operationMethod: "*",
2671
- operationPathname: "*"
2672
- });
2612
+ function printInformation(taskIndex) {
2613
+ return {
2614
+ register: (tap) => {
2615
+ const fn = tap.fn;
2616
+ if (tap.type === "promise") {
2617
+ tap.fn = (...args) => {
2618
+ const task = args[taskIndex];
2619
+ const proxyTask = proxyTaskWrapper(tap.name, task);
2620
+ args[taskIndex] = proxyTask;
2621
+ proxyTask.output = "Processing...";
2622
+ return fn(...args);
2623
+ };
2673
2624
  }
2674
- for (const op of selectedOperationDefinitions) {
2675
- matcher.append({
2676
- persist: !!this.options.persist,
2677
- ignore: this.options.mode === "add",
2678
- moduleName: op.module.name,
2679
- operationMethod: op.method,
2680
- operationPathname: op.pathname
2681
- });
2625
+ if (tap.type === "sync") {
2626
+ tap.fn = (...args) => {
2627
+ const task = args[taskIndex];
2628
+ const proxyTask = proxyTaskWrapper(tap.name, task);
2629
+ args[taskIndex] = proxyTask;
2630
+ proxyTask.output = "Processing...";
2631
+ return fn(...args);
2632
+ };
2682
2633
  }
2683
- });
2684
- }
2685
- };
2634
+ if (tap.type === "async") {
2635
+ tap.fn = (...args) => {
2636
+ const task = args[taskIndex];
2637
+ const proxyTask = proxyTaskWrapper(tap.name, task);
2638
+ args[taskIndex] = proxyTask;
2639
+ proxyTask.output = "Processing...";
2640
+ return fn(...args);
2641
+ };
2642
+ }
2643
+ return tap;
2644
+ }
2645
+ };
2646
+ }
2686
2647
 
2687
- // src/plugins/initialize/initialize.plugin.ts
2648
+ // src/compiler/intercepter/perfect-error-message.ts
2688
2649
  import * as R23 from "ramda";
2689
- var InitializePlugin = class _InitializePlugin {
2690
- constructor(options) {
2691
- this.options = options;
2692
- }
2693
- apply(compiler) {
2694
- compiler.hooks.setup.tap(_InitializePlugin.name, (task) => {
2695
- new DownloadHttpFilePlugin().apply(compiler);
2696
- new DownloadLocalFilePlugin().apply(compiler);
2697
- new GenerateDeclarationPlugin().apply(compiler);
2698
- if (this.options.build) {
2699
- new ShakingPlugin().apply(compiler);
2700
- }
2701
- if (this.options.interactive) {
2702
- new TerminalSelectPlugin(
2703
- typeof this.options.interactive === "object" ? this.options.interactive : { mode: "except" }
2704
- ).apply(compiler);
2650
+ function perfectErrorMessage() {
2651
+ return {
2652
+ register: (tap) => {
2653
+ const fn = tap.fn;
2654
+ function prefix(err) {
2655
+ if (err instanceof Error) {
2656
+ err.message = `[Plugin: ${tap.name}] ${err.message}`;
2657
+ }
2705
2658
  }
2706
- const rc = compiler.context.rc;
2707
- if (rc.mode === "micro-function") {
2708
- new GenerateMicroFunctionPlugin().apply(compiler);
2709
- } else if (rc.mode === "nestjs-module") {
2710
- new GenerateNestjsModulePlugin().apply(compiler);
2659
+ if (tap.type === "promise") {
2660
+ tap.fn = async (...args) => {
2661
+ try {
2662
+ return await fn(...args);
2663
+ } catch (err) {
2664
+ prefix(err);
2665
+ throw err;
2666
+ }
2667
+ };
2711
2668
  }
2712
- if (rc.plugins && rc.plugins.length) {
2713
- for (const plugin of rc.plugins) {
2714
- plugin.apply(compiler);
2715
- }
2669
+ if (tap.type === "sync") {
2670
+ tap.fn = (...args) => {
2671
+ try {
2672
+ return fn(...args);
2673
+ } catch (err) {
2674
+ prefix(err);
2675
+ throw err;
2676
+ }
2677
+ };
2716
2678
  }
2717
- });
2718
- if (this.options.includes && this.options.includes.length) {
2719
- const modulesIncludes = this.options.includes;
2720
- compiler.hooks.afterSetup.tap(_InitializePlugin.name, (task) => {
2721
- const rc = compiler.context.rc;
2722
- const matcher = compiler.context.matcher;
2723
- const notExistModules = modulesIncludes.filter((moduleName) => !(moduleName in rc.modules));
2724
- if (notExistModules.length) {
2725
- throw new Error(`Cannot find module(s) ${notExistModules.join(", ")} in config file.`);
2726
- }
2727
- const ignoredModules = R23.difference(R23.keys(rc.modules), modulesIncludes);
2728
- for (const moduleName of ignoredModules) {
2729
- matcher.append({
2730
- persist: false,
2731
- ignore: true,
2732
- moduleName,
2733
- operationMethod: "*",
2734
- operationPathname: "*"
2679
+ if (tap.type === "async") {
2680
+ tap.fn = (...args) => {
2681
+ const callback = R23.last(args);
2682
+ return fn(...R23.init(args), (err, result) => {
2683
+ prefix(err);
2684
+ return callback(err, result);
2735
2685
  });
2736
- }
2737
- });
2686
+ };
2687
+ }
2688
+ return tap;
2738
2689
  }
2739
- }
2740
- };
2741
-
2742
- // src/plugins/overwrite-query-options/overwrite-query-options.plugin.ts
2743
- var QsArrayFormatUnion = Object.values(QsArrayFormat);
2690
+ };
2691
+ }
2744
2692
 
2745
2693
  // src/compiler/compiler.ts
2746
2694
  var Compiler = class {