imean-service-engine 2.0.0 → 2.0.2

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 (72) hide show
  1. package/dist/index.d.mts +77 -52
  2. package/dist/index.d.ts +77 -52
  3. package/dist/index.js +2078 -1945
  4. package/dist/index.mjs +2076 -1944
  5. package/package.json +9 -2
  6. package/.vscode/settings.json +0 -8
  7. package/src/core/checker.ts +0 -33
  8. package/src/core/decorators.test.ts +0 -96
  9. package/src/core/decorators.ts +0 -68
  10. package/src/core/engine.test.ts +0 -218
  11. package/src/core/engine.ts +0 -635
  12. package/src/core/errors.ts +0 -28
  13. package/src/core/factory.test.ts +0 -73
  14. package/src/core/factory.ts +0 -92
  15. package/src/core/logger.ts +0 -65
  16. package/src/core/testing.ts +0 -73
  17. package/src/core/types.ts +0 -191
  18. package/src/index.ts +0 -49
  19. package/src/metadata/README.md +0 -422
  20. package/src/metadata/metadata.test.ts +0 -369
  21. package/src/metadata/metadata.ts +0 -512
  22. package/src/plugins/action/action-plugin.test.ts +0 -660
  23. package/src/plugins/action/decorator.ts +0 -14
  24. package/src/plugins/action/index.ts +0 -4
  25. package/src/plugins/action/plugin.ts +0 -349
  26. package/src/plugins/action/types.ts +0 -49
  27. package/src/plugins/action/utils.test.ts +0 -196
  28. package/src/plugins/action/utils.ts +0 -111
  29. package/src/plugins/cache/adapter.test.ts +0 -689
  30. package/src/plugins/cache/adapter.ts +0 -324
  31. package/src/plugins/cache/cache-plugin.test.ts +0 -269
  32. package/src/plugins/cache/decorator.ts +0 -26
  33. package/src/plugins/cache/index.ts +0 -20
  34. package/src/plugins/cache/plugin.ts +0 -299
  35. package/src/plugins/cache/types.ts +0 -69
  36. package/src/plugins/client-code/client-code-plugin.test.ts +0 -511
  37. package/src/plugins/client-code/format.ts +0 -9
  38. package/src/plugins/client-code/generator.test.ts +0 -52
  39. package/src/plugins/client-code/generator.ts +0 -263
  40. package/src/plugins/client-code/index.ts +0 -15
  41. package/src/plugins/client-code/plugin.ts +0 -158
  42. package/src/plugins/client-code/types.ts +0 -52
  43. package/src/plugins/client-code/utils.ts +0 -164
  44. package/src/plugins/graceful-shutdown/graceful-shutdown-plugin.test.ts +0 -401
  45. package/src/plugins/graceful-shutdown/index.ts +0 -3
  46. package/src/plugins/graceful-shutdown/plugin.ts +0 -279
  47. package/src/plugins/graceful-shutdown/types.ts +0 -17
  48. package/src/plugins/rate-limit/rate-limit-plugin.example.ts +0 -171
  49. package/src/plugins/route/components/Layout.tsx +0 -42
  50. package/src/plugins/route/components/ServiceStatusPage.tsx +0 -141
  51. package/src/plugins/route/decorator.ts +0 -50
  52. package/src/plugins/route/index.ts +0 -16
  53. package/src/plugins/route/plugin.ts +0 -218
  54. package/src/plugins/route/route-plugin.test.ts +0 -759
  55. package/src/plugins/route/types.ts +0 -72
  56. package/src/plugins/schedule/README.md +0 -309
  57. package/src/plugins/schedule/decorator.ts +0 -25
  58. package/src/plugins/schedule/index.ts +0 -12
  59. package/src/plugins/schedule/mock-etcd.ts +0 -145
  60. package/src/plugins/schedule/plugin.ts +0 -164
  61. package/src/plugins/schedule/schedule-plugin.test.ts +0 -312
  62. package/src/plugins/schedule/scheduler.ts +0 -164
  63. package/src/plugins/schedule/types.ts +0 -94
  64. package/src/plugins/schedule/utils.test.ts +0 -163
  65. package/src/plugins/schedule/utils.ts +0 -41
  66. package/tests/integration/client.test.ts +0 -203
  67. package/tests/integration/dev-service.ts +0 -301
  68. package/tests/integration/generated/client.ts +0 -123
  69. package/tests/integration/start-service.ts +0 -21
  70. package/tsconfig.json +0 -27
  71. package/tsup.config.ts +0 -16
  72. package/vitest.config.ts +0 -19
