@keq-request/cli 5.0.0-alpha.10 → 5.0.0-alpha.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cli.cjs +673 -222
  3. package/dist/cli.cjs.map +1 -1
  4. package/dist/cli.js +673 -222
  5. package/dist/cli.js.map +1 -1
  6. package/dist/compiler/compiler.d.ts +29 -0
  7. package/dist/compiler/compiler.d.ts.map +1 -0
  8. package/dist/compiler/index.d.ts +2 -0
  9. package/dist/compiler/index.d.ts.map +1 -0
  10. package/dist/compiler/intercepter/perfect-error-message.d.ts +3 -0
  11. package/dist/compiler/intercepter/perfect-error-message.d.ts.map +1 -0
  12. package/dist/compiler/intercepter/print-information.d.ts +5 -0
  13. package/dist/compiler/intercepter/print-information.d.ts.map +1 -0
  14. package/dist/index.cjs +620 -154
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.ts +9 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +609 -150
  19. package/dist/index.js.map +1 -1
  20. package/dist/plugins/body-fallback/index.d.ts +6 -0
  21. package/dist/plugins/body-fallback/index.d.ts.map +1 -0
  22. package/dist/plugins/eslint/index.d.ts +15 -0
  23. package/dist/plugins/eslint/index.d.ts.map +1 -0
  24. package/dist/plugins/index.d.ts +4 -0
  25. package/dist/plugins/index.d.ts.map +1 -0
  26. package/dist/plugins/prettier/index.d.ts +6 -0
  27. package/dist/plugins/prettier/index.d.ts.map +1 -0
  28. package/dist/plugins.cjs +159 -0
  29. package/dist/plugins.cjs.map +1 -0
  30. package/dist/plugins.js +120 -0
  31. package/dist/plugins.js.map +1 -0
  32. package/dist/renderer/json-schema/index.d.ts.map +1 -1
  33. package/dist/renderer/operation-request/index.d.ts.map +1 -1
  34. package/dist/renderer/operation-type/index.d.ts +2 -1
  35. package/dist/renderer/operation-type/index.d.ts.map +1 -1
  36. package/dist/renderer/request/index.d.ts.map +1 -1
  37. package/dist/tasks/compile/index.d.ts +3 -5
  38. package/dist/tasks/compile/index.d.ts.map +1 -1
  39. package/dist/tasks/compile/utils/compile-operation-definition.d.ts +5 -2
  40. package/dist/tasks/compile/utils/compile-operation-definition.d.ts.map +1 -1
  41. package/dist/tasks/compile/utils/compile-schema-definition.d.ts +5 -2
  42. package/dist/tasks/compile/utils/compile-schema-definition.d.ts.map +1 -1
  43. package/dist/tasks/download/index.d.ts +3 -3
  44. package/dist/tasks/download/index.d.ts.map +1 -1
  45. package/dist/tasks/index.d.ts +9 -11
  46. package/dist/tasks/index.d.ts.map +1 -1
  47. package/dist/tasks/interactive/index.d.ts +9 -6
  48. package/dist/tasks/interactive/index.d.ts.map +1 -1
  49. package/dist/tasks/persist/index.d.ts +3 -8
  50. package/dist/tasks/persist/index.d.ts.map +1 -1
  51. package/dist/tasks/setup/index.d.ts +7 -1
  52. package/dist/tasks/setup/index.d.ts.map +1 -1
  53. package/dist/tasks/shaking/index.d.ts +4 -5
  54. package/dist/tasks/shaking/index.d.ts.map +1 -1
  55. package/dist/tasks/types/base-task-options.d.ts +6 -0
  56. package/dist/tasks/types/base-task-options.d.ts.map +1 -0
  57. package/dist/tasks/types/file.d.ts +4 -0
  58. package/dist/tasks/types/file.d.ts.map +1 -0
  59. package/dist/tasks/types/index.d.ts +6 -0
  60. package/dist/tasks/types/index.d.ts.map +1 -0
  61. package/dist/tasks/types/task-context.d.ts +4 -0
  62. package/dist/tasks/types/task-context.d.ts.map +1 -1
  63. package/dist/tasks/types/task-wrapper.d.ts +4 -0
  64. package/dist/tasks/types/task-wrapper.d.ts.map +1 -0
  65. package/dist/tasks/utils/anchor.d.ts +20 -0
  66. package/dist/tasks/utils/anchor.d.ts.map +1 -0
  67. package/dist/tasks/utils/artifact.d.ts +2 -0
  68. package/dist/tasks/utils/artifact.d.ts.map +1 -1
  69. package/dist/tasks/utils/index.d.ts +11 -0
  70. package/dist/tasks/utils/index.d.ts.map +1 -0
  71. package/dist/tasks/utils/proxy-task-wrapper.d.ts +3 -0
  72. package/dist/tasks/utils/proxy-task-wrapper.d.ts.map +1 -0
  73. package/dist/tasks/validate/index.d.ts +3 -6
  74. package/dist/tasks/validate/index.d.ts.map +1 -1
  75. package/dist/types/index.d.ts +7 -0
  76. package/dist/types/index.d.ts.map +1 -0
  77. package/dist/types/plugin.d.ts +5 -0
  78. package/dist/types/plugin.d.ts.map +1 -0
  79. package/dist/types/runtime-config.d.ts +4 -1
  80. package/dist/types/runtime-config.d.ts.map +1 -1
  81. package/package.json +20 -4
  82. package/dist/tasks/append-ignore-rule/index.d.ts +0 -10
  83. package/dist/tasks/append-ignore-rule/index.d.ts.map +0 -1
package/dist/index.cjs CHANGED
@@ -28,23 +28,25 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
30
  // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ ApiDocument: () => ApiDocument,
34
+ ApiDocumentV3_1: () => ApiDocumentV3_1,
35
+ Artifact: () => Artifact,
36
+ Compiler: () => Compiler,
33
37
  FileNamingStyle: () => FileNamingStyle,
34
- build: () => build,
38
+ ModuleDefinition: () => ModuleDefinition,
39
+ OperationDefinition: () => OperationDefinition,
40
+ RuntimeConfig: () => RuntimeConfig,
41
+ SchemaDefinition: () => SchemaDefinition,
35
42
  defineKeqConfig: () => defineKeqConfig
36
43
  });
37
- module.exports = __toCommonJS(index_exports);
44
+ module.exports = __toCommonJS(src_exports);
38
45
 
39
- // src/tasks/index.ts
40
- var import_listr22 = require("listr2");
41
-
42
- // src/tasks/setup/index.ts
43
- var R3 = __toESM(require("ramda"), 1);
44
- var import_fs_extra2 = __toESM(require("fs-extra"), 1);
45
- var import_path = __toESM(require("path"), 1);
46
- var import_value = require("@sinclair/typebox/value");
47
- var import_cosmiconfig = require("cosmiconfig");
46
+ // src/define-keq-config.ts
47
+ function defineKeqConfig(config) {
48
+ return config;
49
+ }
48
50
 
49
51
  // src/types/runtime-config.ts
50
52
  var import_typebox2 = require("@sinclair/typebox");
@@ -113,9 +115,21 @@ var RuntimeConfig = import_typebox2.Type.Object({
113
115
  /**
114
116
  * Whether to tolerate wrong swagger structure
115
117
  */
116
- tolerant: import_typebox2.Type.Optional(import_typebox2.Type.Boolean({ default: false }))
118
+ tolerant: import_typebox2.Type.Optional(import_typebox2.Type.Boolean({ default: false })),
119
+ plugins: import_typebox2.Type.Optional(import_typebox2.Type.Array(import_typebox2.Type.Any(), { default: [] }))
117
120
  });
118
121
 
