fragment-ts 1.0.23 → 1.0.24

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 (49) hide show
  1. package/dist/cli/commands/init.command.js +1 -1
  2. package/dist/core/decorators/application.decorator.d.ts +1 -6
  3. package/dist/core/decorators/application.decorator.d.ts.map +1 -1
  4. package/dist/core/decorators/application.decorator.js +2 -7
  5. package/dist/core/decorators/application.decorator.js.map +1 -1
  6. package/dist/core/decorators/auto-configuration.decorator.d.ts.map +1 -1
  7. package/dist/core/decorators/auto-configuration.decorator.js +5 -4
  8. package/dist/core/decorators/auto-configuration.decorator.js.map +1 -1
  9. package/dist/core/decorators/conditional.decorators.d.ts +0 -4
  10. package/dist/core/decorators/conditional.decorators.d.ts.map +1 -1
  11. package/dist/core/decorators/conditional.decorators.js +0 -32
  12. package/dist/core/decorators/conditional.decorators.js.map +1 -1
  13. package/dist/core/decorators/controller.decorator.d.ts.map +1 -1
  14. package/dist/core/decorators/controller.decorator.js +2 -1
  15. package/dist/core/decorators/controller.decorator.js.map +1 -1
  16. package/dist/core/decorators/http.decorators.d.ts +0 -1
  17. package/dist/core/decorators/http.decorators.d.ts.map +1 -1
  18. package/dist/core/decorators/http.decorators.js +10 -10
  19. package/dist/core/decorators/http.decorators.js.map +1 -1
  20. package/dist/core/decorators/injectable.decorator.d.ts +0 -3
  21. package/dist/core/decorators/injectable.decorator.d.ts.map +1 -1
  22. package/dist/core/decorators/injectable.decorator.js +5 -12
  23. package/dist/core/decorators/injectable.decorator.js.map +1 -1
  24. package/dist/core/decorators/injection.decorators.d.ts +37 -2
  25. package/dist/core/decorators/injection.decorators.d.ts.map +1 -1
  26. package/dist/core/decorators/injection.decorators.js +75 -43
  27. package/dist/core/decorators/injection.decorators.js.map +1 -1
  28. package/dist/core/decorators/repository.decorator.d.ts.map +1 -1
  29. package/dist/core/decorators/repository.decorator.js +5 -4
  30. package/dist/core/decorators/repository.decorator.js.map +1 -1
  31. package/dist/core/decorators/service.decorator.d.ts.map +1 -1
  32. package/dist/core/decorators/service.decorator.js +5 -4
  33. package/dist/core/decorators/service.decorator.js.map +1 -1
  34. package/dist/core/metadata/metadata-storage.d.ts +20 -9
  35. package/dist/core/metadata/metadata-storage.d.ts.map +1 -1
  36. package/dist/core/metadata/metadata-storage.js +10 -58
  37. package/dist/core/metadata/metadata-storage.js.map +1 -1
  38. package/package.json +1 -1
  39. package/src/cli/commands/init.command.ts +1 -1
  40. package/src/core/decorators/application.decorator.ts +3 -13
  41. package/src/core/decorators/auto-configuration.decorator.ts +10 -8
  42. package/src/core/decorators/conditional.decorators.ts +1 -37
  43. package/src/core/decorators/controller.decorator.ts +3 -1
  44. package/src/core/decorators/http.decorators.ts +32 -11
  45. package/src/core/decorators/injectable.decorator.ts +8 -15
  46. package/src/core/decorators/injection.decorators.ts +103 -50
  47. package/src/core/decorators/repository.decorator.ts +10 -8
  48. package/src/core/decorators/service.decorator.ts +10 -8
  49. package/src/core/metadata/metadata-storage.ts +43 -75
