create-dp-koa 1.1.2 → 1.1.3

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 (84) hide show
  1. package/package.json +1 -1
  2. package/template/scripts/sync-template.mjs +20 -0
  3. package/template/src/app.ts +1 -2
  4. package/template/src/{framework/plugins → plugins}/registry.ts +2 -2
  5. package/template/src/plugins/weboffice/http/routes.ts +1 -1
  6. package/template/src/plugins/weboffice/index.ts +3 -3
  7. package/template/src/plugins/weboffice/services/webofficeCallback.service.ts +3 -4
  8. package/template/src/utils/testDataInitializer.ts +1 -1
  9. package/template/tsconfig.json +6 -0
  10. package/template/src/annotations/decorators/ConfigManagement.ts +0 -9
  11. package/template/src/annotations/decorators/DistributedTracing.ts +0 -9
  12. package/template/src/annotations/decorators/EnterprisePerformance.ts +0 -9
  13. package/template/src/annotations/decorators/PerformanceMonitor.ts +0 -32
  14. package/template/src/annotations/decorators/SecurityAudit.ts +0 -9
  15. package/template/src/annotations/index.ts +0 -50
  16. package/template/src/annotations/processors/ConfigManagementProcessor.ts +0 -369
  17. package/template/src/annotations/processors/DistributedTracingProcessor.ts +0 -288
  18. package/template/src/annotations/processors/EnterprisePerformanceProcessor.ts +0 -189
  19. package/template/src/annotations/processors/PerformanceMonitorProcessor.ts +0 -101
  20. package/template/src/annotations/processors/SecurityAuditProcessor.ts +0 -345
  21. package/template/src/annotations/processors/SwaggerProcessor.ts +0 -612
  22. package/template/src/annotations/processors/index.ts +0 -10
  23. package/template/src/examples/InterceptorExampleRunner.ts +0 -284
  24. package/template/src/examples/ServiceInterceptorExample.ts +0 -214
  25. package/template/src/examples/cacheExamples.ts +0 -155
  26. package/template/src/framework/decorator/controller.ts +0 -311
  27. package/template/src/framework/decorator/processor/AnnotationDecorators.ts +0 -100
  28. package/template/src/framework/decorator/processor/AnnotationProcessor.ts +0 -160
  29. package/template/src/framework/decorator/processor/AnnotationProcessorConfig.ts +0 -45
  30. package/template/src/framework/decorator/processor/AnnotationRegistry.ts +0 -117
  31. package/template/src/framework/decorator/processor/AnnotationSystemInitializer.ts +0 -95
  32. package/template/src/framework/decorator/processor/ProcessorManager.ts +0 -76
  33. package/template/src/framework/decorator/processor/processors/CustomProcessors.ts +0 -126
  34. package/template/src/framework/decorator/processor/processors/DefaultProcessors.ts +0 -207
  35. package/template/src/framework/decorator/refactored/DecoratorFactory.ts +0 -99
  36. package/template/src/framework/decorator/refactored/DecoratorMetadataManager.ts +0 -125
  37. package/template/src/framework/decorator/refactored/DecoratorValidator.ts +0 -128
  38. package/template/src/framework/decorator/refactored/TypeSafeDecorators.ts +0 -139
  39. package/template/src/framework/decorator/refactored/index.ts +0 -98
  40. package/template/src/framework/decorator/swagger.ts +0 -150
  41. package/template/src/framework/interceptors/AdvancedServiceCallInterceptor.ts +0 -375
  42. package/template/src/framework/interceptors/ServiceCallInterceptor.ts +0 -348
  43. package/template/src/framework/interceptors/index.ts +0 -19
  44. package/template/src/framework/plugins/types.ts +0 -15
  45. package/template/src/framework/types/ServiceResult.ts +0 -151
  46. package/template/src/framework/types/index.ts +0 -16
  47. package/template/src/framework/utils/CacheManager.ts +0 -430
  48. package/template/src/framework/utils/CacheService.ts +0 -248
  49. package/template/src/framework/utils/DtoValidator.ts +0 -164
  50. package/template/src/framework/utils/MigrationHelper.ts +0 -179
  51. package/template/src/framework/utils/MigrationManager.ts +0 -256
  52. package/template/src/framework/utils/NewRouter.ts +0 -207
  53. package/template/src/framework/utils/TransactionManager.ts +0 -172
  54. package/template/src/framework/utils/bootstrap.ts +0 -445
  55. package/template/src/framework/utils/cache.ts +0 -269
  56. package/template/src/framework/utils/databaseConfig.ts +0 -148
  57. package/template/src/framework/utils/db.ts +0 -39
  58. package/template/src/framework/utils/dbMonitor.ts +0 -106
  59. package/template/src/framework/utils/function.ts +0 -61
  60. package/template/src/framework/utils/gracefulShutdown.ts +0 -131
  61. package/template/src/framework/utils/logger.ts +0 -388
  62. package/template/src/framework/utils/metrics.ts +0 -182
  63. package/template/src/framework/utils/router.ts +0 -417
  64. package/template/src/framework/utils/swagger.ts +0 -184
  65. package/template/src/framework/utils/testDb.ts +0 -19
  66. package/template/src/framework/utils/token.ts +0 -23
  67. package/template/src/framework/utils/transform.ts +0 -17
  68. package/template/src/libs/aokEmailSender.ts +0 -42
  69. package/template/src/libs/captcha.ts +0 -37
  70. package/template/src/libs/cos.ts +0 -45
  71. package/template/src/libs/mCache.ts +0 -7
  72. package/template/src/libs/serviceValidate.ts +0 -3
  73. package/template/src/libs/tecentSms.ts +0 -51
  74. package/template/src/middlewares/a.middleware.ts +0 -6
  75. package/template/src/middlewares/error.middleware.ts +0 -14
  76. package/template/src/middlewares/logging.middleware.ts +0 -187
  77. package/template/src/middlewares/static.middleware.ts +0 -79
  78. package/template/src/middlewares/swagger.middleware.ts +0 -70
  79. package/template/src/middlewares/token.middleware.ts +0 -32
  80. package/template/src/migrations/1700000000000-InitialDatabaseStructure.ts +0 -172
  81. package/template/src/migrations/index.ts +0 -6
  82. package/template/src/repository/base/BaseRepository.ts +0 -124
  83. package/template/src/repository/interfaces/IBaseRepository.ts +0 -67
  84. package/template/src/service/base.service.ts +0 -116