122
+ // src/compiler/compiler.ts
123
+ var import_tapable = require("tapable");
124
+ var import_listr22 = require("listr2");
125
+
126
+ // src/tasks/setup/index.ts
127
+ var R3 = __toESM(require("ramda"), 1);
128
+ var import_fs_extra2 = __toESM(require("fs-extra"), 1);
129
+ var import_path = __toESM(require("path"), 1);
130
+ var import_value = require("@sinclair/typebox/value");
131
+ var import_cosmiconfig = require("cosmiconfig");
132
+
119
133
  // src/utils/ignore-matcher.ts
120
134
  var R = __toESM(require("ramda"), 1);
121
135
  var import_fs_extra = __toESM(require("fs-extra"), 1);
@@ -264,9 +278,8 @@ function getProjectModuleSystem(pkgInfo) {
264
278
 
265
279
  // src/tasks/setup/index.ts
266
280
  var explore = (0, import_cosmiconfig.cosmiconfig)("keq");
267
- function createSetupTask(options) {
281
+ function main(compiler, options) {
268
282
  return {
269
- title: "Setup",
270
283
  task: async (context, task) => {
271
284
  const result = options?.config ? await explore.load(options.config) : await explore.search();
272
285
  if (!result || "isEmpty" in result && result.isEmpty) {
@@ -291,13 +304,23 @@ function createSetupTask(options) {
291
304
  const moduleSystem = getProjectModuleSystem(packageJsonInfo);
292
305
  rc.esm = moduleSystem === "esm";
293
306
  }
294
- let filter2 = new IgnoreMatcher([]);
307
+ let matcher = new IgnoreMatcher([]);
295
308
  if (result.filepath) {
296
309
  const ignoreFilepath = import_path.default.resolve(import_path.default.dirname(result.filepath), ".keqignore");
297
310
  if (await import_fs_extra2.default.exists(ignoreFilepath)) {
298
- filter2 = await IgnoreMatcher.read(ignoreFilepath);
311
+ matcher = await IgnoreMatcher.read(ignoreFilepath);
299
312
  }
300
313
  }
314
+ const ignoreRules = options.ignore === false ? [] : options.ignore?.rules || [];
315
+ for (const rule of ignoreRules) {
316
+ matcher.append({
317
+ persist: !!rule.persist,
318
+ ignore: rule.ignore,
319
+ moduleName: rule.moduleName,
320
+ operationMethod: rule.operationMethod,
321
+ operationPathname: rule.operationPathname
322
+ });
323
+ }
301
324
  if (options?.modules && options.modules.length) {
302
325
  const notExistModules = options.modules.filter((moduleName) => !(moduleName in rc.modules));
303
326
  if (notExistModules.length) {
@@ -305,7 +328,7 @@ function createSetupTask(options) {
305
328
  }
306
329
  const ignoredModules = R3.difference(R3.keys(rc.modules), options.modules);
307
330
  for (const moduleName of ignoredModules) {
308
- filter2.append({
331
+ matcher.append({
309
332
  persist: false,
310
333
  ignore: true,
311
334
  moduleName,
@@ -314,10 +337,33 @@ function createSetupTask(options) {
314
337
  });
315
338
  }
316
339
  }
317
- context.setup = { rc, matcher: filter2 };
340
+ context.setup = { rc, matcher };
341
+ if (rc.plugins && rc.plugins.length) {
342
+ for (const plugin of rc.plugins) {
343
+ plugin.apply(compiler);
344
+ }
345
+ }
318
346
  }
319
347
  };
320
348
  }
349
+ function createSetupTask(compiler, options) {
350
+ return {
351
+ title: "Setup",
352
+ enabled: options?.enabled,
353
+ skip: options?.skip,
354
+ task: (context, task) => task.newListr(
355
+ [
356
+ main(compiler, options),
357
+ {
358
+ task: (context2, task2) => compiler.hooks.afterSetup.promise(task2)
359
+ }
360
+ ],
361
+ {
362
+ concurrent: false
363
+ }
364
+ )
365
+ };
366
+ }
321
367
 
322
368
  // src/tasks/download/index.ts
323
369
  var import_listr2 = require("listr2");
@@ -530,7 +576,7 @@ var logger = {
530
576
  };
531
577
 
532
578
  // src/tasks/utils/api-document_v3_1.ts
533
- var import_openapi_shaking = __toESM(require("@opendoc/openapi-shaking"), 1);
579
+ var import_openapi_shaking = require("@opendoc/openapi-shaking");
534
580
  var ApiDocumentV3_1 = class _ApiDocumentV3_1 {
535
581
  module;
536
582
  swagger;
@@ -586,7 +632,7 @@ var ApiDocumentV3_1 = class _ApiDocumentV3_1 {
586
632
  });
587
633
  return filter2(operationDefinition);
588
634
  };
589
- const sharkedSwagger = import_openapi_shaking.default.openapiShakingSync(
635
+ const sharkedSwagger = (0, import_openapi_shaking.openapiShakingSync)(
590
636
  this.swagger,
591
637
  isAccepted,
592
638
  { tolerant: true }
@@ -780,8 +826,8 @@ function dereferenceDeep($ref, swagger) {
780
826
  const stack = [$ref];
781
827
  let value;
782
828
  while (true) {
783
- const last = stack[stack.length - 1];
784
- value = dereference(last, swagger);
829
+ const last2 = stack[stack.length - 1];
830
+ value = dereference(last2, swagger);
785
831
  if (JsonSchemaUtils.isRef(value)) {
786
832
  if (!stack.includes(value.$ref)) {
787
833
  stack.push(value.$ref);
@@ -892,11 +938,8 @@ var ApiDocument = class _ApiDocument {
892
938
  };
893
939
 
894
940
  // src/tasks/download/index.ts
895
- function createDownloadTask(options) {
941
+ function main2(compiler, options) {
896
942
  return {
897
- title: "Download",
898
- enabled: options?.enabled,
899
- skip: options?.skip,
900
943
  task: (context, task) => {
901
944
  if (!context.setup) {
902
945
  throw new Error("Please run setup task first.");
@@ -934,13 +977,28 @@ function createDownloadTask(options) {
934
977
  }
935
978
  };
936
979
  }
937
-
938
- // src/tasks/validate/index.ts
939
- function createValidateTask(options) {
980
+ function createDownloadTask(compiler, options) {
940
981
  return {
941
- title: "Validate",
982
+ title: "Download",
942
983
  enabled: options?.enabled,
943
984
  skip: options?.skip,
985
+ task: (_, task) => task.newListr(
986
+ [
987
+ main2(compiler, options),
988
+ {
989
+ task: (context, task2) => compiler.hooks.afterDownload.promise(task2)
990
+ }
991
+ ],
992
+ {
993
+ concurrent: false
994
+ }
995
+ )
996
+ };
997
+ }
998
+
999
+ // src/tasks/validate/index.ts
1000
+ function main3() {
1001
+ return {
944
1002
  task: (context, task) => {
945
1003
  if (!context.setup) throw new Error("Please run setup task first.");
946
1004
  if (!context.downloaded) throw new Error("Please run download task first.");
@@ -977,13 +1035,28 @@ ${errors?.map((e) => ` - ${e.message}`).join("\n")}`;
977
1035
  }
978
1036
  };
979
1037
  }
980
-
981
- // src/tasks/shaking/index.ts
982
- function createShakingTask(options) {
1038
+ function createValidateTask(compiler, options) {
983
1039
  return {
984
- title: "Shaking",
1040
+ title: "Validate",
985
1041
  enabled: options?.enabled,
986
1042
  skip: options?.skip,
1043
+ task: (context, task) => task.newListr(
1044
+ [
1045
+ main3(),
1046
+ {
1047
+ task: (context2, task2) => compiler.hooks.afterValidate.promise(task2)
1048
+ }
1049
+ ],
1050
+ {
1051
+ concurrent: false
1052
+ }
1053
+ )
1054
+ };
1055
+ }
1056
+
1057
+ // src/tasks/shaking/index.ts
1058
+ function main4(compiler, options) {
1059
+ return {
987
1060
  task: (context, task) => {
988
1061
  if (!context.setup) throw new Error("Please run setup task first.");
989
1062
  if (!context.validated) throw new Error("Please run validate task first.");
@@ -1021,15 +1094,31 @@ function createShakingTask(options) {
1021
1094
  }
1022
1095
  };
1023
1096
  }
1097
+ function createShakingTask(compiler, options) {
1098
+ return {
1099
+ title: "Shaking",
1100
+ enabled: options?.enabled,
1101
+ skip: options?.skip,
1102
+ task: (context, task) => task.newListr(
1103
+ [
1104
+ main4(compiler, options),
1105
+ {
1106
+ task: (context2, task2) => compiler.hooks.afterShaking.promise(task2)
1107
+ }
1108
+ ],
1109
+ {
1110
+ concurrent: false
1111
+ }
1112
+ )
1113
+ };
1114
+ }
1024
1115
 
1025
1116
  // src/tasks/persist/index.ts
1026
1117
  var path6 = __toESM(require("path"), 1);
1027
1118
  var import_fs_extra5 = __toESM(require("fs-extra"), 1);
1028
- function createPersistArtifactTask(options) {
1119
+ function createPersistArtifactTask() {
1029
1120
  return {
1030
1121
  title: "Write files",
1031
- enabled: options?.persistArtifacts,
1032
- skip: options?.skip,
1033
1122
  task: async (context, task) => {
1034
1123
  if (!context.setup) throw new Error("Please run setup task first.");
1035
1124
  if (!context.compiled) throw new Error("Please run compile task first.");
@@ -1040,21 +1129,21 @@ function createPersistArtifactTask(options) {
1040
1129
  }
1041
1130
  const total = artifacts.length;
1042
1131
  let completed = 0;
1043
- await Promise.all(artifacts.map(async (artifact) => {
1132
+ const files = await Promise.all(artifacts.map(async (artifact) => {
1044
1133
  const realpath = `./${path6.join(rc.outdir, artifact.filepath)}`;
1045
1134
  await import_fs_extra5.default.ensureFile(realpath);
1046
1135
  await import_fs_extra5.default.writeFile(realpath, artifact.toCode({ esm: !!rc.esm }));
1047
1136
  completed += 1;
1048
1137
  task.output = `Persisted ${completed}/${total} files`;
1138
+ return { path: path6.resolve(realpath) };
1049
1139
  }));
1140
+ context.persisted = { files };
1050
1141
  }
1051
1142
  };
1052
1143
  }
1053
- function createPersistIgnoreTask(options) {
1144
+ function createPersistIgnoreTask() {
1054
1145
  return {
1055
1146
  title: "Update .keqignore",
1056
- enabled: options?.persistIgnore,
1057
- skip: options?.skip,
1058
1147
  task: async (context, task) => {
1059
1148
  if (!context.setup) throw new Error("Please run setup task first.");
1060
1149
  const matcher = context.setup.matcher;
@@ -1062,15 +1151,12 @@ function createPersistIgnoreTask(options) {
1062
1151
  }
1063
1152
  };
1064
1153
  }
1065
- function createPersistTask(options) {
1154
+ function main5() {
1066
1155
  return {
1067
- title: "Persist",
1068
- enabled: options?.enabled,
1069
- skip: options?.skip,
1070
1156
  task: (context, task) => task.newListr(
1071
1157
  [
1072
- createPersistArtifactTask(options),
1073
- createPersistIgnoreTask(options)
1158
+ createPersistArtifactTask(),
1159
+ createPersistIgnoreTask()
1074
1160
  ],
1075
1161
  {
1076
1162
  concurrent: true,
@@ -1081,8 +1167,29 @@ function createPersistTask(options) {
1081
1167
  )
1082
1168
  };
1083
1169
  }
1170
+ function createPersistTask(compiler, options) {
1171
+ return {
1172
+ title: "Persist",
1173
+ enabled: options?.enabled,
1174
+ skip: options?.skip,
1175
+ task: (context, task) => task.newListr(
1176
+ [
1177
+ main5(),
1178
+ {
1179
+ task: (context2, task2) => compiler.hooks.afterPersist.promise(task2)
1180
+ }
1181
+ ],
1182
+ {
1183
+ concurrent: false
1184
+ }
1185
+ )
1186
+ };
1187
+ }
1084
1188
 
1085
1189
  // src/tasks/compile/utils/compile-schema-definition.ts
1190
+ var R14 = __toESM(require("ramda"), 1);
1191
+
1192
+ // src/renderer/json-schema/index.ts
1086
1193
  var R12 = __toESM(require("ramda"), 1);
1087
1194
 
1088
1195
  // src/renderer/utils/generate-schema.ts
@@ -1208,14 +1315,102 @@ async function jsonSchemaRenderer(schemaDefinition) {
1208
1315
  let $comment = generateComment(schemaDefinition.schema);
1209
1316
  if ($comment) $comment += "\n";
1210
1317
  if (typeof schemaDefinition.schema === "boolean") {
1211
- return `${$comment}type ${schemaDefinition.name} = unknown`;
1318
+ return [
1319
+ "/* @anchor:file:start */",
1320
+ "",
1321
+ $comment || void 0,
1322
+ `type ${schemaDefinition.name} = unknown`,
1323
+ "",
1324
+ "/* @anchor:file:end */"
1325
+ ].filter(R12.isNotNil).join("\n");
1212
1326
  }
1213
1327
  if (JsonSchemaUtils.isNonArray(schemaDefinition.schema) && schemaDefinition.schema.type === "object") {
1214
- return `${$comment}export interface ${schemaDefinition.name} ${generateSchema(schemaDefinition.schema)}`;
1328
+ return [
1329
+ "/* @anchor:file:start */",
1330
+ "",
1331
+ $comment || void 0,
1332
+ `export interface ${schemaDefinition.name} ${generateSchema(schemaDefinition.schema)}`,
1333
+ "",
1334
+ "/* @anchor:file:end */"
1335
+ ].filter(R12.isNotNil).join("\n");
1215
1336
  }
1216
- return `${$comment}export type ${schemaDefinition.name} = ${generateSchema(schemaDefinition.schema)}`;
1337
+ return [
1338
+ "/* @anchor:file:start */",
1339
+ "",
1340
+ $comment || void 0,
1341
+ `export type ${schemaDefinition.name} = ${generateSchema(schemaDefinition.schema)}`,
1342
+ "",
1343
+ "/* @anchor:file:end */"
1344
+ ].filter(R12.isNotNil).join("\n");
1217
1345
  }
1218
1346
 
1347
+ // src/tasks/utils/anchor.ts
1348
+ var AnchorBlock = class {
1349
+ constructor(artifact) {
1350
+ this.artifact = artifact;
1351
+ }
1352
+ /**
1353
+ * Append content to the end of the anchor block.
1354
+ */
1355
+ append(anchorName, content) {
1356
+ const lines = this.artifact.content.split("\n");
1357
+ const anchor = `@anchor:${anchorName}:end`;
1358
+ const anchorIndex = lines.findIndex((line) => line.includes(`/* ${anchor} */`));
1359
+ if (anchorIndex === -1) {
1360
+ throw new Error(`"${anchor}" not found in artifact "${this.artifact.filepath}".`);
1361
+ }
1362
+ lines.splice(anchorIndex, 0, content);
1363
+ this.artifact.content = lines.join("\n");
1364
+ }
1365
+ prepend(anchorName, content) {
1366
+ const lines = this.artifact.content.split("\n");
1367
+ const anchor = `@anchor:${anchorName}:start`;
1368
+ const anchorIndex = lines.findIndex((line) => line.includes(`/* ${anchor} */`));
1369
+ if (anchorIndex === -1) {
1370
+ throw new Error(`"${anchor}" not found in artifact "${this.artifact.filepath}".`);
1371
+ }
1372
+ lines.splice(anchorIndex + 1, 0, content);
1373
+ this.artifact.content = lines.join("\n");
1374
+ }
1375
+ replace(anchorName, content) {
1376
+ const lines = this.artifact.content.split("\n");
1377
+ const startIndex = lines.findIndex((line) => line.includes(`/* @anchor:${anchorName}:start */`));
1378
+ const endIndex = lines.findIndex((line) => line.includes(`/* @anchor:${anchorName}:end */`));
1379
+ if (startIndex === -1 || endIndex === -1 || endIndex <= startIndex) {
1380
+ throw new Error(`"@anchor:${anchorName}:start" or "@anchor:${anchorName}:end" not found in artifact "${this.artifact.filepath}".`);
1381
+ }
1382
+ lines.splice(startIndex + 1, endIndex - startIndex - 1, content);
1383
+ this.artifact.content = lines.join("\n");
1384
+ }
1385
+ };
1386
+ var Anchor = class {
1387
+ constructor(artifact) {
1388
+ this.artifact = artifact;
1389
+ this.block = new AnchorBlock(artifact);
1390
+ }
1391
+ block;
1392
+ append(anchorName, content) {
1393
+ const lines = this.artifact.content.split("\n");
1394
+ const anchor = `@anchor:${anchorName}`;
1395
+ const anchorIndex = lines.findIndex((line) => line.includes(`/* ${anchor} */`));
1396
+ if (anchorIndex === -1) {
1397
+ throw new Error(`"${anchor}" not found in artifact "${this.artifact.filepath}".`);
1398
+ }
1399
+ lines.splice(anchorIndex + 1, 0, content);
1400
+ this.artifact.content = lines.join("\n");
1401
+ }
1402
+ prepend(anchorName, content) {
1403
+ const lines = this.artifact.content.split("\n");
1404
+ const anchor = `@anchor:${anchorName}`;
1405
+ const anchorIndex = lines.findIndex((line) => line.includes(`/* ${anchor} */`));
1406
+ if (anchorIndex === -1) {
1407
+ throw new Error(`"${anchor}" not found in artifact "${this.artifact.filepath}".`);
1408
+ }
1409
+ lines.splice(anchorIndex, 0, content);
1410
+ this.artifact.content = lines.join("\n");
1411
+ }
1412
+ };
1413
+
1219
1414
  // src/tasks/utils/artifact.ts
1220
1415
  var path8 = __toESM(require("path"), 1);
1221
1416
  var changeCase = __toESM(require("change-case"), 1);
@@ -1300,6 +1495,7 @@ var Artifact = class {
1300
1495
  warns = [];
1301
1496
  content;
1302
1497
  extensionName;
1498
+ anchor = new Anchor(this);
1303
1499
  constructor(options) {
1304
1500
  this.id = options.id;
1305
1501
  this.filepath = options.filepath;
@@ -1356,6 +1552,10 @@ var Artifact = class {
1356
1552
  }
1357
1553
  };
1358
1554
 
1555
+ // src/tasks/utils/json-schema.ts
1556
+ var R13 = __toESM(require("ramda"), 1);
1557
+ var import_jsonpath_plus5 = require("jsonpath-plus");
1558
+
1359
1559
  // src/tasks/compile/utils/compile-schema-definition.ts
1360
1560
  function genSchemaDefinitionFilepath(schemaDefinition) {
1361
1561
  const filename = `${schemaDefinition.name}.schema.ts`;
@@ -1380,17 +1580,18 @@ var isArtifactCompiledBy = function(schemaDefinition) {
1380
1580
  return (artifact) => artifact.id === genSchemaDefinitionFilepath(schemaDefinition);
1381
1581
  };
1382
1582
  async function compileSchemaDefinition(options) {
1383
- const { schemaDefinitions } = options;
1583
+ const { task, compiler, schemaDefinitions } = options;
1384
1584
  const artifacts = await Promise.all(
1385
1585
  schemaDefinitions.map(async (schemaDefinition) => {
1386
1586
  const content = await jsonSchemaRenderer(schemaDefinition);
1387
1587
  const filepath = genSchemaDefinitionFilepath(schemaDefinition);
1388
- return new Artifact({
1588
+ const artifact = new Artifact({
1389
1589
  id: filepath,
1390
1590
  filepath,
1391
1591
  content,
1392
1592
  extensionName: ".schema.ts"
1393
1593
  });
1594
+ return await compiler.hooks.afterCompileSchema.promise(artifact, schemaDefinition, task);
1394
1595
  })
1395
1596
  );
1396
1597
  for (const schemaDefinition of schemaDefinitions) {
@@ -1406,7 +1607,7 @@ async function compileSchemaDefinition(options) {
1406
1607
  artifact.addDependence(dependentArtifact, [dependentSchemaDefinition.name]);
1407
1608
  }
1408
1609
  }
1409
- const schemaDefinitionsGroupByModuleName = R12.groupBy(
1610
+ const schemaDefinitionsGroupByModuleName = R14.groupBy(
1410
1611
  (schemaDefinition) => schemaDefinition.module.name,
1411
1612
  schemaDefinitions
1412
1613
  );
@@ -1431,41 +1632,93 @@ async function compileSchemaDefinition(options) {
1431
1632
  }
1432
1633
 
1433
1634
  // src/tasks/compile/utils/compile-operation-definition.ts
1434
- var R15 = __toESM(require("ramda"), 1);
1635
+ var R17 = __toESM(require("ramda"), 1);
1435
1636
 
1436
1637
  // src/renderer/operation-type/index.ts
1437
- var R13 = __toESM(require("ramda"), 1);
1638
+ var R15 = __toESM(require("ramda"), 1);
1438
1639
  var changeCase2 = __toESM(require("change-case"), 1);
1439
1640
  function typeNameFactory(operationDefinition) {
1440
1641
  const pascalCaseOperationId = changeCase2.pascalCase(operationDefinition.operationId);
1441
1642
  return (name) => `${pascalCaseOperationId}${name}`;
1442
1643
  }
1443
- async function operationTypeRenderer(operationDefinition, alias = R13.identity) {
1444
- const { operation } = operationDefinition;
1445
- if (!operation.responses) return "";
1446
- const typeName = typeNameFactory(operationDefinition);
1644
+ function responseBodies(operation, alias = R15.identity, typeName) {
1645
+ if (!operation.responses || R15.isEmpty(operation.responses)) {
1646
+ return `export interface ${typeName("ResponseBodies")} {}`;
1647
+ }
1447
1648
  const $responses = Object.entries(operation.responses).map(([statusCode, response]) => {
1448
1649
  if (!JsonSchemaUtils.isRef(response)) {
1449
1650
  const $value = Object.values(response.content || {}).map((mediaTypeObject) => mediaTypeObject.schema).filter((schema) => !!schema).map((schema) => generateSchema(schema, alias)).join(" | ");
1450
1651
  return indent(2, `${statusCode}: ${$value || "void"}`);
1451
1652
  }
1452
1653
  }).join("\n");
1453
- let $requestBody = `export type ${typeName("RequestBody")} = {}`;
1654
+ return [
1655
+ `export interface ${typeName("ResponseBodies")} {`,
1656
+ $responses,
1657
+ "}"
1658
+ ].join("\n");
1659
+ }
1660
+ function requestBodies(operation, alias = R15.identity, typeName) {
1661
+ let $requestBodies = `export interface ${typeName("RequestBodies")} {}`;
1662
+ if (operation.requestBody && !JsonSchemaUtils.isRef(operation.requestBody)) {
1663
+ const $mediaTypes = Object.entries(operation.requestBody.content || {}).map(([mediaType, mediaTypeObject]) => [mediaType, mediaTypeObject.schema]).map(([mediaType, schema]) => {
1664
+ if (!schema) return `${JSON.stringify(mediaType)}: unknown`;
1665
+ return `${JSON.stringify(mediaType)}: ${generateSchema(schema, alias)}`;
1666
+ }).map((pair) => indent(2, pair));
1667
+ $requestBodies = [
1668
+ `export interface ${typeName("RequestBodies")} {`,
1669
+ ...$mediaTypes,
1670
+ "}"
1671
+ ].join("\n");
1672
+ }
1673
+ return $requestBodies;
1674
+ }
1675
+ function parameterBodies(operationDefinition, alias = R15.identity, typeName) {
1676
+ const { operation } = operationDefinition;
1677
+ let parameterBodies2 = "";
1454
1678
  if (operation.requestBody && !JsonSchemaUtils.isRef(operation.requestBody)) {
1455
- const $value = Object.entries(operation.requestBody.content || {}).map(([mediaType, mediaTypeObject]) => [mediaType, mediaTypeObject.schema]).filter(([, schema]) => !!schema).map(([mediaType, schema]) => {
1456
- if (mediaType === "multipart/form-data") {
1457
- return `FormData | ${generateSchema(schema, alias)}`;
1458
- } else if (mediaType === "application/x-www-form-urlencoded") {
1459
- return `URLSearchParams | ${generateSchema(schema, alias)}`;
1679
+ const $mediaTypes = Object.entries(operation.requestBody.content || {}).map(([mediaType, mediaTypeObject]) => [mediaType, mediaTypeObject.schema]).map(([mediaType, schemaOrRef]) => {
1680
+ if (!schemaOrRef) return `${JSON.stringify(mediaType)}: unknown`;
1681
+ const schema = JsonSchemaUtils.isRef(schemaOrRef) ? SwaggerUtils.dereferenceDeep(schemaOrRef.$ref, operationDefinition.document.swagger) : schemaOrRef;
1682
+ if (schema.type === "object" || schema.properties) {
1683
+ return `${JSON.stringify(mediaType)}: ${generateSchema(schemaOrRef, alias)} & { [key: string]: any }`;
1460
1684
  }
1461
- return generateSchema(schema, alias);
1462
- }).join(" | ");
1463
- $requestBody = `export type ${typeName("RequestBody")} = ${$value || "unknown"}`;
1685
+ return `${JSON.stringify(mediaType)}: { [key: string]: any }`;
1686
+ }).map((pair) => indent(2, pair));
1687
+ parameterBodies2 = [
1688
+ `interface ${typeName("ParameterBodies")} {`,
1689
+ ...$mediaTypes,
1690
+ "}",
1691
+ ""
1692
+ ].join("\n");
1693
+ }
1694
+ return parameterBodies2;
1695
+ }
1696
+ function requestParameters(operation, alias = R15.identity, typeName) {
1697
+ const mediaTypes = operation.requestBody && !JsonSchemaUtils.isRef(operation.requestBody) ? Object.keys(operation.requestBody.content || {}) : [];
1698
+ const base = `${typeName("RequestQuery")} & ${typeName("RouteParameters")} & ${typeName("RequestHeaders")}`;
1699
+ if (mediaTypes.length === 1) {
1700
+ return `export type ${typeName("RequestParameters")} = ${base} & ${typeName("RequestBodies")}[${JSON.stringify(mediaTypes[0])}]`;
1701
+ }
1702
+ if (mediaTypes.length > 1) {
1703
+ const unions = mediaTypes.map((mediaType) => `(${base} & ${typeName("RequestBodies")}[${JSON.stringify(mediaType)}] & { "content-type": ${JSON.stringify(mediaType)} })`).join("\n| ");
1704
+ return `export type ${typeName("RequestParameters")} = ${unions}`;
1464
1705
  }
1706
+ return `export type ${typeName("RequestParameters")} = ${base}`;
1707
+ }
1708
+ async function operationTypeRenderer(operationDefinition, alias = R15.identity) {
1709
+ const { operation } = operationDefinition;
1710
+ if (!operation.responses) return "";
1711
+ const typeName = typeNameFactory(operationDefinition);
1712
+ const $responseBodies = responseBodies(operation, alias, typeName);
1713
+ const $requestBodies = requestBodies(operation, alias, typeName);
1714
+ const $parameterBodies = parameterBodies(operationDefinition, alias, typeName);
1715
+ const $requestParameters = requestParameters(operation, alias, typeName);
1465
1716
  return [
1466
- `export interface ${typeName("ResponseBodies")} {`,
1467
- $responses,
1468
- "}",
1717
+ "/* @anchor:file:start */",
1718
+ "",
1719
+ $responseBodies,
1720
+ "",
1721
+ $requestBodies,
1469
1722
  "",
1470
1723
  generateParameters(`${typeName("RequestQuery")}`, operation.parameters?.filter((p) => !JsonSchemaUtils.isRef(p) && p.in === "query") || [], alias),
1471
1724
  "",
@@ -1473,18 +1726,19 @@ async function operationTypeRenderer(operationDefinition, alias = R13.identity)
1473
1726
  "",
1474
1727
  generateParameters(`${typeName("RequestHeaders")}`, operation.parameters?.filter((p) => !JsonSchemaUtils.isRef(p) && p.in === "header") || [], alias),
1475
1728
  "",
1476
- $requestBody,
1477
- "",
1478
- `export type ${typeName("RequestParameters")} = ${typeName("RequestQuery")} & ${typeName("RouteParameters")} & ${typeName("RequestHeaders")} & ${typeName("RequestBody")}`,
1729
+ $parameterBodies || void 0,
1730
+ $requestParameters,
1479
1731
  "",
1480
- `export interface Operation<STATUS extends keyof ${typeName("ResponseBodies")}> extends KeqOperation {`,
1481
- ` requestParams: ${typeName("RouteParameters")} & { [key: string]: KeqParamValue }`,
1482
- ` requestQuery: ${typeName("RequestQuery")} & { [key: string]: KeqQueryValue }`,
1732
+ `export interface Operation<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends keyof ${typeName("ParameterBodies")}> extends KeqOperation {`,
1733
+ ` requestParams: ${typeName("RouteParameters")} & { [key: string]: KeqPathParameterInit }`,
1734
+ ` requestQuery: ${typeName("RequestQuery")} & { [key: string]: KeqQueryInit }`,
1483
1735
  ` requestHeaders: ${typeName("RequestHeaders")} & { [key: string]: string | number }`,
1484
- ` requestBody: ${typeName("RequestBody")}`,
1736
+ ` requestBody: ${$parameterBodies ? `${typeName("ParameterBodies")}[CONTENT_TYPE] | ` : "object | "}BodyInit`,
1485
1737
  ` responseBody: ${typeName("ResponseBodies")}[STATUS]`,
1486
- "}"
1487
- ].join("\n");
1738
+ "}",
1739
+ "",
1740
+ "/* @anchor:file:end */"
1741
+ ].filter(R15.isNotNil).join("\n");
1488
1742
  }
1489
1743
  function generateParameters(name, parameters, alias) {
1490
1744
  if (parameters.length === 0) {
@@ -1504,7 +1758,7 @@ function generateParameters(name, parameters, alias) {
1504
1758
  }
1505
1759
 
1506
1760
  // src/renderer/operation-request/index.ts
1507
- var R14 = __toESM(require("ramda"), 1);
1761
+ var R16 = __toESM(require("ramda"), 1);
1508
1762
  function errorToComment(err, mediaType) {
1509
1763
  const $err = String(err).split("\n").map(((line) => ` * ${line}`)).join("\n");
1510
1764
  return [
@@ -1514,23 +1768,8 @@ function errorToComment(err, mediaType) {
1514
1768
  " */"
1515
1769
  ].join("\n");
1516
1770
  }
1517
- async function operationRequestRenderer(operationDefinition, options) {
1518
- const { operation, operationId, method, pathname } = operationDefinition;
1519
- const { qs } = options;
1520
- if (!operation.responses) return "";
1521
- const typeName = typeNameFactory(operationDefinition);
1522
- const moduleName = operationDefinition.module.name;
1523
- const parameters = operation.parameters?.filter((p) => !JsonSchemaUtils.isRef(p)) || [];
1524
- const queryParameters = parameters.filter((p) => p.in === "query");
1525
- const headersParameters = parameters.filter((p) => p.in === "header");
1526
- const pathParameters = parameters.filter((p) => p.in === "path");
1527
- const $queryParameters = queryParameters.map((p) => {
1528
- const option = qs(p);
1529
- const $option = !option || R14.isEmpty(option) ? "" : `, ${JSON.stringify(option)}`;
1530
- return ` if (args && ${JSON.stringify(p.name)} in args) req.query(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}]${$option})`;
1531
- }).concat("").join("\n");
1532
- const $headerParameters = headersParameters.map((p) => ` if (args && ${JSON.stringify(p.name)} in args) req.header(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}])`).concat("").join("\n");
1533
- const $pathParameters = pathParameters.map((p) => ` if (args && ${JSON.stringify(p.name)} in args) req.params(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}])`).concat("").join("\n");
1771
+ function requestBodyRenderer(operationDefinition, typeName) {
1772
+ const { operation } = operationDefinition;
1534
1773
  const requestBodyContent = operation.requestBody?.content || {};
1535
1774
  const $requestBody = Object.entries(requestBodyContent).map(([mediaType, mediaTypeObject]) => {
1536
1775
  if (!mediaTypeObject.schema) return;
@@ -1559,27 +1798,107 @@ async function operationRequestRenderer(operationDefinition, options) {
1559
1798
  } catch (err) {
1560
1799
  return indent(2, errorToComment(err, mediaType));
1561
1800
  }
1562
- }).filter(R14.isNotNil).join("\n");
1801
+ }).filter(R16.isNotNil).join("\n");
1802
+ return $requestBody;
1803
+ }
1804
+ function requestHeadersRenderer(operationDefinition, typeName) {
1805
+ const { operation } = operationDefinition;
1806
+ const $headers = (operation.parameters || []).filter((p) => !JsonSchemaUtils.isRef(p)).filter((p) => p.in === "header").map((p) => ` if (args && ${JSON.stringify(p.name)} in args) req.header(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}])`).concat("").join("\n");
1807
+ return $headers;
1808
+ }
1809
+ function requestQueryRenderer(operationDefinition, qs, typeName) {
1810
+ const { operation } = operationDefinition;
1811
+ const $query = (operation.parameters || []).filter((p) => !JsonSchemaUtils.isRef(p)).filter((p) => p.in === "query").map((p) => {
1812
+ const option = qs(p);
1813
+ const $option = !option || R16.isEmpty(option) ? "" : `, ${JSON.stringify(option)}`;
1814
+ return ` if (args && ${JSON.stringify(p.name)} in args) req.query(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}]${$option})`;
1815
+ }).concat("").join("\n");
1816
+ return $query;
1817
+ }
1818
+ function requestPathParametersRenderer(operationDefinition, typeName) {
1819
+ const { operation } = operationDefinition;
1820
+ const $pathParameters = (operation.parameters || []).filter((p) => !JsonSchemaUtils.isRef(p)).filter((p) => p.in === "path").map((p) => ` if (args && ${JSON.stringify(p.name)} in args) req.params(${JSON.stringify(p.name)}, args[${JSON.stringify(p.name)}])`).concat("").join("\n");
1821
+ return $pathParameters;
1822
+ }
1823
+ function getRequestMediaTypes(operationDefinition) {
1824
+ const { operation } = operationDefinition;
1825
+ const requestBodyContent = operation.requestBody?.content || {};
1826
+ return Object.keys(requestBodyContent);
1827
+ }
1828
+ function mediaTypeRenderer(operationDefinition) {
1829
+ const mediaTypes = getRequestMediaTypes(operationDefinition);
1830
+ if (mediaTypes.length === 1 && !mediaTypes[0].endsWith("/*")) {
1831
+ return ` req.type("${mediaTypes[0]}")
1832
+ `;
1833
+ } else if (mediaTypes.some((mediaType) => mediaType === "*/*")) {
1834
+ } else if (mediaTypes.some((mediaType) => mediaType.endsWith("/*"))) {
1835
+ return ' if(args?.["content-type"]) req.type(args["content-type"])\n';
1836
+ } else if (mediaTypes.length > 1) {
1837
+ return ' if(args?.["content-type"]) req.type(args["content-type"])\n';
1838
+ }
1839
+ return "";
1840
+ }
1841
+ function operationDeclarationRenderer(operationDefinition, typeName) {
1842
+ const { operationId } = operationDefinition;
1843
+ const mediaTypes = getRequestMediaTypes(operationDefinition);
1844
+ if (mediaTypes.length === 0) {
1845
+ return `function ${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}>(args?: ${typeName("RequestParameters")}): Keq<Operation<STATUS, never>>`;
1846
+ } else if (mediaTypes.length === 1) {
1847
+ return `function ${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}>(args?: ${typeName("RequestParameters")}): Keq<Operation<STATUS, ${JSON.stringify(mediaTypes[0])}>>`;
1848
+ } else if (mediaTypes.length > 1) {
1849
+ return `function ${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}, CONTENT_TYPE extends ${typeName("RequestParameters")}["content-type"]>(args?: Extract<${typeName("RequestParameters")}, { "content-type": CONTENT_TYPE }>): Keq<Operation<STATUS, CONTENT_TYPE>>`;
1850
+ }
1851
+ throw new Error("[operationDeclarationRenderer] Unreachable");
1852
+ }
1853
+ async function operationRequestRenderer(operationDefinition, options) {
1854
+ const { operation, operationId, method, pathname } = operationDefinition;
1855
+ const { qs } = options;
1856
+ if (!operation.responses) return "";
1857
+ const typeName = typeNameFactory(operationDefinition);
1858
+ const moduleName = operationDefinition.module.name;
1859
+ const $queryParameters = requestQueryRenderer(operationDefinition, qs, typeName);
1860
+ const $headerParameters = requestHeadersRenderer(operationDefinition, typeName);
1861
+ const $pathParameters = requestPathParametersRenderer(operationDefinition, typeName);
1862
+ const $mediaType = mediaTypeRenderer(operationDefinition);
1863
+ const $requestBody = requestBodyRenderer(operationDefinition, typeName);
1864
+ const $operationDeclaration = operationDeclarationRenderer(operationDefinition, typeName);
1563
1865
  return [
1866
+ "/* @anchor:file:start */",
1867
+ "",
1564
1868
  `const moduleName = "${moduleName}"`,
1565
1869
  `const method = "${method}"`,
1566
1870
  `const pathname = "${pathname}"`,
1567
1871
  "",
1568
- `export function ${operationId}<STATUS extends keyof ${typeName("ResponseBodies")}>(args?: ${typeName("RequestParameters")}): Keq<Operation<STATUS>> {`,
1872
+ "/* @anchor:operation-declaration */",
1873
+ `export ${$operationDeclaration} {`,
1569
1874
  ` const req = request.post<${typeName("ResponseBodies")}[STATUS]>("${pathname}")`,
1570
1875
  " .option('module', { name: moduleName, pathname, method })",
1571
1876
  "",
1877
+ $mediaType || void 0,
1878
+ " /* @anchor:query:start */",
1572
1879
  $queryParameters || void 0,
1880
+ " /* @anchor:query:end */",
1881
+ "",
1882
+ " /* @anchor:headers:start */",
1573
1883
  $headerParameters || void 0,
1884
+ " /* @anchor:headers:end */",
1885
+ "",
1886
+ " /* @anchor:path-parameters:start */",
1574
1887
  $pathParameters || void 0,
1575
- $requestBody ? `${$requestBody}
1576
- ` : void 0,
1577
- " return req",
1888
+ " /* @anchor:path-parameters:end */",
1889
+ "",
1890
+ " /* @anchor:body:start */",
1891
+ $requestBody || void 0,
1892
+ " /* @anchor:body:end */",
1893
+ "",
1894
+ " /* @anchor:operation-return */",
1895
+ ` return req as ReturnType<typeof ${operationId}>`,
1578
1896
  "}",
1579
1897
  "",
1580
1898
  `${operationId}.pathname = pathname`,
1581
- `${operationId}.method = method`
1582
- ].filter(R14.isNotNil).join("\n");
1899
+ `${operationId}.method = method`,
1900
+ "/* @anchor:file:end */"
1901
+ ].filter(R16.isNotNil).join("\n");
1583
1902
  }
1584
1903
 
1585
1904
  // src/tasks/compile/utils/compile-operation-definition.ts
@@ -1610,7 +1929,7 @@ function genEntrypointFilepath2(moduleName) {
1610
1929
  ].join("/");
1611
1930
  }
1612
1931
  async function compileOperationDefinition(options) {
1613
- const { rc, requestArtifact, schemaArtifacts, operationDefinitions } = options;
1932
+ const { compiler, task, rc, requestArtifact, schemaArtifacts, operationDefinitions } = options;
1614
1933
  const alias = (name) => `${name}Schema`;
1615
1934
  const qs = (parameter) => {
1616
1935
  if (typeof rc.qs === "function") {
@@ -1644,7 +1963,7 @@ async function compileOperationDefinition(options) {
1644
1963
  content,
1645
1964
  extensionName: ".type.ts"
1646
1965
  });
1647
- typeArtifact.addDependence("keq", ["KeqOperation", "KeqQueryValue", "KeqParamValue"]);
1966
+ typeArtifact.addDependence("keq", ["KeqOperation", "KeqQueryInit", "KeqPathParameterInit"]);
1648
1967
  const dependentSchemaDefinitions = operationDefinition.getDependencies();
1649
1968
  for (const dependentSchemaDefinition of dependentSchemaDefinitions) {
1650
1969
  const dependentArtifact = schemaArtifacts.find(isArtifactCompiledBy(dependentSchemaDefinition));
@@ -1656,7 +1975,7 @@ async function compileOperationDefinition(options) {
1656
1975
  new DependencyIdentifier(dependentSchemaDefinition.name, alias(dependentSchemaDefinition.name))
1657
1976
  ]);
1658
1977
  }
1659
- return typeArtifact;
1978
+ return await compiler.hooks.afterCompileOperationType.promise(typeArtifact, operationDefinition, task);
1660
1979
  }
1661
1980
  async function createRequestArtifact(operationDefinition, typeArtifact) {
1662
1981
  const typeName = typeNameFactory(operationDefinition);
@@ -1683,13 +2002,13 @@ async function compileOperationDefinition(options) {
1683
2002
  [
1684
2003
  `${typeName("RequestQuery")}`,
1685
2004
  `${typeName("RequestHeaders")}`,
1686
- `${typeName("RequestBody")}`
2005
+ `${typeName("RequestBodies")}`
1687
2006
  ],
1688
2007
  { export: true }
1689
2008
  );
1690
- return artifact;
2009
+ return await compiler.hooks.afterCompileOperationRequest.promise(artifact, operationDefinition, task);
1691
2010
  }
1692
- const artifacts = R15.unnest(
2011
+ const artifacts = R17.unnest(
1693
2012
  await Promise.all(
1694
2013
  operationDefinitions.map(async (operationDefinition) => {
1695
2014
  const typeArtifact = await createTypeArtifact(operationDefinition);
@@ -1698,7 +2017,7 @@ async function compileOperationDefinition(options) {
1698
2017
  })
1699
2018
  )
1700
2019
  );
1701
- const operationDefinitionsGroupByModuleName = R15.groupBy(
2020
+ const operationDefinitionsGroupByModuleName = R17.groupBy(
1702
2021
  (operationDefinition) => operationDefinition.module.name,
1703
2022
  operationDefinitions
1704
2023
  );
@@ -1726,32 +2045,38 @@ async function compileOperationDefinition(options) {
1726
2045
  async function requestRenderer() {
1727
2046
  return [
1728
2047
  "import { KeqRequest } from 'keq'",
1729
- "export const request = new KeqRequest()"
2048
+ "",
2049
+ "/* @anchor:file:start */",
2050
+ "",
2051
+ "/* @anchor:request-declaration */",
2052
+ "export const request = new KeqRequest()",
2053
+ "",
2054
+ "/* @anchor:file:end"
1730
2055
  ].join("\n");
1731
2056
  }
1732
2057
 
1733
2058
  // src/tasks/compile/index.ts
1734
- function createCompileTask(options) {
2059
+ function main6(compiler) {
1735
2060
  return {
1736
- title: "Compile",
1737
- enabled: options?.enabled,
1738
- skip: options?.skip,
1739
2061
  task: async (context, task) => {
1740
2062
  if (!context.setup) throw new Error("Please run setup task first.");
1741
2063
  if (!context.shaken) throw new Error("Please run shaking task first.");
1742
2064
  const rc = context.setup.rc;
1743
2065
  const matcher = context.setup.matcher;
1744
2066
  const documents = context.shaken.documents.filter((document) => !matcher.isModuleIgnored(document.module));
1745
- const requestArtifact = new Artifact({
1746
- id: "request",
1747
- filepath: "request",
1748
- content: await requestRenderer(),
1749
- extensionName: ".ts"
1750
- });
2067
+ const requestArtifact = await compiler.hooks.afterCompileKeqRequest.promise(
2068
+ new Artifact({
2069
+ id: "request",
2070
+ filepath: "request",
2071
+ content: await requestRenderer(),
2072
+ extensionName: ".ts"
2073
+ }),
2074
+ task
2075
+ );
1751
2076
  const schemaDefinitions = documents.flatMap((document) => document.schemas);
1752
2077
  const operationDefinitions = documents.flatMap((document) => document.operations);
1753
- const schemaArtifacts = await compileSchemaDefinition({ schemaDefinitions });
1754
- const operationArtifacts = await compileOperationDefinition({ rc, operationDefinitions, schemaArtifacts, requestArtifact });
2078
+ const schemaArtifacts = await compileSchemaDefinition({ compiler, task, schemaDefinitions });
2079
+ const operationArtifacts = await compileOperationDefinition({ compiler, task, rc, operationDefinitions, schemaArtifacts, requestArtifact });
1755
2080
  const artifacts = [requestArtifact, ...schemaArtifacts, ...operationArtifacts];
1756
2081
  context.compiled = {
1757
2082
  artifacts
@@ -1759,6 +2084,24 @@ function createCompileTask(options) {
1759
2084
  }
1760
2085
  };
1761
2086
  }
2087
+ function createCompileTask(compiler, options) {
2088
+ return {
2089
+ title: "Compile",
2090
+ enabled: options?.enabled,
2091
+ skip: options?.skip,
2092
+ task: (context, task) => task.newListr(
2093
+ [
2094
+ main6(compiler),
2095
+ {
2096
+ task: (context2, task2) => compiler.hooks.afterCompile.promise(task2)
2097
+ }
2098
+ ],
2099
+ {
2100
+ concurrent: false
2101
+ }
2102
+ )
2103
+ };
2104
+ }
1762
2105
 
1763
2106
  // src/tasks/interactive/utils/select-operation-definitions.ts
1764
2107
  var import_inquirer_select_pro = require("inquirer-select-pro");
@@ -1795,7 +2138,7 @@ function createInteractiveTask(options) {
1795
2138
  const documents = context.validated.documents;
1796
2139
  const operationDefinitions = documents.flatMap((document) => document.operations);
1797
2140
  const selectedOperationDefinitions = await selectOperationDefinitions(task, operationDefinitions);
1798
- if (options.override) {
2141
+ if (options.clear) {
1799
2142
  matcher.append({
1800
2143
  persist: false,
1801
2144
  ignore: true,
@@ -1806,7 +2149,7 @@ function createInteractiveTask(options) {
1806
2149
  }
1807
2150
  for (const op of selectedOperationDefinitions) {
1808
2151
  matcher.append({
1809
- persist: true,
2152
+ persist: !!options.persist,
1810
2153
  ignore: options.mode === "add",
1811
2154
  moduleName: op.module.name,
1812
2155
  operationMethod: op.method,
@@ -1817,39 +2160,162 @@ function createInteractiveTask(options) {
1817
2160
  };
1818
2161
  }
1819
2162
 
1820
- // src/tasks/index.ts
1821
- async function build(options) {
1822
- const tasks = new import_listr22.Listr(
1823
- [
1824
- createSetupTask(options),
1825
- createDownloadTask({ skipIgnoredModules: !options.interactive }),
1826
- createValidateTask(),
1827
- createInteractiveTask({ mode: "except", override: true, enabled: !!options.interactive }),
1828
- createShakingTask({ skipIgnoredModules: true, skipEmptyDocuments: true }),
1829
- createCompileTask(),
1830
- createPersistTask({ persistIgnore: false })
1831
- ],
1832
- {
1833
- concurrent: false,
1834
- renderer: "default",
1835
- rendererOptions: {
1836
- suffixSkips: true,
1837
- collapseSubtasks: false,
1838
- collapseErrors: false
2163
+ // src/compiler/intercepter/perfect-error-message.ts
2164
+ var R18 = __toESM(require("ramda"), 1);
2165
+ function perfectErrorMessage() {
2166
+ return {
2167
+ register: (tap) => {
2168
+ const fn = tap.fn;
2169
+ function prefix(err) {
2170
+ if (err instanceof Error) {
2171
+ err.message = `[Plugin: ${tap.name}] ${err.message}`;
2172
+ }
2173
+ }
2174
+ if (tap.type === "promise") {
2175
+ tap.fn = async (...args) => {
2176
+ try {
2177
+ return await fn(...args);
2178
+ } catch (err) {
2179
+ prefix(err);
2180
+ throw err;
2181
+ }
2182
+ };
2183
+ }
2184
+ if (tap.type === "sync") {
2185
+ tap.fn = (...args) => {
2186
+ try {
2187
+ return fn(...args);
2188
+ } catch (err) {
2189
+ prefix(err);
2190
+ throw err;
2191
+ }
2192
+ };
2193
+ }
2194
+ if (tap.type === "async") {
2195
+ tap.fn = (...args) => {
2196
+ const callback = R18.last(args);
2197
+ return fn(...R18.init(args), (err, result) => {
2198
+ prefix(err);
2199
+ return callback(err, result);
2200
+ });
2201
+ };
1839
2202
  }
2203
+ return tap;
1840
2204
  }
1841
- );
1842
- await tasks.run({});
2205
+ };
1843
2206
  }
1844
2207
 
1845
- // src/define-keq-config.ts
1846
- function defineKeqConfig(config) {
1847
- return config;
2208
+ // src/compiler/intercepter/print-information.ts
2209
+ function proxyTaskWrapper(pluginName, task) {
2210
+ return new Proxy(task, {
2211
+ set(target, prop2, value) {
2212
+ if (prop2 !== "output") {
2213
+ return Reflect.set(target, prop2, value);
2214
+ }
2215
+ target.output = `[Plugin: ${pluginName}] ${value}`;
2216
+ return true;
2217
+ }
2218
+ });
1848
2219
  }
2220
+ function printInformation(taskIndex) {
2221
+ return {
2222
+ register: (tap) => {
2223
+ const fn = tap.fn;
2224
+ if (tap.type === "promise") {
2225
+ tap.fn = (...args) => {
2226
+ const task = args[taskIndex];
2227
+ const proxyTask = proxyTaskWrapper(tap.name, task);
2228
+ args[taskIndex] = proxyTask;
2229
+ proxyTask.output = "Processing...";
2230
+ return fn(...args);
2231
+ };
2232
+ }
2233
+ if (tap.type === "sync") {
2234
+ tap.fn = (...args) => {
2235
+ const task = args[taskIndex];
2236
+ const proxyTask = proxyTaskWrapper(tap.name, task);
2237
+ args[taskIndex] = proxyTask;
2238
+ proxyTask.output = "Processing...";
2239
+ return fn(...args);
2240
+ };
2241
+ }
2242
+ if (tap.type === "async") {
2243
+ tap.fn = (...args) => {
2244
+ const task = args[taskIndex];
2245
+ const proxyTask = proxyTaskWrapper(tap.name, task);
2246
+ args[taskIndex] = proxyTask;
2247
+ proxyTask.output = "Processing...";
2248
+ return fn(...args);
2249
+ };
2250
+ }
2251
+ return tap;
2252
+ }
2253
+ };
2254
+ }
2255
+
2256
+ // src/compiler/compiler.ts
2257
+ var Compiler = class {
2258
+ constructor(options) {
2259
+ this.options = options;
2260
+ for (const hook of Object.values(this.hooks)) {
2261
+ hook.intercept(perfectErrorMessage());
2262
+ }
2263
+ this.hooks.afterSetup.intercept(printInformation(0));
2264
+ this.hooks.afterPersist.intercept(printInformation(0));
2265
+ }
2266
+ context = {};
2267
+ hooks = {
2268
+ // core
2269
+ afterSetup: new import_tapable.AsyncSeriesHook(["task"]),
2270
+ afterDownload: new import_tapable.AsyncSeriesHook(["task"]),
2271
+ afterValidate: new import_tapable.AsyncSeriesHook(["task"]),
2272
+ afterShaking: new import_tapable.AsyncSeriesHook(["task"]),
2273
+ afterCompile: new import_tapable.AsyncSeriesHook(["task"]),
2274
+ afterPersist: new import_tapable.AsyncSeriesHook(["task"]),
2275
+ done: new import_tapable.SyncHook(),
2276
+ // compile
2277
+ afterCompileKeqRequest: new import_tapable.AsyncSeriesWaterfallHook(["artifact", "task"]),
2278
+ afterCompileSchema: new import_tapable.AsyncSeriesWaterfallHook(["artifact", "schema", "task"]),
2279
+ afterCompileOperationType: new import_tapable.AsyncSeriesWaterfallHook(["artifact", "operation", "task"]),
2280
+ afterCompileOperationRequest: new import_tapable.AsyncSeriesWaterfallHook(["artifact", "operation", "task"])
2281
+ };
2282
+ async run() {
2283
+ const options = this.options;
2284
+ const tasks = new import_listr22.Listr(
2285
+ [
2286
+ createSetupTask(this, options),
2287
+ createDownloadTask(this, { skipIgnoredModules: !options.interactive }),
2288
+ createValidateTask(this, { enabled: !!options.build }),
2289
+ createInteractiveTask({ enabled: !!options.interactive, ...typeof options.interactive === "object" ? options.interactive : { mode: "except" } }),
2290
+ createShakingTask(this, { enabled: !!options.build, ...typeof options.build === "object" ? options.build.shaking : void 0 }),
2291
+ createCompileTask(this, { enabled: !!options.build }),
2292
+ createPersistTask(this, { enabled: !!options.build })
2293
+ ],
2294
+ {
2295
+ concurrent: false,
2296
+ renderer: "default",
2297
+ rendererOptions: {
2298
+ suffixSkips: true,
2299
+ collapseSubtasks: false,
2300
+ collapseErrors: false
2301
+ }
2302
+ }
2303
+ );
2304
+ await tasks.run(this.context);
2305
+ await this.hooks.done.promise();
2306
+ }
2307
+ };
1849
2308
  // Annotate the CommonJS export names for ESM import in node:
1850
2309
  0 && (module.exports = {
2310
+ ApiDocument,
2311
+ ApiDocumentV3_1,
2312
+ Artifact,
2313
+ Compiler,
1851
2314
  FileNamingStyle,
1852
- build,
2315
+ ModuleDefinition,
2316
+ OperationDefinition,
2317
+ RuntimeConfig,
2318
+ SchemaDefinition,
1853
2319
  defineKeqConfig
1854
2320
  });
1855
2321
  //# sourceMappingURL=index.cjs.map