wormajs 0.0.1

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 (236) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -0
  3. package/dist/bin/actions.js +245 -0
  4. package/dist/bin/cli.js +27 -0
  5. package/dist/bin/progressRenderer.js +47 -0
  6. package/dist/bin/renderer.js +551 -0
  7. package/dist/bin/theme.js +26 -0
  8. package/dist/config.js +19 -0
  9. package/dist/constant.js +162 -0
  10. package/dist/core/WorkerPool.js +102 -0
  11. package/dist/core/loader/astLoader/generates/array.js +34 -0
  12. package/dist/core/loader/astLoader/generates/enum.js +61 -0
  13. package/dist/core/loader/astLoader/generates/group.js +41 -0
  14. package/dist/core/loader/astLoader/generates/index.js +71 -0
  15. package/dist/core/loader/astLoader/generates/interface.js +59 -0
  16. package/dist/core/loader/astLoader/generates/simple.js +67 -0
  17. package/dist/core/loader/astLoader/generates/tuple.js +54 -0
  18. package/dist/core/loader/astLoader/generates/type.js +2 -0
  19. package/dist/core/loader/astLoader/generates/utils.js +86 -0
  20. package/dist/core/loader/astLoader/helper.js +21 -0
  21. package/dist/core/loader/astLoader/index.js +24 -0
  22. package/dist/core/loader/astLoader/normalize/index.js +70 -0
  23. package/dist/core/loader/astLoader/normalize/normalizer.js +69 -0
  24. package/dist/core/loader/astLoader/normalize/rules/convertTypeArray.js +68 -0
  25. package/dist/core/loader/astLoader/normalize/rules/handleEmptyType.js +8 -0
  26. package/dist/core/loader/astLoader/normalize/rules/inferType.js +43 -0
  27. package/dist/core/loader/astLoader/normalize/rules/mergeAnyOf.js +45 -0
  28. package/dist/core/loader/astLoader/normalize/rules/normalizeCombiningKeywords.js +26 -0
  29. package/dist/core/loader/astLoader/normalize/rules/normalizeEnum.js +38 -0
  30. package/dist/core/loader/astLoader/normalize/rules/normalizeNullType.js +24 -0
  31. package/dist/core/loader/astLoader/normalize/rules/removeRedundantKeywords.js +27 -0
  32. package/dist/core/loader/astLoader/normalize/rules/simplifySingleType.js +8 -0
  33. package/dist/core/loader/astLoader/normalize/rules/validateSchema.js +14 -0
  34. package/dist/core/loader/astLoader/parsers/array.js +28 -0
  35. package/dist/core/loader/astLoader/parsers/enum.js +49 -0
  36. package/dist/core/loader/astLoader/parsers/forward/array.js +12 -0
  37. package/dist/core/loader/astLoader/parsers/forward/enum.js +10 -0
  38. package/dist/core/loader/astLoader/parsers/forward/group.js +12 -0
  39. package/dist/core/loader/astLoader/parsers/forward/index.js +20 -0
  40. package/dist/core/loader/astLoader/parsers/forward/object.js +12 -0
  41. package/dist/core/loader/astLoader/parsers/forward/tuple.js +11 -0
  42. package/dist/core/loader/astLoader/parsers/forward/type.js +2 -0
  43. package/dist/core/loader/astLoader/parsers/group.js +50 -0
  44. package/dist/core/loader/astLoader/parsers/index.js +66 -0
  45. package/dist/core/loader/astLoader/parsers/object.js +44 -0
  46. package/dist/core/loader/astLoader/parsers/reference.js +41 -0
  47. package/dist/core/loader/astLoader/parsers/simple.js +48 -0
  48. package/dist/core/loader/astLoader/parsers/tuple.js +36 -0
  49. package/dist/core/loader/astLoader/parsers/type.js +2 -0
  50. package/dist/core/loader/astLoader/parsers/utils.js +58 -0
  51. package/dist/core/loader/callingCodeLoader/helper.js +183 -0
  52. package/dist/core/loader/callingCodeLoader/index.js +40 -0
  53. package/dist/core/loader/index.js +20 -0
  54. package/dist/core/loader/schemaLoader/index.js +101 -0
  55. package/dist/core/loader/standardLoader/helper.js +142 -0
  56. package/dist/core/loader/standardLoader/index.js +38 -0
  57. package/dist/core/loader/standardLoader/standards.js +105 -0
  58. package/dist/core/parser/index.js +18 -0
  59. package/dist/core/parser/openApiParser/helper.js +165 -0
  60. package/dist/core/parser/openApiParser/index.js +14 -0
  61. package/dist/core/parser/templateParser/helper.js +333 -0
  62. package/dist/core/parser/templateParser/index.js +314 -0
  63. package/dist/core/workerPool/index.js +6 -0
  64. package/dist/core/workerPool/poolManager.js +45 -0
  65. package/dist/core/workerPool/swagger2Worker.js +24 -0
  66. package/dist/core/workerPool/worker.js +61 -0
  67. package/dist/createConfig.js +37 -0
  68. package/dist/defineConfig.js +6 -0
  69. package/dist/functions/getAutoTemplateType.js +37 -0
  70. package/dist/functions/getFrameworkTag.js +18 -0
  71. package/dist/functions/prepareConfig.js +41 -0
  72. package/dist/functions/readWormaRc.js +155 -0
  73. package/dist/functions/wormaJson.js +232 -0
  74. package/dist/generate.js +84 -0
  75. package/dist/helper/PluginDriver.js +98 -0
  76. package/dist/helper/comment.js +88 -0
  77. package/dist/helper/config/ConfigHelper.js +79 -0
  78. package/dist/helper/config/ConfigManager.js +88 -0
  79. package/dist/helper/config/GeneratorHelper.js +343 -0
  80. package/dist/helper/config/index.js +19 -0
  81. package/dist/helper/config/type.js +2 -0
  82. package/dist/helper/config/zType.js +170 -0
  83. package/dist/helper/document/index.js +160 -0
  84. package/dist/helper/index.js +23 -0
  85. package/dist/helper/logger/index.js +76 -0
  86. package/dist/helper/progress.js +66 -0
  87. package/dist/helper/template/index.js +475 -0
  88. package/dist/index.js +33 -0
  89. package/dist/plugins/createPlugin.js +30 -0
  90. package/dist/plugins/index.js +34 -0
  91. package/dist/plugins/presets/aiDoc.js +173 -0
  92. package/dist/plugins/presets/apifox.js +56 -0
  93. package/dist/plugins/presets/filterApi.js +129 -0
  94. package/dist/plugins/presets/importType.js +49 -0
  95. package/dist/plugins/presets/payloadModifier/hepler.js +195 -0
  96. package/dist/plugins/presets/payloadModifier/index.js +122 -0
  97. package/dist/plugins/presets/payloadModifier/type.js +2 -0
  98. package/dist/plugins/presets/platform.js +73 -0
  99. package/dist/plugins/presets/rename.js +209 -0
  100. package/dist/plugins/presets/tagModifier.js +104 -0
  101. package/dist/plugins/presets/utils.js +36 -0
  102. package/dist/readConfig.js +92 -0
  103. package/dist/resolveWorkspaces.js +83 -0
  104. package/dist/template/index.js +180 -0
  105. package/dist/template/presets/ai-doc/SKILL.md.handlebars +29 -0
  106. package/dist/template/presets/ai-doc/references/{tag}/{api}.md.handlebars +54 -0
  107. package/dist/template/presets/alova/common/#index.cjs.handlebars +12 -0
  108. package/dist/template/presets/alova/common/components.d.cts.handlebars +1 -0
  109. package/dist/template/presets/alova/common/helper.cjs.handlebars +13 -0
  110. package/dist/template/presets/alova/common/services/#index.cjs.handlebars +13 -0
  111. package/dist/template/presets/alova/common/services/{tag}.cjs.handlebars +28 -0
  112. package/dist/template/presets/alova/common/services/{tag}.d.cts.handlebars +15 -0
  113. package/dist/template/presets/alova/common/typed.d.cts.handlebars +1 -0
  114. package/dist/template/presets/alova/module/#index.js.handlebars +12 -0
  115. package/dist/template/presets/alova/module/components.d.ts.handlebars +1 -0
  116. package/dist/template/presets/alova/module/helper.js.handlebars +11 -0
  117. package/dist/template/presets/alova/module/services/#index.js.handlebars +9 -0
  118. package/dist/template/presets/alova/module/services/{tag}.d.ts.handlebars +15 -0
  119. package/dist/template/presets/alova/module/services/{tag}.js.handlebars +21 -0
  120. package/dist/template/presets/alova/module/typed.d.ts.handlebars +1 -0
  121. package/dist/template/presets/alova/partials/api-jsdoc.handlebars +44 -0
  122. package/dist/template/presets/alova/partials/build-payload-body.handlebars +22 -0
  123. package/dist/template/presets/alova/partials/comment.handlebars +19 -0
  124. package/dist/template/presets/alova/partials/components-body.handlebars +4 -0
  125. package/dist/template/presets/alova/partials/dts-extra-config.handlebars +8 -0
  126. package/dist/template/presets/alova/partials/dts-fn-declare.handlebars +1 -0
  127. package/dist/template/presets/alova/partials/extract-responded.handlebars +11 -0
  128. package/dist/template/presets/alova/partials/stateshook-import.handlebars +9 -0
  129. package/dist/template/presets/alova/partials/stateshook-option.handlebars +9 -0
  130. package/dist/template/presets/alova/partials/typed-body.handlebars +43 -0
  131. package/dist/template/presets/alova/typescript/#index.ts.handlebars +14 -0
  132. package/dist/template/presets/alova/typescript/components.d.ts.handlebars +1 -0
  133. package/dist/template/presets/alova/typescript/helper.ts.handlebars +9 -0
  134. package/dist/template/presets/alova/typescript/services/#index.ts.handlebars +9 -0
  135. package/dist/template/presets/alova/typescript/services/{tag}.ts.handlebars +35 -0
  136. package/dist/template/presets/alova/typescript/typed.ts.handlebars +1 -0
  137. package/dist/template/presets/alova-globals/common/#index.cjs.handlebars +41 -0
  138. package/dist/template/presets/alova-globals/common/apiDefinitions.cjs.handlebars +12 -0
  139. package/dist/template/presets/alova-globals/common/createApis.cjs.handlebars +48 -0
  140. package/dist/template/presets/alova-globals/common/globals.d.cts.handlebars +2 -0
  141. package/dist/template/presets/alova-globals/module/#index.js.handlebars +2 -0
  142. package/dist/template/presets/alova-globals/module/apiDefinitions.js.handlebars +12 -0
  143. package/dist/template/presets/alova-globals/module/createApis.js.handlebars +44 -0
  144. package/dist/template/presets/alova-globals/module/globals.d.ts.handlebars +2 -0
  145. package/dist/template/presets/alova-globals/partials/comment.handlebars +19 -0
  146. package/dist/template/presets/alova-globals/partials/createApis-proxy-js.handlebars +55 -0
  147. package/dist/template/presets/alova-globals/partials/globals-d-ts.handlebars +148 -0
  148. package/dist/template/presets/alova-globals/partials/index-esm.handlebars +38 -0
  149. package/dist/template/presets/alova-globals/partials/withConfigType-jsdoc.handlebars +22 -0
  150. package/dist/template/presets/alova-globals/typescript/#index.ts.handlebars +2 -0
  151. package/dist/template/presets/alova-globals/typescript/apiDefinitions.ts.handlebars +12 -0
  152. package/dist/template/presets/alova-globals/typescript/createApis.ts.handlebars +99 -0
  153. package/dist/template/presets/alova-globals/typescript/globals.d.ts.handlebars +2 -0
  154. package/dist/template/presets/axios/common/#index.cjs.handlebars +22 -0
  155. package/dist/template/presets/axios/common/components.d.cts.handlebars +1 -0
  156. package/dist/template/presets/axios/common/helper.cjs.handlebars +27 -0
  157. package/dist/template/presets/axios/common/services/#index.cjs.handlebars +13 -0
  158. package/dist/template/presets/axios/common/services/{tag}.cjs.handlebars +28 -0
  159. package/dist/template/presets/axios/common/services/{tag}.d.cts.handlebars +11 -0
  160. package/dist/template/presets/axios/module/#index.js.handlebars +20 -0
  161. package/dist/template/presets/axios/module/components.d.ts.handlebars +1 -0
  162. package/dist/template/presets/axios/module/helper.js.handlebars +25 -0
  163. package/dist/template/presets/axios/module/services/#index.js.handlebars +9 -0
  164. package/dist/template/presets/axios/module/services/{tag}.d.ts.handlebars +11 -0
  165. package/dist/template/presets/axios/module/services/{tag}.js.handlebars +20 -0
  166. package/dist/template/presets/axios/partials/api-jsdoc.handlebars +44 -0
  167. package/dist/template/presets/axios/partials/comment.handlebars +19 -0
  168. package/dist/template/presets/axios/partials/components-body.handlebars +4 -0
  169. package/dist/template/presets/axios/partials/dts-fn-declare.handlebars +1 -0
  170. package/dist/template/presets/axios/partials/dts-types.handlebars +7 -0
  171. package/dist/template/presets/axios/typescript/#index.ts.handlebars +20 -0
  172. package/dist/template/presets/axios/typescript/components.d.ts.handlebars +1 -0
  173. package/dist/template/presets/axios/typescript/helper.ts.handlebars +28 -0
  174. package/dist/template/presets/axios/typescript/services/#index.ts.handlebars +9 -0
  175. package/dist/template/presets/axios/typescript/services/{tag}.ts.handlebars +31 -0
  176. package/dist/template/presets/config/common/worma.config.js.handlebars +9 -0
  177. package/dist/template/presets/config/module/worma.config.js.handlebars +9 -0
  178. package/dist/template/presets/config/partials/generator-content.handlebars +45 -0
  179. package/dist/template/presets/config/typescript/worma.config.ts.handlebars +9 -0
  180. package/dist/template/presets/fetch/common/#index.cjs.handlebars +17 -0
  181. package/dist/template/presets/fetch/common/FetchClient.cjs.handlebars +48 -0
  182. package/dist/template/presets/fetch/common/components.d.cts.handlebars +1 -0
  183. package/dist/template/presets/fetch/common/helper.cjs.handlebars +27 -0
  184. package/dist/template/presets/fetch/common/services/#index.cjs.handlebars +13 -0
  185. package/dist/template/presets/fetch/common/services/{tag}.cjs.handlebars +23 -0
  186. package/dist/template/presets/fetch/common/services/{tag}.d.cts.handlebars +10 -0
  187. package/dist/template/presets/fetch/module/#index.js.handlebars +15 -0
  188. package/dist/template/presets/fetch/module/FetchClient.js.handlebars +46 -0
  189. package/dist/template/presets/fetch/module/components.d.ts.handlebars +1 -0
  190. package/dist/template/presets/fetch/module/helper.js.handlebars +25 -0
  191. package/dist/template/presets/fetch/module/services/#index.js.handlebars +9 -0
  192. package/dist/template/presets/fetch/module/services/{tag}.d.ts.handlebars +10 -0
  193. package/dist/template/presets/fetch/module/services/{tag}.js.handlebars +15 -0
  194. package/dist/template/presets/fetch/partials/api-jsdoc.handlebars +44 -0
  195. package/dist/template/presets/fetch/partials/comment.handlebars +19 -0
  196. package/dist/template/presets/fetch/partials/components-body.handlebars +4 -0
  197. package/dist/template/presets/fetch/partials/dts-fn-declare.handlebars +1 -0
  198. package/dist/template/presets/fetch/partials/dts-types.handlebars +7 -0
  199. package/dist/template/presets/fetch/typescript/#index.ts.handlebars +15 -0
  200. package/dist/template/presets/fetch/typescript/FetchClient.ts.handlebars +59 -0
  201. package/dist/template/presets/fetch/typescript/components.d.ts.handlebars +1 -0
  202. package/dist/template/presets/fetch/typescript/helper.ts.handlebars +28 -0
  203. package/dist/template/presets/fetch/typescript/services/#index.ts.handlebars +9 -0
  204. package/dist/template/presets/fetch/typescript/services/{tag}.ts.handlebars +25 -0
  205. package/dist/template/presets/ky/module/#index.js.handlebars +14 -0
  206. package/dist/template/presets/ky/module/components.d.ts.handlebars +1 -0
  207. package/dist/template/presets/ky/module/helper.js.handlebars +27 -0
  208. package/dist/template/presets/ky/module/services/#index.js.handlebars +9 -0
  209. package/dist/template/presets/ky/module/services/{tag}.d.ts.handlebars +11 -0
  210. package/dist/template/presets/ky/module/services/{tag}.js.handlebars +19 -0
  211. package/dist/template/presets/ky/partials/api-jsdoc.handlebars +44 -0
  212. package/dist/template/presets/ky/partials/comment.handlebars +19 -0
  213. package/dist/template/presets/ky/partials/components-body.handlebars +4 -0
  214. package/dist/template/presets/ky/partials/dts-fn-declare.handlebars +1 -0
  215. package/dist/template/presets/ky/partials/dts-types.handlebars +9 -0
  216. package/dist/template/presets/ky/typescript/#index.ts.handlebars +14 -0
  217. package/dist/template/presets/ky/typescript/components.d.ts.handlebars +1 -0
  218. package/dist/template/presets/ky/typescript/helper.ts.handlebars +30 -0
  219. package/dist/template/presets/ky/typescript/services/#index.ts.handlebars +9 -0
  220. package/dist/template/presets/ky/typescript/services/{tag}.ts.handlebars +30 -0
  221. package/dist/tsconfig.build.tsbuildinfo +1 -0
  222. package/dist/type/api.js +14 -0
  223. package/dist/type/ast.js +24 -0
  224. package/dist/type/base.js +17 -0
  225. package/dist/type/index.js +20 -0
  226. package/dist/type/lib.js +17 -0
  227. package/dist/type/openapi.js +2 -0
  228. package/dist/utils/base.js +212 -0
  229. package/dist/utils/format.js +64 -0
  230. package/dist/utils/index.js +21 -0
  231. package/dist/utils/openapi.js +417 -0
  232. package/dist/utils/readPackageJson.js +35 -0
  233. package/dist/utils/template.js +93 -0
  234. package/package.json +88 -0
  235. package/typings/index.d.ts +512 -0
  236. package/typings/plugins.d.ts +727 -0
