keq 2.9.0 → 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/esm/src/constant.d.ts +2 -0
  3. package/dist/esm/src/constant.js +2 -0
  4. package/dist/esm/src/core.d.ts +30 -0
  5. package/dist/esm/src/core.js +162 -53
  6. package/dist/esm/src/exception/abort.exception.d.ts +3 -0
  7. package/dist/esm/src/exception/abort.exception.js +6 -0
  8. package/dist/esm/src/index.d.ts +1 -0
  9. package/dist/esm/src/index.js +1 -0
  10. package/dist/esm/src/is/is-abort-signal.d.ts +1 -0
  11. package/dist/esm/src/is/is-abort-signal.js +8 -0
  12. package/dist/esm/src/middlewares/fetch-arguments-middleware.js +5 -1
  13. package/dist/esm/src/middlewares/retry-middleware.js +20 -3
  14. package/dist/esm/src/middlewares/timeout-middleware.js +3 -1
  15. package/dist/esm/src/types/keq-context.d.ts +10 -1
  16. package/dist/esm/src/types/keq-context.js +1 -1
  17. package/dist/umd/src/constant.d.ts +2 -0
  18. package/dist/umd/src/constant.js +3 -1
  19. package/dist/umd/src/core.d.ts +30 -0
  20. package/dist/umd/src/core.js +162 -53
  21. package/dist/umd/src/exception/abort.exception.d.ts +3 -0
  22. package/dist/umd/src/exception/abort.exception.js +20 -0
  23. package/dist/umd/src/index.d.ts +1 -0
  24. package/dist/umd/src/index.js +4 -2
  25. package/dist/umd/src/is/is-abort-signal.d.ts +1 -0
  26. package/dist/umd/src/is/is-abort-signal.js +22 -0
  27. package/dist/umd/src/middlewares/fetch-arguments-middleware.js +4 -0
  28. package/dist/umd/src/middlewares/retry-middleware.js +21 -4
  29. package/dist/umd/src/middlewares/timeout-middleware.js +4 -2
  30. package/dist/umd/src/types/keq-context.d.ts +10 -1
  31. package/package.json +10 -13
  32. package/.claude/settings.local.json +0 -26
  33. package/packages/cache/.turbo/turbo-build.log +0 -29
  34. package/packages/cache/dist/index.d.mts +0 -354
  35. package/packages/cache/dist/index.d.mts.map +0 -1
  36. package/packages/cache/dist/index.d.ts +0 -353
  37. package/packages/cache/dist/index.d.ts.map +0 -1
  38. package/packages/cache/dist/index.js +0 -1271
  39. package/packages/cache/dist/index.js.map +0 -1
  40. package/packages/cache/dist/index.mjs +0 -1237
  41. package/packages/cache/dist/index.mjs.map +0 -1
  42. package/packages/cli/.turbo/turbo-build.log +0 -91
  43. package/packages/cli/dist/cli.cjs +0 -1364
  44. package/packages/cli/dist/cli.cjs.map +0 -1
  45. package/packages/cli/dist/cli.d.cts +0 -1
  46. package/packages/cli/dist/cli.d.mts +0 -1
  47. package/packages/cli/dist/cli.mjs +0 -1359
  48. package/packages/cli/dist/cli.mjs.map +0 -1
  49. package/packages/cli/dist/compiler-0Kli6UCr.cjs +0 -738
  50. package/packages/cli/dist/compiler-0Kli6UCr.cjs.map +0 -1
  51. package/packages/cli/dist/compiler-C3AE8j54.mjs +0 -715
  52. package/packages/cli/dist/compiler-C3AE8j54.mjs.map +0 -1
  53. package/packages/cli/dist/index.cjs +0 -20
  54. package/packages/cli/dist/index.cjs.map +0 -1
  55. package/packages/cli/dist/index.d.cts +0 -17
  56. package/packages/cli/dist/index.d.cts.map +0 -1
  57. package/packages/cli/dist/index.d.mts +0 -17
  58. package/packages/cli/dist/index.d.mts.map +0 -1
  59. package/packages/cli/dist/index.mjs +0 -10
  60. package/packages/cli/dist/index.mjs.map +0 -1
  61. package/packages/cli/dist/init-BNhD2oCI.mjs +0 -168
  62. package/packages/cli/dist/init-BNhD2oCI.mjs.map +0 -1
  63. package/packages/cli/dist/init-DqxLcRSQ.cjs +0 -170
  64. package/packages/cli/dist/init-DqxLcRSQ.cjs.map +0 -1
  65. package/packages/cli/dist/logger-D7PyVZo3.cjs +0 -46
  66. package/packages/cli/dist/logger-D7PyVZo3.cjs.map +0 -1
  67. package/packages/cli/dist/logger-QLBHySQ3.mjs +0 -12
  68. package/packages/cli/dist/logger-QLBHySQ3.mjs.map +0 -1
  69. package/packages/cli/dist/micro-function.translator-BmJZzkKh.cjs +0 -16
  70. package/packages/cli/dist/micro-function.translator-BmJZzkKh.cjs.map +0 -1
  71. package/packages/cli/dist/micro-function.translator-CDfkj4Tt.mjs +0 -11
  72. package/packages/cli/dist/micro-function.translator-CDfkj4Tt.mjs.map +0 -1
  73. package/packages/cli/dist/mock-command-Bp1LxSls.mjs +0 -350
  74. package/packages/cli/dist/mock-command-Bp1LxSls.mjs.map +0 -1
  75. package/packages/cli/dist/mock-command-WZcfy5Iq.cjs +0 -353
  76. package/packages/cli/dist/mock-command-WZcfy5Iq.cjs.map +0 -1
  77. package/packages/cli/dist/plugins-CgMhaNZq.cjs +0 -3558
  78. package/packages/cli/dist/plugins-CgMhaNZq.cjs.map +0 -1
  79. package/packages/cli/dist/plugins-DCvJ8iHR.mjs +0 -3280
  80. package/packages/cli/dist/plugins-DCvJ8iHR.mjs.map +0 -1
  81. package/packages/cli/dist/plugins.cjs +0 -36
  82. package/packages/cli/dist/plugins.d.cts +0 -2
  83. package/packages/cli/dist/plugins.d.mts +0 -2
  84. package/packages/cli/dist/plugins.mjs +0 -2
  85. package/packages/cli/dist/runtime-config-BWQlPhiB.d.cts +0 -780
  86. package/packages/cli/dist/runtime-config-BWQlPhiB.d.cts.map +0 -1
  87. package/packages/cli/dist/runtime-config-CrzK-Ucf.d.mts +0 -780
  88. package/packages/cli/dist/runtime-config-CrzK-Ucf.d.mts.map +0 -1
  89. package/packages/cli/dist/translators.cjs +0 -14
  90. package/packages/cli/dist/translators.cjs.map +0 -1
  91. package/packages/cli/dist/translators.d.cts +0 -14
  92. package/packages/cli/dist/translators.d.cts.map +0 -1
  93. package/packages/cli/dist/translators.d.mts +0 -14
  94. package/packages/cli/dist/translators.d.mts.map +0 -1
  95. package/packages/cli/dist/translators.mjs +0 -12
  96. package/packages/cli/dist/translators.mjs.map +0 -1
  97. package/packages/cli/node_modules/.bin/eslint +0 -21
  98. package/packages/cli/node_modules/.bin/jiti +0 -21
  99. package/packages/cli/node_modules/.bin/js-yaml +0 -21
  100. package/packages/cli/node_modules/.bin/jsf +0 -21
  101. package/packages/cli/node_modules/.bin/jsonpath +0 -21
  102. package/packages/cli/node_modules/.bin/jsonpath-plus +0 -21
  103. package/packages/cli/node_modules/.bin/semver +0 -21
  104. package/packages/cli/node_modules/.bin/tsc +0 -21
  105. package/packages/cli/node_modules/.bin/tsserver +0 -21
  106. package/packages/exception/.turbo/turbo-build.log +0 -29
  107. package/packages/exception/dist/index.d.mts +0 -21
  108. package/packages/exception/dist/index.d.mts.map +0 -1
  109. package/packages/exception/dist/index.d.ts +0 -21
  110. package/packages/exception/dist/index.d.ts.map +0 -1
  111. package/packages/exception/dist/index.js +0 -104
  112. package/packages/exception/dist/index.js.map +0 -1
  113. package/packages/exception/dist/index.mjs +0 -99
  114. package/packages/exception/dist/index.mjs.map +0 -1
  115. package/packages/headers/.turbo/turbo-build.log +0 -29
  116. package/packages/headers/dist/index.d.mts +0 -46
  117. package/packages/headers/dist/index.d.mts.map +0 -1
  118. package/packages/headers/dist/index.d.ts +0 -46
  119. package/packages/headers/dist/index.d.ts.map +0 -1
  120. package/packages/headers/dist/index.js +0 -81
  121. package/packages/headers/dist/index.js.map +0 -1
  122. package/packages/headers/dist/index.mjs +0 -75
  123. package/packages/headers/dist/index.mjs.map +0 -1
  124. package/packages/keq/.turbo/turbo-build.log +0 -29
  125. package/packages/keq/dist/index.d.mts +0 -962
  126. package/packages/keq/dist/index.d.mts.map +0 -1
  127. package/packages/keq/dist/index.d.ts +0 -962
  128. package/packages/keq/dist/index.d.ts.map +0 -1
  129. package/packages/keq/dist/index.js +0 -1876
  130. package/packages/keq/dist/index.js.map +0 -1
  131. package/packages/keq/dist/index.mjs +0 -1814
  132. package/packages/keq/dist/index.mjs.map +0 -1
  133. package/packages/nestjs/.turbo/turbo-build.log +0 -29
  134. package/packages/nestjs/dist/index.d.mts +0 -52
  135. package/packages/nestjs/dist/index.d.mts.map +0 -1
  136. package/packages/nestjs/dist/index.d.ts +0 -52
  137. package/packages/nestjs/dist/index.d.ts.map +0 -1
  138. package/packages/nestjs/dist/index.js +0 -166
  139. package/packages/nestjs/dist/index.js.map +0 -1
  140. package/packages/nestjs/dist/index.mjs +0 -136
  141. package/packages/nestjs/dist/index.mjs.map +0 -1
  142. package/packages/test/.turbo/turbo-build.log +0 -6
  143. package/packages/url/.turbo/turbo-build.log +0 -29
  144. package/packages/url/dist/index.d.mts +0 -9
  145. package/packages/url/dist/index.d.mts.map +0 -1
  146. package/packages/url/dist/index.d.ts +0 -9
  147. package/packages/url/dist/index.d.ts.map +0 -1
  148. package/packages/url/dist/index.js +0 -43
  149. package/packages/url/dist/index.js.map +0 -1
  150. package/packages/url/dist/index.mjs +0 -40
  151. package/packages/url/dist/index.mjs.map +0 -1