@@ -1,512 +0,0 @@
1
- /**
2
- * 通用元数据管理工具库
3
- *
4
- * 提供类和方法装饰器的元数据收集能力,与业务逻辑解耦
5
- * 类似于 reflect-metadata,但更简单、更轻量
6
- *
7
- * 新设计:支持双向访问
8
- * - key -> classes: 通过装饰器 key 查找所有被装饰的类
9
- * - class -> keys: 通过类查找所有装饰它的 key
10
- * - class + key -> metadata: 通过类和 key 获取元数据
11
- */
12
-
13
- // TypeScript 类型辅助
14
- type Class = new (...args: any[]) => any;
15
-
16
- /**
17
- * 固定的元数据键,用于在类上记录该类被哪些装饰器装饰了
18
- * 这个 key 存储的是 Set<symbol>,包含所有装饰该类的 key
19
- */
20
- const DECORATED_KEYS_KEY = Symbol.for("imean:decoratedKeys");
21
-
22
- /**
23
- * key -> classes 映射
24
- * 记录某个装饰器 key 装饰了哪些类
25
- * 使用 Map 而不是 WeakMap,因为我们需要能够遍历所有被装饰的类
26
- */
27
- const keyToClassesMap = new Map<symbol, Set<Class>>();
28
-
29
- /**
30
- * class -> keys 映射
31
- * 记录某个类被哪些装饰器 key 装饰了
32
- * 使用 WeakMap 存储,key 是类构造函数,value 是 Set<symbol>
33
- * 这个映射实际上存储在 classMetadataStore 中,使用 DECORATED_KEYS_KEY 作为 key
34
- */
35
- // 注意:这个映射通过 classMetadataStore 和 DECORATED_KEYS_KEY 实现,不需要单独的 WeakMap
36
-
37
- /**
38
- * 类级别的元数据存储(用于存储每个类独有的元数据)
39
- * 使用 WeakMap 存储,key 是类构造函数,value 是 Map<symbol, metadata>
40
- *
41
- * 存储结构:
42
- * - key: 类构造函数
43
- * - value: Map<symbol, any>
44
- * - DECORATED_KEYS_KEY -> Set<symbol> (记录该类被哪些 key 装饰)
45
- * - 其他 key -> 实际的元数据
46
- */
47
- export const classMetadataStore = new WeakMap<
48
- Class,
49
- Map<symbol, any>
50
- >();
51
-
52
- /**
53
- * 方法元数据存储(按类和方法名组织)
54
- * 使用 WeakMap 存储,key 是类构造函数,value 是 Map<symbol, MethodMetadata>
55
- */
56
- const methodMetadataStore = new WeakMap<
57
- Class,
58
- Map<symbol, MethodMetadata>
59
- >();
60
-
61
- /**
62
- * 方法元数据项
63
- */
64
- export interface MethodMetadataItem {
65
- type: string;
66
- options?: any;
67
- [key: string]: any;
68
- }
69
-
70
- /**
71
- * 方法元数据存储结构(按方法名组织)
72
- */
73
- export interface MethodMetadata {
74
- [methodName: string]: MethodMetadataItem[];
75
- }
76
-
77
- /**
78
- * 获取或创建类的元数据 Map
79
- *
80
- * @param targetClass 类构造函数
81
- * @returns 类的元数据 Map
82
- */
83
- function getOrCreateClassMetadataMap(targetClass: Class): Map<symbol, any> {
84
- let metadataMap = classMetadataStore.get(targetClass);
85
- if (!metadataMap) {
86
- metadataMap = new Map();
87
- classMetadataStore.set(targetClass, metadataMap);
88
- }
89
- return metadataMap;
90
- }
91
-
92
- /**
93
- * 获取或创建类被装饰的 keys Set
94
- *
95
- * @param targetClass 类构造函数
96
- * @returns 装饰该类的 keys Set
97
- */
98
- function getOrCreateDecoratedKeysSet(targetClass: Class): Set<symbol> {
99
- const metadataMap = getOrCreateClassMetadataMap(targetClass);
100
- let decoratedKeys = metadataMap.get(DECORATED_KEYS_KEY);
101
- if (!decoratedKeys) {
102
- decoratedKeys = new Set<symbol>();
103
- metadataMap.set(DECORATED_KEYS_KEY, decoratedKeys);
104
- }
105
- return decoratedKeys as Set<symbol>;
106
- }
107
-
108
- /**
109
- * 注册装饰器 key 和类的关联关系(双向映射)
110
- *
111
- * @param targetClass 类构造函数
112
- * @param metadataKey 装饰器 key
113
- */
114
- function registerKeyClassRelation(targetClass: Class, metadataKey: symbol): void {
115
- // 1. 在类上记录这个 key
116
- const decoratedKeys = getOrCreateDecoratedKeysSet(targetClass);
117
- decoratedKeys.add(metadataKey);
118
-
119
- // 2. 在 keyToClassesMap 中记录这个类
120
- if (!keyToClassesMap.has(metadataKey)) {
121
- keyToClassesMap.set(metadataKey, new Set());
122
- }
123
- keyToClassesMap.get(metadataKey)!.add(targetClass);
124
- }
125
-
126
- /**
127
- * 创建类装饰器工厂
128
- *
129
- * @param metadataKey 元数据的键(可选,默认使用内置键)
130
- * @returns 类装饰器工厂函数
131
- *
132
- * @example
133
- * ```typescript
134
- * const Module = createClassDecorator();
135
- *
136
- * @Module({ name: "user-module", version: "1.0.0" })
137
- * class UserService {}
138
- * ```
139
- */
140
- export function createClassDecorator(metadataKey: symbol = Symbol.for("imean:classMetadata")) {
141
- return function <T extends Class>(
142
- metadata?: Record<string, any>
143
- ): (target: T, context: ClassDecoratorContext) => void {
144
- return function (target: T, context: ClassDecoratorContext) {
145
- context.addInitializer(function (this: any) {
146
- // 注册双向映射关系
147
- registerKeyClassRelation(target, metadataKey);
148
-
149
- // 获取或创建该类的元数据 Map
150
- const metadataMap = getOrCreateClassMetadataMap(target);
151
-
152
- // 获取现有的元数据
153
- const existingMetadata = metadataMap.get(metadataKey) || {};
154
-
155
- // 合并元数据
156
- const mergedMetadata = {
157
- ...existingMetadata,
158
- ...metadata,
159
- };
160
-
161
- // 存储到类级别的 store
162
- metadataMap.set(metadataKey, mergedMetadata);
163
- });
164
- };
165
- };
166
- }
167
-
168
- /**
169
- * 创建方法装饰器工厂
170
- *
171
- * @param metadataKey 元数据的键(可选,默认使用内置键)
172
- * @returns 方法装饰器工厂函数
173
- *
174
- * @example
175
- * ```typescript
176
- * const Handler = createMethodDecorator();
177
- *
178
- * class UserService {
179
- * @Handler({ type: 'route', options: { method: 'GET' } })
180
- * getUser() {}
181
- * }
182
- * ```
183
- */
184
- export function createMethodDecorator(
185
- metadataKey: symbol = Symbol.for("imean:methodMetadata")
186
- ) {
187
- return function <T = Record<string, any>>(
188
- metadata: T & { type: string }
189
- ): (target: Function, context: ClassMethodDecoratorContext) => void {
190
- return function (target: Function, context: ClassMethodDecoratorContext) {
191
- const methodName = context.name.toString();
192
-
193
- // 定义收集元数据的函数
194
- const collectMetadata = (targetClass: Class) => {
195
- if (!targetClass) return;
196
-
197
- // 注册双向映射关系(方法装饰器也会在类上注册)
198
- registerKeyClassRelation(targetClass, metadataKey);
199
-
200
- // 获取或创建该类的元数据 Map
201
- let metadataMap = methodMetadataStore.get(targetClass);
202
- if (!metadataMap) {
203
- metadataMap = new Map();
204
- methodMetadataStore.set(targetClass, metadataMap);
205
- }
206
-
207
- // 获取现有的元数据存储(按方法名组织)
208
- const existingMetadataMap: MethodMetadata =
209
- metadataMap.get(metadataKey) || {};
210
-
211
- // 获取该方法的现有元数据列表
212
- const existingMetadata: MethodMetadataItem[] =
213
- existingMetadataMap[methodName] || [];
214
-
215
- // 创建新的元数据项
216
- const newMetadata: MethodMetadataItem = {
217
- ...metadata,
218
- type: metadata.type,
219
- };
220
-
221
- // 追加到现有元数据列表(支持多应用)
222
- existingMetadataMap[methodName] = [...existingMetadata, newMetadata];
223
-
224
- // 存储到全局 store
225
- metadataMap.set(metadataKey, existingMetadataMap);
226
- };
227
-
228
- // 尝试获取类构造函数
229
- let targetClass: Class | null = null;
230
- try {
231
- if (target.constructor && typeof target.constructor === "function") {
232
- targetClass = target.constructor as Class;
233
- }
234
- } catch (e) {
235
- // 如果无法访问,将在 addInitializer 中处理
236
- }
237
-
238
- // 如果类可用,立即收集
239
- if (targetClass) {
240
- collectMetadata(targetClass);
241
- }
242
-
243
- // 同时在 addInitializer 中收集(用于实例化时的情况)
244
- context.addInitializer(function (this: any) {
245
- const instanceClass = this.constructor as Class;
246
- if (instanceClass && instanceClass !== targetClass) {
247
- collectMetadata(instanceClass);
248
- }
249
- });
250
- };
251
- };
252
- }
253
-
254
- /**
255
- * 通过装饰器 key 获取所有被装饰的类
256
- *
257
- * @param metadataKey 装饰器 key
258
- * @returns 被该 key 装饰的所有类的 Set
259
- *
260
- * @example
261
- * ```typescript
262
- * const Module = createClassDecorator();
263
- * const key = Symbol.for("imean:classMetadata");
264
- *
265
- * @Module({ name: "module1" })
266
- * class Module1 {}
267
- *
268
- * @Module({ name: "module2" })
269
- * class Module2 {}
270
- *
271
- * const classes = getClassesByKey(key);
272
- * // Set { Module1, Module2 }
273
- * ```
274
- */
275
- export function getClassesByKey(metadataKey: symbol): Set<Class> {
276
- return keyToClassesMap.get(metadataKey) || new Set();
277
- }
278
-
279
- /**
280
- * 获取类被哪些装饰器 key 装饰了
281
- *
282
- * @param target 类或类实例
283
- * @returns 装饰该类的所有 key 的 Set
284
- *
285
- * @example
286
- * ```typescript
287
- * const Module = createClassDecorator();
288
- * const Config = createClassDecorator(Symbol.for("config"));
289
- *
290
- * @Module({ name: "test" })
291
- * @Config({ env: "prod" })
292
- * class TestService {}
293
- *
294
- * const keys = getKeysByClass(TestService);
295
- * // Set { Symbol(imean:classMetadata), Symbol(config) }
296
- * ```
297
- */
298
- export function getKeysByClass(target: any): Set<symbol> {
299
- // 获取类构造函数
300
- let targetClass: Class | null = null;
301
-
302
- if (target && typeof target === "function" && target.prototype) {
303
- // target 是类构造函数
304
- targetClass = target as Class;
305
- } else if (
306
- target &&
307
- target.constructor &&
308
- typeof target.constructor === "function"
309
- ) {
310
- // target 是实例,通过 constructor 获取类
311
- targetClass = target.constructor as Class;
312
- }
313
-
314
- if (!targetClass) {
315
- return new Set();
316
- }
317
-
318
- // 从类级别的 store 获取装饰的 keys
319
- const metadataMap = classMetadataStore.get(targetClass);
320
- if (!metadataMap) {
321
- return new Set();
322
- }
323
-
324
- return (metadataMap.get(DECORATED_KEYS_KEY) as Set<symbol>) || new Set();
325
- }
326
-
327
- /**
328
- * 获取类的元数据
329
- *
330
- * @param target 类或类实例
331
- * @param metadataKey 元数据键(可选)
332
- * @returns 类的元数据对象
333
- */
334
- export function getClassMetadata(
335
- target: any,
336
- metadataKey: symbol = Symbol.for("imean:classMetadata")
337
- ): any {
338
- // 获取类构造函数
339
- let targetClass: Class | null = null;
340
-
341
- if (target && typeof target === "function" && target.prototype) {
342
- // target 是类构造函数
343
- targetClass = target as Class;
344
- } else if (
345
- target &&
346
- target.constructor &&
347
- typeof target.constructor === "function"
348
- ) {
349
- // target 是实例,通过 constructor 获取类
350
- targetClass = target.constructor as Class;
351
- }
352
-
353
- if (!targetClass) {
354
- return {};
355
- }
356
-
357
- // 从类级别的 store 获取元数据
358
- const metadataMap = classMetadataStore.get(targetClass);
359
- if (!metadataMap) {
360
- return {};
361
- }
362
-
363
- return metadataMap.get(metadataKey) || {};
364
- }
365
-
366
- /**
367
- * 获取方法的元数据列表
368
- *
369
- * @param target 类或类实例
370
- * @param methodName 方法名
371
- * @param metadataKey 元数据键(可选)
372
- * @returns 方法的元数据列表
373
- */
374
- export function getMethodMetadata(
375
- target: any,
376
- methodName: string | symbol,
377
- metadataKey: symbol = Symbol.for("imean:methodMetadata")
378
- ): MethodMetadataItem[] {
379
- // 获取类构造函数
380
- let targetClass: Class | null = null;
381
-
382
- if (target && typeof target === "function" && target.prototype) {
383
- // target 是类构造函数
384
- targetClass = target as Class;
385
- } else if (
386
- target &&
387
- target.constructor &&
388
- typeof target.constructor === "function"
389
- ) {
390
- // target 是实例,通过 constructor 获取类
391
- targetClass = target.constructor as Class;
392
- }
393
-
394
- if (!targetClass) {
395
- return [];
396
- }
397
-
398
- // 从全局 store 获取元数据
399
- const metadataMap = methodMetadataStore.get(targetClass);
400
- if (!metadataMap) {
401
- return [];
402
- }
403
-
404
- const methodMetadata: MethodMetadata = metadataMap.get(metadataKey) || {};
405
- return methodMetadata[String(methodName)] || [];
406
- }
407
-
408
- /**
409
- * 获取类的所有方法元数据
410
- *
411
- * @param target 类或类实例
412
- * @param metadataKey 元数据键(可选)
413
- * @returns 所有方法的元数据映射(方法名 -> 元数据列表)
414
- */
415
- export function getAllMethodMetadata(
416
- target: any,
417
- metadataKey: symbol = Symbol.for("imean:methodMetadata")
418
- ): Map<string | symbol, MethodMetadataItem[]> {
419
- const result = new Map<string | symbol, MethodMetadataItem[]>();
420
-
421
- // 获取类构造函数
422
- let targetClass: Class | null = null;
423
-
424
- if (target && typeof target === "function" && target.prototype) {
425
- // target 是类构造函数
426
- targetClass = target as Class;
427
- } else if (
428
- target &&
429
- target.constructor &&
430
- typeof target.constructor === "function"
431
- ) {
432
- // target 是实例,通过 constructor 获取类
433
- targetClass = target.constructor as Class;
434
- }
435
-
436
- if (!targetClass) {
437
- return result;
438
- }
439
-
440
- // 从全局 store 获取元数据
441
- const metadataMap = methodMetadataStore.get(targetClass);
442
- if (!metadataMap) {
443
- return result;
444
- }
445
-
446
- const allMetadata: MethodMetadata = metadataMap.get(metadataKey) || {};
447
-
448
- // 遍历所有方法的元数据
449
- for (const [methodName, metadataList] of Object.entries(allMetadata)) {
450
- if (metadataList.length > 0) {
451
- result.set(methodName, metadataList);
452
- }
453
- }
454
-
455
- return result;
456
- }
457
-
458
- /**
459
- * 检查类是否有指定的元数据键
460
- *
461
- * @param target 类或类实例
462
- * @param metadataKey 元数据键(可选)
463
- * @returns 是否存在元数据
464
- */
465
- export function hasClassMetadata(
466
- target: any,
467
- metadataKey: symbol = Symbol.for("imean:classMetadata")
468
- ): boolean {
469
- // 获取类构造函数
470
- let targetClass: Class | null = null;
471
-
472
- if (target && typeof target === "function" && target.prototype) {
473
- // target 是类构造函数
474
- targetClass = target as Class;
475
- } else if (
476
- target &&
477
- target.constructor &&
478
- typeof target.constructor === "function"
479
- ) {
480
- // target 是实例,通过 constructor 获取类
481
- targetClass = target.constructor as Class;
482
- }
483
-
484
- if (!targetClass) {
485
- return false;
486
- }
487
-
488
- // 从全局 store 检查
489
- const metadataMap = classMetadataStore.get(targetClass);
490
- if (!metadataMap) {
491
- return false;
492
- }
493
-
494
- return metadataMap.has(metadataKey) && metadataMap.get(metadataKey) != null;
495
- }
496
-
497
- /**
498
- * 检查方法是否有元数据
499
- *
500
- * @param target 类或类实例
501
- * @param methodName 方法名
502
- * @param metadataKey 元数据键(可选)
503
- * @returns 是否存在元数据
504
- */
505
- export function hasMethodMetadata(
506
- target: any,
507
- methodName: string | symbol,
508
- metadataKey: symbol = Symbol.for("imean:methodMetadata")
509
- ): boolean {
510
- const metadata = getMethodMetadata(target, methodName, metadataKey);
511
- return metadata.length > 0;
512
- }