@@ -1,417 +0,0 @@
1
- import koaRouter from 'koa-router'
2
- import path from "path"
3
- import { IParamTypeEnum } from "@src/framework/decorator/controller"
4
- import { getRandoNumer, isPromise } from "@src/framework/utils/function"
5
- const _router = new koaRouter()
6
- import { Provider } from "dp-ioc2"
7
- import { validate } from "class-validator"
8
- import { Context } from "koa"
9
- import { logger } from '@src/framework/utils/logger'
10
- import { createCache, CacheType } from "@src/framework/utils/cache";
11
-
12
- // 导入新的路由系统
13
- import { callControllerWithProcessors } from '@src/framework/utils/NewRouter';
14
-
15
- // 配置开关:是否使用新的注解处理器系统
16
- // 动态检查环境变量,而不是在模块加载时固定
17
- function isNewAnnotationSystemEnabled(): boolean {
18
- return process.env.USE_NEW_ANNOTATION_SYSTEM === '1';
19
- }
20
-
21
- // 使用统一的缓存管理创建控制器结果缓存
22
- const controllerResultCacheStore = createCache('controller-result', CacheType.CONTROLLER, {
23
- stdTTL: 20, // 20秒过期
24
- maxKeys: 2000 // 控制器缓存可以更多
25
- });
26
-
27
- const responseValidate = async function (controller: any, methods: string, res: any) {
28
- if (controller.$_ResponseValidateIf && controller.$_ResponseValidateIf.get(methods)) {
29
- const { fn, clas } = controller.$_ResponseValidateIf.get(methods);
30
- let _callResult = fn(res);
31
- if (isPromise(_callResult)) {
32
- _callResult = await _callResult;
33
- }
34
- if (_callResult && (_callResult instanceof Object)) {
35
- const _dto = new clas;
36
- let dataObject = _callResult;
37
- // for (let i in dataObject) {
38
- // _dto[i] = dataObject[i]
39
- // }
40
- Object.assign(_dto, dataObject);
41
- return await validate(_dto, {
42
- skipMissingProperties: false,
43
- forbidNonWhitelisted: true,
44
- whitelist: true,
45
- });
46
- // return await validate(_dto);
47
- }
48
- } else if (controller.$_ResponseValidator && controller.$_ResponseValidator.get(methods)) {
49
- const { clas, objectKey } = controller.$_ResponseValidator.get(methods);
50
- if (res instanceof Object) {
51
- const _dto = new clas;
52
- let dataObject = res;
53
- if (objectKey && res[objectKey] && (res[objectKey] instanceof Object)) {
54
- dataObject = res[objectKey];
55
- }
56
- // 严格验证所有字段
57
- Object.assign(_dto, dataObject);
58
- return await validate(_dto, {
59
- skipMissingProperties: false,
60
- forbidNonWhitelisted: true,
61
- whitelist: true,
62
- });
63
- }
64
- }
65
- return []
66
- }
67
-
68
-
69
- async function callController(ctx: Context, controller: any, methods: string) {
70
- if (isNewAnnotationSystemEnabled()) {
71
- // 使用新的注解处理器系统
72
- return await callControllerWithProcessors(ctx, controller, methods);
73
- } else {
74
- // 使用原有的逻辑
75
- return await callControllerLegacy(ctx, controller, methods);
76
- }
77
- }
78
-
79
- async function callControllerLegacy(ctx: Context, controller: any, methods: string) {
80
- const callParam: any[] = [];
81
- if (controller.$_MethdosParamInfo) {
82
- const paramsInfo: undefined | { type: IParamTypeEnum, validate: any }[] = controller.$_MethdosParamInfo.get(methods);
83
- if (paramsInfo && paramsInfo.length > 0) {
84
- // console.log(paramsInfo,"参数信息")
85
- for (let paramInfo of paramsInfo) {
86
-
87
- let data = undefined;
88
- if (paramInfo.type == IParamTypeEnum.Body) {
89
- data = ctx.request.body;
90
- }
91
-
92
- switch (paramInfo.type) {
93
- case IParamTypeEnum.Body:
94
- data = ctx.request.body;
95
- break;
96
- case IParamTypeEnum.Query:
97
- data = ctx.query;
98
- break;
99
- case IParamTypeEnum.Params:
100
- data = ctx.params;
101
- break;
102
- case IParamTypeEnum.Headers:
103
- data = ctx.request.headers;
104
- break;
105
- case IParamTypeEnum.State:
106
- data = ctx.state;
107
- break;
108
- }
109
- //这里可以统一做参数校验(仅当 validate 为 DTO 类构造函数时)
110
- if (paramInfo.validate && typeof paramInfo.validate === 'function') {
111
- const waitToValidateObject = new paramInfo.validate();
112
-
113
- for (let i in data) {
114
- if (waitToValidateObject.$_Transform && waitToValidateObject.$_Transform.get(i)) {
115
- const func = waitToValidateObject.$_Transform.get(i);
116
- const result = func(data[i]);
117
- if (isPromise(result)) {
118
- waitToValidateObject[i] = await result;
119
- } else {
120
- waitToValidateObject[i] = result;
121
- }
122
- } else {
123
- waitToValidateObject[i] = data[i]
124
- }
125
- }
126
-
127
- const validateErrors = await validate(waitToValidateObject);
128
-
129
- if (validateErrors.length > 0) {
130
- ctx.status = 400;
131
- return ctx.body = validateErrors;
132
- }
133
- }
134
- callParam.push(data);
135
- }
136
- }
137
- }
138
- // 调用controller
139
- try {
140
-
141
- let controllerCacheInfo: any = null;
142
- if (controller.$_ControllerCache && controller.$_ControllerCache.get(methods)) {
143
- const { cacheyFn, options } = controller.$_ControllerCache.get(methods);
144
- if (options && (options.enable === undefined || options.enable)) {
145
- const cacheKey = cacheyFn(...callParam);
146
- if (cacheKey) {
147
- const cacheResult = controllerResultCacheStore.get(cacheKey);
148
- if (cacheResult) {
149
- return ctx.body = cacheResult;
150
- }
151
-
152
- controllerCacheInfo = {
153
- cacheyFn, options, cacheKey,
154
- }
155
- }
156
- }
157
-
158
-
159
-
160
-
161
- }
162
-
163
- const callResult = controller[methods].apply(controller, callParam);
164
- if (controller.$_ResponseCode) {
165
- const code = controller.$_ResponseCode.get(methods) ?? 200;
166
- ctx.status = code;
167
- }
168
- if (controller.$_ResponseHeader) {
169
- const responseHeaders = controller.$_ResponseHeader.get(methods);
170
- if (responseHeaders) {
171
- responseHeaders.keys().forEach((key: string) => {
172
- const value = responseHeaders.get(key);
173
- if (value) {
174
- ctx.set(key, value);
175
- }
176
- });
177
- }
178
- }
179
-
180
-
181
-
182
- if (isPromise(callResult)) {
183
- const res = await callResult;
184
- const resValidateResult = await responseValidate(controller, methods, res);
185
- if (resValidateResult.length > 0) {
186
- ctx.status = 400;
187
- logger.error(resValidateResult.join(', '))
188
- return ctx.body = `接口${methods}返回数据参数校验异常`;
189
- }
190
- ctx.body = res;
191
- } else {
192
- const resValidateResult = await responseValidate(controller, methods, callResult);
193
- if (resValidateResult.length > 0) {
194
- ctx.status = 400;
195
- return ctx.body = resValidateResult;
196
- }
197
- ctx.body = callResult;
198
- }
199
-
200
- // 可以在这里 加入 控制器方法缓存的数据
201
- if (controllerCacheInfo) {
202
- // 创建缓存
203
- const { options, cacheKey, } = controllerCacheInfo;
204
- if (options && (options.enable === undefined || options.enable)) {
205
- let ttl = 20;
206
- if (options && options.ttl) {
207
- if (options.ttl instanceof Object) {
208
- ttl = getRandoNumer(options.ttl.min, options.ttl.max)
209
- }
210
- }
211
- controllerResultCacheStore.set(cacheKey, ctx.body, ttl)
212
- }
213
-
214
- }
215
-
216
- } catch (err) {
217
- throw err;
218
- // 这里要抛出异常,并且以更详细的信息抛出来
219
- }
220
- }
221
- /**
222
- * 绑定路由
223
- * @param path 路由路径
224
- * @param controller 控制器
225
- */
226
- export const bindRouter = (...args: any[]) => {
227
- if (args.length < 2) {
228
- throw new Error("路由绑定至少2个参数");
229
- }
230
- const _path: string = args[0];
231
- const Controller: any = args[args.length - 1];
232
-
233
- const middlewares: any = [];
234
- //表示有中间件
235
- if (args.length > 2) {
236
- for (let i in args) {
237
- let index = Number(i);
238
- if (index != 0 && index != args.length - 1) {
239
- middlewares.push(args[i]);
240
- }
241
- }
242
- }
243
-
244
- const controller = Provider<any>(Controller);
245
- // 绑定post方法
246
- if (controller.$_PostMethods) {
247
- const postMethods: Array<{ methodName: string, url: string }> = Array.from(controller.$_PostMethods);
248
- postMethods.forEach(_methods => {
249
- const { methodName, url } = _methods;
250
- const methods = methodName;
251
- if (controller[methods]) {
252
- const _url = path.join(_path, url).replace(/\\/g, "/");
253
-
254
- const cb = async (ctx: any) => {
255
- // 读取该方法的参数注解信息
256
- await callController(ctx, controller, methods);
257
- }
258
- if (middlewares.length > 0) {
259
- for (const middleware of middlewares) {
260
- _router.use(_url, middleware);
261
- }
262
- }
263
- _router.post(_url, cb)
264
-
265
- // 如果URL以斜杠结尾,同时注册无斜杠版本
266
- if (_url.endsWith('/') && _url !== '/') {
267
- const urlWithoutSlash = _url.slice(0, -1);
268
- if (middlewares.length > 0) {
269
- for (const middleware of middlewares) {
270
- _router.use(urlWithoutSlash, middleware);
271
- }
272
- }
273
- _router.post(urlWithoutSlash, cb)
274
- }
275
- }
276
- })
277
- }
278
-
279
- // 绑定 get方法
280
- if (controller.$_GetMethods) {
281
- const postMethods: Array<{ methodName: string, url: string }> = Array.from(controller.$_GetMethods);
282
- postMethods.forEach(_methods => {
283
- const { methodName, url } = _methods;
284
- const methods = methodName;
285
- if (controller[methods]) {
286
- const _url = path.join(_path, url).replace(/\\/g, "/");
287
- const cb = async (ctx: any) => {
288
- // 读取该方法的参数注解信息
289
- await callController(ctx, controller, methods);
290
- }
291
- if (middlewares.length > 0) {
292
- for (const middleware of middlewares) {
293
- _router.use(_url, middleware);
294
- }
295
- }
296
- _router.get(_url, cb)
297
-
298
- // 如果URL以斜杠结尾,同时注册无斜杠版本
299
- if (_url.endsWith('/') && _url !== '/') {
300
- const urlWithoutSlash = _url.slice(0, -1);
301
- if (middlewares.length > 0) {
302
- for (const middleware of middlewares) {
303
- _router.use(urlWithoutSlash, middleware);
304
- }
305
- }
306
- _router.get(urlWithoutSlash, cb)
307
- }
308
-
309
- }
310
- })
311
- }
312
-
313
- // 绑定 put 方法
314
- if (controller.$_PutMethods) {
315
- const postMethods: Array<{ methodName: string, url: string }> = Array.from(controller.$_PutMethods);
316
- postMethods.forEach(_methods => {
317
- const { methodName, url } = _methods;
318
- const methods = methodName;
319
- if (controller[methods]) {
320
- const _url = path.join(_path, url).replace(/\\/g, "/");
321
-
322
- const cb = async (ctx: any) => {
323
- // 读取该方法的参数注解信息
324
- await callController(ctx, controller, methods);
325
- }
326
- if (middlewares.length > 0) {
327
- for (const middleware of middlewares) {
328
- _router.use(_url, middleware);
329
- }
330
- }
331
- _router.put(_url, cb)
332
-
333
- // 如果URL以斜杠结尾,同时注册无斜杠版本
334
- if (_url.endsWith('/') && _url !== '/') {
335
- const urlWithoutSlash = _url.slice(0, -1);
336
- if (middlewares.length > 0) {
337
- for (const middleware of middlewares) {
338
- _router.use(urlWithoutSlash, middleware);
339
- }
340
- }
341
- _router.put(urlWithoutSlash, cb)
342
- }
343
- }
344
- })
345
- }
346
-
347
- // 绑定 del 方法
348
- if (controller.$_DelMethods) {
349
- const postMethods: Array<{ methodName: string, url: string }> = Array.from(controller.$_DelMethods);
350
- postMethods.forEach(_methods => {
351
- const { methodName, url } = _methods;
352
- const methods = methodName;
353
- if (controller[methods]) {
354
- const _url = path.join(_path, url).replace(/\\/g, "/");
355
- const cb = async (ctx: any) => {
356
- // 读取该方法的参数注解信息
357
- await callController(ctx, controller, methods);
358
- }
359
- if (middlewares.length > 0) {
360
- for (const middleware of middlewares) {
361
- _router.use(_url, middleware);
362
- }
363
- }
364
- _router.del(_url, cb)
365
-
366
- // 如果URL以斜杠结尾,同时注册无斜杠版本
367
- if (_url.endsWith('/') && _url !== '/') {
368
- const urlWithoutSlash = _url.slice(0, -1);
369
- if (middlewares.length > 0) {
370
- for (const middleware of middlewares) {
371
- _router.use(urlWithoutSlash, middleware);
372
- }
373
- }
374
- _router.del(urlWithoutSlash, cb)
375
- }
376
- }
377
- })
378
- }
379
-
380
-
381
- // 绑定 all 方法
382
- if (controller.$_AllMethods) {
383
- const postMethods: Array<{ methodName: string, url: string }> = Array.from(controller.$_AllMethods);
384
- postMethods.forEach(_methods => {
385
- const { methodName, url } = _methods;
386
- const methods = methodName;
387
- if (controller[methods]) {
388
- const _url = path.join(_path, url).replace(/\\/g, "/");
389
- const cb = async (ctx: any) => {
390
- // 读取该方法的参数注解信息
391
- await callController(ctx, controller, methods);
392
- }
393
- if (middlewares.length > 0) {
394
- for (const middleware of middlewares) {
395
- _router.use(_url, middleware);
396
- }
397
- }
398
- _router.all(_url, cb)
399
-
400
- // 如果URL以斜杠结尾,同时注册无斜杠版本
401
- if (_url.endsWith('/') && _url !== '/') {
402
- const urlWithoutSlash = _url.slice(0, -1);
403
- if (middlewares.length > 0) {
404
- for (const middleware of middlewares) {
405
- _router.use(urlWithoutSlash, middleware);
406
- }
407
- }
408
- _router.all(urlWithoutSlash, cb)
409
- }
410
- }
411
- })
412
- }
413
-
414
- }
415
-
416
- // 导出路由对象
417
- export const router = _router;
@@ -1,184 +0,0 @@
1
- import swaggerJsdoc from 'swagger-jsdoc';
2
- import { logger } from './logger';
3
-
4
- /**
5
- * Swagger配置
6
- */
7
- const swaggerOptions: swaggerJsdoc.Options = {
8
- definition: {
9
- openapi: '3.0.0',
10
- info: {
11
- title: 'DP Koa Framework API',
12
- version: '1.0.0',
13
- description: '基于Koa的企业级框架API文档',
14
- contact: {
15
- name: 'API Support',
16
- email: 'support@example.com',
17
- },
18
- license: {
19
- name: 'MIT',
20
- url: 'https://opensource.org/licenses/MIT',
21
- },
22
- },
23
- servers: [
24
- {
25
- url: process.env.API_BASE_URL || 'http://localhost:3000',
26
- description: '开发环境',
27
- },
28
- ],
29
- components: {
30
- securitySchemes: {
31
- bearerAuth: {
32
- type: 'http',
33
- scheme: 'bearer',
34
- bearerFormat: 'JWT',
35
- description: 'JWT授权',
36
- },
37
- },
38
- },
39
- tags: [
40
- {
41
- name: '示例',
42
- description: '示例API接口',
43
- },
44
- {
45
- name: '用户',
46
- description: '用户相关接口',
47
- },
48
- {
49
- name: '健康检查',
50
- description: '系统健康检查接口',
51
- },
52
- ],
53
- },
54
- apis: [
55
- './src/controllers/**/*.ts',
56
- './src/dto/**/*.ts',
57
- ],
58
- };
59
-
60
- /**
61
- * 生成Swagger规范
62
- */
63
- export function getSwaggerSpec(): any {
64
- const spec = swaggerJsdoc(swaggerOptions);
65
- return spec;
66
- }
67
-
68
- /**
69
- * 从Controller中提取Swagger信息
70
- */
71
- export function extractSwaggerFromController(controller: any, methodName: string, routePath: string, httpMethod: string) {
72
- try {
73
- // 获取方法的Swagger元数据
74
- const metadata: any = {
75
- operationId: `${methodName}`,
76
- tags: [],
77
- summary: '',
78
- description: '',
79
- parameters: [],
80
- requestBody: null,
81
- responses: {},
82
- };
83
-
84
- // 获取类级别的标签
85
- if (controller.constructor.$_SwaggerTags) {
86
- metadata.tags = controller.constructor.$_SwaggerTags;
87
- }
88
-
89
- // 获取方法级别的元数据
90
- if (controller.$_SwaggerMethods && controller.$_SwaggerMethods.has(methodName)) {
91
- const methodMeta = controller.$_SwaggerMethods.get(methodName);
92
- metadata.summary = methodMeta.summary || methodName;
93
- metadata.description = methodMeta.description || '';
94
- metadata.operationId = methodMeta.operationId || methodName;
95
- if (methodMeta.tags && methodMeta.tags.length > 0) {
96
- metadata.tags = methodMeta.tags;
97
- }
98
- }
99
-
100
- // 获取参数信息
101
- if (controller.$_SwaggerParams && controller.$_SwaggerParams.has(methodName)) {
102
- const params = controller.$_SwaggerParams.get(methodName);
103
- metadata.parameters = params.map((param: any) => ({
104
- name: param.name,
105
- in: param.in,
106
- description: param.description,
107
- required: param.required || false,
108
- schema: param.schema || { type: 'string' },
109
- example: param.example,
110
- }));
111
- }
112
-
113
- // 获取请求体信息
114
- if (controller.$_SwaggerBodies && controller.$_SwaggerBodies.has(methodName)) {
115
- const body = controller.$_SwaggerBodies.get(methodName);
116
- metadata.requestBody = {
117
- description: body.description || '',
118
- required: body.required || false,
119
- content: {
120
- 'application/json': {
121
- schema: body.schema,
122
- examples: body.examples,
123
- },
124
- },
125
- };
126
- }
127
-
128
- // 获取响应信息
129
- if (controller.$_SwaggerResponses && controller.$_SwaggerResponses.has(methodName)) {
130
- const responses = controller.$_SwaggerResponses.get(methodName);
131
- responses.forEach((response: any) => {
132
- metadata.responses[response.status] = {
133
- description: response.description,
134
- content: response.schema ? {
135
- 'application/json': {
136
- schema: response.schema,
137
- examples: response.examples,
138
- },
139
- } : undefined,
140
- };
141
- });
142
- } else {
143
- // 默认成功响应
144
- metadata.responses['200'] = {
145
- description: '成功响应',
146
- content: {
147
- 'application/json': {
148
- schema: {
149
- type: 'object',
150
- properties: {
151
- code: { type: 'number' },
152
- data: { type: 'object' },
153
- message: { type: 'string' },
154
- },
155
- },
156
- },
157
- },
158
- };
159
- }
160
-
161
- return metadata;
162
- } catch (error) {
163
- logger.error('提取Swagger信息失败:', error as Error);
164
- return null;
165
- }
166
- }
167
-
168
- /**
169
- * 根据路径参数生成Swagger路径定义
170
- */
171
- export function generateSwaggerPath(path: string, httpMethod: string, swaggerData: any): string {
172
- // 将路径参数转换为Swagger格式
173
- let swaggerPath = path;
174
- const params = swaggerData?.parameters || [];
175
-
176
- params.forEach((param: any) => {
177
- if (param.in === 'path') {
178
- swaggerPath = swaggerPath.replace(`/${param.name}`, `/{${param.name}}`);
179
- }
180
- });
181
-
182
- return swaggerPath;
183
- }
184
-
@@ -1,19 +0,0 @@
1
- import { DataSource } from "typeorm"
2
- import "reflect-metadata"
3
-
4
- export const createTestDataSource = async (entities: any[]) => {
5
- return new DataSource({
6
- type: "sqlite",
7
- database: ":memory:",
8
- dropSchema: true,
9
- synchronize: true,
10
- logging: false,
11
- entities: entities
12
- }).initialize()
13
- }
14
-
15
- export const closeTestDataSource = async (dataSource: DataSource) => {
16
- if (dataSource.isInitialized) {
17
- await dataSource.destroy()
18
- }
19
- }
@@ -1,23 +0,0 @@
1
- import { Context } from "koa";
2
-
3
- export function getTokenFromHeader(ctx: Context): string | null {
4
- // 1. 从Authorization头获取token
5
- const authHeader = ctx.headers.authorization || ctx.headers.Authorization;
6
- if (!authHeader) {
7
- return null;
8
- }
9
-
10
- // 2. 检查Bearer token格式
11
- if (typeof authHeader === 'string') {
12
- const parts = authHeader.split(' ');
13
- if (parts.length === 2 && parts[0] === 'Bearer') {
14
- return parts[1];
15
- }
16
- }
17
-
18
- return null;
19
- }
20
-
21
- export function setTokenToHeader(ctx: Context, token: string): void {
22
- ctx.set('Authorization', `Bearer ${token}`);
23
- }
@@ -1,17 +0,0 @@
1
- /**
2
- * 转为数字类型
3
- * @param val
4
- * @returns
5
- */
6
- export function ToNumber(val: any) {
7
- return Number(val);
8
- }
9
-
10
- /**
11
- * 去除多余的空格
12
- * @param val
13
- * @returns
14
- */
15
- export function Trim(val: string) {
16
- return String(val).trim();
17
- }
@@ -1,42 +0,0 @@
1
-
2
- type EmailParams = {
3
- to: string;
4
- templateId: string;
5
- templateData?: Record<string, string>;
6
- };
7
-
8
- export class AokEmailSender{
9
- private apiKey: string;
10
- private apiUrl: string;
11
-
12
- constructor(apiKey: string, apiUrl = 'https://www.aoksend.com/index/api/send_email') {
13
- this.apiKey = apiKey;
14
- this.apiUrl = apiUrl;
15
- }
16
-
17
- async sendEmail(params: EmailParams): Promise<any> {
18
- try {
19
- const formData = new URLSearchParams();
20
- formData.append('app_key', this.apiKey);
21
- formData.append('to', params.to);
22
- formData.append('template_id', params.templateId || '');
23
- formData.append('data', JSON.stringify(params.templateData || {}));
24
-
25
- const response = await fetch(this.apiUrl, {
26
- method: 'POST',
27
- headers: {
28
- 'Content-Type': 'application/x-www-form-urlencoded'
29
- },
30
- body: formData.toString()
31
- });
32
- ``
33
- if (!response.ok) {
34
- const errorData = await response.json();
35
- throw new Error(errorData.message || 'Failed to send email');
36
- }
37
- return await response.json();
38
- } catch (error) {
39
- throw new Error(error instanceof Error ? error.message : 'Failed to send email');
40
- }
41
- }
42
- }