@jayfong/x-server 2.118.1 → 3.0.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 (290) hide show
  1. package/lib/_virtual/_rolldown/runtime.mjs +4 -0
  2. package/lib/cli/api_generator.d.mts +74 -0
  3. package/lib/cli/api_generator.mjs +310 -0
  4. package/lib/cli/build_util.d.mts +17 -0
  5. package/lib/cli/build_util.mjs +156 -0
  6. package/lib/cli/cli.d.mts +1 -0
  7. package/lib/cli/cli.mjs +355 -0
  8. package/lib/cli/css_register.d.mts +1 -0
  9. package/lib/cli/css_register.mjs +7 -0
  10. package/lib/cli/deploy_util.d.mts +23 -0
  11. package/lib/cli/deploy_util.mjs +70 -0
  12. package/lib/cli/dev_util.d.mts +7 -0
  13. package/lib/cli/dev_util.mjs +25 -0
  14. package/lib/cli/env_util.d.mts +45 -0
  15. package/lib/cli/env_util.mjs +207 -0
  16. package/lib/cli/esbuild_register.d.mts +1 -0
  17. package/lib/cli/esbuild_register.mjs +7 -0
  18. package/lib/cli/template_util.d.mts +18 -0
  19. package/lib/cli/template_util.mjs +85 -0
  20. package/lib/cli/templates/crons.ts +1 -1
  21. package/lib/cli/templates/handlers.ts +1 -1
  22. package/lib/cli/templates/hooks.ts +1 -1
  23. package/lib/cli/templates/models.ts +7 -7
  24. package/lib/cli/templates/package.json +11 -1
  25. package/lib/cli/templates/routes.ts +2 -1
  26. package/lib/core/ctx_storage.d.mts +3 -0
  27. package/lib/core/ctx_storage.mjs +4 -0
  28. package/lib/core/define_bus.d.mts +37 -0
  29. package/lib/core/define_bus.mjs +12 -0
  30. package/lib/core/{define_cron.d.ts → define_cron.d.mts} +2 -2
  31. package/lib/core/define_cron.mjs +11 -0
  32. package/lib/core/{define_handler.d.ts → define_handler.d.mts} +19 -19
  33. package/lib/core/define_handler.mjs +44 -0
  34. package/lib/core/define_hook.d.mts +2 -0
  35. package/lib/core/define_hook.mjs +6 -0
  36. package/lib/core/define_server.d.mts +3 -0
  37. package/lib/core/define_server.mjs +8 -0
  38. package/lib/core/{define_task.d.ts → define_task.d.mts} +2 -2
  39. package/lib/core/define_task.mjs +102 -0
  40. package/lib/core/get_handler_url.d.mts +2 -0
  41. package/lib/core/get_handler_url.mjs +7 -0
  42. package/lib/core/handler.d.mts +16 -0
  43. package/lib/core/handler.mjs +132 -0
  44. package/lib/core/http_error.d.mts +2 -0
  45. package/lib/core/http_error.mjs +1 -0
  46. package/lib/core/http_header.d.mts +856 -0
  47. package/lib/core/http_header.mjs +860 -0
  48. package/lib/core/http_method.d.mts +3 -0
  49. package/lib/core/http_method.mjs +10 -0
  50. package/lib/core/http_redirect.d.mts +5 -0
  51. package/lib/core/http_redirect.mjs +10 -0
  52. package/lib/core/server.d.mts +20 -0
  53. package/lib/core/server.mjs +186 -0
  54. package/lib/core/types.d.mts +256 -0
  55. package/lib/exports.d.mts +46 -0
  56. package/lib/exports.mjs +46 -0
  57. package/lib/index.d.mts +48 -0
  58. package/lib/index.mjs +45 -0
  59. package/lib/plugins/base.d.mts +4 -0
  60. package/lib/plugins/compress.d.mts +12 -0
  61. package/lib/plugins/compress.mjs +15 -0
  62. package/lib/plugins/cookie.d.mts +12 -0
  63. package/lib/plugins/cookie.mjs +15 -0
  64. package/lib/plugins/cors.d.mts +22 -0
  65. package/lib/plugins/cors.mjs +34 -0
  66. package/lib/plugins/file_parser.d.mts +15 -0
  67. package/lib/plugins/file_parser.mjs +24 -0
  68. package/lib/plugins/form_body_parser.d.mts +12 -0
  69. package/lib/plugins/form_body_parser.mjs +15 -0
  70. package/lib/plugins/ws_parser.d.mts +12 -0
  71. package/lib/plugins/ws_parser.mjs +15 -0
  72. package/lib/plugins/xml_parser.d.mts +19 -0
  73. package/lib/plugins/xml_parser.mjs +40 -0
  74. package/lib/services/ai.d.mts +31 -0
  75. package/lib/services/ai.mjs +44 -0
  76. package/lib/services/base.d.mts +4 -0
  77. package/lib/services/base.mjs +1 -0
  78. package/lib/services/cache.d.mts +165 -0
  79. package/lib/services/cache.mjs +323 -0
  80. package/lib/services/captcha.d.mts +65 -0
  81. package/lib/services/captcha.mjs +61 -0
  82. package/lib/services/{crypto.js → crypto.d.mts} +19 -78
  83. package/lib/services/crypto.mjs +141 -0
  84. package/lib/services/db_value.d.mts +60 -0
  85. package/lib/services/db_value.mjs +64 -0
  86. package/lib/services/dingtalk.d.mts +39 -0
  87. package/lib/services/dingtalk.mjs +44 -0
  88. package/lib/services/dispose.d.mts +17 -0
  89. package/lib/services/dispose.mjs +18 -0
  90. package/lib/services/emoji.d.mts +10 -0
  91. package/lib/services/emoji.mjs +2025 -0
  92. package/lib/services/file_store.d.mts +49 -0
  93. package/lib/services/file_store.mjs +58 -0
  94. package/lib/services/html.d.mts +11 -0
  95. package/lib/services/html.mjs +12 -0
  96. package/lib/services/jwt.d.mts +33 -0
  97. package/lib/services/jwt.mjs +42 -0
  98. package/lib/services/log.d.mts +37 -0
  99. package/lib/services/log.mjs +99 -0
  100. package/lib/services/mail.d.mts +22 -0
  101. package/lib/services/mail.mjs +28 -0
  102. package/lib/services/pay.d.mts +123 -0
  103. package/lib/services/pay.mjs +157 -0
  104. package/lib/services/random.d.mts +27 -0
  105. package/lib/services/random.mjs +42 -0
  106. package/lib/services/rate_limit.d.mts +37 -0
  107. package/lib/services/rate_limit.mjs +40 -0
  108. package/lib/services/redis.d.mts +11 -0
  109. package/lib/services/redis.mjs +6 -0
  110. package/lib/services/sensitive_words.d.mts +29 -0
  111. package/lib/services/sensitive_words.mjs +37 -0
  112. package/lib/services/sms.d.mts +40 -0
  113. package/lib/services/sms.mjs +30238 -0
  114. package/lib/types/dto.d.mts +30 -0
  115. package/lib/types/dto.mjs +1 -0
  116. package/lib/x.d.mts +11 -0
  117. package/lib/x.mjs +21 -0
  118. package/lib/x_init.d.mts +1 -0
  119. package/lib/x_init.mjs +10 -0
  120. package/package.json +99 -43
  121. package/lib/_cjs/cli/api_generator.js +0 -438
  122. package/lib/_cjs/cli/build_util.js +0 -243
  123. package/lib/_cjs/cli/cli.js +0 -378
  124. package/lib/_cjs/cli/css_register.js +0 -7
  125. package/lib/_cjs/cli/deploy_util.js +0 -76
  126. package/lib/_cjs/cli/dev_util.js +0 -25
  127. package/lib/_cjs/cli/env_util.js +0 -252
  128. package/lib/_cjs/cli/esbuild_register.js +0 -7
  129. package/lib/_cjs/cli/template_util.js +0 -101
  130. package/lib/_cjs/cli/templates/crons.ts +0 -2
  131. package/lib/_cjs/cli/templates/handlers.ts +0 -3
  132. package/lib/_cjs/cli/templates/hooks.ts +0 -2
  133. package/lib/_cjs/cli/templates/models.ts +0 -123
  134. package/lib/_cjs/cli/templates/package.json +0 -3
  135. package/lib/_cjs/cli/templates/routes.ts +0 -68
  136. package/lib/_cjs/core/ctx_storage.js +0 -6
  137. package/lib/_cjs/core/define_bus.js +0 -31
  138. package/lib/_cjs/core/define_cron.js +0 -13
  139. package/lib/_cjs/core/define_handler.js +0 -56
  140. package/lib/_cjs/core/define_hook.js +0 -8
  141. package/lib/_cjs/core/define_server.js +0 -10
  142. package/lib/_cjs/core/define_task.js +0 -113
  143. package/lib/_cjs/core/get_handler_url.js +0 -11
  144. package/lib/_cjs/core/handler.js +0 -216
  145. package/lib/_cjs/core/http_error.js +0 -6
  146. package/lib/_cjs/core/http_header.js +0 -142
  147. package/lib/_cjs/core/http_method.js +0 -12
  148. package/lib/_cjs/core/http_redirect.js +0 -11
  149. package/lib/_cjs/core/server.js +0 -221
  150. package/lib/_cjs/core/types.js +0 -8
  151. package/lib/_cjs/exports.js +0 -273
  152. package/lib/_cjs/index.js +0 -15
  153. package/lib/_cjs/plugins/base.js +0 -3
  154. package/lib/_cjs/plugins/compress.js +0 -18
  155. package/lib/_cjs/plugins/cookie.js +0 -18
  156. package/lib/_cjs/plugins/cors.js +0 -38
  157. package/lib/_cjs/plugins/file_parser.js +0 -28
  158. package/lib/_cjs/plugins/form_body_parser.js +0 -18
  159. package/lib/_cjs/plugins/ws_parser.js +0 -18
  160. package/lib/_cjs/plugins/xml_parser.js +0 -48
  161. package/lib/_cjs/services/ai.js +0 -48
  162. package/lib/_cjs/services/base.js +0 -3
  163. package/lib/_cjs/services/cache.js +0 -400
  164. package/lib/_cjs/services/captcha.js +0 -78
  165. package/lib/_cjs/services/crypto.js +0 -175
  166. package/lib/_cjs/services/db_value.js +0 -77
  167. package/lib/_cjs/services/dingtalk.js +0 -51
  168. package/lib/_cjs/services/dispose.js +0 -23
  169. package/lib/_cjs/services/emoji.js +0 -2034
  170. package/lib/_cjs/services/file_store.js +0 -67
  171. package/lib/_cjs/services/html.js +0 -17
  172. package/lib/_cjs/services/jwt.js +0 -65
  173. package/lib/_cjs/services/log.js +0 -108
  174. package/lib/_cjs/services/mail.js +0 -31
  175. package/lib/_cjs/services/pay.js +0 -191
  176. package/lib/_cjs/services/random.js +0 -51
  177. package/lib/_cjs/services/rate_limit.js +0 -54
  178. package/lib/_cjs/services/redis.js +0 -12
  179. package/lib/_cjs/services/sensitive_words.js +0 -62
  180. package/lib/_cjs/services/sms.js +0 -84
  181. package/lib/_cjs/types/dto.js +0 -3
  182. package/lib/_cjs/x.js +0 -35
  183. package/lib/cli/api_generator.d.ts +0 -74
  184. package/lib/cli/api_generator.js +0 -432
  185. package/lib/cli/build_util.d.ts +0 -17
  186. package/lib/cli/build_util.js +0 -236
  187. package/lib/cli/cli.d.ts +0 -2
  188. package/lib/cli/cli.js +0 -374
  189. package/lib/cli/css_register.js +0 -5
  190. package/lib/cli/deploy_util.d.ts +0 -23
  191. package/lib/cli/deploy_util.js +0 -70
  192. package/lib/cli/dev_util.d.ts +0 -8
  193. package/lib/cli/dev_util.js +0 -19
  194. package/lib/cli/env_util.d.ts +0 -45
  195. package/lib/cli/env_util.js +0 -246
  196. package/lib/cli/esbuild_register.js +0 -5
  197. package/lib/cli/template_util.d.ts +0 -18
  198. package/lib/cli/template_util.js +0 -95
  199. package/lib/core/ctx_storage.d.ts +0 -3
  200. package/lib/core/ctx_storage.js +0 -2
  201. package/lib/core/define_bus.d.ts +0 -37
  202. package/lib/core/define_bus.js +0 -27
  203. package/lib/core/define_cron.js +0 -9
  204. package/lib/core/define_handler.js +0 -48
  205. package/lib/core/define_hook.d.ts +0 -2
  206. package/lib/core/define_hook.js +0 -4
  207. package/lib/core/define_server.d.ts +0 -3
  208. package/lib/core/define_server.js +0 -6
  209. package/lib/core/define_task.js +0 -107
  210. package/lib/core/get_handler_url.d.ts +0 -2
  211. package/lib/core/get_handler_url.js +0 -7
  212. package/lib/core/handler.d.ts +0 -16
  213. package/lib/core/handler.js +0 -209
  214. package/lib/core/http_error.d.ts +0 -2
  215. package/lib/core/http_error.js +0 -2
  216. package/lib/core/http_header.d.ts +0 -856
  217. package/lib/core/http_header.js +0 -139
  218. package/lib/core/http_method.d.ts +0 -3
  219. package/lib/core/http_method.js +0 -8
  220. package/lib/core/http_redirect.d.ts +0 -5
  221. package/lib/core/http_redirect.js +0 -6
  222. package/lib/core/server.d.ts +0 -20
  223. package/lib/core/server.js +0 -215
  224. package/lib/core/types.d.ts +0 -265
  225. package/lib/core/types.js +0 -4
  226. package/lib/exports.d.ts +0 -45
  227. package/lib/exports.js +0 -47
  228. package/lib/index.d.ts +0 -2
  229. package/lib/index.js +0 -3
  230. package/lib/plugins/base.d.ts +0 -4
  231. package/lib/plugins/base.js +0 -1
  232. package/lib/plugins/compress.d.ts +0 -13
  233. package/lib/plugins/compress.js +0 -12
  234. package/lib/plugins/cookie.d.ts +0 -13
  235. package/lib/plugins/cookie.js +0 -12
  236. package/lib/plugins/cors.d.ts +0 -22
  237. package/lib/plugins/cors.js +0 -33
  238. package/lib/plugins/file_parser.d.ts +0 -16
  239. package/lib/plugins/file_parser.js +0 -22
  240. package/lib/plugins/form_body_parser.d.ts +0 -13
  241. package/lib/plugins/form_body_parser.js +0 -12
  242. package/lib/plugins/ws_parser.d.ts +0 -13
  243. package/lib/plugins/ws_parser.js +0 -12
  244. package/lib/plugins/xml_parser.d.ts +0 -19
  245. package/lib/plugins/xml_parser.js +0 -43
  246. package/lib/services/ai.d.ts +0 -31
  247. package/lib/services/ai.js +0 -43
  248. package/lib/services/base.d.ts +0 -4
  249. package/lib/services/base.js +0 -1
  250. package/lib/services/cache.d.ts +0 -173
  251. package/lib/services/cache.js +0 -394
  252. package/lib/services/captcha.d.ts +0 -65
  253. package/lib/services/captcha.js +0 -72
  254. package/lib/services/crypto.d.ts +0 -110
  255. package/lib/services/db_value.d.ts +0 -60
  256. package/lib/services/db_value.js +0 -72
  257. package/lib/services/dingtalk.d.ts +0 -39
  258. package/lib/services/dingtalk.js +0 -45
  259. package/lib/services/dispose.d.ts +0 -17
  260. package/lib/services/dispose.js +0 -17
  261. package/lib/services/emoji.d.ts +0 -10
  262. package/lib/services/emoji.js +0 -2029
  263. package/lib/services/file_store.d.ts +0 -49
  264. package/lib/services/file_store.js +0 -61
  265. package/lib/services/html.d.ts +0 -11
  266. package/lib/services/html.js +0 -12
  267. package/lib/services/jwt.d.ts +0 -34
  268. package/lib/services/jwt.js +0 -59
  269. package/lib/services/log.d.ts +0 -37
  270. package/lib/services/log.js +0 -102
  271. package/lib/services/mail.d.ts +0 -23
  272. package/lib/services/mail.js +0 -25
  273. package/lib/services/pay.d.ts +0 -123
  274. package/lib/services/pay.js +0 -185
  275. package/lib/services/random.d.ts +0 -27
  276. package/lib/services/random.js +0 -45
  277. package/lib/services/rate_limit.d.ts +0 -37
  278. package/lib/services/rate_limit.js +0 -49
  279. package/lib/services/redis.d.ts +0 -12
  280. package/lib/services/redis.js +0 -7
  281. package/lib/services/sensitive_words.d.ts +0 -30
  282. package/lib/services/sensitive_words.js +0 -57
  283. package/lib/services/sms.d.ts +0 -40
  284. package/lib/services/sms.js +0 -78
  285. package/lib/types/dto.d.ts +0 -86
  286. package/lib/types/dto.js +0 -1
  287. package/lib/x.d.ts +0 -17
  288. package/lib/x.js +0 -30
  289. /package/lib/{cli/css_register.d.ts → core/types.mjs} +0 -0
  290. /package/lib/{cli/esbuild_register.d.ts → plugins/base.mjs} +0 -0
