fragment-ts 1.0.29 โ 1.0.30
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.
- package/dist/cli/commands/init.command.js +1 -1
- package/dist/core/container/di-container.d.ts +7 -7
- package/dist/core/container/di-container.d.ts.map +1 -1
- package/dist/core/container/di-container.js +162 -130
- package/dist/core/container/di-container.js.map +1 -1
- package/dist/core/decorators/application.decorator.d.ts.map +1 -1
- package/dist/core/decorators/application.decorator.js +2 -1
- package/dist/core/decorators/application.decorator.js.map +1 -1
- package/dist/core/decorators/auto-configuration.decorator.d.ts.map +1 -1
- package/dist/core/decorators/auto-configuration.decorator.js +4 -3
- package/dist/core/decorators/auto-configuration.decorator.js.map +1 -1
- package/dist/core/decorators/controller.decorator.d.ts.map +1 -1
- package/dist/core/decorators/controller.decorator.js +1 -0
- package/dist/core/decorators/controller.decorator.js.map +1 -1
- package/dist/core/decorators/http.decorators.d.ts.map +1 -1
- package/dist/core/decorators/http.decorators.js +9 -0
- package/dist/core/decorators/http.decorators.js.map +1 -1
- package/dist/core/decorators/injectable.decorator.d.ts.map +1 -1
- package/dist/core/decorators/injectable.decorator.js +1 -0
- package/dist/core/decorators/injectable.decorator.js.map +1 -1
- package/dist/core/decorators/injection.decorators.d.ts.map +1 -1
- package/dist/core/decorators/injection.decorators.js +45 -21
- package/dist/core/decorators/injection.decorators.js.map +1 -1
- package/dist/core/decorators/repository.decorator.d.ts.map +1 -1
- package/dist/core/decorators/repository.decorator.js +1 -0
- package/dist/core/decorators/repository.decorator.js.map +1 -1
- package/dist/core/decorators/service.decorator.d.ts.map +1 -1
- package/dist/core/decorators/service.decorator.js +1 -0
- package/dist/core/decorators/service.decorator.js.map +1 -1
- package/dist/core/metadata/metadata-storage.d.ts +10 -13
- package/dist/core/metadata/metadata-storage.d.ts.map +1 -1
- package/dist/core/metadata/metadata-storage.js +21 -18
- package/dist/core/metadata/metadata-storage.js.map +1 -1
- package/dist/web/application.d.ts +0 -6
- package/dist/web/application.d.ts.map +1 -1
- package/dist/web/application.js +93 -41
- package/dist/web/application.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/init.command.ts +1 -1
- package/src/core/container/di-container.ts +248 -181
- package/src/core/decorators/application.decorator.ts +2 -1
- package/src/core/decorators/auto-configuration.decorator.ts +9 -8
- package/src/core/decorators/controller.decorator.ts +2 -1
- package/src/core/decorators/http.decorators.ts +17 -0
- package/src/core/decorators/injectable.decorator.ts +1 -0
- package/src/core/decorators/injection.decorators.ts +59 -24
- package/src/core/decorators/repository.decorator.ts +1 -0
- package/src/core/decorators/service.decorator.ts +1 -0
- package/src/core/metadata/metadata-storage.ts +47 -37
- package/src/web/application.ts +128 -62
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { Injectable } from
|
|
2
|
-
import { METADATA_KEYS } from
|
|
3
|
-
import { MetadataStorage } from
|
|
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
|
-
|
|
7
|
+
console.log(`๐ง Registering AutoConfiguration: ${target.name}`);
|
|
8
|
+
Injectable("singleton")(target);
|
|
8
9
|
Reflect.defineMetadata(METADATA_KEYS.AUTO_CONFIGURATION, true, target);
|
|
9
|
-
|
|
10
|
+
|
|
10
11
|
const storage = MetadataStorage.getInstance();
|
|
11
12
|
storage.addClass({
|
|
12
13
|
target,
|
|
13
|
-
type:
|
|
14
|
-
scope:
|
|
14
|
+
type: "auto-configuration",
|
|
15
|
+
scope: "singleton",
|
|
15
16
|
});
|
|
16
17
|
};
|
|
17
|
-
}
|
|
18
|
+
}
|
|
@@ -4,9 +4,10 @@ import { MetadataStorage } from "../metadata/metadata-storage";
|
|
|
4
4
|
|
|
5
5
|
export function Controller(path: string = ""): ClassDecorator {
|
|
6
6
|
return (target: any) => {
|
|
7
|
+
console.log(`๐ฎ Registering Controller: ${target.name} at ${path || '/'}`);
|
|
7
8
|
Injectable("singleton")(target);
|
|
8
9
|
Reflect.defineMetadata(METADATA_KEYS.CONTROLLER, path, target);
|
|
9
|
-
|
|
10
|
+
|
|
10
11
|
const storage = MetadataStorage.getInstance();
|
|
11
12
|
storage.addClass({
|
|
12
13
|
target,
|
|
@@ -8,6 +8,13 @@ function createHttpMethodDecorator(method: string) {
|
|
|
8
8
|
propertyKey: string | symbol,
|
|
9
9
|
descriptor: PropertyDescriptor,
|
|
10
10
|
) => {
|
|
11
|
+
const className = target.constructor.name;
|
|
12
|
+
const methodName = String(propertyKey);
|
|
13
|
+
|
|
14
|
+
console.log(
|
|
15
|
+
`โก Registering ${method.toUpperCase()} route: ${className}.${methodName} at ${path || "/"}`,
|
|
16
|
+
);
|
|
17
|
+
|
|
11
18
|
Reflect.defineMetadata(
|
|
12
19
|
METADATA_KEYS.HTTP_METHOD,
|
|
13
20
|
method,
|
|
@@ -50,6 +57,16 @@ function createParamDecorator(type: string) {
|
|
|
50
57
|
throw new Error(`@${type}() cannot be used on constructor parameters`);
|
|
51
58
|
}
|
|
52
59
|
|
|
60
|
+
const className = target.constructor.name;
|
|
61
|
+
const methodName = String(propertyKey);
|
|
62
|
+
const paramDisplay = paramName
|
|
63
|
+
? `${paramName} (index: ${parameterIndex})`
|
|
64
|
+
: `index: ${parameterIndex}`;
|
|
65
|
+
|
|
66
|
+
console.log(
|
|
67
|
+
` ๐ฅ Registering @${type} parameter for ${className}.${methodName}: ${paramDisplay}`,
|
|
68
|
+
);
|
|
69
|
+
|
|
53
70
|
const storage = MetadataStorage.getInstance();
|
|
54
71
|
|
|
55
72
|
storage.addParam({
|
|
@@ -5,6 +5,7 @@ export type Scope = 'singleton' | 'request' | 'transient';
|
|
|
5
5
|
|
|
6
6
|
export function Injectable(scope: Scope = 'singleton'): ClassDecorator {
|
|
7
7
|
return (target: any) => {
|
|
8
|
+
console.log(`๐ Registering Injectable: ${target.name} [${scope}]`);
|
|
8
9
|
Reflect.defineMetadata(METADATA_KEYS.INJECTABLE, true, target);
|
|
9
10
|
Reflect.defineMetadata(METADATA_KEYS.SCOPE, scope, target);
|
|
10
11
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { METADATA_KEYS } from "../metadata/metadata-keys";
|
|
2
2
|
import { MetadataStorage } from "../metadata/metadata-storage";
|
|
3
|
+
import { DIContainer } from "../container/di-container";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @Autowired - Automatically inject dependencies by type
|
|
@@ -7,21 +8,24 @@ import { MetadataStorage } from "../metadata/metadata-storage";
|
|
|
7
8
|
*/
|
|
8
9
|
export function Autowired(): PropertyDecorator {
|
|
9
10
|
return (target: any, propertyKey: string | symbol) => {
|
|
11
|
+
// Get the design type from TypeScript metadata
|
|
12
|
+
const type = Reflect.getMetadata("design:type", target, propertyKey);
|
|
13
|
+
if (!type || type === Object) {
|
|
14
|
+
console.warn(
|
|
15
|
+
`โ ๏ธ Could not determine type for ${target.constructor.name}.${String(propertyKey)}. ` +
|
|
16
|
+
`Ensure emitDecoratorMetadata is enabled in tsconfig.json`,
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
// Store metadata for property injection
|
|
11
21
|
const storage = MetadataStorage.getInstance();
|
|
12
22
|
storage.addPropertyInjection?.(target.constructor, propertyKey.toString(), {
|
|
13
23
|
type: "autowired",
|
|
14
24
|
key: propertyKey.toString(),
|
|
25
|
+
metadata: { type },
|
|
15
26
|
});
|
|
16
27
|
|
|
17
28
|
// Also store in Reflect metadata for backward compatibility
|
|
18
|
-
const type = Reflect.getMetadata("design:type", target, propertyKey);
|
|
19
|
-
if (!type || type === Object) {
|
|
20
|
-
console.warn(
|
|
21
|
-
`โ ๏ธ Could not determine type for ${target.constructor.name}.${String(propertyKey)}. ` +
|
|
22
|
-
`Ensure emitDecoratorMetadata is enabled in tsconfig.json`,
|
|
23
|
-
);
|
|
24
|
-
}
|
|
25
29
|
Reflect.defineMetadata(METADATA_KEYS.AUTOWIRED, type, target, propertyKey);
|
|
26
30
|
};
|
|
27
31
|
}
|
|
@@ -33,6 +37,15 @@ export function Autowired(): PropertyDecorator {
|
|
|
33
37
|
*/
|
|
34
38
|
export function Inject(token: string | Function): PropertyDecorator {
|
|
35
39
|
return (target: any, propertyKey: string | symbol) => {
|
|
40
|
+
// Store metadata for property injection
|
|
41
|
+
const storage = MetadataStorage.getInstance();
|
|
42
|
+
storage.addPropertyInjection?.(target.constructor, propertyKey.toString(), {
|
|
43
|
+
type: "inject",
|
|
44
|
+
key: propertyKey.toString(),
|
|
45
|
+
metadata: { token },
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Also store in Reflect metadata for backward compatibility
|
|
36
49
|
Reflect.defineMetadata(METADATA_KEYS.INJECT, token, target, propertyKey);
|
|
37
50
|
};
|
|
38
51
|
}
|
|
@@ -43,6 +56,15 @@ export function Inject(token: string | Function): PropertyDecorator {
|
|
|
43
56
|
*/
|
|
44
57
|
export function InjectRepository(entity: Function): PropertyDecorator {
|
|
45
58
|
return (target: any, propertyKey: string | symbol) => {
|
|
59
|
+
// Store metadata for property injection
|
|
60
|
+
const storage = MetadataStorage.getInstance();
|
|
61
|
+
storage.addPropertyInjection?.(target.constructor, propertyKey.toString(), {
|
|
62
|
+
type: "repository",
|
|
63
|
+
key: propertyKey.toString(),
|
|
64
|
+
metadata: { entity },
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Also store in Reflect metadata for backward compatibility
|
|
46
68
|
Reflect.defineMetadata(
|
|
47
69
|
METADATA_KEYS.INJECT_REPOSITORY,
|
|
48
70
|
entity,
|
|
@@ -69,6 +91,15 @@ export function Qualifier(name: string): PropertyDecorator {
|
|
|
69
91
|
*/
|
|
70
92
|
export function Value(expression: string): PropertyDecorator {
|
|
71
93
|
return (target: any, propertyKey: string | symbol) => {
|
|
94
|
+
// Store metadata for property injection
|
|
95
|
+
const storage = MetadataStorage.getInstance();
|
|
96
|
+
storage.addPropertyInjection?.(target.constructor, propertyKey.toString(), {
|
|
97
|
+
type: "value",
|
|
98
|
+
key: propertyKey.toString(),
|
|
99
|
+
metadata: { expression },
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
// Also store in Reflect metadata for backward compatibility
|
|
72
103
|
Reflect.defineMetadata(
|
|
73
104
|
METADATA_KEYS.VALUE,
|
|
74
105
|
expression,
|
|
@@ -94,27 +125,21 @@ export function Optional(): PropertyDecorator {
|
|
|
94
125
|
*/
|
|
95
126
|
export function Lazy(): PropertyDecorator {
|
|
96
127
|
return (target: any, propertyKey: string | symbol) => {
|
|
128
|
+
// Mark as lazy in metadata
|
|
97
129
|
Reflect.defineMetadata(METADATA_KEYS.LAZY, true, target, propertyKey);
|
|
98
130
|
|
|
131
|
+
// Store metadata for property injection
|
|
132
|
+
const storage = MetadataStorage.getInstance();
|
|
133
|
+
storage.addPropertyInjection?.(target.constructor, propertyKey.toString(), {
|
|
134
|
+
type: "lazy",
|
|
135
|
+
key: propertyKey.toString(),
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Get the type for later resolution
|
|
99
139
|
const type = Reflect.getMetadata("design:type", target, propertyKey);
|
|
100
140
|
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
let resolved = false;
|
|
104
|
-
|
|
105
|
-
Object.defineProperty(target, propertyKey, {
|
|
106
|
-
get() {
|
|
107
|
-
if (!resolved) {
|
|
108
|
-
const { DIContainer } = require("../container/di-container");
|
|
109
|
-
const container = DIContainer.getInstance();
|
|
110
|
-
cached = container.resolve(type);
|
|
111
|
-
resolved = true;
|
|
112
|
-
}
|
|
113
|
-
return cached;
|
|
114
|
-
},
|
|
115
|
-
enumerable: true,
|
|
116
|
-
configurable: true,
|
|
117
|
-
});
|
|
141
|
+
// This will be handled by the container during injection
|
|
142
|
+
// (not directly creating the getter here to avoid container dependency)
|
|
118
143
|
};
|
|
119
144
|
}
|
|
120
145
|
|
|
@@ -128,6 +153,11 @@ export function PostConstruct(): MethodDecorator {
|
|
|
128
153
|
propertyKey: string | symbol,
|
|
129
154
|
descriptor: PropertyDescriptor,
|
|
130
155
|
) => {
|
|
156
|
+
const className = target.constructor.name;
|
|
157
|
+
console.log(
|
|
158
|
+
` ๐๏ธ Registering @PostConstruct: ${className}.${String(propertyKey)}`,
|
|
159
|
+
);
|
|
160
|
+
|
|
131
161
|
Reflect.defineMetadata(
|
|
132
162
|
METADATA_KEYS.POST_CONSTRUCT,
|
|
133
163
|
propertyKey,
|
|
@@ -146,6 +176,11 @@ export function PreDestroy(): MethodDecorator {
|
|
|
146
176
|
propertyKey: string | symbol,
|
|
147
177
|
descriptor: PropertyDescriptor,
|
|
148
178
|
) => {
|
|
179
|
+
const className = target.constructor.name;
|
|
180
|
+
console.log(
|
|
181
|
+
` ๐งน Registering @PreDestroy: ${className}.${String(propertyKey)}`,
|
|
182
|
+
);
|
|
183
|
+
|
|
149
184
|
Reflect.defineMetadata(
|
|
150
185
|
METADATA_KEYS.PRE_DESTROY,
|
|
151
186
|
propertyKey,
|
|
@@ -4,6 +4,7 @@ import { MetadataStorage } from '../metadata/metadata-storage';
|
|
|
4
4
|
|
|
5
5
|
export function Repository(): ClassDecorator {
|
|
6
6
|
return (target: any) => {
|
|
7
|
+
console.log(`๐พ Registering Repository: ${target.name}`);
|
|
7
8
|
Injectable('singleton')(target);
|
|
8
9
|
Reflect.defineMetadata(METADATA_KEYS.REPOSITORY, true, target);
|
|
9
10
|
|
|
@@ -4,6 +4,7 @@ import { MetadataStorage } from '../metadata/metadata-storage';
|
|
|
4
4
|
|
|
5
5
|
export function Service(): ClassDecorator {
|
|
6
6
|
return (target: any) => {
|
|
7
|
+
console.log(`โ๏ธ Registering Service: ${target.name}`);
|
|
7
8
|
Injectable('singleton')(target);
|
|
8
9
|
Reflect.defineMetadata(METADATA_KEYS.SERVICE, true, target);
|
|
9
10
|
|
|
@@ -28,19 +28,19 @@ export interface ParamMetadata {
|
|
|
28
28
|
paramName?: string;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
export interface PropertyInjectionMetadata {
|
|
32
|
+
type: "autowired" | "inject" | "repository" | "value" | "lazy";
|
|
33
|
+
key: string;
|
|
34
|
+
metadata?: any;
|
|
35
|
+
}
|
|
36
|
+
|
|
31
37
|
export class MetadataStorage {
|
|
32
38
|
private static instance: MetadataStorage;
|
|
33
39
|
private classes: Map<any, ClassMetadata> = new Map();
|
|
34
40
|
private methods: Map<string, MethodMetadata> = new Map();
|
|
35
41
|
private params: Map<string, ParamMetadata[]> = new Map();
|
|
36
|
-
private propertyInjections: Map<
|
|
37
|
-
|
|
38
|
-
{
|
|
39
|
-
type: string;
|
|
40
|
-
key: string;
|
|
41
|
-
metadata?: any;
|
|
42
|
-
}[]
|
|
43
|
-
> = new Map();
|
|
42
|
+
private propertyInjections: Map<string, PropertyInjectionMetadata[]> =
|
|
43
|
+
new Map();
|
|
44
44
|
|
|
45
45
|
static getInstance(): MetadataStorage {
|
|
46
46
|
if (!MetadataStorage.instance) {
|
|
@@ -49,35 +49,6 @@ export class MetadataStorage {
|
|
|
49
49
|
return MetadataStorage.instance;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
addPropertyInjection(
|
|
53
|
-
target: any,
|
|
54
|
-
propertyKey: string,
|
|
55
|
-
injection: { type: string; key: string; metadata?: any },
|
|
56
|
-
): void {
|
|
57
|
-
const className = target.name || target.constructor?.name;
|
|
58
|
-
const key = `${className}.${propertyKey}`;
|
|
59
|
-
const injections = this.propertyInjections.get(key) || [];
|
|
60
|
-
injections.push(injection);
|
|
61
|
-
this.propertyInjections.set(key, injections);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
getAllPropertyInjections(target: any): {
|
|
65
|
-
propertyKey: string;
|
|
66
|
-
injections: { type: string; key: string; metadata?: any }[];
|
|
67
|
-
}[] {
|
|
68
|
-
const className = target.name || target.constructor?.name;
|
|
69
|
-
const injections: { propertyKey: string; injections: any[] }[] = [];
|
|
70
|
-
|
|
71
|
-
this.propertyInjections.forEach((value, key) => {
|
|
72
|
-
if (key.startsWith(`${className}.`)) {
|
|
73
|
-
const propertyKey = key.split(".")[1];
|
|
74
|
-
injections.push({ propertyKey, injections: value });
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
return injections;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
52
|
addClass(metadata: ClassMetadata): void {
|
|
82
53
|
this.classes.set(metadata.target, metadata);
|
|
83
54
|
}
|
|
@@ -125,4 +96,43 @@ export class MetadataStorage {
|
|
|
125
96
|
const key = `${targetName}.${propertyKey}`;
|
|
126
97
|
return this.params.get(key) || [];
|
|
127
98
|
}
|
|
99
|
+
|
|
100
|
+
addPropertyInjection(
|
|
101
|
+
target: any,
|
|
102
|
+
propertyKey: string,
|
|
103
|
+
injection: PropertyInjectionMetadata,
|
|
104
|
+
): void {
|
|
105
|
+
const className = target.name || target.constructor?.name;
|
|
106
|
+
const key = `${className}.${propertyKey}`;
|
|
107
|
+
|
|
108
|
+
if (!this.propertyInjections.has(key)) {
|
|
109
|
+
this.propertyInjections.set(key, []);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const injections = this.propertyInjections.get(key)!;
|
|
113
|
+
injections.push(injection);
|
|
114
|
+
|
|
115
|
+
console.log(
|
|
116
|
+
` ๐ฏ Registered property injection: ${className}.${propertyKey} [${injection.type}]`,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
getPropertyInjections(
|
|
121
|
+
target: any,
|
|
122
|
+
): { propertyKey: string; injections: PropertyInjectionMetadata[] }[] {
|
|
123
|
+
const className = target.name || target.constructor?.name;
|
|
124
|
+
const result: {
|
|
125
|
+
propertyKey: string;
|
|
126
|
+
injections: PropertyInjectionMetadata[];
|
|
127
|
+
}[] = [];
|
|
128
|
+
|
|
129
|
+
this.propertyInjections.forEach((injections, key) => {
|
|
130
|
+
if (key.startsWith(`${className}.`)) {
|
|
131
|
+
const propertyKey = key.split(".")[1];
|
|
132
|
+
result.push({ propertyKey, injections });
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
128
138
|
}
|