@@ -1,7 +1,23 @@
1
- import { ClassMetadata, MethodMetadata, ParamMetadata } from "../types/decoration.types";
2
- /**
3
- * Central storage for all metadata: classes, methods, parameters
4
- */
1
+ export interface ClassMetadata {
2
+ target: any;
3
+ type: "injectable" | "service" | "controller" | "repository" | "auto-configuration";
4
+ scope?: "singleton" | "request" | "transient";
5
+ path?: string;
6
+ }
7
+ export interface MethodMetadata {
8
+ target: any;
9
+ propertyKey: string;
10
+ method: string;
11
+ path: string;
12
+ paramMetadata: ParamMetadata[];
13
+ }
14
+ export interface ParamMetadata {
15
+ target: any;
16
+ propertyKey: string;
17
+ index: number;
18
+ type: "body" | "param" | "query" | "header" | "req" | "res";
19
+ paramName?: string;
20
+ }
5
21
  export declare class MetadataStorage {
6
22
  private static instance;
7
23
  private classes;
@@ -11,15 +27,10 @@ export declare class MetadataStorage {
11
27
  addClass(metadata: ClassMetadata): void;
12
28
  getClass(target: any): ClassMetadata | undefined;
13
29
  getAllClasses(): ClassMetadata[];
14
- hasClass(target: any): boolean;
15
- private getMethodKey;
16
30
  addMethod(metadata: MethodMetadata): void;
17
31
  getMethod(target: any, propertyKey: string): MethodMetadata | undefined;
18
32
  getAllMethods(): MethodMetadata[];
19
- hasMethod(target: any, propertyKey: string): boolean;
20
- private getParamKey;
21
33
  addParam(metadata: ParamMetadata): void;
22
34
  getParams(target: any, propertyKey: string): ParamMetadata[];
23
- hasParam(target: any, propertyKey: string, index?: number): boolean;
24
35
  }
25
36
  //# sourceMappingURL=metadata-storage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"metadata-storage.d.ts","sourceRoot":"","sources":["../../../src/core/metadata/metadata-storage.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,aAAa,EACd,MAAM,2BAA2B,CAAC;AAEnC;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkB;IAGzC,OAAO,CAAC,OAAO,CAA2C;IAC1D,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,MAAM,CAA2C;IAGzD,MAAM,CAAC,WAAW,IAAI,eAAe;IAQrC,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAOvC,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,aAAa,GAAG,SAAS;IAKhD,aAAa,IAAI,aAAa,EAAE;IAIhC,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,OAAO;IAK9B,OAAO,CAAC,YAAY;IAIpB,SAAS,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAiBzC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAMvE,aAAa,IAAI,cAAc,EAAE;IAIjC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO;IAOpD,OAAO,CAAC,WAAW;IAInB,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAmBvC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,EAAE;IAM5D,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO;CAQpE"}
1
+ {"version":3,"file":"metadata-storage.d.ts","sourceRoot":"","sources":["../../../src/core/metadata/metadata-storage.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,GAAG,CAAC;IACZ,IAAI,EACA,YAAY,GACZ,SAAS,GACT,YAAY,GACZ,YAAY,GACZ,oBAAoB,CAAC;IACzB,KAAK,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,WAAW,CAAC;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,GAAG,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,aAAa,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,GAAG,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAkB;IACzC,OAAO,CAAC,OAAO,CAAsC;IACrD,OAAO,CAAC,OAAO,CAA0C;IACzD,OAAO,CAAC,MAAM,CAA2C;IAEzD,MAAM,CAAC,WAAW,IAAI,eAAe;IAOrC,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAIvC,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,aAAa,GAAG,SAAS;IAIhD,aAAa,IAAI,aAAa,EAAE;IAIhC,SAAS,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI;IAYzC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAKvE,aAAa,IAAI,cAAc,EAAE;IAIjC,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI;IAOvC,SAAS,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,EAAE;CAO7D"}
@@ -1,101 +1,53 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MetadataStorage = void 0;
4
- /**
5
- * Central storage for all metadata: classes, methods, parameters
6
- */
7
4
  class MetadataStorage {
8
5
  constructor() {
9
- // Maps for storing metadata
10
6
  this.classes = new Map();
11
7
  this.methods = new Map();
12
8
  this.params = new Map();
13
9
  }
14
- // Singleton instance
15
10
  static getInstance() {
16
11
  if (!MetadataStorage.instance) {
17
12
  MetadataStorage.instance = new MetadataStorage();
18
13
  }
19
14
  return MetadataStorage.instance;
20
15
  }
21
- // ----- Classes -----
22
16
  addClass(metadata) {
23
- if (!metadata?.target)
24
- return;
25
- if (!this.classes.has(metadata.target)) {
26
- this.classes.set(metadata.target, metadata);
27
- }
17
+ this.classes.set(metadata.target, metadata);
28
18
  }
29
19
  getClass(target) {
30
- if (!target)
31
- return undefined;
32
20
  return this.classes.get(target);
33
21
  }
34
22
  getAllClasses() {
35
23
  return Array.from(this.classes.values());
36
24
  }
37
- hasClass(target) {
38
- return !!target && this.classes.has(target);
39
- }
40
- // ----- Methods -----
41
- getMethodKey(target, propertyKey) {
42
- return `${target.name}_${propertyKey}`;
43
- }
44
25
  addMethod(metadata) {
45
- if (!metadata?.target || !metadata.propertyKey)
46
- return;
47
- const targetForKey = metadata.target.prototype || metadata.target;
48
- const key = this.getMethodKey(metadata.target, metadata.propertyKey);
49
- // Attach existing params for this method
50
- const existingParams = this.getParams(targetForKey, metadata.propertyKey).sort((a, b) => a.index - b.index);
51
- metadata.paramMetadata = existingParams;
26
+ const key = `${metadata.target.name}.${metadata.propertyKey}`;
27
+ const existingParams = this.getParams(metadata.target, metadata.propertyKey);
28
+ metadata.paramMetadata = existingParams.sort((a, b) => a.index - b.index);
52
29
  this.methods.set(key, metadata);
53
30
  }
54
31
  getMethod(target, propertyKey) {
55
- if (!target || !propertyKey)
56
- return undefined;
57
- const key = this.getMethodKey(target.constructor || target, propertyKey);
32
+ const key = `${target.name}.${propertyKey}`;
58
33
  return this.methods.get(key);
59
34
  }
60
35
  getAllMethods() {
61
36
  return Array.from(this.methods.values());
62
37
  }
63
- hasMethod(target, propertyKey) {
64
- if (!target || !propertyKey)
65
- return false;
66
- const key = this.getMethodKey(target.constructor || target, propertyKey);
67
- return this.methods.has(key);
68
- }
69
- // ----- Params -----
70
- getParamKey(target, propertyKey) {
71
- return `${target.constructor.name}_${propertyKey}`;
72
- }
73
38
  addParam(metadata) {
74
- if (!metadata?.target || !metadata.propertyKey)
75
- return;
76
- const key = this.getParamKey(metadata.target, metadata.propertyKey);
39
+ const key = `${metadata.target.constructor.name}.${metadata.propertyKey}`;
77
40
  const existing = this.params.get(key) || [];
78
- // Deduplicate by propertyKey + index
79
- if (!existing.some((p) => p.index === metadata.index && p.propertyKey === metadata.propertyKey)) {
80
- existing.push(metadata);
81
- }
41
+ existing.push(metadata);
82
42
  this.params.set(key, existing);
83
43
  }
84
44
  getParams(target, propertyKey) {
85
- if (!target || !propertyKey)
45
+ const targetName = target.name || target.constructor?.name;
46
+ if (!targetName)
86
47
  return [];
87
- const key = this.getParamKey(target, propertyKey);
48
+ const key = `${targetName}.${propertyKey}`;
88
49
  return this.params.get(key) || [];
89
50
  }
90
- hasParam(target, propertyKey, index) {
91
- if (!target || !propertyKey)
92
- return false;
93
- const key = this.getParamKey(target, propertyKey);
94
- const existing = this.params.get(key) || [];
95
- return index !== undefined
96
- ? existing.some((p) => p.index === index)
97
- : existing.length > 0;
98
- }
99
51
  }
100
52
  exports.MetadataStorage = MetadataStorage;
101
53
  //# sourceMappingURL=metadata-storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"metadata-storage.js","sourceRoot":"","sources":["../../../src/core/metadata/metadata-storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"metadata-storage.js","sourceRoot":"","sources":["../../../src/core/metadata/metadata-storage.ts"],"names":[],"mappings":";;;AA8BA,MAAa,eAAe;IAA5B;QAEU,YAAO,GAA4B,IAAI,GAAG,EAAE,CAAC;QAC7C,YAAO,GAAgC,IAAI,GAAG,EAAE,CAAC;QACjD,WAAM,GAAiC,IAAI,GAAG,EAAE,CAAC;IAwD3D,CAAC;IAtDC,MAAM,CAAC,WAAW;QAChB,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC;YAC9B,eAAe,CAAC,QAAQ,GAAG,IAAI,eAAe,EAAE,CAAC;QACnD,CAAC;QACD,OAAO,eAAe,CAAC,QAAQ,CAAC;IAClC,CAAC;IAED,QAAQ,CAAC,QAAuB;QAC9B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC9C,CAAC;IAED,QAAQ,CAAC,MAAW;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,aAAa;QACX,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,SAAS,CAAC,QAAwB;QAChC,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QAE9D,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CACnC,QAAQ,CAAC,MAAM,EACf,QAAQ,CAAC,WAAW,CACrB,CAAC;QACF,QAAQ,CAAC,aAAa,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAE1E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAClC,CAAC;IAED,SAAS,CAAC,MAAW,EAAE,WAAmB;QACxC,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,WAAW,EAAE,CAAC;QAC5C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,aAAa;QACX,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,QAAQ,CAAC,QAAuB;QAC9B,MAAM,GAAG,GAAG,GAAG,QAAQ,CAAC,MAAM,CAAC,WAAW,CAAC,IAAI,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;QAC1E,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAC5C,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC;IAED,SAAS,CAAC,MAAW,EAAE,WAAmB;QACxC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC;QAC3D,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAC;QAE3B,MAAM,GAAG,GAAG,GAAG,UAAU,IAAI,WAAW,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;IACpC,CAAC;CACF;AA5DD,0CA4DC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fragment-ts",
3
- "version": "1.0.23",
3
+ "version": "1.0.24",
4
4
  "description": "Spring Boot-style framework for TypeScript with Express and TypeORM",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -173,7 +173,7 @@ export class InitCommand {
173
173
  "migrate:revert": "fragment migrate:revert",
174
174
  },
175
175
  dependencies: {
176
- "fragment-ts": "^1.0.23",
176
+ "fragment-ts": "^1.0.24",
177
177
  "reflect-metadata": "^0.1.13",
178
178
  },
179
179
  devDependencies: {
@@ -1,5 +1,4 @@
1
1
  import { METADATA_KEYS } from "../metadata/metadata-keys";
2
- import { MetadataStorage } from "../metadata/metadata-storage";
3
2
 
4
3
  export interface ApplicationOptions {
5
4
  port?: number;
@@ -9,28 +8,19 @@ export interface ApplicationOptions {
9
8
  }
10
9
 
11
10
  export function FragmentApplication(
12
- options: {
13
- port?: number;
14
- host?: string;
15
- configPath?: string;
16
- autoScan?: boolean;
17
- } = {},
11
+ options: ApplicationOptions = {},
18
12
  ): ClassDecorator {
19
13
  return (target: any) => {
20
14
  Reflect.defineMetadata(
21
15
  METADATA_KEYS.APPLICATION,
22
16
  {
17
+ ...options,
23
18
  port: options.port || 3000,
24
19
  host: options.host || "0.0.0.0",
25
20
  configPath: options.configPath || "fragment.json",
26
- autoScan: options.autoScan ?? true,
21
+ autoScan: options.autoScan || true,
27
22
  },
28
23
  target,
29
24
  );
30
- MetadataStorage.getInstance().addClass({
31
- target,
32
- type: "injectable",
33
- scope: "singleton",
34
- });
35
25
  };
36
26
  }
@@ -1,15 +1,17 @@
1
- import { Injectable } from "./injectable.decorator";
2
- import { METADATA_KEYS } from "../metadata/metadata-keys";
3
- import { MetadataStorage } from "../metadata/metadata-storage";
1
+ import { Injectable } from './injectable.decorator';
2
+ import { METADATA_KEYS } from '../metadata/metadata-keys';
3
+ import { MetadataStorage } from '../metadata/metadata-storage';
4
4
 
5
5
  export function AutoConfiguration(): ClassDecorator {
6
6
  return (target: any) => {
7
- Injectable("singleton")(target);
7
+ Injectable('singleton')(target);
8
8
  Reflect.defineMetadata(METADATA_KEYS.AUTO_CONFIGURATION, true, target);
9
- MetadataStorage.getInstance().addClass({
9
+
10
+ const storage = MetadataStorage.getInstance();
11
+ storage.addClass({
10
12
  target,
11
- type: "auto-configuration",
12
- scope: "singleton",
13
+ type: 'auto-configuration',
14
+ scope: 'singleton'
13
15
  });
14
16
  };
15
- }
17
+ }
@@ -1,55 +1,19 @@
1
- import { METADATA_KEYS } from "../metadata/metadata-keys";
2
- import { MetadataStorage } from "../metadata/metadata-storage";
3
-
4
- /**
5
- * Conditional decorators
6
- * Ensures the class is registered in MetadataStorage
7
- */
1
+ import { METADATA_KEYS } from '../metadata/metadata-keys';
8
2
 
9
3
  export function ConditionalOnClass(classRef: any): ClassDecorator {
10
4
  return (target: any) => {
11
5
  Reflect.defineMetadata(METADATA_KEYS.CONDITIONAL_ON_CLASS, classRef, target);
12
-
13
- // Register in MetadataStorage if not already
14
- const storage = MetadataStorage.getInstance();
15
- if (!storage.getClass(target)) {
16
- storage.addClass({
17
- target,
18
- type: 'injectable', // default type
19
- scope: 'singleton',
20
- });
21
- }
22
6
  };
23
7
  }
24
8
 
25
9
  export function ConditionalOnMissingBean(token: any): ClassDecorator {
26
10
  return (target: any) => {
27
11
  Reflect.defineMetadata(METADATA_KEYS.CONDITIONAL_ON_MISSING_BEAN, token, target);
28
-
29
- // Register in MetadataStorage if not already
30
- const storage = MetadataStorage.getInstance();
31
- if (!storage.getClass(target)) {
32
- storage.addClass({
33
- target,
34
- type: 'injectable',
35
- scope: 'singleton',
36
- });
37
- }
38
12
  };
39
13
  }
40
14
 
41
15
  export function ConditionalOnProperty(key: string, expectedValue?: any): ClassDecorator {
42
16
  return (target: any) => {
43
17
  Reflect.defineMetadata(METADATA_KEYS.CONDITIONAL_ON_PROPERTY, { key, expectedValue }, target);
44
-
45
- // Register in MetadataStorage if not already
46
- const storage = MetadataStorage.getInstance();
47
- if (!storage.getClass(target)) {
48
- storage.addClass({
49
- target,
50
- type: 'injectable',
51
- scope: 'singleton',
52
- });
53
- }
54
18
  };
55
19
  }
@@ -6,7 +6,9 @@ export function Controller(path: string = ""): ClassDecorator {
6
6
  return (target: any) => {
7
7
  Injectable("singleton")(target);
8
8
  Reflect.defineMetadata(METADATA_KEYS.CONTROLLER, path, target);
9
- MetadataStorage.getInstance().addClass({
9
+
10
+ const storage = MetadataStorage.getInstance();
11
+ storage.addClass({
10
12
  target,
11
13
  type: "controller",
12
14
  scope: "singleton",
@@ -1,20 +1,33 @@
1
- import "reflect-metadata";
2
1
  import { METADATA_KEYS } from "../metadata/metadata-keys";
3
2
  import { MetadataStorage } from "../metadata/metadata-storage";
4
3
 
5
4
  function createHttpMethodDecorator(method: string) {
6
5
  return (path: string = ""): MethodDecorator => {
7
- return (target: any, propertyKey: string | symbol) => {
8
- Reflect.defineMetadata(METADATA_KEYS.HTTP_METHOD, method, target, propertyKey);
9
- Reflect.defineMetadata(METADATA_KEYS.ROUTE_PATH, path, target, propertyKey);
6
+ return (
7
+ target: any,
8
+ propertyKey: string | symbol,
9
+ descriptor: PropertyDescriptor,
10
+ ) => {
11
+ Reflect.defineMetadata(
12
+ METADATA_KEYS.HTTP_METHOD,
13
+ method,
14
+ target,
15
+ propertyKey,
16
+ );
17
+ Reflect.defineMetadata(
18
+ METADATA_KEYS.ROUTE_PATH,
19
+ path,
20
+ target,
21
+ propertyKey,
22
+ );
10
23
 
11
24
  const storage = MetadataStorage.getInstance();
12
25
  storage.addMethod({
13
26
  target: target.constructor,
14
- propertyKey: propertyKey.toString(),
27
+ propertyKey: propertyKey as string,
15
28
  method,
16
29
  path,
17
- paramMetadata: storage.getParams(target, propertyKey.toString()),
30
+ paramMetadata: storage.getParams(target, propertyKey as string),
18
31
  });
19
32
  };
20
33
  };
@@ -26,15 +39,23 @@ export const Put = createHttpMethodDecorator("PUT");
26
39
  export const Delete = createHttpMethodDecorator("DELETE");
27
40
  export const Patch = createHttpMethodDecorator("PATCH");
28
41
 
29
- // Parameter decorators
30
42
  function createParamDecorator(type: string) {
31
43
  return (paramName?: string): ParameterDecorator => {
32
- return (target, propertyKey, index) => {
33
- if (!propertyKey) throw new Error(`@${type} cannot be used on constructor params`);
34
- MetadataStorage.getInstance().addParam({
44
+ return (
45
+ target: Object,
46
+ propertyKey: string | symbol | undefined,
47
+ parameterIndex: number,
48
+ ): void => {
49
+ if (!propertyKey) {
50
+ throw new Error(`@${type}() cannot be used on constructor parameters`);
51
+ }
52
+
53
+ const storage = MetadataStorage.getInstance();
54
+
55
+ storage.addParam({
35
56
  target,
36
57
  propertyKey: propertyKey.toString(),
37
- index,
58
+ index: parameterIndex,
38
59
  type: type as any,
39
60
  paramName,
40
61
  });
@@ -1,25 +1,18 @@
1
- import { METADATA_KEYS } from "../metadata/metadata-keys";
2
- import { MetadataStorage } from "../metadata/metadata-storage";
1
+ import { METADATA_KEYS } from '../metadata/metadata-keys';
2
+ import { MetadataStorage } from '../metadata/metadata-storage';
3
3
 
4
4
  export type Scope = 'singleton' | 'request' | 'transient';
5
5
 
6
- /**
7
- * @Injectable - Marks a class as injectable with a scope
8
- */
9
6
  export function Injectable(scope: Scope = 'singleton'): ClassDecorator {
10
7
  return (target: any) => {
11
- // Define Reflect metadata
12
8
  Reflect.defineMetadata(METADATA_KEYS.INJECTABLE, true, target);
13
9
  Reflect.defineMetadata(METADATA_KEYS.SCOPE, scope, target);
14
-
15
- // Register in MetadataStorage if not already
10
+
16
11
  const storage = MetadataStorage.getInstance();
17
- if (!storage.getClass(target)) {
18
- storage.addClass({
19
- target,
20
- type: 'injectable',
21
- scope
22
- });
23
- }
12
+ storage.addClass({
13
+ target,
14
+ type: 'injectable',
15
+ scope
16
+ });
24
17
  };
25
18
  }
@@ -1,97 +1,150 @@
1
- import "reflect-metadata";
2
1
  import { METADATA_KEYS } from "../metadata/metadata-keys";
3
- import { MetadataStorage } from "../metadata/metadata-storage";
4
2
 
3
+ /**
4
+ * @Autowired - Automatically inject dependencies by type
5
+ * Usage: @Autowired() private myService: MyService;
6
+ */
5
7
  export function Autowired(): PropertyDecorator {
6
- return (target, propertyKey) => {
8
+ return (target: any, propertyKey: string | symbol) => {
9
+ // Get the design type from TypeScript metadata
7
10
  const type = Reflect.getMetadata("design:type", target, propertyKey);
8
- if (!type)
9
- throw new Error(`Cannot use @Autowired on ${String(propertyKey)}`);
10
- Reflect.defineMetadata(METADATA_KEYS.AUTOWIRED, type, target, propertyKey);
11
11
 
12
- MetadataStorage.getInstance().addParam({
13
- target,
14
- propertyKey: propertyKey.toString(),
15
- index: -1,
16
- type: "autowired",
17
- });
12
+ if (!type || type === Object) {
13
+ throw new Error(
14
+ `Cannot use @Autowired on property "${String(propertyKey)}" in ${target.constructor.name}. ` +
15
+ `Make sure TypeScript emitDecoratorMetadata is enabled and the type is explicitly declared.`,
16
+ );
17
+ }
18
+
19
+ // Store the type in metadata so DI container can resolve it
20
+ Reflect.defineMetadata(METADATA_KEYS.AUTOWIRED, type, target, propertyKey);
18
21
  };
19
22
  }
20
23
 
24
+ /**
25
+ * @Inject - Inject dependency by token (string or class)
26
+ * Usage: @Inject('MyService') private service: MyService;
27
+ * or: @Inject(MyService) private service: MyService;
28
+ */
21
29
  export function Inject(token: string | Function): PropertyDecorator {
22
- return (target, propertyKey) => {
30
+ return (target: any, propertyKey: string | symbol) => {
23
31
  Reflect.defineMetadata(METADATA_KEYS.INJECT, token, target, propertyKey);
24
- MetadataStorage.getInstance().addParam({
25
- target,
26
- propertyKey: propertyKey.toString(),
27
- index: -1,
28
- type: "inject",
29
- paramName: typeof token === "string" ? token : undefined,
30
- });
31
32
  };
32
33
  }
33
34
 
35
+ /**
36
+ * @InjectRepository - Inject TypeORM repository for an entity
37
+ * Usage: @InjectRepository(User) private userRepo: Repository<User>;
38
+ */
34
39
  export function InjectRepository(entity: Function): PropertyDecorator {
35
- return (target, propertyKey) => {
40
+ return (target: any, propertyKey: string | symbol) => {
36
41
  Reflect.defineMetadata(
37
42
  METADATA_KEYS.INJECT_REPOSITORY,
38
43
  entity,
39
44
  target,
40
45
  propertyKey,
41
46
  );
42
- MetadataStorage.getInstance().addParam({
43
- target,
44
- propertyKey: propertyKey.toString(),
45
- index: -1,
46
- type: "inject-repo",
47
- });
48
47
  };
49
48
  }
50
49
 
50
+ /**
51
+ * @Qualifier - Specify which bean to inject when multiple exist
52
+ * Usage: @Qualifier('primary') @Autowired() private service: MyService;
53
+ */
54
+ export function Qualifier(name: string): PropertyDecorator {
55
+ return (target: any, propertyKey: string | symbol) => {
56
+ Reflect.defineMetadata(METADATA_KEYS.QUALIFIER, name, target, propertyKey);
57
+ };
58
+ }
59
+
60
+ /**
61
+ * @Value - Inject configuration value from environment or config
62
+ * Usage: @Value('${PORT}') private port: number;
63
+ * or: @Value('${DB_HOST:localhost}') private host: string;
64
+ */
51
65
  export function Value(expression: string): PropertyDecorator {
52
- return (target, propertyKey) => {
66
+ return (target: any, propertyKey: string | symbol) => {
53
67
  Reflect.defineMetadata(
54
68
  METADATA_KEYS.VALUE,
55
69
  expression,
56
70
  target,
57
71
  propertyKey,
58
72
  );
59
- MetadataStorage.getInstance().addParam({
60
- target,
61
- propertyKey: propertyKey.toString(),
62
- index: -1,
63
- type: "value",
64
- });
65
73
  };
66
74
  }
67
75
 
68
76
  /**
69
- * @Qualifier - Specify which bean to inject when multiple exist
70
- * Usage: @Qualifier('primary') @Autowired() private service: MyService;
77
+ * @Optional - Mark dependency as optional (won't throw if not found)
78
+ * Usage: @Optional() @Autowired() private service?: MyService;
71
79
  */
72
- export function Qualifier(name: string): PropertyDecorator {
80
+ export function Optional(): PropertyDecorator {
73
81
  return (target: any, propertyKey: string | symbol) => {
74
- if (!propertyKey) return;
82
+ Reflect.defineMetadata(METADATA_KEYS.OPTIONAL, true, target, propertyKey);
83
+ };
84
+ }
75
85
 
76
- Reflect.defineMetadata(METADATA_KEYS.QUALIFIER, name, target, propertyKey);
86
+ /**
87
+ * @Lazy - Lazy load dependency (create on first access)
88
+ * Usage: @Lazy() @Autowired() private service: MyService;
89
+ */
90
+ export function Lazy(): PropertyDecorator {
91
+ return (target: any, propertyKey: string | symbol) => {
92
+ Reflect.defineMetadata(METADATA_KEYS.LAZY, true, target, propertyKey);
77
93
 
78
- MetadataStorage.getInstance().addParam({
79
- target,
80
- propertyKey: propertyKey.toString(),
81
- index: -1,
82
- type: "qualifier",
94
+ const type = Reflect.getMetadata("design:type", target, propertyKey);
95
+
96
+ // Create a getter that resolves on first access
97
+ let cached: any = null;
98
+ let resolved = false;
99
+
100
+ Object.defineProperty(target, propertyKey, {
101
+ get() {
102
+ if (!resolved) {
103
+ const { DIContainer } = require("../container/di-container");
104
+ const container = DIContainer.getInstance();
105
+ cached = container.resolve(type);
106
+ resolved = true;
107
+ }
108
+ return cached;
109
+ },
110
+ enumerable: true,
111
+ configurable: true,
83
112
  });
84
113
  };
85
114
  }
86
115
 
87
- export function Optional(): PropertyDecorator {
88
- return (target, propertyKey) => {
89
- Reflect.defineMetadata(METADATA_KEYS.OPTIONAL, true, target, propertyKey);
116
+ /**
117
+ * @PostConstruct - Method called after dependency injection is complete
118
+ * Usage: @PostConstruct() init() { ... }
119
+ */
120
+ export function PostConstruct(): MethodDecorator {
121
+ return (
122
+ target: any,
123
+ propertyKey: string | symbol,
124
+ descriptor: PropertyDescriptor,
125
+ ) => {
126
+ Reflect.defineMetadata(
127
+ METADATA_KEYS.POST_CONSTRUCT,
128
+ propertyKey,
129
+ target.constructor,
130
+ );
90
131
  };
91
132
  }
92
133
 
93
- export function Lazy(): PropertyDecorator {
94
- return (target, propertyKey) => {
95
- Reflect.defineMetadata(METADATA_KEYS.LAZY, true, target, propertyKey);
134
+ /**
135
+ * @PreDestroy - Method called before bean is destroyed
136
+ * Usage: @PreDestroy() cleanup() { ... }
137
+ */
138
+ export function PreDestroy(): MethodDecorator {
139
+ return (
140
+ target: any,
141
+ propertyKey: string | symbol,
142
+ descriptor: PropertyDescriptor,
143
+ ) => {
144
+ Reflect.defineMetadata(
145
+ METADATA_KEYS.PRE_DESTROY,
146
+ propertyKey,
147
+ target.constructor,
148
+ );
96
149
  };
97
150
  }
@@ -1,15 +1,17 @@
1
- import { Injectable } from "./injectable.decorator";
2
- import { METADATA_KEYS } from "../metadata/metadata-keys";
3
- import { MetadataStorage } from "../metadata/metadata-storage";
1
+ import { Injectable } from './injectable.decorator';
2
+ import { METADATA_KEYS } from '../metadata/metadata-keys';
3
+ import { MetadataStorage } from '../metadata/metadata-storage';
4
4
 
5
5
  export function Repository(): ClassDecorator {
6
6
  return (target: any) => {
7
- Injectable("singleton")(target);
7
+ Injectable('singleton')(target);
8
8
  Reflect.defineMetadata(METADATA_KEYS.REPOSITORY, true, target);
9
- MetadataStorage.getInstance().addClass({
9
+
10
+ const storage = MetadataStorage.getInstance();
11
+ storage.addClass({
10
12
  target,
11
- type: "repository",
12
- scope: "singleton",
13
+ type: 'repository',
14
+ scope: 'singleton'
13
15
  });
14
16
  };
15
- }
17
+ }