@@ -1,438 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
- exports.__esModule = true;
6
- exports.ApiGenerator = void 0;
7
- var _nodePath = _interopRequireDefault(require("node:path"));
8
- var _debug = _interopRequireDefault(require("debug"));
9
- var _fsExtra = _interopRequireDefault(require("fs-extra"));
10
- var _tsMorph = _interopRequireWildcard(require("ts-morph"));
11
- var _vtils = require("vtils");
12
- var _http_method = require("../core/http_method");
13
- /** 注释 */
14
-
15
- /** 接口传输数据 */
16
-
17
- /** 接口数据 */
18
-
19
- class ApiGenerator {
20
- constructor(options = {}) {
21
- this.options = options;
22
- this.cwd = void 0;
23
- this.debug = (0, _debug.default)('api');
24
- // 几种情况:
25
- // /index.ts
26
- // /user/index.ts
27
- // /post.ts
28
- // /user/list.ts
29
- this.categoryUrlRe = /^.+\/src\/handlers\/(?:index\.ts|(.*)\/index\.ts|(.*)\.ts)$/;
30
- this.checker = void 0;
31
- this.cwd = this.options.cwd || process.cwd();
32
- }
33
- async start() {
34
- this.debug('启动项目...');
35
- const tsConfigPath = _nodePath.default.join(this.cwd, 'tsconfig.json');
36
- const handlersPath = _nodePath.default.join(this.cwd, 'node_modules/.x/handlers.ts');
37
- const entryFile = _nodePath.default.join(this.cwd, 'src/generated/handlers.ts');
38
-
39
- // 仅使用 ts-morph 初始化项目
40
- const moProject = new _tsMorph.default.Project({
41
- tsConfigFilePath: tsConfigPath
42
- });
43
- moProject.createSourceFile(entryFile, await _fsExtra.default.readFile(handlersPath, 'utf-8'));
44
- const program = moProject.getProgram().compilerObject;
45
- const checker = program.getTypeChecker();
46
- this.checker = checker;
47
- const entrySourceFile = program.getSourceFile(entryFile);
48
- const moduleSymbol = checker.getSymbolAtLocation(entrySourceFile);
49
- const categorySymbols = checker.getExportsOfModule(moduleSymbol);
50
- const apiData = [];
51
- for (const categorySymbol of categorySymbols) {
52
- // 分类的类型
53
- const categoryType = checker.getTypeOfSymbol(categorySymbol);
54
-
55
- // 处理器列表
56
- const handlerSymbols = categoryType.getProperties();
57
-
58
- // 分类源文件
59
- const categorySourceFile = handlerSymbols[0].getDeclarations()[0].getSourceFile();
60
-
61
- // 分类源文件路径
62
- const categorySourceFilePath = categorySourceFile.fileName;
63
-
64
- // 忽略仅开发时生效的路由
65
- if (/@dev[/.]/.test(categorySourceFilePath)) continue;
66
-
67
- // 支持 include, exclude
68
- if (this.options.include?.length) {
69
- if (this.options.include.every(item => !categorySourceFilePath.includes(item))) continue;
70
- }
71
- if (this.options.exclude?.length) {
72
- if (this.options.exclude.some(item => categorySourceFilePath.includes(item))) continue;
73
- }
74
-
75
- // 分类 URL
76
- const categoryUrlMatch = categorySourceFilePath.match(this.categoryUrlRe);
77
- let categoryUrl = categoryUrlMatch[1] ?? categoryUrlMatch[2] ?? '';
78
- categoryUrl = categoryUrl === '' ? '/' : `/${categoryUrl}/`;
79
- for (const handlerSymbol of handlerSymbols) {
80
- // 处理器路径
81
- let handlerPath = [handlerSymbol.getName()];
82
- const handlerNode = handlerSymbol.getDeclarations()[0];
83
-
84
- // 支持自定义 requestPath
85
- if (
86
- // const xx = defineHandler
87
- _tsMorph.ts.isVariableDeclaration(handlerNode) && handlerNode.initializer &&
88
- // defineHandler()
89
- _tsMorph.ts.isCallExpression(handlerNode.initializer) &&
90
- // defineHandler({})
91
- _tsMorph.ts.isObjectLiteralExpression(handlerNode.initializer.arguments[0])) {
92
- const props = handlerNode.initializer.arguments[0].properties;
93
- const requestPathNode = props.find(item => item.name?.getText() === 'requestPath');
94
- if (requestPathNode &&
95
- // requestPath: ''
96
- _tsMorph.ts.isPropertyAssignment(requestPathNode)) {
97
- const customHandlerPath =
98
- // requestPath: 'xx'
99
- _tsMorph.ts.isStringLiteral(requestPathNode.initializer) ? requestPathNode.initializer.text :
100
- // requestPath: ['xx']
101
- _tsMorph.ts.isArrayLiteralExpression(requestPathNode.initializer) ? requestPathNode.initializer.elements.filter(item => _tsMorph.ts.isStringLiteral(item)).map(item => item.text) : '';
102
- if (customHandlerPath.length) {
103
- handlerPath = (0, _vtils.castArray)(customHandlerPath);
104
- }
105
- }
106
- }
107
-
108
- // 处理器 URL
109
- const handlerUrl = handlerPath.map(path => `${categoryUrl}${path}`);
110
-
111
- // 处理器注释
112
- const handlerComment = this.getComment(handlerSymbol);
113
- if (handlerComment.tags.has('private')) {
114
- this.debug('跳过生成接口: %s', `${handlerUrl}`);
115
- continue;
116
- }
117
- this.debug('生成接口: %s ...', handlerUrl);
118
- const handlerType = checker.getTypeAtLocation(handlerNode);
119
- const [requestType, responseType, methodType] = checker.getTypeArguments(handlerType);
120
- const handlerCategory = (0, _vtils.pascalCase)(categoryUrl) || 'Index';
121
- const handlerDescription = handlerComment.description || handlerUrl.join(', ');
122
- const handlerMethod = methodType.value;
123
- const httpMethod = _http_method.HandlerMethodToHttpMethod[handlerMethod];
124
- const requestData = this.getApiDto({
125
- type: requestType
126
- });
127
- const responseData = this.getApiDto({
128
- type: responseType
129
- });
130
- const requestDataJsonSchema = this.apiDataToJsonSchema(requestData);
131
- const responseDataJsonSchema = this.apiDataToJsonSchema(responseData);
132
- const handlerDescriptionDividerIndex = handlerDescription.indexOf('\n\n');
133
- const apiName = handlerDescriptionDividerIndex === -1 ? handlerDescription : handlerDescription.substring(0, handlerDescriptionDividerIndex);
134
- const apiDesc = handlerDescriptionDividerIndex === -1 ? '' : handlerDescription.substring(handlerDescriptionDividerIndex + 2);
135
- apiData.push({
136
- category: handlerCategory,
137
- name: apiName,
138
- desc: apiDesc,
139
- path: handlerUrl,
140
- handlerMethod: handlerMethod,
141
- method: httpMethod,
142
- requestData: requestData,
143
- responseData: responseData,
144
- requestDataJsonSchema: requestDataJsonSchema,
145
- responseDataJsonSchema: responseDataJsonSchema
146
- });
147
- }
148
- }
149
- this.debug('写入文件...');
150
- const prefix = this.options.name ? `${this.options.name}_` : '';
151
- await Promise.all([_fsExtra.default.outputJSON(_nodePath.default.join(this.cwd, `temp/${prefix}api.json`), apiData, {
152
- spaces: 2
153
- }), _fsExtra.default.outputJSON(_nodePath.default.join(this.cwd, `temp/${prefix}yapi.json`), this.apiDataToYApiData(apiData), {
154
- spaces: 2
155
- }), _fsExtra.default.outputJSON(_nodePath.default.join(this.cwd, `temp/${prefix}openapi31.json`), this.apiDataToOpenAPI31Data(apiData), {
156
- spaces: 2
157
- })]);
158
- }
159
-
160
- // ref: https://github.com/styleguidist/react-docgen-typescript/blob/master/src/parser.ts#L777
161
- getComment(symbol) {
162
- if (!symbol) {
163
- return {
164
- existing: false,
165
- description: '',
166
- tags: new Map()
167
- };
168
- }
169
- const description = _tsMorph.ts.displayPartsToString(symbol.getDocumentationComment(this.checker)).trim();
170
- const tags = symbol.getJsDocTags().map(item => {
171
- return {
172
- label: item.name,
173
- value: _tsMorph.ts.displayPartsToString(item.text).trim()
174
- };
175
- });
176
- return {
177
- existing: !!description,
178
- description: description,
179
- tags: tags.reduce((res, item) => {
180
- res.set(item.label, item.value);
181
- return res;
182
- }, new Map())
183
- };
184
- }
185
- getApiDto({
186
- type,
187
- keySymbol = type.symbol || type.aliasSymbol
188
- }) {
189
- const hasTypeFlag = (flag, _type = type) => (_type.flags & flag) === flag;
190
- let valueSymbol = type.symbol || type.aliasSymbol;
191
- const keySymbolName = keySymbol?.getName() || '';
192
- let valueSymbolName = valueSymbol?.getName() || '';
193
- const comment = this.getComment(keySymbol);
194
- let isRequired = keySymbol ? !(keySymbol.getFlags() & _tsMorph.ts.SymbolFlags.Optional) : false;
195
- const apiName = keySymbolName || '__type';
196
-
197
- // Decimal, Prisma 生成的
198
- if (valueSymbolName === 'Decimal') {
199
- return {
200
- name: apiName,
201
- desc: comment.description,
202
- required: isRequired,
203
- type: 'number',
204
- enum: [],
205
- children: []
206
- };
207
- }
208
-
209
- // WS
210
- if (valueSymbolName === 'SocketStream') {
211
- return {
212
- name: 'ws',
213
- desc: comment.description,
214
- required: isRequired,
215
- type: 'object',
216
- enum: [],
217
- children: []
218
- };
219
- }
220
-
221
- // 文件
222
- if (valueSymbolName === 'MultipartFile') {
223
- return {
224
- name: 'file',
225
- desc: comment.description,
226
- required: isRequired,
227
- type: 'file',
228
- enum: [],
229
- children: []
230
- };
231
- }
232
-
233
- // Buffer
234
- if (valueSymbolName === 'Buffer') {
235
- return {
236
- name: 'buffer',
237
- desc: comment.description,
238
- required: isRequired,
239
- type: 'object',
240
- enum: [],
241
- children: []
242
- };
243
- }
244
-
245
- // 联合类型
246
- // 布尔、枚举也会用这表示
247
- const rawUnionTypes = type.isUnion() && type.types || [];
248
- const unionTypes = rawUnionTypes.filter(item => !hasTypeFlag(_tsMorph.ts.TypeFlags.Null, item) && !hasTypeFlag(_tsMorph.ts.TypeFlags.Undefined, item));
249
- const isUnion = !!unionTypes.length;
250
- if (isUnion) {
251
- if (unionTypes.length !== rawUnionTypes.length) {
252
- isRequired = false;
253
- }
254
- type = unionTypes[0];
255
- valueSymbol = type.symbol || type.aliasSymbol;
256
- valueSymbolName = this.checker.getBaseTypeOfLiteralType(type).getSymbol()?.getName() || '';
257
- }
258
- const isIntersection = type.isIntersection();
259
- const intersectionTypes = isIntersection && type.types || [];
260
- const isDate = valueSymbolName === 'Date';
261
- const isRegExp = valueSymbolName === 'RegExp';
262
- const isBigIntLiteral = hasTypeFlag(_tsMorph.ts.TypeFlags.BigIntLiteral);
263
- const isBigInt = hasTypeFlag(_tsMorph.ts.TypeFlags.BigInt) || isBigIntLiteral;
264
- const isArray = valueSymbolName === 'Array' || valueSymbolName === 'ReadonlyArray';
265
- const isStringLiteral = hasTypeFlag(_tsMorph.ts.TypeFlags.StringLiteral);
266
- const isString = hasTypeFlag(_tsMorph.ts.TypeFlags.String) || isStringLiteral ||
267
- // BigInt 类型视为字符串
268
- isBigInt ||
269
- // Date 类型视为字符串
270
- isDate ||
271
- // RegExp 类型视为字符串
272
- isRegExp;
273
- const isNumberLiteral = hasTypeFlag(_tsMorph.ts.TypeFlags.NumberLiteral);
274
- const isNumber = hasTypeFlag(_tsMorph.ts.TypeFlags.Number) || isNumberLiteral;
275
- const isBoolean = hasTypeFlag(_tsMorph.ts.TypeFlags.Boolean) || hasTypeFlag(_tsMorph.ts.TypeFlags.BooleanLiteral);
276
- const isLiteral = isStringLiteral || isNumberLiteral || isBigIntLiteral;
277
- const isObject = !isArray && !isString && !isNumber && !isBoolean && hasTypeFlag(_tsMorph.ts.TypeFlags.Object) ||
278
- // 交集类型视为对象
279
- isIntersection;
280
- const apiDesc = keySymbol && this.getComment(keySymbol).description || '';
281
- const apiEnum = (isUnion ? unionTypes.map(item => item.value) : isLiteral ? [type.value] : []).filter(v => v != null);
282
- const apiType = isArray ? 'array' : isString ? 'string' : isNumber ? 'number' : isBoolean ? 'boolean' : 'object';
283
- const apiRequired = isRequired;
284
- const apiChildren = isArray ? [this.getApiDto({
285
- type: this.checker.getTypeArguments(type)[0]
286
- })] : isObject ? (0, _vtils.ii)(() => {
287
- const childSymbols = this.checker.getAllPossiblePropertiesOfTypes(intersectionTypes.length ? intersectionTypes : [type]);
288
- return childSymbols.map(childSymbol => {
289
- const childType = this.checker.getTypeOfSymbol(childSymbol);
290
- return this.getApiDto({
291
- type: childType,
292
- keySymbol: childSymbol
293
- });
294
- });
295
- }) : [];
296
- return {
297
- name: apiName,
298
- desc: apiDesc,
299
- enum: apiEnum,
300
- type: apiType,
301
- required: apiRequired,
302
- children: apiChildren
303
- };
304
- }
305
- apiDataToJsonSchema(apiData, jsonSchema = {}) {
306
- jsonSchema.description = apiData.desc;
307
- if (apiData.type === 'object') {
308
- jsonSchema.type = 'object';
309
- jsonSchema.properties = apiData.children.reduce((res, item) => {
310
- res[item.name] = this.apiDataToJsonSchema(item);
311
- return res;
312
- }, {});
313
- jsonSchema.required = apiData.children.filter(item => item.required).map(item => item.name);
314
- } else if (apiData.type === 'array') {
315
- jsonSchema.type = 'array';
316
- jsonSchema.items = apiData.children.map(item => this.apiDataToJsonSchema(item))[0];
317
- } else {
318
- jsonSchema.type = apiData.type;
319
- if (apiData.enum.length) {
320
- jsonSchema.enum = apiData.enum;
321
- }
322
- }
323
- return jsonSchema;
324
- }
325
- apiDataToYApiData(handles) {
326
- const data = {};
327
- for (const handle of handles) {
328
- for (const path of handle.path) {
329
- data[handle.category] = data[handle.category] || [];
330
- data[handle.category].push(handle.handlerMethod === 'GET' ? {
331
- method: handle.method.toUpperCase(),
332
- title: handle.name,
333
- markdown: handle.desc,
334
- path: path,
335
- res_body_type: 'json',
336
- req_body_is_json_schema: false,
337
- res_body_is_json_schema: true,
338
- req_params: [],
339
- req_query: handle.requestData.children.map(item => ({
340
- required: item.required ? 1 : 0,
341
- name: item.name,
342
- desc: item.desc,
343
- type: 'string'
344
- })),
345
- req_headers: [],
346
- req_body_form: [],
347
- res_body: JSON.stringify(handle.responseDataJsonSchema)
348
- } : handle.handlerMethod === 'FILE' ? {
349
- method: handle.method.toUpperCase(),
350
- title: handle.name,
351
- markdown: handle.desc,
352
- path: path,
353
- req_body_type: 'form',
354
- res_body_type: 'json',
355
- req_body_is_json_schema: false,
356
- res_body_is_json_schema: true,
357
- req_params: [],
358
- req_query: [],
359
- req_headers: [],
360
- req_body_form: handle.requestData.children.map(item => ({
361
- required: item.required ? 1 : 0,
362
- name: item.name,
363
- desc: item.desc,
364
- type: item.type === 'file' ? 'file' : 'text'
365
- })),
366
- res_body: JSON.stringify(handle.responseDataJsonSchema)
367
- } : {
368
- method: handle.method.toUpperCase(),
369
- title: handle.name,
370
- markdown: handle.desc,
371
- path: path,
372
- req_body_type: 'json',
373
- res_body_type: 'json',
374
- req_body_is_json_schema: true,
375
- res_body_is_json_schema: true,
376
- req_params: [],
377
- req_query: [],
378
- req_headers: [],
379
- req_body_form: [],
380
- req_body_other: JSON.stringify(handle.requestDataJsonSchema),
381
- res_body: JSON.stringify(handle.responseDataJsonSchema)
382
- });
383
- }
384
- }
385
- return Object.keys(data).map(cat => ({
386
- name: cat,
387
- desc: cat,
388
- list: data[cat]
389
- }));
390
- }
391
- apiDataToOpenAPI31Data(handles) {
392
- const data = {
393
- openapi: '3.1.0',
394
- info: {
395
- title: `${process.env.APP_NAME}`,
396
- version: '1.0.0'
397
- },
398
- paths: {},
399
- servers: [{
400
- url: `${process.env.APP_URL}`.replace(/\/+$/, ''),
401
- description: '生产'
402
- }, {
403
- url: `http://127.0.0.1:${process.env.APP_PORT}`,
404
- description: '本地'
405
- }]
406
- };
407
- for (const handle of handles) {
408
- for (const path of handle.path) {
409
- data.paths[path] = {
410
- [handle.method.toLowerCase()]: {
411
- tags: [handle.category],
412
- summary: handle.name,
413
- description: handle.desc,
414
- requestBody: {
415
- content: {
416
- 'application/json': {
417
- schema: handle.requestDataJsonSchema
418
- }
419
- }
420
- },
421
- responses: {
422
- '200': {
423
- description: 'success',
424
- content: {
425
- 'application/json': {
426
- schema: handle.responseDataJsonSchema
427
- }
428
- }
429
- }
430
- }
431
- }
432
- };
433
- }
434
- }
435
- return data;
436
- }
437
- }
438
- exports.ApiGenerator = ApiGenerator;
@@ -1,243 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5
- exports.__esModule = true;
6
- exports.BuildUtil = void 0;
7
- var _nodePath = _interopRequireDefault(require("node:path"));
8
- var _compressing = _interopRequireDefault(require("compressing"));
9
- var esbuild = _interopRequireWildcard(require("esbuild"));
10
- var _execa = _interopRequireDefault(require("execa"));
11
- var _fsExtra = _interopRequireDefault(require("fs-extra"));
12
- var _vtils = require("vtils");
13
- class BuildUtil {
14
- static async build(options) {
15
- const mainFile = _nodePath.default.join(options.cwd, 'src/main.ts');
16
- const pkgFile = _nodePath.default.join(options.cwd, 'package.json');
17
- const pkgContent = await _fsExtra.default.readJson(pkgFile);
18
- const distDir = _nodePath.default.join(options.cwd, options.channel ? `dist/${options.channel}` : 'dist');
19
- const tempDir = _nodePath.default.join(options.cwd, options.channel ? `temp/${options.channel}` : 'temp');
20
- const distMainFile = _nodePath.default.join(distDir, 'main.js');
21
- const distPkgFile = _nodePath.default.join(distDir, 'package.json');
22
- const distNvmrcFile = _nodePath.default.join(distDir, '.nvmrc');
23
- const distPm2File = _nodePath.default.join(distDir, 'pm2.config.js');
24
- const distNoInstallFile = _nodePath.default.join(distDir, 'no_install.lock');
25
- const distBundleFile = _nodePath.default.join(tempDir, `app.${pkgContent.version}.tgz`);
26
- await _fsExtra.default.ensureDir(distDir);
27
- await _fsExtra.default.ensureDir(tempDir);
28
-
29
- // 处理 external
30
- const external = (0, _vtils.uniq)([...(options.external || []),
31
- // bull 始终作为外部依赖
32
- 'bull']);
33
- const externalWithVersions = (await Promise.all(external.map(async item => {
34
- try {
35
- // 为何不用 require.resolve:
36
- // Package subpath './package.json' is not defined by "exports"
37
- const itemPkgFile = _nodePath.default.join(process.cwd(), `node_modules/${item}/package.json`);
38
- const itemPkgContent = await _fsExtra.default.readJson(itemPkgFile);
39
- return {
40
- name: item,
41
- version: itemPkgContent.version
42
- };
43
- } catch {
44
- return {
45
- name: item,
46
- version: ''
47
- };
48
- }
49
- }))).filter(item => !!item.version);
50
-
51
- // fix: hexoid 构建问题
52
- try {
53
- const hexoidPackageJsonFile = require.resolve('hexoid/package.json');
54
- const pkg = await _fsExtra.default.readJson(hexoidPackageJsonFile);
55
- delete pkg.module;
56
- await _fsExtra.default.writeJson(hexoidPackageJsonFile, pkg);
57
- } catch {}
58
-
59
- // 构建
60
- if (!options.noEmptyDistDir) {
61
- await _fsExtra.default.emptyDir(distDir);
62
- }
63
- // @ts-ignore
64
- const {
65
- default: macrosPlugin
66
- } = await import('unplugin-macros/esbuild');
67
- await esbuild.build({
68
- entryPoints: [mainFile],
69
- bundle: true,
70
- outfile: distMainFile,
71
- platform: 'node',
72
- // https://esbuild.github.io/api/#main-fields
73
- // 当 platform 是 node 时,
74
- // esbuild 默认的 mainFields 是 main,module,
75
- // 这会导致 treeShaking 失效
76
- mainFields: ['module', 'main'],
77
- target: `node${process.version.slice(1)}`,
78
- external: external,
79
- minify: options.minify ?? true,
80
- format: 'cjs',
81
- sourcemap: false,
82
- treeShaking: true,
83
- banner: {
84
- js: [...Object.keys(options.inlineEnvs || {}).map(key => `process.env[${JSON.stringify(key)}]=${JSON.stringify(options.inlineEnvs[key])};`), `process.env["X_SERVER_ENVS"]=${JSON.stringify(JSON.stringify(options.inlineEnvs || {}))};`].join('\n')
85
- },
86
- plugins: [{
87
- name: 'extract-assets',
88
- async setup(build) {
89
- build.onLoad({
90
- filter: /\/svg-captcha\/lib\/option-manager\.js$/
91
- }, async args => {
92
- let js = await _fsExtra.default.readFile(args.path, 'utf-8');
93
- js = js.replace('../fonts/Comismsh.ttf', './assets/svg-captcha/fonts/Comismsh.ttf');
94
- await _fsExtra.default.copy(_nodePath.default.dirname(require.resolve('svg-captcha/fonts/LICENSE.md')), _nodePath.default.join(distDir, 'assets/svg-captcha/fonts'));
95
- return {
96
- contents: js,
97
- loader: 'js'
98
- };
99
- });
100
-
101
- // build.onLoad(
102
- // { filter: /\/bull\/lib\/commands\/index\.js$/ },
103
- // async args => {
104
- // let js = await fs.readFile(args.path, 'utf-8');
105
- // js = js.replace(/__dirname/g, '"./assets/bull/commands"');
106
- // await fs.copy(
107
- // path.dirname(require.resolve('bull/lib/commands/index.js')),
108
- // path.join(distDir, 'assets/bull/commands'),
109
- // );
110
- // return {
111
- // contents: js,
112
- // loader: 'js',
113
- // };
114
- // },
115
- // );
116
-
117
- build.onLoad({
118
- filter: /\/vm2\/lib\/vm\.js$/
119
- }, async args => {
120
- let js = await _fsExtra.default.readFile(args.path, 'utf-8');
121
- const jsDir = _nodePath.default.dirname(args.path);
122
- const assetsDir = _nodePath.default.join(distDir, 'assets/vm2');
123
- await _fsExtra.default.ensureDir(assetsDir);
124
- js = js.replace(/__dirname/g, '"./assets/vm2"');
125
- await Promise.all([_fsExtra.default.copyFile(_nodePath.default.join(jsDir, 'bridge.js'), _nodePath.default.join(assetsDir, 'bridge.js')), _fsExtra.default.copyFile(_nodePath.default.join(jsDir, 'setup-sandbox.js'), _nodePath.default.join(assetsDir, 'setup-sandbox.js'))]);
126
- return {
127
- contents: js,
128
- loader: 'js'
129
- };
130
- });
131
-
132
- // 支持仅开发时生效的路由
133
- build.onLoad({
134
- filter: /@dev[/.]/
135
- }, async () => {
136
- return {
137
- contents: 'module.exports = {}',
138
- loader: 'js'
139
- };
140
- });
141
-
142
- // 支持构建时排除文件
143
- if (options.excludeFiles?.length) {
144
- const excludeRegExps = options.excludeFiles.map(item => new RegExp(item));
145
- build.onLoad({
146
- filter: /\.ts$/
147
- }, async args => {
148
- if (excludeRegExps.some(re => re.test(args.path))) {
149
- return {
150
- // 不用 export {} 避免 esbuild 检测报错
151
- contents: 'module.exports = {}',
152
- loader: 'js'
153
- };
154
- }
155
- });
156
- }
157
- }
158
- }, macrosPlugin()],
159
- loader: {
160
- // 兼容 x-text-render 在服务端使用
161
- // dev 时用 css_register 兼容
162
- // https://esbuild.github.io/content-types/#empty-file
163
- '.css': 'empty'
164
- }
165
- });
166
-
167
- // 兼容 prisma
168
- const prismaSchemaFile = _nodePath.default.join(options.cwd, 'src/db/schema.prisma');
169
- if (await _fsExtra.default.pathExists(prismaSchemaFile)) {
170
- // 复制 schema.prisma
171
- const distPrismaSchemaFile = _nodePath.default.join(distDir, _nodePath.default.basename(prismaSchemaFile));
172
- await _fsExtra.default.copyFile(prismaSchemaFile, distPrismaSchemaFile);
173
-
174
- // 多 schema 文件兼容
175
- const multipleSchemaDir = _nodePath.default.join(options.cwd, 'src/db/schema');
176
- if (await _fsExtra.default.pathExists(multipleSchemaDir)) {
177
- const distMultipleSchemaDir = _nodePath.default.join(distDir, _nodePath.default.basename(multipleSchemaDir));
178
- await _fsExtra.default.copy(multipleSchemaDir, distMultipleSchemaDir);
179
- }
180
- }
181
-
182
- // 写入 pkg
183
- const deps = externalWithVersions.reduce((res, item) => {
184
- res[item.name] = item.version;
185
- return res;
186
- }, {});
187
- const distPkgContent = {
188
- name: options.appId,
189
- version: pkgContent.version,
190
- dependencies: deps
191
- };
192
- await _fsExtra.default.writeJSON(distPkgFile, distPkgContent);
193
-
194
- // .nvmrc
195
- const nvmrcFile = _nodePath.default.join(options.cwd, '.nvmrc');
196
- const hasNvmrc = await _fsExtra.default.pathExists(nvmrcFile);
197
- if (hasNvmrc) {
198
- await _fsExtra.default.writeFile(distNvmrcFile, await _fsExtra.default.readFile(nvmrcFile));
199
- }
200
-
201
- // 写入 pm2 配置
202
- await _fsExtra.default.writeFile(distPm2File, (0, _vtils.dedent)`
203
- module.exports = {
204
- apps: [
205
- {
206
- name: ${JSON.stringify(distPkgContent.name)},
207
- script: './main.js',
208
- interpreter: 'node',
209
- interpreter_args: ${JSON.stringify(options.pm2NodeArgs || [])},
210
- ${hasNvmrc ? `
211
- env: {
212
- PATH: \`\${require('child_process').execSync('fnm exec which node').toString().trim().replace(/\\/node$/, '')}:\${process.env.PATH}\`,
213
- },
214
- ` : ''}
215
- ${options.pm2MaxMemoryRestart ? `max_memory_restart: '${options.pm2MaxMemoryRestart}',` : ''}
216
- ${options.pm2CronRestart ? `cron_restart: '${options.pm2CronRestart}',` : ''}
217
- },
218
- ],
219
- }
220
- `);
221
- if (externalWithVersions.length) {
222
- if (options.noInstall) {
223
- await _fsExtra.default.writeFile(distNoInstallFile, '');
224
- } else {
225
- // 安装 external 依赖
226
- await (0, _execa.default)('tyn', {
227
- cwd: distDir,
228
- stdio: 'inherit',
229
- // @ts-ignore
230
- env: {
231
- // 禁止 yarn 更新检测,因网络原因容易超时长时间卡住
232
- // https://classic.yarnpkg.com/lang/en/docs/yarnrc/#toc-disable-self-update-check
233
- yarn_disable_self_update_check: 'true'
234
- }
235
- });
236
- }
237
- }
238
-
239
- // 打包为 tgz
240
- await _compressing.default.tgz.compressDir(distDir, distBundleFile);
241
- }
242
- }
243
- exports.BuildUtil = BuildUtil;