@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,3 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
package/lib/_cjs/x.js DELETED
@@ -1,35 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
- exports.__esModule = true;
5
- exports.x = void 0;
6
- var _nodeOs = _interopRequireDefault(require("node:os"));
7
- var _nodePath = _interopRequireDefault(require("node:path"));
8
- var _fsExtra = _interopRequireDefault(require("fs-extra"));
9
- var _ctx_storage = require("./core/ctx_storage");
10
- var _crypto = require("./services/crypto");
11
- var _db_value = require("./services/db_value");
12
- var _dispose = require("./services/dispose");
13
- var _emoji = require("./services/emoji");
14
- var _html = require("./services/html");
15
- var _log = require("./services/log");
16
- var _random = require("./services/random");
17
- const env = JSON.parse(process.env.X_SERVER_ENVS || '{}');
18
- const x = exports.x = {
19
- appId: env.APP_ID,
20
- env: env,
21
- dataDir: _nodePath.default.join(_nodeOs.default.homedir(), `.xs/${env.APP_ID}`),
22
- get ctx() {
23
- return _ctx_storage.ctxStorage.getStore();
24
- },
25
- register: (...services) => {
26
- for (const service of services) {
27
- // @ts-ignore
28
- x[service.serviceName] = service;
29
- }
30
- }
31
- };
32
- _fsExtra.default.ensureDirSync(x.dataDir);
33
- x.register(new _dispose.DisposeService({
34
- disposeOnExit: true
35
- }), new _log.LogService(), new _emoji.EmojiService(), new _db_value.DbValueService(), new _crypto.CryptoService(), new _html.HtmlService(), new _random.RandomService());
@@ -1,74 +0,0 @@
1
- import createDebug from 'debug';
2
- import type { JSONSchema4 } from 'json-schema';
3
- import type { OpenAPIV3_1 } from 'openapi-types';
4
- import { ts } from 'ts-morph';
5
- import type { LiteralUnion } from 'vtils/types';
6
- import type { XHandler } from '../core/types';
7
- /** 注释 */
8
- type Comment = {
9
- existing: boolean;
10
- description: string;
11
- tags: Map<LiteralUnion<'private', string>, string>;
12
- };
13
- /** 接口传输数据 */
14
- type ApiDto = {
15
- name: string;
16
- desc: string;
17
- type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'file';
18
- enum: any[];
19
- required: boolean;
20
- children: ApiDto[];
21
- };
22
- /** 接口数据 */
23
- type ApiData = {
24
- category: string;
25
- name: string;
26
- desc: string;
27
- path: string[];
28
- handlerMethod: XHandler.Method;
29
- method: string;
30
- requestData: ApiDto;
31
- responseData: ApiDto;
32
- requestDataJsonSchema: JSONSchema4;
33
- responseDataJsonSchema: JSONSchema4;
34
- };
35
- export type ApiGeneratorOptions = {
36
- cwd?: string;
37
- include?: string[];
38
- exclude?: string[];
39
- name?: string;
40
- };
41
- export declare class ApiGenerator {
42
- private options;
43
- private cwd;
44
- constructor(options?: ApiGeneratorOptions);
45
- debug: createDebug.Debugger;
46
- categoryUrlRe: RegExp;
47
- checker: ts.TypeChecker;
48
- start(): Promise<void>;
49
- getComment(symbol?: ts.Symbol): Comment;
50
- getApiDto({ type, keySymbol, }: {
51
- type: ts.Type;
52
- keySymbol?: ts.Symbol;
53
- }): ApiDto;
54
- apiDataToJsonSchema(apiData: ApiDto, jsonSchema?: JSONSchema4): JSONSchema4;
55
- apiDataToYApiData(handles: ApiData[]): {
56
- name: string;
57
- desc: string;
58
- list: any;
59
- }[];
60
- apiDataToOpenAPI31Data(handles: ApiData[]): Omit<Omit<import("openapi-types").OpenAPIV3.Document<{}>, "paths" | "components">, "info" | "paths" | "components" | "servers" | "webhooks" | "jsonSchemaDialect"> & {
61
- info: OpenAPIV3_1.InfoObject;
62
- jsonSchemaDialect?: string;
63
- servers?: OpenAPIV3_1.ServerObject[];
64
- } & Pick<{
65
- paths: OpenAPIV3_1.PathsObject<{}, {}>;
66
- webhooks: Record<string, OpenAPIV3_1.PathItemObject | OpenAPIV3_1.ReferenceObject>;
67
- components: OpenAPIV3_1.ComponentsObject;
68
- }, "paths"> & Omit<Partial<{
69
- paths: OpenAPIV3_1.PathsObject<{}, {}>;
70
- webhooks: Record<string, OpenAPIV3_1.PathItemObject | OpenAPIV3_1.ReferenceObject>;
71
- components: OpenAPIV3_1.ComponentsObject;
72
- }>, "paths">;
73
- }
74
- export {};
@@ -1,432 +0,0 @@
1
- import path from 'node:path';
2
- import createDebug from 'debug';
3
- import fs from 'fs-extra';
4
- import mo, { ts } from 'ts-morph';
5
- import { castArray, ii, pascalCase } from 'vtils';
6
- import { HandlerMethodToHttpMethod } from "../core/http_method";
7
-
8
- /** 注释 */
9
-
10
- /** 接口传输数据 */
11
-
12
- /** 接口数据 */
13
-
14
- export class ApiGenerator {
15
- constructor(options = {}) {
16
- this.options = options;
17
- this.cwd = void 0;
18
- this.debug = createDebug('api');
19
- // 几种情况:
20
- // /index.ts
21
- // /user/index.ts
22
- // /post.ts
23
- // /user/list.ts
24
- this.categoryUrlRe = /^.+\/src\/handlers\/(?:index\.ts|(.*)\/index\.ts|(.*)\.ts)$/;
25
- this.checker = void 0;
26
- this.cwd = this.options.cwd || process.cwd();
27
- }
28
- async start() {
29
- this.debug('启动项目...');
30
- const tsConfigPath = path.join(this.cwd, 'tsconfig.json');
31
- const handlersPath = path.join(this.cwd, 'node_modules/.x/handlers.ts');
32
- const entryFile = path.join(this.cwd, 'src/generated/handlers.ts');
33
-
34
- // 仅使用 ts-morph 初始化项目
35
- const moProject = new mo.Project({
36
- tsConfigFilePath: tsConfigPath
37
- });
38
- moProject.createSourceFile(entryFile, await fs.readFile(handlersPath, 'utf-8'));
39
- const program = moProject.getProgram().compilerObject;
40
- const checker = program.getTypeChecker();
41
- this.checker = checker;
42
- const entrySourceFile = program.getSourceFile(entryFile);
43
- const moduleSymbol = checker.getSymbolAtLocation(entrySourceFile);
44
- const categorySymbols = checker.getExportsOfModule(moduleSymbol);
45
- const apiData = [];
46
- for (const categorySymbol of categorySymbols) {
47
- // 分类的类型
48
- const categoryType = checker.getTypeOfSymbol(categorySymbol);
49
-
50
- // 处理器列表
51
- const handlerSymbols = categoryType.getProperties();
52
-
53
- // 分类源文件
54
- const categorySourceFile = handlerSymbols[0].getDeclarations()[0].getSourceFile();
55
-
56
- // 分类源文件路径
57
- const categorySourceFilePath = categorySourceFile.fileName;
58
-
59
- // 忽略仅开发时生效的路由
60
- if (/@dev[/.]/.test(categorySourceFilePath)) continue;
61
-
62
- // 支持 include, exclude
63
- if (this.options.include?.length) {
64
- if (this.options.include.every(item => !categorySourceFilePath.includes(item))) continue;
65
- }
66
- if (this.options.exclude?.length) {
67
- if (this.options.exclude.some(item => categorySourceFilePath.includes(item))) continue;
68
- }
69
-
70
- // 分类 URL
71
- const categoryUrlMatch = categorySourceFilePath.match(this.categoryUrlRe);
72
- let categoryUrl = categoryUrlMatch[1] ?? categoryUrlMatch[2] ?? '';
73
- categoryUrl = categoryUrl === '' ? '/' : `/${categoryUrl}/`;
74
- for (const handlerSymbol of handlerSymbols) {
75
- // 处理器路径
76
- let handlerPath = [handlerSymbol.getName()];
77
- const handlerNode = handlerSymbol.getDeclarations()[0];
78
-
79
- // 支持自定义 requestPath
80
- if (
81
- // const xx = defineHandler
82
- ts.isVariableDeclaration(handlerNode) && handlerNode.initializer &&
83
- // defineHandler()
84
- ts.isCallExpression(handlerNode.initializer) &&
85
- // defineHandler({})
86
- ts.isObjectLiteralExpression(handlerNode.initializer.arguments[0])) {
87
- const props = handlerNode.initializer.arguments[0].properties;
88
- const requestPathNode = props.find(item => item.name?.getText() === 'requestPath');
89
- if (requestPathNode &&
90
- // requestPath: ''
91
- ts.isPropertyAssignment(requestPathNode)) {
92
- const customHandlerPath =
93
- // requestPath: 'xx'
94
- ts.isStringLiteral(requestPathNode.initializer) ? requestPathNode.initializer.text :
95
- // requestPath: ['xx']
96
- ts.isArrayLiteralExpression(requestPathNode.initializer) ? requestPathNode.initializer.elements.filter(item => ts.isStringLiteral(item)).map(item => item.text) : '';
97
- if (customHandlerPath.length) {
98
- handlerPath = castArray(customHandlerPath);
99
- }
100
- }
101
- }
102
-
103
- // 处理器 URL
104
- const handlerUrl = handlerPath.map(path => `${categoryUrl}${path}`);
105
-
106
- // 处理器注释
107
- const handlerComment = this.getComment(handlerSymbol);
108
- if (handlerComment.tags.has('private')) {
109
- this.debug('跳过生成接口: %s', `${handlerUrl}`);
110
- continue;
111
- }
112
- this.debug('生成接口: %s ...', handlerUrl);
113
- const handlerType = checker.getTypeAtLocation(handlerNode);
114
- const [requestType, responseType, methodType] = checker.getTypeArguments(handlerType);
115
- const handlerCategory = pascalCase(categoryUrl) || 'Index';
116
- const handlerDescription = handlerComment.description || handlerUrl.join(', ');
117
- const handlerMethod = methodType.value;
118
- const httpMethod = HandlerMethodToHttpMethod[handlerMethod];
119
- const requestData = this.getApiDto({
120
- type: requestType
121
- });
122
- const responseData = this.getApiDto({
123
- type: responseType
124
- });
125
- const requestDataJsonSchema = this.apiDataToJsonSchema(requestData);
126
- const responseDataJsonSchema = this.apiDataToJsonSchema(responseData);
127
- const handlerDescriptionDividerIndex = handlerDescription.indexOf('\n\n');
128
- const apiName = handlerDescriptionDividerIndex === -1 ? handlerDescription : handlerDescription.substring(0, handlerDescriptionDividerIndex);
129
- const apiDesc = handlerDescriptionDividerIndex === -1 ? '' : handlerDescription.substring(handlerDescriptionDividerIndex + 2);
130
- apiData.push({
131
- category: handlerCategory,
132
- name: apiName,
133
- desc: apiDesc,
134
- path: handlerUrl,
135
- handlerMethod: handlerMethod,
136
- method: httpMethod,
137
- requestData: requestData,
138
- responseData: responseData,
139
- requestDataJsonSchema: requestDataJsonSchema,
140
- responseDataJsonSchema: responseDataJsonSchema
141
- });
142
- }
143
- }
144
- this.debug('写入文件...');
145
- const prefix = this.options.name ? `${this.options.name}_` : '';
146
- await Promise.all([fs.outputJSON(path.join(this.cwd, `temp/${prefix}api.json`), apiData, {
147
- spaces: 2
148
- }), fs.outputJSON(path.join(this.cwd, `temp/${prefix}yapi.json`), this.apiDataToYApiData(apiData), {
149
- spaces: 2
150
- }), fs.outputJSON(path.join(this.cwd, `temp/${prefix}openapi31.json`), this.apiDataToOpenAPI31Data(apiData), {
151
- spaces: 2
152
- })]);
153
- }
154
-
155
- // ref: https://github.com/styleguidist/react-docgen-typescript/blob/master/src/parser.ts#L777
156
- getComment(symbol) {
157
- if (!symbol) {
158
- return {
159
- existing: false,
160
- description: '',
161
- tags: new Map()
162
- };
163
- }
164
- const description = ts.displayPartsToString(symbol.getDocumentationComment(this.checker)).trim();
165
- const tags = symbol.getJsDocTags().map(item => {
166
- return {
167
- label: item.name,
168
- value: ts.displayPartsToString(item.text).trim()
169
- };
170
- });
171
- return {
172
- existing: !!description,
173
- description: description,
174
- tags: tags.reduce((res, item) => {
175
- res.set(item.label, item.value);
176
- return res;
177
- }, new Map())
178
- };
179
- }
180
- getApiDto({
181
- type,
182
- keySymbol = type.symbol || type.aliasSymbol
183
- }) {
184
- const hasTypeFlag = (flag, _type = type) => (_type.flags & flag) === flag;
185
- let valueSymbol = type.symbol || type.aliasSymbol;
186
- const keySymbolName = keySymbol?.getName() || '';
187
- let valueSymbolName = valueSymbol?.getName() || '';
188
- const comment = this.getComment(keySymbol);
189
- let isRequired = keySymbol ? !(keySymbol.getFlags() & ts.SymbolFlags.Optional) : false;
190
- const apiName = keySymbolName || '__type';
191
-
192
- // Decimal, Prisma 生成的
193
- if (valueSymbolName === 'Decimal') {
194
- return {
195
- name: apiName,
196
- desc: comment.description,
197
- required: isRequired,
198
- type: 'number',
199
- enum: [],
200
- children: []
201
- };
202
- }
203
-
204
- // WS
205
- if (valueSymbolName === 'SocketStream') {
206
- return {
207
- name: 'ws',
208
- desc: comment.description,
209
- required: isRequired,
210
- type: 'object',
211
- enum: [],
212
- children: []
213
- };
214
- }
215
-
216
- // 文件
217
- if (valueSymbolName === 'MultipartFile') {
218
- return {
219
- name: 'file',
220
- desc: comment.description,
221
- required: isRequired,
222
- type: 'file',
223
- enum: [],
224
- children: []
225
- };
226
- }
227
-
228
- // Buffer
229
- if (valueSymbolName === 'Buffer') {
230
- return {
231
- name: 'buffer',
232
- desc: comment.description,
233
- required: isRequired,
234
- type: 'object',
235
- enum: [],
236
- children: []
237
- };
238
- }
239
-
240
- // 联合类型
241
- // 布尔、枚举也会用这表示
242
- const rawUnionTypes = type.isUnion() && type.types || [];
243
- const unionTypes = rawUnionTypes.filter(item => !hasTypeFlag(ts.TypeFlags.Null, item) && !hasTypeFlag(ts.TypeFlags.Undefined, item));
244
- const isUnion = !!unionTypes.length;
245
- if (isUnion) {
246
- if (unionTypes.length !== rawUnionTypes.length) {
247
- isRequired = false;
248
- }
249
- type = unionTypes[0];
250
- valueSymbol = type.symbol || type.aliasSymbol;
251
- valueSymbolName = this.checker.getBaseTypeOfLiteralType(type).getSymbol()?.getName() || '';
252
- }
253
- const isIntersection = type.isIntersection();
254
- const intersectionTypes = isIntersection && type.types || [];
255
- const isDate = valueSymbolName === 'Date';
256
- const isRegExp = valueSymbolName === 'RegExp';
257
- const isBigIntLiteral = hasTypeFlag(ts.TypeFlags.BigIntLiteral);
258
- const isBigInt = hasTypeFlag(ts.TypeFlags.BigInt) || isBigIntLiteral;
259
- const isArray = valueSymbolName === 'Array' || valueSymbolName === 'ReadonlyArray';
260
- const isStringLiteral = hasTypeFlag(ts.TypeFlags.StringLiteral);
261
- const isString = hasTypeFlag(ts.TypeFlags.String) || isStringLiteral ||
262
- // BigInt 类型视为字符串
263
- isBigInt ||
264
- // Date 类型视为字符串
265
- isDate ||
266
- // RegExp 类型视为字符串
267
- isRegExp;
268
- const isNumberLiteral = hasTypeFlag(ts.TypeFlags.NumberLiteral);
269
- const isNumber = hasTypeFlag(ts.TypeFlags.Number) || isNumberLiteral;
270
- const isBoolean = hasTypeFlag(ts.TypeFlags.Boolean) || hasTypeFlag(ts.TypeFlags.BooleanLiteral);
271
- const isLiteral = isStringLiteral || isNumberLiteral || isBigIntLiteral;
272
- const isObject = !isArray && !isString && !isNumber && !isBoolean && hasTypeFlag(ts.TypeFlags.Object) ||
273
- // 交集类型视为对象
274
- isIntersection;
275
- const apiDesc = keySymbol && this.getComment(keySymbol).description || '';
276
- const apiEnum = (isUnion ? unionTypes.map(item => item.value) : isLiteral ? [type.value] : []).filter(v => v != null);
277
- const apiType = isArray ? 'array' : isString ? 'string' : isNumber ? 'number' : isBoolean ? 'boolean' : 'object';
278
- const apiRequired = isRequired;
279
- const apiChildren = isArray ? [this.getApiDto({
280
- type: this.checker.getTypeArguments(type)[0]
281
- })] : isObject ? ii(() => {
282
- const childSymbols = this.checker.getAllPossiblePropertiesOfTypes(intersectionTypes.length ? intersectionTypes : [type]);
283
- return childSymbols.map(childSymbol => {
284
- const childType = this.checker.getTypeOfSymbol(childSymbol);
285
- return this.getApiDto({
286
- type: childType,
287
- keySymbol: childSymbol
288
- });
289
- });
290
- }) : [];
291
- return {
292
- name: apiName,
293
- desc: apiDesc,
294
- enum: apiEnum,
295
- type: apiType,
296
- required: apiRequired,
297
- children: apiChildren
298
- };
299
- }
300
- apiDataToJsonSchema(apiData, jsonSchema = {}) {
301
- jsonSchema.description = apiData.desc;
302
- if (apiData.type === 'object') {
303
- jsonSchema.type = 'object';
304
- jsonSchema.properties = apiData.children.reduce((res, item) => {
305
- res[item.name] = this.apiDataToJsonSchema(item);
306
- return res;
307
- }, {});
308
- jsonSchema.required = apiData.children.filter(item => item.required).map(item => item.name);
309
- } else if (apiData.type === 'array') {
310
- jsonSchema.type = 'array';
311
- jsonSchema.items = apiData.children.map(item => this.apiDataToJsonSchema(item))[0];
312
- } else {
313
- jsonSchema.type = apiData.type;
314
- if (apiData.enum.length) {
315
- jsonSchema.enum = apiData.enum;
316
- }
317
- }
318
- return jsonSchema;
319
- }
320
- apiDataToYApiData(handles) {
321
- const data = {};
322
- for (const handle of handles) {
323
- for (const path of handle.path) {
324
- data[handle.category] = data[handle.category] || [];
325
- data[handle.category].push(handle.handlerMethod === 'GET' ? {
326
- method: handle.method.toUpperCase(),
327
- title: handle.name,
328
- markdown: handle.desc,
329
- path: path,
330
- res_body_type: 'json',
331
- req_body_is_json_schema: false,
332
- res_body_is_json_schema: true,
333
- req_params: [],
334
- req_query: handle.requestData.children.map(item => ({
335
- required: item.required ? 1 : 0,
336
- name: item.name,
337
- desc: item.desc,
338
- type: 'string'
339
- })),
340
- req_headers: [],
341
- req_body_form: [],
342
- res_body: JSON.stringify(handle.responseDataJsonSchema)
343
- } : handle.handlerMethod === 'FILE' ? {
344
- method: handle.method.toUpperCase(),
345
- title: handle.name,
346
- markdown: handle.desc,
347
- path: path,
348
- req_body_type: 'form',
349
- res_body_type: 'json',
350
- req_body_is_json_schema: false,
351
- res_body_is_json_schema: true,
352
- req_params: [],
353
- req_query: [],
354
- req_headers: [],
355
- req_body_form: handle.requestData.children.map(item => ({
356
- required: item.required ? 1 : 0,
357
- name: item.name,
358
- desc: item.desc,
359
- type: item.type === 'file' ? 'file' : 'text'
360
- })),
361
- res_body: JSON.stringify(handle.responseDataJsonSchema)
362
- } : {
363
- method: handle.method.toUpperCase(),
364
- title: handle.name,
365
- markdown: handle.desc,
366
- path: path,
367
- req_body_type: 'json',
368
- res_body_type: 'json',
369
- req_body_is_json_schema: true,
370
- res_body_is_json_schema: true,
371
- req_params: [],
372
- req_query: [],
373
- req_headers: [],
374
- req_body_form: [],
375
- req_body_other: JSON.stringify(handle.requestDataJsonSchema),
376
- res_body: JSON.stringify(handle.responseDataJsonSchema)
377
- });
378
- }
379
- }
380
- return Object.keys(data).map(cat => ({
381
- name: cat,
382
- desc: cat,
383
- list: data[cat]
384
- }));
385
- }
386
- apiDataToOpenAPI31Data(handles) {
387
- const data = {
388
- openapi: '3.1.0',
389
- info: {
390
- title: `${process.env.APP_NAME}`,
391
- version: '1.0.0'
392
- },
393
- paths: {},
394
- servers: [{
395
- url: `${process.env.APP_URL}`.replace(/\/+$/, ''),
396
- description: '生产'
397
- }, {
398
- url: `http://127.0.0.1:${process.env.APP_PORT}`,
399
- description: '本地'
400
- }]
401
- };
402
- for (const handle of handles) {
403
- for (const path of handle.path) {
404
- data.paths[path] = {
405
- [handle.method.toLowerCase()]: {
406
- tags: [handle.category],
407
- summary: handle.name,
408
- description: handle.desc,
409
- requestBody: {
410
- content: {
411
- 'application/json': {
412
- schema: handle.requestDataJsonSchema
413
- }
414
- }
415
- },
416
- responses: {
417
- '200': {
418
- description: 'success',
419
- content: {
420
- 'application/json': {
421
- schema: handle.responseDataJsonSchema
422
- }
423
- }
424
- }
425
- }
426
- }
427
- };
428
- }
429
- }
430
- return data;
431
- }
432
- }
@@ -1,17 +0,0 @@
1
- export interface BuildOptions {
2
- appId: string;
3
- cwd: string;
4
- external?: string[];
5
- inlineEnvs?: Record<string, any>;
6
- minify?: boolean;
7
- noInstall?: boolean;
8
- channel?: string;
9
- excludeFiles?: string[];
10
- noEmptyDistDir?: boolean;
11
- pm2MaxMemoryRestart?: string;
12
- pm2CronRestart?: string;
13
- pm2NodeArgs?: string | string[];
14
- }
15
- export declare class BuildUtil {
16
- static build(options: BuildOptions): Promise<void>;
17
- }