@@ -1,738 +0,0 @@
1
- const require_logger = require("./logger-D7PyVZo3.cjs");
2
- const require_plugins = require("./plugins-CgMhaNZq.cjs");
3
- const require_micro_function_translator = require("./micro-function.translator-BmJZzkKh.cjs");
4
- let listr2 = require("listr2");
5
- let tapable = require("tapable");
6
- let fs_extra = require("fs-extra");
7
- fs_extra = require_logger.__toESM(fs_extra, 1);
8
- let path = require("path");
9
- path = require_logger.__toESM(path, 1);
10
- let cosmiconfig = require("cosmiconfig");
11
- let ramda = require("ramda");
12
- ramda = require_logger.__toESM(ramda, 1);
13
- let picomatch = require("picomatch");
14
- picomatch = require_logger.__toESM(picomatch, 1);
15
- let node_fs = require("node:fs");
16
- node_fs = require_logger.__toESM(node_fs, 1);
17
- let node_path = require("node:path");
18
- node_path = require_logger.__toESM(node_path, 1);
19
- let _sinclair_typebox_value = require("@sinclair/typebox/value");
20
- let _sinclair_typebox = require("@sinclair/typebox");
21
- let _scalar_openapi_parser = require("@scalar/openapi-parser");
22
- //#region src/constants/file-naming-style.ts
23
- /**
24
- * File naming style options
25
- */
26
- let FileNamingStyle = /* @__PURE__ */ function(FileNamingStyle) {
27
- /** Camel case style (e.g., myFileName) */
28
- FileNamingStyle["camelCase"] = "camelCase";
29
- /** Capital case style (e.g., My File Name) */
30
- FileNamingStyle["capitalCase"] = "capitalCase";
31
- /** Constant case style (e.g., MY_FILE_NAME) */
32
- FileNamingStyle["constantCase"] = "constantCase";
33
- /** Dot case style (e.g., my.file.name) */
34
- FileNamingStyle["dotCase"] = "dotCase";
35
- /** Header case style (e.g., My-File-Name) */
36
- FileNamingStyle["headerCase"] = "headerCase";
37
- /** No case style (e.g., my file name) */
38
- FileNamingStyle["noCase"] = "noCase";
39
- /** Param case style (e.g., my-file-name) */
40
- FileNamingStyle["paramCase"] = "paramCase";
41
- /** Pascal case style (e.g., MyFileName) */
42
- FileNamingStyle["pascalCase"] = "pascalCase";
43
- /** Path case style (e.g., my/file/name) */
44
- FileNamingStyle["pathCase"] = "pathCase";
45
- /** Sentence case style (e.g., My file name) */
46
- FileNamingStyle["sentenceCase"] = "sentenceCase";
47
- /** Snake case style (e.g., my_file_name) */
48
- FileNamingStyle["snakeCase"] = "snakeCase";
49
- /** Kebab case style (e.g., my-file-name) */
50
- FileNamingStyle["kebabCase"] = "kebabCase";
51
- return FileNamingStyle;
52
- }({});
53
- //#endregion
54
- //#region src/utils/matcher.ts
55
- const ALL_HTTP_METHODS = [
56
- "get",
57
- "post",
58
- "put",
59
- "delete",
60
- "patch",
61
- "head",
62
- "options"
63
- ];
64
- function deduplicateRules(rules) {
65
- const sorted = ramda.sortBy(ramda.prop("deny"), rules);
66
- return ramda.uniqWith((a, b) => a.moduleName === b.moduleName && a.operationMethod === b.operationMethod && a.operationPathname === b.operationPathname, sorted);
67
- }
68
- function sortRulesForOutput(rules) {
69
- return [...rules].sort((a, b) => {
70
- if (a.moduleName === "*" && b.moduleName !== "*") return -1;
71
- if (a.moduleName !== "*" && b.moduleName === "*") return 1;
72
- if (a.moduleName !== b.moduleName) return a.moduleName.localeCompare(b.moduleName);
73
- if (a.operationMethod === "*" && b.operationMethod !== "*") return -1;
74
- if (a.operationMethod !== "*" && b.operationMethod === "*") return 1;
75
- if (a.operationMethod !== b.operationMethod) return a.operationMethod.localeCompare(b.operationMethod);
76
- return a.operationPathname.localeCompare(b.operationPathname);
77
- });
78
- }
79
- function renderBlock(section, rules) {
80
- if (rules.length === 0) return "";
81
- const maxMethodLen = Math.max(...rules.map((r) => r.operationMethod.toUpperCase().length));
82
- const lines = [];
83
- for (const r of rules) {
84
- if (r.leadingComments && r.leadingComments.length > 0) lines.push(...r.leadingComments);
85
- const ruleLine = `${r.operationMethod.toUpperCase().padEnd(maxMethodLen + 2)}${r.moduleName}:${r.operationPathname}`;
86
- lines.push(r.inlineComment ? `${ruleLine} ${r.inlineComment}` : ruleLine);
87
- }
88
- return `[${section}]\n${lines.join("\n")}`;
89
- }
90
- function compileRule(rule) {
91
- return {
92
- rule,
93
- matchModuleName: (0, picomatch.default)(rule.moduleName),
94
- matchMethod: (0, picomatch.default)(rule.operationMethod),
95
- matchPathname: (0, picomatch.default)(rule.operationPathname)
96
- };
97
- }
98
- /**
99
- * Matches API operations and modules against `.keqfilter` rules to determine
100
- * which should be denied (excluded) or allowed during code generation.
101
- * Supports glob patterns (via picomatch) for module names, HTTP methods, and pathnames.
102
- */
103
- var Matcher = class Matcher {
104
- compiled;
105
- preambleComments;
106
- trailingComments;
107
- constructor(rules, meta = {}) {
108
- this.compiled = rules.map(compileRule);
109
- this.preambleComments = meta.preambleComments ?? [];
110
- this.trailingComments = meta.trailingComments ?? [];
111
- }
112
- get rules() {
113
- return this.compiled.map((c) => c.rule);
114
- }
115
- /**
116
- * Parse `.keqfilter` file content into a Matcher instance.
117
- *
118
- * File format:
119
- * ```
120
- * [deny]
121
- * GET petStore:/pets
122
- * * userService:/**
123
- *
124
- * [allow]
125
- * GET petStore:/pets/details
126
- * ```
127
- *
128
- * Line format: `METHOD module:/pathname`
129
- * - method: HTTP method or `*`, case-insensitive
130
- * - module:/pathname: module name + `:` + path pattern (glob supported)
131
- */
132
- static parse(content) {
133
- const normalized = content.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
134
- const rules = [];
135
- let currentDeny = null;
136
- let firstSectionSeen = false;
137
- let preambleComments = [];
138
- const pendingComments = [];
139
- for (const rawLine of normalized.split("\n")) {
140
- const line = rawLine.replace(/#.*$/, "").trim();
141
- if (!line) {
142
- pendingComments.push(rawLine);
143
- continue;
144
- }
145
- if (line === "[deny]") {
146
- if (!firstSectionSeen) {
147
- preambleComments = [...pendingComments];
148
- pendingComments.length = 0;
149
- firstSectionSeen = true;
150
- } else while (pendingComments.length > 0 && pendingComments[0].trim() === "") pendingComments.shift();
151
- currentDeny = true;
152
- continue;
153
- }
154
- if (line === "[allow]") {
155
- if (!firstSectionSeen) {
156
- preambleComments = [...pendingComments];
157
- pendingComments.length = 0;
158
- firstSectionSeen = true;
159
- } else while (pendingComments.length > 0 && pendingComments[0].trim() === "") pendingComments.shift();
160
- currentDeny = false;
161
- continue;
162
- }
163
- if (currentDeny === null) continue;
164
- const matched = line.match(/^([^\s]+)\s+([^:\s]+):(.*)$/);
165
- if (!matched) throw new Error(`Invalid filter rule: "${line}"`);
166
- const [, operationMethod, moduleName, operationPathname] = matched;
167
- const inlineCommentMatch = rawLine.match(/\s+(#.*)$/);
168
- const inlineComment = inlineCommentMatch ? inlineCommentMatch[1] : void 0;
169
- rules.push({
170
- persist: true,
171
- deny: currentDeny,
172
- moduleName,
173
- operationMethod: operationMethod.toLowerCase(),
174
- operationPathname,
175
- leadingComments: pendingComments.length > 0 ? [...pendingComments] : void 0,
176
- inlineComment
177
- });
178
- pendingComments.length = 0;
179
- }
180
- const trailingComments = [...pendingComments];
181
- while (trailingComments.length > 0 && trailingComments[trailingComments.length - 1].trim() === "") trailingComments.pop();
182
- while (preambleComments.length > 0 && preambleComments[preambleComments.length - 1].trim() === "") preambleComments.pop();
183
- return new Matcher(deduplicateRules(rules), {
184
- preambleComments,
185
- trailingComments
186
- });
187
- }
188
- static async read(filepath) {
189
- const content = await fs_extra.default.readFile(filepath, "utf-8");
190
- return Matcher.parse(content);
191
- }
192
- async write(filepath) {
193
- const persistRules = ramda.compose(ramda.reverse, ramda.uniqWith((a, b) => a.moduleName === b.moduleName && a.operationMethod === b.operationMethod && a.operationPathname === b.operationPathname), ramda.filter((rule) => rule.persist))(this.rules);
194
- const denyRules = sortRulesForOutput(persistRules.filter((r) => r.deny));
195
- const allowRules = sortRulesForOutput(persistRules.filter((r) => !r.deny));
196
- const blocks = [renderBlock("deny", denyRules), renderBlock("allow", allowRules)].filter(Boolean);
197
- if (blocks.length === 0) return;
198
- const blockContent = blocks.join("\n\n");
199
- const mainContent = this.preambleComments.length > 0 ? `${this.preambleComments.join("\n")}\n${blockContent}` : blockContent;
200
- const output = this.trailingComments.length > 0 ? `${mainContent}\n\n${this.trailingComments.join("\n")}` : mainContent;
201
- await fs_extra.default.writeFile(filepath, output, "utf-8");
202
- }
203
- append(rule) {
204
- this.compiled.unshift(compileRule(rule));
205
- }
206
- isOperationDenied(operationDefinition) {
207
- const moduleName = operationDefinition.module.name;
208
- const operationMethod = operationDefinition.method.toLowerCase();
209
- const operationPathname = operationDefinition.pathname;
210
- for (const { rule, matchModuleName, matchMethod, matchPathname } of this.compiled) {
211
- if (!matchModuleName(moduleName)) continue;
212
- if (!matchMethod(operationMethod)) continue;
213
- if (!matchPathname(operationPathname)) continue;
214
- return rule.deny;
215
- }
216
- return false;
217
- }
218
- isModuleDenied(moduleDefinition) {
219
- const moduleName = moduleDefinition.name;
220
- for (const { rule, matchModuleName, matchMethod, matchPathname } of this.compiled) {
221
- if (!matchModuleName(moduleName)) continue;
222
- if (!rule.deny) return false;
223
- if (!ALL_HTTP_METHODS.every((m) => matchMethod(m))) continue;
224
- if (!matchPathname("/a/b/c/d")) continue;
225
- return true;
226
- }
227
- return false;
228
- }
229
- };
230
- //#endregion
231
- //#region src/compiler/tasks/setup/utils/find-nearest-package-json.ts
232
- function findNearestPackageJson(startDir = process.cwd()) {
233
- let dir = startDir;
234
- while (true) {
235
- const pkgPath = node_path.default.join(dir, "package.json");
236
- if (node_fs.default.existsSync(pkgPath)) return {
237
- json: JSON.parse(node_fs.default.readFileSync(pkgPath, "utf8")),
238
- path: pkgPath
239
- };
240
- const parent = node_path.default.dirname(dir);
241
- if (parent === dir) break;
242
- dir = parent;
243
- }
244
- return null;
245
- }
246
- //#endregion
247
- //#region src/compiler/tasks/setup/utils/get-project-module-system.ts
248
- function getProjectModuleSystem(pkgInfo) {
249
- if (!pkgInfo?.json) return "cjs";
250
- const { json } = pkgInfo;
251
- if (json.type === "module") return "esm";
252
- return "cjs";
253
- }
254
- //#endregion
255
- //#region src/types/address.ts
256
- const Address = _sinclair_typebox.Type.Object({
257
- url: _sinclair_typebox.Type.String(),
258
- headers: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.Record(_sinclair_typebox.Type.String(), _sinclair_typebox.Type.String(), { default: {} })),
259
- encoding: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.Union([_sinclair_typebox.Type.Literal("utf8"), _sinclair_typebox.Type.Literal("ascii")], { default: "utf8" }))
260
- });
261
- //#endregion
262
- //#region src/utils/is-valid-url.ts
263
- /**
264
- * 通用 URL 验证正则表达式,支持任意协议
265
- *
266
- * 格式: protocol://[user:password@][host][:port][/path][?query][#fragment]
267
- *
268
- * 支持的协议示例:
269
- * - http://, https://
270
- * - file:// (支持 file:///path 和 file://host/path 两种格式)
271
- * - ftp://, sftp://
272
- * - ws://, wss://
273
- * - 以及任何其他自定义协议
274
- */
275
- const URL_REGEX = /^[a-zA-Z][a-zA-Z0-9+.-]*:\/\/(?:[^\s@]+@)?[^\s/:?#]*(?::\d+)?(?:\/[^\s?#]*)?(?:\?[^\s#]*)?(?:#[^\s]*)?$/;
276
- /**
277
- * 验证是否为有效的 URL
278
- *
279
- * @param url - 待验证的 URL 字符串
280
- * @returns 如果是有效的 URL 返回 true,否则返回 false
281
- *
282
- * @example
283
- * ```typescript
284
- * isValidURL('http://example.com') // true
285
- * isValidURL('https://example.com:8080/path?query=1#fragment') // true
286
- * isValidURL('file:///path/to/file.json') // true
287
- * isValidURL('not a url') // false
288
- * ```
289
- */
290
- function isValidURL(url) {
291
- return URL_REGEX.test(url);
292
- }
293
- //#endregion
294
- //#region src/types/runtime-config.ts
295
- const Modules = _sinclair_typebox.Type.Transform(_sinclair_typebox.Type.Record(_sinclair_typebox.Type.String(), _sinclair_typebox.Type.Union([_sinclair_typebox.Type.String(), Address]))).Decode((value) => {
296
- const keys = Object.keys(value);
297
- for (const key of keys) if (!/^[A-Za-z_][A-Za-z0-9_$]*$/.test(key)) 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.`);
298
- const keysGroupByLowerCase = ramda.groupBy(ramda.toLower, keys);
299
- for (const groupKey in keysGroupByLowerCase) {
300
- const keys = keysGroupByLowerCase[groupKey] || [];
301
- if (keys.length > 1) throw new Error(`Module names ${keys.map((name) => `"${name}"`).join(", ")} are case-insensitively duplicated.`);
302
- }
303
- for (const key in value) {
304
- const url = typeof value[key] === "string" ? value[key] : value[key].url;
305
- if (isValidURL(url)) continue;
306
- throw new Error(`The ${JSON.stringify(url)} of module "${key}" is not a valid URL.`);
307
- }
308
- return ramda.map((item) => typeof item !== "string" ? item : {
309
- url: item,
310
- headers: {},
311
- encoding: "utf8"
312
- }, value);
313
- }).Encode((value) => value);
314
- const RawConfig = _sinclair_typebox.Type.Object({
315
- /**
316
- * Output directory for generated files
317
- */
318
- outdir: _sinclair_typebox.Type.String({ default: `${process.cwd()}/api` }),
319
- /**
320
- * Rendering options that directly control code generation output
321
- */
322
- rendering: _sinclair_typebox.Type.Object({
323
- /**
324
- * Whether to generate ES Module code
325
- *
326
- * If not specified, the module system will be inferred from the nearest package.json "type" field
327
- * or defaults to "cjs" if no package.json is found.
328
- */
329
- esm: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.Boolean({ default: false })),
330
- /**
331
- * File naming style for generated files
332
- */
333
- fileNamingStyle: _sinclair_typebox.Type.Enum(FileNamingStyle, { default: "snakeCase" }),
334
- /**
335
- * Controls how `additionalProperties: true` (or undefined) is rendered in generated TypeScript types.
336
- *
337
- * - `'unknown'` (default): renders as `unknown`, which is stricter and type-safe
338
- * - `'any'`: renders as `any`, which is more permissive
339
- */
340
- additionalPropertiesType: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.Union([_sinclair_typebox.Type.Literal("unknown"), _sinclair_typebox.Type.Literal("any")], { default: "unknown" })),
341
- /**
342
- * Whether to generate entrypoint (index) files that re-export all generated modules.
343
- *
344
- * Disable this to avoid merge conflicts in multi-branch collaborative development,
345
- * as auto-generated index files change frequently.
346
- */
347
- entrypoint: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.Boolean({ default: false }))
348
- }, { default: {} }),
349
- /**
350
- * OpenAPI/Swagger document sources
351
- *
352
- * A map of module names to their document URLs or Address objects.
353
- * The module name must be a valid JavaScript identifier.
354
- */
355
- modules: Modules,
356
- /**
357
- * Enable debug mode to output detailed logs during compilation
358
- */
359
- debug: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.Boolean({ default: false })),
360
- /**
361
- * Whether to tolerate wrong openapi/swagger structure
362
- */
363
- tolerant: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.Boolean({ default: false })),
364
- /**
365
- * Translators to transform generated code
366
- *
367
- * Used to customize the code generation process for different frameworks or patterns.
368
- * Can be a single translator or an array of translators.
369
- */
370
- translators: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.Transform(_sinclair_typebox.Type.Union([_sinclair_typebox.Type.Unsafe(_sinclair_typebox.Type.Any()), _sinclair_typebox.Type.Array(_sinclair_typebox.Type.Unsafe(_sinclair_typebox.Type.Any()))], { default: [] })).Decode((value) => {
371
- if (value === void 0) return [];
372
- if (Array.isArray(value)) return value;
373
- return [value];
374
- }).Encode((value) => value)),
375
- /**
376
- * Plugins to extend code generation functionality
377
- *
378
- * An array of plugin instances that can hook into various stages of the compilation process,
379
- * such as code transformation, formatting, linting, or custom file generation.
380
- */
381
- plugins: _sinclair_typebox.Type.Optional(_sinclair_typebox.Type.Array(_sinclair_typebox.Type.Unsafe(_sinclair_typebox.Type.Any()), { default: [] }))
382
- });
383
- //#endregion
384
- //#region src/compiler/tasks/setup/utils/parse-runtime-config.ts
385
- function parseRuntimeConfig(data) {
386
- try {
387
- const record = typeof data === "object" && data !== null ? data : void 0;
388
- const originalPlugins = record && "plugins" in record ? record.plugins : void 0;
389
- const originalTranslators = record && "translators" in record ? record.translators : void 0;
390
- const sanitized = record ? { ...record } : data;
391
- if (record) {
392
- delete sanitized.plugins;
393
- delete sanitized.translators;
394
- }
395
- const parsed = _sinclair_typebox_value.Value.Parse(RawConfig, sanitized);
396
- if (originalPlugins !== void 0) parsed.plugins = originalPlugins;
397
- if (originalTranslators !== void 0) parsed.translators = originalTranslators;
398
- return parsed;
399
- } catch (error) {
400
- if (error instanceof Error) error.message = `Invalid Config: ${error.message}`;
401
- throw error;
402
- }
403
- }
404
- //#endregion
405
- //#region src/compiler/tasks/setup/index.ts
406
- const explore = (0, cosmiconfig.cosmiconfig)("keq");
407
- function main$3(compiler, options) {
408
- return { task: async (context, task) => {
409
- const result = options?.config ? await explore.load(options.config) : await explore.search();
410
- if (!result || "isEmpty" in result && result.isEmpty) throw new Error("Cannot find config file.");
411
- const rc = parseRuntimeConfig(result.config);
412
- if (options?.debug) {
413
- await fs_extra.default.ensureDir(".keq");
414
- rc.debug = true;
415
- }
416
- rc.tolerant = Boolean(rc.tolerant || options?.tolerant);
417
- if (!rc.translators || !rc.translators.length) rc.translators = [new require_micro_function_translator.MicroFunctionTranslator()];
418
- const packageJsonInfo = findNearestPackageJson();
419
- if (packageJsonInfo) {
420
- const moduleSystem = getProjectModuleSystem(packageJsonInfo);
421
- rc.rendering.esm = moduleSystem === "esm";
422
- }
423
- context.rc = rc;
424
- let matcher = new Matcher([]);
425
- if (options.filter !== false && result.filepath) {
426
- const filterFilepath = path.default.resolve(path.default.dirname(result.filepath), ".keqfilter");
427
- if (await fs_extra.default.exists(filterFilepath)) matcher = await Matcher.read(filterFilepath);
428
- }
429
- const filterRules = options.filter === false ? [] : options.filter?.rules || [];
430
- for (const rule of filterRules) matcher.append({
431
- persist: !!rule.persist,
432
- deny: rule.deny,
433
- moduleName: rule.moduleName,
434
- operationMethod: rule.operationMethod,
435
- operationPathname: rule.operationPathname
436
- });
437
- context.matcher = matcher;
438
- await compiler.hooks.setup.promise(task);
439
- } };
440
- }
441
- function createSetupTask(compiler, options) {
442
- return {
443
- title: "Setup",
444
- enabled: options?.enabled,
445
- skip: options?.skip,
446
- task: (context, task) => task.newListr([main$3(compiler, options), { task: (context, task) => compiler.hooks.afterSetup.promise(task) }], { concurrent: false })
447
- };
448
- }
449
- //#endregion
450
- //#region src/compiler/tasks/download/validate-spec.ts
451
- async function validateSpec(spec, options) {
452
- const { valid, errors } = await (0, _scalar_openapi_parser.validate)(spec);
453
- if (valid) return { valid: true };
454
- const errorLines = errors?.map((e) => {
455
- const path = e.path;
456
- if (path) {
457
- const readablePath = path.replace(/~1/g, "/").replace(/~0/g, "~");
458
- return ` - ${e.message}\n at: ${readablePath}`;
459
- }
460
- return ` - ${e.message}`;
461
- }).join("\n");
462
- let message = `${options.moduleDefinition.name} module openapi/swagger file does not conform to the openapi specifications or have grammatical errors, which may cause unexpected errors: \n${errorLines}`;
463
- if (errors?.some((e) => e.message?.includes("Error-ModelName"))) message += "\n\n [Hint] \"Error-ModelName\" in $ref indicates that SpringDoc failed to resolve a Java class. Check that the referenced class (e.g. cn.dotfashion.soa.api.vo.Response) is on the classpath and properly annotated with @Schema.";
464
- if (errors?.some((e) => e.message?.includes("Property extensions is not expected to be here"))) message += "\n\n [Hint] \"Property extensions is not expected to be here\" is typically caused by SpringDoc/Swagger wrapping x- extensions in an \"extensions\" object. Add SpringdocCompatPlugin to your config plugins to fix this automatically.";
465
- if (options.tolerant) return {
466
- valid: false,
467
- warning: message
468
- };
469
- throw new require_plugins.Exception(options.moduleDefinition, message);
470
- }
471
- //#endregion
472
- //#region src/compiler/tasks/download/index.ts
473
- function main$2(compiler, options) {
474
- return { task: (context, task) => {
475
- if (!context.rc || !context.matcher) throw new Error("Please run setup task first.");
476
- const rc = context.rc;
477
- const matcher = context.matcher;
478
- context.documents = [];
479
- return task.newListr(Object.entries(rc.modules).map(([moduleName, address]) => new require_plugins.ModuleDefinition(moduleName, address)).map((moduleDefinition) => ({
480
- title: moduleDefinition.name,
481
- task: async (ctx, task) => {
482
- if (options?.skipFilteredModules && matcher.isModuleDenied(moduleDefinition)) {
483
- task.skip(`(${moduleDefinition.name}) is filtered`);
484
- return;
485
- }
486
- task.output = `Downloaded from ${moduleDefinition.address.url}`;
487
- const content = await compiler.hooks.download.promise(moduleDefinition.address, moduleDefinition, task);
488
- if (!content) throw new require_plugins.Exception(moduleDefinition, `Cannot download document from ${moduleDefinition.address.url}`);
489
- const spec = JSON.parse(content);
490
- await compiler.hooks.beforeValidate.promise(spec, moduleDefinition);
491
- const result = await validateSpec(spec, {
492
- moduleDefinition,
493
- tolerant: !!compiler.options.tolerant
494
- });
495
- if (result.warning) task.output = result.warning;
496
- require_plugins.OpenapiUtils.dereferenceOperation(spec);
497
- const document = new require_plugins.ApiDocumentV3_1(spec, moduleDefinition);
498
- ctx.documents?.push(document);
499
- }
500
- })), {
501
- concurrent: true,
502
- exitOnError: !compiler.options.tolerant,
503
- collectErrors: compiler.options.tolerant ? "minimal" : false,
504
- rendererOptions: {
505
- collapseSubtasks: false,
506
- suffixSkips: true,
507
- timer: listr2.PRESET_TIMER
508
- }
509
- });
510
- } };
511
- }
512
- function createDownloadTask(compiler, options) {
513
- return {
514
- title: "Download",
515
- enabled: options?.enabled,
516
- skip: options?.skip,
517
- task: (_, task) => task.newListr([main$2(compiler, options), { task: (context, task) => compiler.hooks.afterDownload.promise(task) }], { concurrent: false })
518
- };
519
- }
520
- //#endregion
521
- //#region src/compiler/tasks/persist/index.ts
522
- function createPersistArtifactTask() {
523
- return {
524
- title: "Write files",
525
- task: async (context, task) => {
526
- if (!context.rc) throw new Error("Please run setup task first.");
527
- if (!context.artifacts || context.artifacts.length === 0) {
528
- task.skip("No compiled artifacts to persist.");
529
- return;
530
- }
531
- const rc = context.rc;
532
- const artifacts = context.artifacts;
533
- const total = artifacts.length;
534
- let completed = 0;
535
- context.assets = await Promise.all(artifacts.map(async (artifact) => {
536
- const realpath = `./${path.join(rc.outdir, artifact.filepath)}`;
537
- await fs_extra.default.ensureFile(realpath);
538
- await fs_extra.default.writeFile(realpath, artifact.renderer());
539
- completed += 1;
540
- task.output = `Persisted ${completed}/${total} files`;
541
- return new require_plugins.Asset(path.resolve(realpath));
542
- }));
543
- }
544
- };
545
- }
546
- function createPersistFilterTask() {
547
- return {
548
- title: "Update .keqfilter",
549
- task: async (context, task) => {
550
- if (!context.matcher) throw new Error("Please run setup task first.");
551
- await context.matcher.write(".keqfilter");
552
- }
553
- };
554
- }
555
- function main$1() {
556
- return { task: (context, task) => task.newListr([createPersistArtifactTask(), createPersistFilterTask()], {
557
- concurrent: true,
558
- rendererOptions: { collapseSubtasks: true }
559
- }) };
560
- }
561
- function createPersistTask(compiler, options) {
562
- return {
563
- title: "Persist",
564
- enabled: options?.enabled,
565
- skip: options?.skip,
566
- task: (context, task) => task.newListr([
567
- { task: (context, task) => compiler.hooks.beforePersist.promise(task) },
568
- main$1(),
569
- { task: (context, task) => compiler.hooks.afterPersist.promise(task) }
570
- ], { concurrent: false })
571
- };
572
- }
573
- //#endregion
574
- //#region src/compiler/tasks/compile/index.ts
575
- function main(compiler) {
576
- return { task: async (context, task) => {
577
- if (!context.rc) throw new Error("Please run setup task first.");
578
- if (!context.documents) throw new Error("Please run shaking task first.");
579
- context.artifacts = [];
580
- await compiler.hooks.compile.promise(task);
581
- } };
582
- }
583
- function createCompileTask(compiler, options) {
584
- return {
585
- title: "Compile",
586
- enabled: options?.enabled,
587
- skip: options?.skip,
588
- task: (context, task) => task.newListr([
589
- { task: (context, task) => compiler.hooks.beforeCompile.promise(task) },
590
- main(compiler),
591
- { task: (context, task) => compiler.hooks.afterCompile.promise(task) }
592
- ], { concurrent: false })
593
- };
594
- }
595
- //#endregion
596
- //#region src/compiler/intercepter/print-information.ts
597
- function proxyTaskWrapper(pluginName, task) {
598
- return new Proxy(task, { set(target, prop, value) {
599
- if (prop !== "output") return Reflect.set(target, prop, value);
600
- target.output = `[Plugin: ${pluginName}] ${value}`;
601
- return true;
602
- } });
603
- }
604
- function printInformation(taskIndex) {
605
- return { register: (tap) => {
606
- const fn = tap.fn;
607
- if (tap.type === "promise") tap.fn = (...args) => {
608
- const task = args[taskIndex];
609
- const proxyTask = proxyTaskWrapper(tap.name, task);
610
- args[taskIndex] = proxyTask;
611
- proxyTask.output = "Processing...";
612
- return fn(...args);
613
- };
614
- if (tap.type === "sync") tap.fn = (...args) => {
615
- const task = args[taskIndex];
616
- const proxyTask = proxyTaskWrapper(tap.name, task);
617
- args[taskIndex] = proxyTask;
618
- proxyTask.output = "Processing...";
619
- return fn(...args);
620
- };
621
- if (tap.type === "async") tap.fn = (...args) => {
622
- const task = args[taskIndex];
623
- const proxyTask = proxyTaskWrapper(tap.name, task);
624
- args[taskIndex] = proxyTask;
625
- proxyTask.output = "Processing...";
626
- return fn(...args);
627
- };
628
- return tap;
629
- } };
630
- }
631
- //#endregion
632
- //#region src/compiler/intercepter/perfect-error-message.ts
633
- function perfectErrorMessage() {
634
- return { register: (tap) => {
635
- const fn = tap.fn;
636
- function prefix(err) {
637
- if (err instanceof Error) err.message = `[Plugin: ${tap.name}] ${err.message}`;
638
- }
639
- if (tap.type === "promise") tap.fn = async (...args) => {
640
- try {
641
- return await fn(...args);
642
- } catch (err) {
643
- prefix(err);
644
- throw err;
645
- }
646
- };
647
- if (tap.type === "sync") tap.fn = (...args) => {
648
- try {
649
- return fn(...args);
650
- } catch (err) {
651
- prefix(err);
652
- throw err;
653
- }
654
- };
655
- if (tap.type === "async") tap.fn = (...args) => {
656
- const callback = ramda.last(args);
657
- return fn(...ramda.init(args), (err, result) => {
658
- prefix(err);
659
- return callback(err, result);
660
- });
661
- };
662
- return tap;
663
- } };
664
- }
665
- //#endregion
666
- //#region src/compiler/compiler.ts
667
- var Compiler = class {
668
- context = {};
669
- hooks = {
670
- setup: new tapable.AsyncParallelHook(["task"]),
671
- afterSetup: new tapable.AsyncSeriesHook(["task"]),
672
- beforeDownload: new tapable.AsyncSeriesHook(["task"]),
673
- download: new tapable.AsyncSeriesBailHook([
674
- "address",
675
- "moduleDefinition",
676
- "task"
677
- ]),
678
- beforeValidate: new tapable.AsyncSeriesHook(["spec", "moduleDefinition"]),
679
- afterDownload: new tapable.AsyncSeriesHook(["task"]),
680
- beforeCompile: new tapable.AsyncSeriesHook(["task"]),
681
- compile: new tapable.AsyncParallelHook(["task"]),
682
- afterCompile: new tapable.AsyncSeriesHook(["task"]),
683
- beforePersist: new tapable.AsyncSeriesHook(["task"]),
684
- persist: new tapable.AsyncParallelHook(["task"]),
685
- afterPersist: new tapable.AsyncSeriesHook(["task"]),
686
- done: new tapable.SyncHook()
687
- };
688
- constructor(options) {
689
- this.options = options;
690
- for (const hook of Object.values(this.hooks)) hook.intercept(perfectErrorMessage());
691
- this.hooks.afterSetup.intercept(printInformation(0));
692
- this.hooks.afterPersist.intercept(printInformation(0));
693
- new require_plugins.InitializePlugin({
694
- build: options.build,
695
- fresh: options.fresh,
696
- interactive: options.interactive
697
- }).apply(this);
698
- }
699
- async run() {
700
- const options = this.options;
701
- await new listr2.Listr([
702
- createSetupTask(this, options),
703
- createDownloadTask(this, { skipFilteredModules: !options.interactive }),
704
- createCompileTask(this, { enabled: !!options.build }),
705
- createPersistTask(this, { enabled: !!options.persist })
706
- ], {
707
- concurrent: false,
708
- renderer: options.silent ? "silent" : "default",
709
- rendererOptions: {
710
- suffixSkips: true,
711
- collapseSubtasks: false,
712
- collapseErrors: false
713
- }
714
- }).run(this.context);
715
- await this.hooks.done.promise();
716
- }
717
- };
718
- //#endregion
719
- Object.defineProperty(exports, "Compiler", {
720
- enumerable: true,
721
- get: function() {
722
- return Compiler;
723
- }
724
- });
725
- Object.defineProperty(exports, "FileNamingStyle", {
726
- enumerable: true,
727
- get: function() {
728
- return FileNamingStyle;
729
- }
730
- });
731
- Object.defineProperty(exports, "Matcher", {
732
- enumerable: true,
733
- get: function() {
734
- return Matcher;
735
- }
736
- });
737
-
738
- //# sourceMappingURL=compiler-0Kli6UCr.cjs.map