@@ -0,0 +1,475 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.templateHelper = exports.TemplateHelper = exports.MODULE_TYPES = void 0;
7
+ const promises_1 = __importDefault(require("node:fs/promises"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const handlebars_1 = __importDefault(require("handlebars"));
10
+ const constant_1 = require("../../constant");
11
+ const wormaJson_1 = require("../../functions/wormaJson");
12
+ const logger_1 = require("../../helper/logger");
13
+ const utils_1 = require("../../utils");
14
+ /** M1-A2: Handlebars 实例缓存 —— 同 templatePath 复用编译好的 partials 和 helpers */
15
+ const hbsInstanceCache = new Map();
16
+ const templateCompileCache = new Map();
17
+ function cacheKey(projectPath, output) {
18
+ return `${projectPath}::${output}`;
19
+ }
20
+ /** 模块类型目录名(与 config.type 不同:commonjs -> common) */
21
+ exports.MODULE_TYPES = [constant_1.ModuleTypeDir.TYPESCRIPT, constant_1.ModuleTypeDir.MODULE, constant_1.ModuleTypeDir.COMMON];
22
+ // ---- helpers ----
23
+ const TEMPLATE_EXTENSIONS = [
24
+ constant_1.FileExtension.HBS,
25
+ constant_1.FileExtension.HANDLEBARS,
26
+ constant_1.FileExtension.TS,
27
+ constant_1.FileExtension.TSX,
28
+ constant_1.FileExtension.JS,
29
+ constant_1.FileExtension.JSX,
30
+ constant_1.FileExtension.MJS,
31
+ constant_1.FileExtension.CJS,
32
+ constant_1.FileExtension.D_TS,
33
+ constant_1.FileExtension.D_CTS,
34
+ constant_1.FileExtension.D_MTS,
35
+ ];
36
+ function isTemplateFile(name) {
37
+ return TEMPLATE_EXTENSIONS.some(ext => name.endsWith(ext));
38
+ }
39
+ function parseEntryName(raw) {
40
+ const noOverwrite = raw.startsWith('#');
41
+ return { isNoOverwrite: noOverwrite, name: noOverwrite ? raw.slice(1) : raw };
42
+ }
43
+ function detectTemplateType(fileName, allowTag = true) {
44
+ if (allowTag && fileName.includes(constant_1.TemplatePlaceholder.TAG))
45
+ return 'tag';
46
+ if (fileName.includes(constant_1.TemplatePlaceholder.API))
47
+ return 'api';
48
+ return undefined;
49
+ }
50
+ function normalizeSlashes(p) {
51
+ return p.replace(/\\/g, '/');
52
+ }
53
+ function stripExt(fileName) {
54
+ if (fileName.endsWith(constant_1.FileExtension.HANDLEBARS))
55
+ return fileName.slice(0, -constant_1.FileExtension.HANDLEBARS.length);
56
+ if (fileName.endsWith(constant_1.FileExtension.HBS))
57
+ return fileName.slice(0, -constant_1.FileExtension.HBS.length);
58
+ return fileName;
59
+ }
60
+ function joinPath(...parts) {
61
+ const p = node_path_1.default.join(...parts);
62
+ return p ? normalizeSlashes(p) : p;
63
+ }
64
+ class TemplateHelper {
65
+ // ============ hasTagTemplates / instance ============
66
+ static async hasTagTemplates(templatePath, type) {
67
+ try {
68
+ const helper = TemplateHelper.load({ type, templatePath });
69
+ const files = await helper.resolveTemplateFiles(templatePath);
70
+ return files.some(f => f.templateType != null);
71
+ }
72
+ catch {
73
+ return false;
74
+ }
75
+ }
76
+ static getInstance() {
77
+ if (!TemplateHelper.instance)
78
+ TemplateHelper.instance = new TemplateHelper();
79
+ return TemplateHelper.instance;
80
+ }
81
+ constructor(config) {
82
+ if (config)
83
+ this.config = config;
84
+ }
85
+ load(config) {
86
+ this.config = config;
87
+ return this;
88
+ }
89
+ static load(config) { return new TemplateHelper(config); }
90
+ getExt() { return TemplateHelper.getExt(this.config.type); }
91
+ getModuleType() { return TemplateHelper.getModuleType(this.config.type); }
92
+ static getExt(type) { return type === constant_1.TemplateTypeEnum.TYPESCRIPT ? constant_1.FileExtension.TS : constant_1.FileExtension.JS; }
93
+ static getModuleType(type) {
94
+ return constant_1.MODULE_TYPE_TO_KIND[type] ?? constant_1.ModuleKind.ES_MODULE;
95
+ }
96
+ // ============ 缓存 ============
97
+ static async readData(projectPath, output) {
98
+ const key = cacheKey(projectPath, output);
99
+ const cached = TemplateHelper._cacheData.get(key);
100
+ if (cached)
101
+ return cached;
102
+ try {
103
+ const data = await (0, wormaJson_1.readCacheApis)(projectPath, output);
104
+ if (!data) {
105
+ TemplateHelper._cacheData.delete(key);
106
+ return null;
107
+ }
108
+ TemplateHelper._cacheData.set(key, data);
109
+ return data;
110
+ }
111
+ catch {
112
+ TemplateHelper._cacheData.delete(key);
113
+ return null;
114
+ }
115
+ }
116
+ static getData(projectPath, output) {
117
+ return TemplateHelper._cacheData.get(cacheKey(projectPath, output));
118
+ }
119
+ static async setData(templateData, projectPath, output, config) {
120
+ TemplateHelper._cacheData.set(cacheKey(projectPath, output), {
121
+ path: output,
122
+ serverName: config?.serverName || templateData.title || '',
123
+ apis: templateData.allApis || [],
124
+ });
125
+ }
126
+ /** Flush all in-memory cache entries to disk using directory-based format. Only flushes entries belonging to the given projectPath. */
127
+ static async flushAllData(projectPath) {
128
+ const prefix = `${projectPath}::`;
129
+ for (const [key, cd] of TemplateHelper._cacheData) {
130
+ if (!key.startsWith(prefix))
131
+ continue;
132
+ const apis = cd.apis || [];
133
+ const hashInfo = (0, wormaJson_1.computePerTagHashes)(apis);
134
+ await (0, wormaJson_1.writeCacheEntry)(projectPath, cd.path, cd.serverName || '', apis, hashInfo);
135
+ }
136
+ }
137
+ // ============ unlink ============
138
+ unlink(_files, { output }) {
139
+ const ext = this.getExt();
140
+ const list = _files.filter(Boolean).map(item => typeof item === 'string' ? { fileName: item, output, ext } : Object.assign({ output, ext }, item));
141
+ return Promise.all(list.map(async ({ output, fileName, ext }) => {
142
+ const p = node_path_1.default.join(output, `${fileName}${ext}`);
143
+ if (await (0, utils_1.existsPromise)(p))
144
+ await promises_1.default.unlink(p);
145
+ }));
146
+ }
147
+ // ============ 模板解析 ============
148
+ async resolveTemplateFiles(templatePath) {
149
+ const absolute = node_path_1.default.isAbsolute(templatePath) ? templatePath : node_path_1.default.resolve(process.cwd(), templatePath);
150
+ if (!(await (0, utils_1.existsPromise)(absolute)))
151
+ throw logger_1.logger.throwError(`Template path not found: ${absolute}`);
152
+ if (await this.checkModuleTypeDirs(absolute)) {
153
+ const mt = this.resolveModuleType();
154
+ const md = node_path_1.default.join(absolute, mt);
155
+ if (await (0, utils_1.existsPromise)(md)) {
156
+ logger_1.logger.debug('Resolving template files via module-type dir', { moduleType: mt, templatePath: absolute });
157
+ return this.scanDir(md, '');
158
+ }
159
+ const supported = [];
160
+ for (const m of exports.MODULE_TYPES) {
161
+ if (await (0, utils_1.existsPromise)(node_path_1.default.join(absolute, m)))
162
+ supported.push(m);
163
+ }
164
+ throw logger_1.logger.throwError(`Template "${node_path_1.default.basename(absolute)}" does not support module type "${this.config.type}". Supported types: ${supported.join(', ')}`);
165
+ }
166
+ return this.scanAllTemplateDirs(absolute);
167
+ }
168
+ async checkModuleTypeDirs(tpl) {
169
+ for (const m of exports.MODULE_TYPES) {
170
+ const d = node_path_1.default.join(tpl, m);
171
+ if (await (0, utils_1.existsPromise)(d) && (await promises_1.default.stat(d)).isDirectory())
172
+ return true;
173
+ }
174
+ return false;
175
+ }
176
+ resolveModuleType() {
177
+ const m = {
178
+ [constant_1.TemplateTypeEnum.TYPESCRIPT]: constant_1.ModuleTypeDir.TYPESCRIPT,
179
+ [constant_1.TemplateTypeEnum.MODULE]: constant_1.ModuleTypeDir.MODULE,
180
+ commonjs: constant_1.ModuleTypeDir.COMMON,
181
+ };
182
+ return m[this.config.type] ?? constant_1.ModuleTypeDir.TYPESCRIPT;
183
+ }
184
+ // ---- scan ----
185
+ async scanDir(dir, base, insideTagDir = false) {
186
+ const out = [];
187
+ for (const e of await promises_1.default.readdir(dir, { withFileTypes: true })) {
188
+ const fp = node_path_1.default.join(dir, e.name);
189
+ if (e.isDirectory()) {
190
+ if (e.name === constant_1.TemplateSkipDir.PARTIALS)
191
+ continue;
192
+ if (e.name === constant_1.TemplateSkipDir.TAG_DIR) {
193
+ if (insideTagDir)
194
+ throw logger_1.logger.throwError(`Nested ${constant_1.TemplatePlaceholder.TAG} directory is not allowed: "${joinPath(base, constant_1.TemplatePlaceholder.TAG)}".`);
195
+ out.push(...await this.scanDir(fp, joinPath(base, constant_1.TemplatePlaceholder.TAG), true));
196
+ }
197
+ else {
198
+ out.push(...await this.scanDir(fp, joinPath(base, e.name), insideTagDir));
199
+ }
200
+ }
201
+ else if (e.isFile() && isTemplateFile(e.name)) {
202
+ out.push(this.makeFileInfo(e.name, fp, base, insideTagDir));
203
+ }
204
+ }
205
+ return out;
206
+ }
207
+ async scanAllTemplateDirs(tpl) {
208
+ const out = [];
209
+ for (const e of await promises_1.default.readdir(tpl, { withFileTypes: true })) {
210
+ const fp = node_path_1.default.join(tpl, e.name);
211
+ if (e.isDirectory()) {
212
+ if (e.name === constant_1.TemplateSkipDir.PARTIALS)
213
+ continue;
214
+ if (e.name === constant_1.TemplateSkipDir.TAG_DIR)
215
+ out.push(...await this.scanDir(fp, constant_1.TemplatePlaceholder.TAG, true));
216
+ else
217
+ out.push(...await this.scanDir(fp, e.name));
218
+ }
219
+ else if (e.isFile() && isTemplateFile(e.name)) {
220
+ out.push(this.makeFileInfo(e.name, fp, ''));
221
+ }
222
+ }
223
+ return out;
224
+ }
225
+ makeFileInfo(rawName, absolutePath, base, insideTagDir = false) {
226
+ const { isNoOverwrite, name: actual } = parseEntryName(rawName);
227
+ if (insideTagDir && actual.includes(constant_1.TemplatePlaceholder.TAG))
228
+ throw logger_1.logger.throwError(`Nested ${constant_1.TemplatePlaceholder.TAG} template not allowed: "${joinPath(base, actual)}".`);
229
+ return {
230
+ absolutePath,
231
+ relativePath: base ? joinPath(base, actual) : actual,
232
+ fileName: actual,
233
+ isNoOverwrite,
234
+ templateType: detectTemplateType(actual, !insideTagDir),
235
+ insideTagDir,
236
+ };
237
+ }
238
+ // ============ 渲染 & 输出 ============
239
+ async renderTemplate(templateFilePath, data) {
240
+ const p = node_path_1.default.isAbsolute(this.config.templatePath)
241
+ ? node_path_1.default.join(this.config.templatePath, `${templateFilePath}${constant_1.FileExtension.HANDLEBARS}`)
242
+ : node_path_1.default.resolve(process.cwd(), this.config.templatePath, `${templateFilePath}${constant_1.FileExtension.HANDLEBARS}`);
243
+ if (await (0, utils_1.existsPromise)(p)) {
244
+ const hbs = await this.createHbs();
245
+ return hbs.compile(await promises_1.default.readFile(p, 'utf-8'))(data);
246
+ }
247
+ throw logger_1.logger.throwError(`Template not found: ${templateFilePath}`);
248
+ }
249
+ async renderTemplateFromPath(hbs, absolutePath, data) {
250
+ let template = templateCompileCache.get(absolutePath);
251
+ if (!template) {
252
+ template = hbs.compile(await promises_1.default.readFile(absolutePath, 'utf-8'));
253
+ templateCompileCache.set(absolutePath, template);
254
+ }
255
+ return template(data);
256
+ }
257
+ /** M1-A2: 清除 Handlebars 编译和实例缓存(供测试与 watch 模式使用) */
258
+ static clearTemplateCache() {
259
+ hbsInstanceCache.clear();
260
+ templateCompileCache.clear();
261
+ }
262
+ async createHbs() {
263
+ const cacheKey = this.config.templatePath;
264
+ const cached = hbsInstanceCache.get(cacheKey);
265
+ if (cached) {
266
+ logger_1.logger.debug('Handlebars instance loaded from cache', { templatePath: cacheKey });
267
+ return cached;
268
+ }
269
+ logger_1.logger.debug('Creating new Handlebars instance', { templatePath: cacheKey });
270
+ const hbs = handlebars_1.default.create();
271
+ (0, utils_1.registerCommonHelpers)(hbs);
272
+ await (0, utils_1.registerPartials)(this.config.templatePath, hbs);
273
+ if (this.config.onHandlebarsCreated?.length) {
274
+ logger_1.logger.debug('Running onHandlebarsCreated callbacks', { count: this.config.onHandlebarsCreated.length });
275
+ for (const fn of this.config.onHandlebarsCreated) {
276
+ if (typeof fn === 'function')
277
+ await fn(hbs);
278
+ }
279
+ }
280
+ hbsInstanceCache.set(cacheKey, hbs);
281
+ return hbs;
282
+ }
283
+ /**
284
+ * 9.2.3: Private file writing — now internal to the streaming pipeline.
285
+ * Prettier formatting applied at file level (9.5.2).
286
+ */
287
+ async outputFiles(files, output, writeConcurrency = 32, formatFile = true) {
288
+ const entries = Object.entries(files);
289
+ if (!entries.length)
290
+ return;
291
+ // Collect unique directories and create them
292
+ const dirs = new Set();
293
+ for (const [rp] of entries) {
294
+ const op = node_path_1.default.isAbsolute(rp) ? rp : node_path_1.default.join(output, rp);
295
+ dirs.add(node_path_1.default.dirname(op));
296
+ }
297
+ await Promise.all([...dirs].map(async (d) => {
298
+ if (!(await (0, utils_1.existsPromise)(d)))
299
+ await promises_1.default.mkdir(d, { recursive: true });
300
+ }));
301
+ // Batch concurrent writes to avoid too many file handles
302
+ const concurrency = Math.max(1, writeConcurrency);
303
+ for (let i = 0; i < entries.length; i += concurrency) {
304
+ const batch = entries.slice(i, i + concurrency);
305
+ await Promise.all(batch.map(async ([rp, content]) => {
306
+ const op = node_path_1.default.isAbsolute(rp) ? rp : node_path_1.default.join(output, rp);
307
+ // 9.5.2: Apply prettier at file level for .ts/.js files
308
+ let finalContent = content;
309
+ if (formatFile && /\.(?:ts|js|mjs|cjs|tsx|jsx)$/.test(rp)) {
310
+ try {
311
+ finalContent = await (0, utils_1.format)(content);
312
+ }
313
+ catch {
314
+ // Prettier format failed, use original content
315
+ }
316
+ }
317
+ return promises_1.default.writeFile(op, finalContent);
318
+ }));
319
+ }
320
+ logger_1.logger.debug('Batch file write complete', {
321
+ total: entries.length,
322
+ concurrency,
323
+ formatFile,
324
+ outputDir: output,
325
+ });
326
+ }
327
+ /** Convenience: load template and render to directory in one call */
328
+ static async renderToDir(params) {
329
+ const helper = TemplateHelper.load({ type: params.type, templatePath: params.templatePath });
330
+ return helper.generateFromTemplateDir(params.templatePath, params.outputDir, params.data, params.options);
331
+ }
332
+ // ============ generateFromTemplateDir (unified streaming pipeline) ============
333
+ /**
334
+ * 9.2.1 & 9.2.2: Unified streaming pipeline — the only generation method.
335
+ * Renders per-tag files and writes them immediately, then renders global files.
336
+ * Supports `beforeFileWrite` callback for plugin content modification (9.1.2).
337
+ * Collects and returns all file paths for `codeGenerated` hook (9.1.1).
338
+ */
339
+ async generateFromTemplateDir(templatePath, outputDir, data, options) {
340
+ const tpls = await this.resolveTemplateFiles(templatePath);
341
+ if (!tpls.length)
342
+ throw logger_1.logger.throwError(`No template files found in: ${templatePath}`);
343
+ const totalTemplates = tpls.length;
344
+ const tagTemplates = tpls.filter(f => f.templateType === 'tag').length;
345
+ const apiTemplates = tpls.filter(f => f.templateType === 'api').length;
346
+ const staticTemplates = totalTemplates - tagTemplates - apiTemplates;
347
+ logger_1.logger.debug('Template files resolved', {
348
+ total: totalTemplates,
349
+ tagTemplates,
350
+ apiTemplates,
351
+ staticTemplates,
352
+ });
353
+ const { changedTags, beforeFileWrite, writeConcurrency = 32, formatFile = true } = options ?? {};
354
+ const hbs = await this.createHbs();
355
+ const tags = data.tagedApis?.map(item => item.tagName) || [];
356
+ const apis = data.allApis || [];
357
+ const tagApisMap = new Map();
358
+ data.tagedApis?.forEach(item => tagApisMap.set(item.tagName, item));
359
+ // Collect all file paths for codeGenerated notification
360
+ const allFilePaths = [];
361
+ // --- Phase 1: Per-tag streaming (render → collect → batch write) ---
362
+ const nonDirTagTpls = tpls.filter(f => !f.insideTagDir && f.templateType === 'tag');
363
+ const dirTpls = tpls.filter(f => f.insideTagDir);
364
+ const effectiveTags = changedTags ? tags.filter(t => changedTags.has(t)) : tags;
365
+ let tagFilesWritten = 0;
366
+ logger_1.logger.debug('Phase 1: Per-tag streaming', {
367
+ totalTags: tags.length,
368
+ effectiveTags: effectiveTags.length,
369
+ changedMode: !!changedTags,
370
+ });
371
+ // P1: Collect all per-tag files across all tags, then write in ONE batch.
372
+ // Previously each tag wrote its files immediately via outputFiles(), which
373
+ // meant 35+ small sequential write batches instead of one fully-concurrent batch.
374
+ const allTagFiles = {};
375
+ for (const tag of effectiveTags) {
376
+ const tagApis = tagApisMap.get(tag);
377
+ if (!tagApis)
378
+ continue;
379
+ const tagFiles = {};
380
+ const ctx = { ...data, tagedApis: [tagApis], currentTag: tagApis };
381
+ for (const tf of nonDirTagTpls) {
382
+ Object.assign(tagFiles, await this.renderOne(hbs, tf, ctx, outputDir, { tag, api: undefined }));
383
+ }
384
+ for (const tf of dirTpls) {
385
+ if (tf.templateType === 'api') {
386
+ await this.expandByApi(hbs, tf, ctx, tagApis.apis, api => ({ ...ctx, currentApi: api }), tagFiles, outputDir, tag);
387
+ }
388
+ else {
389
+ Object.assign(tagFiles, await this.renderOne(hbs, tf, ctx, outputDir, { tag, api: undefined }));
390
+ }
391
+ }
392
+ // Apply beforeFileWrite with per-tag metadata, then collect into allTagFiles
393
+ if (beforeFileWrite) {
394
+ for (const [rp, content] of Object.entries(tagFiles)) {
395
+ tagFiles[rp] = await beforeFileWrite({
396
+ filePath: rp,
397
+ content,
398
+ meta: { templateType: 'tag', tag, api: undefined },
399
+ });
400
+ }
401
+ }
402
+ // Collect paths for codeGenerated notification
403
+ for (const rp of Object.keys(tagFiles)) {
404
+ const op = node_path_1.default.isAbsolute(rp) ? rp : node_path_1.default.resolve(outputDir, rp);
405
+ allFilePaths.push(op);
406
+ }
407
+ Object.assign(allTagFiles, tagFiles);
408
+ tagFilesWritten += Object.keys(tagFiles).length;
409
+ }
410
+ // P1: Single batch write for ALL per-tag files — fully utilizes writeConcurrency
411
+ if (Object.keys(allTagFiles).length) {
412
+ await this.outputFiles(allTagFiles, outputDir, writeConcurrency, formatFile);
413
+ }
414
+ logger_1.logger.debug('Phase 1 complete', { tagFilesWritten });
415
+ // --- Phase 2: Global files (API-level + non-tag templates) ---
416
+ const globalFiles = {};
417
+ const globalTpls = tpls.filter(f => !f.insideTagDir);
418
+ logger_1.logger.debug('Phase 2: Global files', { globalTemplateCount: globalTpls.length });
419
+ for (const tf of globalTpls) {
420
+ if (tf.templateType === 'tag' && tags.length)
421
+ continue;
422
+ if (tf.templateType === 'api' && apis.length) {
423
+ await this.expandByApi(hbs, tf, data, apis, api => api, globalFiles, outputDir);
424
+ }
425
+ else if (tf.templateType !== 'tag') {
426
+ Object.assign(globalFiles, await this.renderOne(hbs, tf, data, outputDir));
427
+ }
428
+ }
429
+ await this.applyHooksAndWrite(globalFiles, outputDir, beforeFileWrite, undefined, undefined, undefined, writeConcurrency, formatFile, allFilePaths);
430
+ logger_1.logger.debug('Phase 2 complete', { globalFilesWritten: Object.keys(globalFiles).length });
431
+ logger_1.logger.debug('Generation summary', { totalOutputFiles: allFilePaths.length });
432
+ return { filePaths: allFilePaths };
433
+ }
434
+ async applyHooksAndWrite(files, outputDir, beforeFileWrite, templateType, tag, api, writeConcurrency, formatFile, allFilePaths) {
435
+ if (beforeFileWrite) {
436
+ // Apply beforeFileWrite to each file sequentially for determinism
437
+ for (const [rp, content] of Object.entries(files)) {
438
+ const newContent = await beforeFileWrite({
439
+ filePath: rp,
440
+ content,
441
+ meta: { templateType, tag, api },
442
+ });
443
+ files[rp] = newContent;
444
+ }
445
+ }
446
+ // Collect paths
447
+ for (const rp of Object.keys(files)) {
448
+ const op = node_path_1.default.isAbsolute(rp) ? rp : node_path_1.default.resolve(outputDir, rp);
449
+ allFilePaths.push(op);
450
+ }
451
+ await this.outputFiles(files, outputDir, writeConcurrency, formatFile);
452
+ }
453
+ async expandByApi(hbs, tf, _data, apis, ctxFn, out, outputDir, tag) {
454
+ for (const api of apis) {
455
+ Object.assign(out, await this.renderOne(hbs, tf, ctxFn(api), outputDir, { tag, api: api.name }));
456
+ }
457
+ }
458
+ async renderOne(hbs, tf, data, outputDir, placeholders) {
459
+ const renderData = data.config ? { ...data.config, ...data } : data;
460
+ const content = await this.renderTemplateFromPath(hbs, tf.absolutePath, renderData);
461
+ let relPath = tf.relativePath;
462
+ if (placeholders?.tag)
463
+ relPath = relPath.replace(constant_1.TemplatePlaceholder.TAG, placeholders.tag);
464
+ if (placeholders?.api)
465
+ relPath = relPath.replace(constant_1.TemplatePlaceholder.API, placeholders.api);
466
+ relPath = stripExt(normalizeSlashes(relPath));
467
+ if (tf.isNoOverwrite && await (0, utils_1.existsPromise)(node_path_1.default.join(outputDir, relPath)))
468
+ return {};
469
+ return { [relPath]: `${content.trim()}\n` };
470
+ }
471
+ }
472
+ exports.TemplateHelper = TemplateHelper;
473
+ /** Runtime cache of parsed template data, keyed by `${projectPath}::${output}`. Flushed to disk via flushAllData. */
474
+ TemplateHelper._cacheData = new Map();
475
+ exports.templateHelper = TemplateHelper.getInstance();
package/dist/index.js ADDED
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ var __importDefault = (this && this.__importDefault) || function (mod) {
17
+ return (mod && mod.__esModule) ? mod : { "default": mod };
18
+ };
19
+ Object.defineProperty(exports, "__esModule", { value: true });
20
+ exports.resolveWorkspaces = exports.logger = exports.generate = exports.defineConfig = exports.createConfig = exports.setGlobalConfig = void 0;
21
+ var config_1 = require("./config");
22
+ Object.defineProperty(exports, "setGlobalConfig", { enumerable: true, get: function () { return config_1.setGlobalConfig; } });
23
+ var createConfig_1 = require("./createConfig");
24
+ Object.defineProperty(exports, "createConfig", { enumerable: true, get: function () { return __importDefault(createConfig_1).default; } });
25
+ var defineConfig_1 = require("./defineConfig");
26
+ Object.defineProperty(exports, "defineConfig", { enumerable: true, get: function () { return defineConfig_1.defineConfig; } });
27
+ var generate_1 = require("./generate");
28
+ Object.defineProperty(exports, "generate", { enumerable: true, get: function () { return __importDefault(generate_1).default; } });
29
+ var helper_1 = require("./helper");
30
+ Object.defineProperty(exports, "logger", { enumerable: true, get: function () { return helper_1.logger; } });
31
+ __exportStar(require("./readConfig"), exports);
32
+ var resolveWorkspaces_1 = require("./resolveWorkspaces");
33
+ Object.defineProperty(exports, "resolveWorkspaces", { enumerable: true, get: function () { return __importDefault(resolveWorkspaces_1).default; } });
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPlugin = createPlugin;
4
+ /**
5
+ * Creates a plugin factory function with proper typing
6
+ *
7
+ * @param plugin - Function that creates a plugin instance
8
+ * @returns The original plugin function with proper typing
9
+ *
10
+ * @example
11
+ * // Create a custom plugin
12
+ * const myPlugin = createPlugin((options: MyOptions) => ({
13
+ * handleApi: (apiDescriptor) => {
14
+ * // Plugin implementation
15
+ * return apiDescriptor;
16
+ * }
17
+ * }));
18
+ *
19
+ * // Use the plugin
20
+ * generate({
21
+ * generator: [{
22
+ * // ...
23
+ * plugins: [myPlugin({ key: 'value' })]
24
+ * }]
25
+ * });
26
+ */
27
+ function createPlugin(plugin) {
28
+ return plugin;
29
+ }
30
+ exports.default = createPlugin;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.ky = exports.config = exports.axios = exports.alovaGlobals = exports.alova = void 0;
18
+ __exportStar(require("./createPlugin"), exports);
19
+ __exportStar(require("./presets/aiDoc"), exports);
20
+ __exportStar(require("./presets/apifox"), exports);
21
+ __exportStar(require("./presets/filterApi"), exports);
22
+ __exportStar(require("./presets/importType"), exports);
23
+ __exportStar(require("./presets/payloadModifier"), exports);
24
+ __exportStar(require("./presets/platform"), exports);
25
+ __exportStar(require("./presets/rename"), exports);
26
+ __exportStar(require("./presets/tagModifier"), exports);
27
+ // Template preset plugins
28
+ var template_1 = require("../template");
29
+ Object.defineProperty(exports, "alova", { enumerable: true, get: function () { return template_1.alova; } });
30
+ Object.defineProperty(exports, "alovaGlobals", { enumerable: true, get: function () { return template_1.alovaGlobals; } });
31
+ Object.defineProperty(exports, "axios", { enumerable: true, get: function () { return template_1.axios; } });
32
+ Object.defineProperty(exports, "config", { enumerable: true, get: function () { return template_1.config; } });
33
+ Object.defineProperty(exports, "fetch", { enumerable: true, get: function () { return template_1.fetch; } });
34
+ Object.defineProperty(exports, "ky", { enumerable: true, get: function () { return template_1.ky; } });