fragment-ts 1.0.24 ā 1.0.25
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 +1 -1
- package/dist/core/container/di-container.d.ts.map +1 -1
- package/dist/core/container/di-container.js +118 -63
- package/dist/core/container/di-container.js.map +1 -1
- package/dist/web/application.d.ts.map +1 -1
- package/dist/web/application.js +16 -7
- 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 +193 -77
- package/src/web/application.ts +22 -12
|
@@ -4,12 +4,12 @@ export declare class DIContainer {
|
|
|
4
4
|
private transients;
|
|
5
5
|
private factories;
|
|
6
6
|
private constructing;
|
|
7
|
+
private registered;
|
|
7
8
|
static getInstance(): DIContainer;
|
|
8
9
|
register(token: any, instance?: any, factory?: () => any): void;
|
|
9
10
|
resolve<T>(token: any): T;
|
|
10
11
|
private createInstance;
|
|
11
12
|
private injectProperties;
|
|
12
|
-
private getAllPropertyKeys;
|
|
13
13
|
private resolveValue;
|
|
14
14
|
private resolveRepository;
|
|
15
15
|
has(token: any): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"di-container.d.ts","sourceRoot":"","sources":["../../../src/core/container/di-container.ts"],"names":[],"mappings":"AAGA,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAc;IACrC,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,YAAY,CAAuB;
|
|
1
|
+
{"version":3,"file":"di-container.d.ts","sourceRoot":"","sources":["../../../src/core/container/di-container.ts"],"names":[],"mappings":"AAGA,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAc;IACrC,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,UAAU,CAA4B;IAC9C,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,UAAU,CAAuB;IAEzC,MAAM,CAAC,WAAW,IAAI,WAAW;IAOjC,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,GAAG,IAAI;IAY/D,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC;IAuDzB,OAAO,CAAC,cAAc;IAuCtB,OAAO,CAAC,gBAAgB;IAqJxB,OAAO,CAAC,YAAY;IAyCpB,OAAO,CAAC,iBAAiB;IAiBzB,GAAG,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO;IAIxB,eAAe,IAAI,GAAG,EAAE;IAIxB,KAAK,IAAI,IAAI;IAQb,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -7,7 +7,8 @@ class DIContainer {
|
|
|
7
7
|
this.singletons = new Map();
|
|
8
8
|
this.transients = new Map();
|
|
9
9
|
this.factories = new Map();
|
|
10
|
-
this.constructing = new Set();
|
|
10
|
+
this.constructing = new Set();
|
|
11
|
+
this.registered = new Set(); // Track what's actually injectable
|
|
11
12
|
}
|
|
12
13
|
static getInstance() {
|
|
13
14
|
if (!DIContainer.instance) {
|
|
@@ -16,23 +17,28 @@ class DIContainer {
|
|
|
16
17
|
return DIContainer.instance;
|
|
17
18
|
}
|
|
18
19
|
register(token, instance, factory) {
|
|
20
|
+
// Mark this token as registered
|
|
21
|
+
this.registered.add(token);
|
|
19
22
|
if (instance) {
|
|
20
23
|
this.singletons.set(token, instance);
|
|
21
24
|
}
|
|
22
25
|
else if (factory) {
|
|
23
26
|
this.factories.set(token, factory);
|
|
24
27
|
}
|
|
28
|
+
// If neither instance nor factory, it will be created on-demand
|
|
25
29
|
}
|
|
26
30
|
resolve(token) {
|
|
27
|
-
// Check
|
|
31
|
+
// Check if this is actually an injectable class
|
|
32
|
+
if (typeof token === "function" && !this.registered.has(token)) {
|
|
33
|
+
throw new Error(`Cannot resolve ${token.name}: Not registered as injectable. ` +
|
|
34
|
+
`Did you forget to add @Injectable(), @Service(), @Controller(), or @Repository()?`);
|
|
35
|
+
}
|
|
28
36
|
if (this.constructing.has(token)) {
|
|
29
37
|
throw new Error(`Circular dependency detected for ${token.name || token}`);
|
|
30
38
|
}
|
|
31
|
-
// Return existing singleton
|
|
32
39
|
if (this.singletons.has(token)) {
|
|
33
40
|
return this.singletons.get(token);
|
|
34
41
|
}
|
|
35
|
-
// Use factory if available
|
|
36
42
|
if (this.factories.has(token)) {
|
|
37
43
|
const factory = this.factories.get(token);
|
|
38
44
|
const instance = factory();
|
|
@@ -42,7 +48,6 @@ class DIContainer {
|
|
|
42
48
|
}
|
|
43
49
|
return instance;
|
|
44
50
|
}
|
|
45
|
-
// Create new instance
|
|
46
51
|
if (typeof token === "function") {
|
|
47
52
|
this.constructing.add(token);
|
|
48
53
|
try {
|
|
@@ -62,76 +67,127 @@ class DIContainer {
|
|
|
62
67
|
throw new Error(`Cannot resolve dependency: ${token}`);
|
|
63
68
|
}
|
|
64
69
|
createInstance(target) {
|
|
65
|
-
|
|
70
|
+
console.log(` šØ Creating instance of ${target.name}`);
|
|
66
71
|
const paramTypes = Reflect.getMetadata("design:paramtypes", target) || [];
|
|
67
|
-
|
|
68
|
-
const params = paramTypes.map((type) => {
|
|
72
|
+
const params = paramTypes.map((type, index) => {
|
|
69
73
|
if (!type || type === Object) {
|
|
74
|
+
console.warn(` ā ļø Constructor param ${index} of ${target.name} has no type metadata`);
|
|
70
75
|
return undefined;
|
|
71
76
|
}
|
|
77
|
+
console.log(` š¦ Resolving constructor dependency: ${type.name}`);
|
|
72
78
|
return this.resolve(type);
|
|
73
79
|
});
|
|
74
|
-
// Create instance
|
|
75
80
|
const instance = new target(...params);
|
|
76
|
-
// Inject properties
|
|
81
|
+
// Inject properties
|
|
77
82
|
this.injectProperties(instance);
|
|
78
|
-
// Call post-construct
|
|
79
|
-
|
|
80
|
-
|
|
83
|
+
// Call post-construct
|
|
84
|
+
const postConstructMethod = Reflect.getMetadata(metadata_keys_1.METADATA_KEYS.POST_CONSTRUCT, target);
|
|
85
|
+
if (postConstructMethod &&
|
|
86
|
+
typeof instance[postConstructMethod] === "function") {
|
|
87
|
+
console.log(` šÆ Calling @PostConstruct: ${target.name}.${postConstructMethod}()`);
|
|
88
|
+
instance[postConstructMethod]();
|
|
81
89
|
}
|
|
82
90
|
return instance;
|
|
83
91
|
}
|
|
84
92
|
injectProperties(instance) {
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
//
|
|
90
|
-
const
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
93
|
+
const target = instance.constructor;
|
|
94
|
+
let currentProto = target.prototype;
|
|
95
|
+
// Walk the prototype chain
|
|
96
|
+
while (currentProto && currentProto !== Object.prototype) {
|
|
97
|
+
// Get all property names including inherited ones
|
|
98
|
+
const propertyNames = Object.getOwnPropertyNames(currentProto);
|
|
99
|
+
for (const prop of propertyNames) {
|
|
100
|
+
// Skip constructor
|
|
101
|
+
if (prop === "constructor")
|
|
102
|
+
continue;
|
|
103
|
+
// Check @Autowired - stores the TYPE to inject
|
|
104
|
+
const autowiredType = Reflect.getMetadata(metadata_keys_1.METADATA_KEYS.AUTOWIRED, currentProto, prop);
|
|
105
|
+
if (autowiredType) {
|
|
106
|
+
console.log(` š @Autowired: ${target.name}.${prop} = ${autowiredType.name}`);
|
|
107
|
+
const isOptional = Reflect.getMetadata(metadata_keys_1.METADATA_KEYS.OPTIONAL, currentProto, prop);
|
|
108
|
+
try {
|
|
109
|
+
instance[prop] = this.resolve(autowiredType);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
if (!isOptional) {
|
|
113
|
+
throw new Error(`Failed to autowire ${autowiredType.name} into ${target.name}.${prop}: ${error}`);
|
|
114
|
+
}
|
|
115
|
+
console.warn(` ā ļø Optional autowired dependency ${autowiredType.name} not available`);
|
|
116
|
+
instance[prop] = undefined;
|
|
117
|
+
}
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
// Check @Inject - stores the TOKEN to inject
|
|
121
|
+
const injectToken = Reflect.getMetadata(metadata_keys_1.METADATA_KEYS.INJECT, currentProto, prop);
|
|
122
|
+
if (injectToken) {
|
|
123
|
+
const tokenName = typeof injectToken === "string" ? injectToken : injectToken.name;
|
|
124
|
+
console.log(` š @Inject: ${target.name}.${prop} = ${tokenName}`);
|
|
125
|
+
const isOptional = Reflect.getMetadata(metadata_keys_1.METADATA_KEYS.OPTIONAL, currentProto, prop);
|
|
126
|
+
try {
|
|
127
|
+
instance[prop] = this.resolve(injectToken);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
if (!isOptional) {
|
|
131
|
+
throw new Error(`Failed to inject ${tokenName} into ${target.name}.${prop}: ${error}`);
|
|
132
|
+
}
|
|
133
|
+
console.warn(` ā ļø Optional inject dependency ${tokenName} not available`);
|
|
134
|
+
instance[prop] = undefined;
|
|
135
|
+
}
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
// Check @Value
|
|
139
|
+
const valueExpression = Reflect.getMetadata(metadata_keys_1.METADATA_KEYS.VALUE, currentProto, prop);
|
|
140
|
+
if (valueExpression !== undefined) {
|
|
141
|
+
console.log(` š§ @Value: ${target.name}.${prop} = ${valueExpression}`);
|
|
142
|
+
instance[prop] = this.resolveValue(valueExpression);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
// Check @InjectRepository
|
|
146
|
+
const repositoryEntity = Reflect.getMetadata(metadata_keys_1.METADATA_KEYS.INJECT_REPOSITORY, currentProto, prop);
|
|
147
|
+
if (repositoryEntity) {
|
|
148
|
+
console.log(` š¾ @InjectRepository: ${target.name}.${prop} = Repository<${repositoryEntity.name}>`);
|
|
149
|
+
instance[prop] = this.resolveRepository(repositoryEntity);
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// Check @Lazy
|
|
153
|
+
const isLazy = Reflect.getMetadata(metadata_keys_1.METADATA_KEYS.LAZY, currentProto, prop);
|
|
154
|
+
if (isLazy) {
|
|
155
|
+
const type = Reflect.getMetadata("design:type", currentProto, prop);
|
|
156
|
+
console.log(` ā³ @Lazy: ${target.name}.${prop} (will resolve on access)`);
|
|
157
|
+
let cached = null;
|
|
158
|
+
let resolved = false;
|
|
159
|
+
Object.defineProperty(instance, prop, {
|
|
160
|
+
get: () => {
|
|
161
|
+
if (!resolved) {
|
|
162
|
+
console.log(` š Lazy-loading ${type.name} for ${target.name}.${prop}`);
|
|
163
|
+
cached = this.resolve(type);
|
|
164
|
+
resolved = true;
|
|
165
|
+
}
|
|
166
|
+
return cached;
|
|
167
|
+
},
|
|
168
|
+
enumerable: true,
|
|
169
|
+
configurable: true,
|
|
170
|
+
});
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
112
173
|
}
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
getAllPropertyKeys(obj) {
|
|
116
|
-
const keys = new Set();
|
|
117
|
-
let current = obj;
|
|
118
|
-
while (current && current !== Object.prototype) {
|
|
119
|
-
Object.getOwnPropertyNames(current).forEach((key) => keys.add(key));
|
|
120
|
-
current = Object.getPrototypeOf(current);
|
|
174
|
+
currentProto = Object.getPrototypeOf(currentProto);
|
|
121
175
|
}
|
|
122
|
-
return Array.from(keys);
|
|
123
176
|
}
|
|
124
177
|
resolveValue(expression) {
|
|
125
|
-
|
|
126
|
-
const match = expression.match(/\$\{([^}]+)\}|\$([A-Z_][A-Z0-9_]*)/i);
|
|
178
|
+
const match = expression.match(/\$\{([^:}]+)(?::([^}]*))?\}|\$([A-Z_][A-Z0-9_]*)/i);
|
|
127
179
|
if (match) {
|
|
128
|
-
const key = match[1] || match[
|
|
180
|
+
const key = match[1] || match[3];
|
|
181
|
+
const defaultValue = match[2];
|
|
129
182
|
const value = process.env[key];
|
|
130
183
|
if (value === undefined) {
|
|
131
|
-
|
|
184
|
+
if (defaultValue !== undefined) {
|
|
185
|
+
return defaultValue;
|
|
186
|
+
}
|
|
187
|
+
console.warn(`ā ļø Environment variable "${key}" not defined`);
|
|
132
188
|
return "";
|
|
133
189
|
}
|
|
134
|
-
//
|
|
190
|
+
// Parse JSON
|
|
135
191
|
if (value.startsWith("{") || value.startsWith("[")) {
|
|
136
192
|
try {
|
|
137
193
|
return JSON.parse(value);
|
|
@@ -141,8 +197,8 @@ class DIContainer {
|
|
|
141
197
|
}
|
|
142
198
|
}
|
|
143
199
|
// Parse numbers
|
|
144
|
-
if (/^\d
|
|
145
|
-
return
|
|
200
|
+
if (/^\d+(\.\d+)?$/.test(value)) {
|
|
201
|
+
return parseFloat(value);
|
|
146
202
|
}
|
|
147
203
|
// Parse booleans
|
|
148
204
|
if (value.toLowerCase() === "true")
|
|
@@ -155,20 +211,19 @@ class DIContainer {
|
|
|
155
211
|
}
|
|
156
212
|
resolveRepository(entity) {
|
|
157
213
|
try {
|
|
158
|
-
// Import TypeORM module dynamically to avoid circular dependencies
|
|
159
214
|
const { TypeORMModule } = require("../../typeorm/typeorm-module");
|
|
160
215
|
const dataSource = TypeORMModule.getDataSource();
|
|
216
|
+
if (!dataSource || !dataSource.isInitialized) {
|
|
217
|
+
throw new Error("TypeORM DataSource not initialized");
|
|
218
|
+
}
|
|
161
219
|
return dataSource.getRepository(entity);
|
|
162
220
|
}
|
|
163
221
|
catch (error) {
|
|
164
|
-
throw new Error(`Failed to resolve repository for
|
|
165
|
-
`Make sure TypeORM is initialized before using @InjectRepository.`);
|
|
222
|
+
throw new Error(`Failed to resolve repository for ${entity.name}: ${error?.message}`);
|
|
166
223
|
}
|
|
167
224
|
}
|
|
168
225
|
has(token) {
|
|
169
|
-
return
|
|
170
|
-
this.factories.has(token) ||
|
|
171
|
-
typeof token === "function");
|
|
226
|
+
return this.registered.has(token);
|
|
172
227
|
}
|
|
173
228
|
getAllInstances() {
|
|
174
229
|
return Array.from(this.singletons.values());
|
|
@@ -178,8 +233,8 @@ class DIContainer {
|
|
|
178
233
|
this.transients.clear();
|
|
179
234
|
this.factories.clear();
|
|
180
235
|
this.constructing.clear();
|
|
236
|
+
this.registered.clear();
|
|
181
237
|
}
|
|
182
|
-
// For testing purposes
|
|
183
238
|
reset() {
|
|
184
239
|
this.clear();
|
|
185
240
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"di-container.js","sourceRoot":"","sources":["../../../src/core/container/di-container.ts"],"names":[],"mappings":";;;AAAA,6DAA0D;AAG1D,MAAa,WAAW;IAAxB;QAEU,eAAU,GAAkB,IAAI,GAAG,EAAE,CAAC;QACtC,eAAU,GAAkB,IAAI,GAAG,EAAE,CAAC;QACtC,cAAS,GAAwB,IAAI,GAAG,EAAE,CAAC;QAC3C,iBAAY,GAAa,IAAI,GAAG,EAAE,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"di-container.js","sourceRoot":"","sources":["../../../src/core/container/di-container.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../../src/web/application.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,OAAO,EAAmC,MAAM,SAAS,CAAC;AAY5E,qBAAa,sBAAsB;IACjC,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,eAAe,CAAkB;;IAUzC,OAAO,CAAC,eAAe;IAQjB,SAAS,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IA6B7C;;OAEG;YACW,cAAc;IAqB5B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAgC3B,OAAO,CAAC,6BAA6B;
|
|
1
|
+
{"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../../src/web/application.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,OAAO,EAAmC,MAAM,SAAS,CAAC;AAY5E,qBAAa,sBAAsB;IACjC,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,eAAe,CAAkB;;IAUzC,OAAO,CAAC,eAAe;IAQjB,SAAS,CAAC,QAAQ,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;IA6B7C;;OAEG;YACW,cAAc;IAqB5B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAgC3B,OAAO,CAAC,6BAA6B;IAgDrC,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,cAAc;IAqCtB,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,cAAc;IA+DtB,OAAO,CAAC,cAAc;IAWtB,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,uBAAuB;IA+B/B,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,YAAY;IAapB,aAAa,IAAI,OAAO;CAGzB"}
|
package/dist/web/application.js
CHANGED
|
@@ -134,30 +134,39 @@ class FragmentWebApplication {
|
|
|
134
134
|
}
|
|
135
135
|
discoverAndRegisterComponents() {
|
|
136
136
|
const classes = this.metadataStorage.getAllClasses();
|
|
137
|
-
|
|
137
|
+
console.log(`\nš¦ Discovered ${classes.length} component(s)`);
|
|
138
|
+
// Group by type for display
|
|
138
139
|
const grouped = classes.reduce((acc, cls) => {
|
|
139
140
|
if (!acc[cls.type])
|
|
140
141
|
acc[cls.type] = [];
|
|
141
142
|
acc[cls.type].push(cls);
|
|
142
143
|
return acc;
|
|
143
144
|
}, {});
|
|
144
|
-
const total = classes.length;
|
|
145
|
-
const registered = classes.filter((m) => this.shouldRegister(m.target)).length;
|
|
146
|
-
console.log(`\nš¦ Discovered ${total} component(s)`);
|
|
147
145
|
Object.entries(grouped).forEach(([type, items]) => {
|
|
148
146
|
const icon = this.getTypeIcon(type);
|
|
149
147
|
console.log(` ${icon} ${items.length} ${type}(s)`);
|
|
150
148
|
});
|
|
151
|
-
let
|
|
149
|
+
let registered = 0;
|
|
150
|
+
let skipped = 0;
|
|
152
151
|
classes.forEach((metadata) => {
|
|
153
152
|
if (this.shouldRegister(metadata.target)) {
|
|
153
|
+
// CRITICAL: Register with container
|
|
154
154
|
if (!this.container.has(metadata.target)) {
|
|
155
155
|
this.container.register(metadata.target);
|
|
156
|
-
|
|
156
|
+
registered++;
|
|
157
|
+
console.log(` ā Registered: ${metadata.target.name}`);
|
|
157
158
|
}
|
|
158
159
|
}
|
|
160
|
+
else {
|
|
161
|
+
skipped++;
|
|
162
|
+
console.log(` ā Skipped: ${metadata.target.name} (conditional check failed)`);
|
|
163
|
+
}
|
|
159
164
|
});
|
|
160
|
-
console.log(
|
|
165
|
+
console.log(`\n ā Registered ${registered}/${classes.length} component(s)`);
|
|
166
|
+
if (skipped > 0) {
|
|
167
|
+
console.log(` ā Skipped ${skipped} (conditions not met)`);
|
|
168
|
+
}
|
|
169
|
+
console.log("");
|
|
161
170
|
}
|
|
162
171
|
getTypeIcon(type) {
|
|
163
172
|
const icons = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application.js","sourceRoot":"","sources":["../../src/web/application.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,sDAA4E;AAC5E,oDAA4B;AAC5B,gDAAwB;AACxB,8DAAsC;AACtC,uCAAyB;AACzB,2CAA6B;AAC7B,iEAA6D;AAC7D,wEAAoE;AACpE,kEAA+D;AAC/D,yEAAqE;AACrE,8DAA0D;AAE1D,MAAa,sBAAsB;IAKjC;QACE,IAAI,CAAC,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,0BAAW,CAAC,WAAW,EAAE,CAAC;QAC3C,IAAI,CAAC,eAAe,GAAG,kCAAe,CAAC,WAAW,EAAE,CAAC;QACrD,IAAI,CAAC,eAAe,EAAE,CAAC;QACvB,IAAI,
|
|
1
|
+
{"version":3,"file":"application.js","sourceRoot":"","sources":["../../src/web/application.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -6,7 +6,8 @@ export class DIContainer {
|
|
|
6
6
|
private singletons: Map<any, any> = new Map();
|
|
7
7
|
private transients: Map<any, any> = new Map();
|
|
8
8
|
private factories: Map<any, () => any> = new Map();
|
|
9
|
-
private constructing: Set<any> = new Set();
|
|
9
|
+
private constructing: Set<any> = new Set();
|
|
10
|
+
private registered: Set<any> = new Set(); // Track what's actually injectable
|
|
10
11
|
|
|
11
12
|
static getInstance(): DIContainer {
|
|
12
13
|
if (!DIContainer.instance) {
|
|
@@ -16,27 +17,36 @@ export class DIContainer {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
register(token: any, instance?: any, factory?: () => any): void {
|
|
20
|
+
// Mark this token as registered
|
|
21
|
+
this.registered.add(token);
|
|
22
|
+
|
|
19
23
|
if (instance) {
|
|
20
24
|
this.singletons.set(token, instance);
|
|
21
25
|
} else if (factory) {
|
|
22
26
|
this.factories.set(token, factory);
|
|
23
27
|
}
|
|
28
|
+
// If neither instance nor factory, it will be created on-demand
|
|
24
29
|
}
|
|
25
30
|
|
|
26
31
|
resolve<T>(token: any): T {
|
|
27
|
-
// Check
|
|
32
|
+
// Check if this is actually an injectable class
|
|
33
|
+
if (typeof token === "function" && !this.registered.has(token)) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
`Cannot resolve ${token.name}: Not registered as injectable. ` +
|
|
36
|
+
`Did you forget to add @Injectable(), @Service(), @Controller(), or @Repository()?`,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
28
40
|
if (this.constructing.has(token)) {
|
|
29
41
|
throw new Error(
|
|
30
42
|
`Circular dependency detected for ${token.name || token}`,
|
|
31
43
|
);
|
|
32
44
|
}
|
|
33
45
|
|
|
34
|
-
// Return existing singleton
|
|
35
46
|
if (this.singletons.has(token)) {
|
|
36
47
|
return this.singletons.get(token);
|
|
37
48
|
}
|
|
38
49
|
|
|
39
|
-
// Use factory if available
|
|
40
50
|
if (this.factories.has(token)) {
|
|
41
51
|
const factory = this.factories.get(token)!;
|
|
42
52
|
const instance = factory();
|
|
@@ -50,7 +60,6 @@ export class DIContainer {
|
|
|
50
60
|
return instance;
|
|
51
61
|
}
|
|
52
62
|
|
|
53
|
-
// Create new instance
|
|
54
63
|
if (typeof token === "function") {
|
|
55
64
|
this.constructing.add(token);
|
|
56
65
|
|
|
@@ -75,103 +84,211 @@ export class DIContainer {
|
|
|
75
84
|
}
|
|
76
85
|
|
|
77
86
|
private createInstance(target: any): any {
|
|
78
|
-
|
|
87
|
+
console.log(` šØ Creating instance of ${target.name}`);
|
|
88
|
+
|
|
79
89
|
const paramTypes = Reflect.getMetadata("design:paramtypes", target) || [];
|
|
80
90
|
|
|
81
|
-
|
|
82
|
-
const params = paramTypes.map((type: any) => {
|
|
91
|
+
const params = paramTypes.map((type: any, index: number) => {
|
|
83
92
|
if (!type || type === Object) {
|
|
93
|
+
console.warn(
|
|
94
|
+
` ā ļø Constructor param ${index} of ${target.name} has no type metadata`,
|
|
95
|
+
);
|
|
84
96
|
return undefined;
|
|
85
97
|
}
|
|
98
|
+
console.log(` š¦ Resolving constructor dependency: ${type.name}`);
|
|
86
99
|
return this.resolve(type);
|
|
87
100
|
});
|
|
88
101
|
|
|
89
|
-
// Create instance
|
|
90
102
|
const instance = new target(...params);
|
|
91
103
|
|
|
92
|
-
// Inject properties
|
|
104
|
+
// Inject properties
|
|
93
105
|
this.injectProperties(instance);
|
|
94
106
|
|
|
95
|
-
// Call post-construct
|
|
96
|
-
|
|
97
|
-
|
|
107
|
+
// Call post-construct
|
|
108
|
+
const postConstructMethod = Reflect.getMetadata(
|
|
109
|
+
METADATA_KEYS.POST_CONSTRUCT,
|
|
110
|
+
target,
|
|
111
|
+
);
|
|
112
|
+
if (
|
|
113
|
+
postConstructMethod &&
|
|
114
|
+
typeof instance[postConstructMethod] === "function"
|
|
115
|
+
) {
|
|
116
|
+
console.log(
|
|
117
|
+
` šÆ Calling @PostConstruct: ${target.name}.${postConstructMethod}()`,
|
|
118
|
+
);
|
|
119
|
+
instance[postConstructMethod]();
|
|
98
120
|
}
|
|
99
121
|
|
|
100
122
|
return instance;
|
|
101
123
|
}
|
|
102
124
|
|
|
103
125
|
private injectProperties(instance: any): void {
|
|
104
|
-
const
|
|
126
|
+
const target = instance.constructor;
|
|
127
|
+
let currentProto = target.prototype;
|
|
128
|
+
|
|
129
|
+
// Walk the prototype chain
|
|
130
|
+
while (currentProto && currentProto !== Object.prototype) {
|
|
131
|
+
// Get all property names including inherited ones
|
|
132
|
+
const propertyNames = Object.getOwnPropertyNames(currentProto);
|
|
133
|
+
|
|
134
|
+
for (const prop of propertyNames) {
|
|
135
|
+
// Skip constructor
|
|
136
|
+
if (prop === "constructor") continue;
|
|
137
|
+
|
|
138
|
+
// Check @Autowired - stores the TYPE to inject
|
|
139
|
+
const autowiredType = Reflect.getMetadata(
|
|
140
|
+
METADATA_KEYS.AUTOWIRED,
|
|
141
|
+
currentProto,
|
|
142
|
+
prop,
|
|
143
|
+
);
|
|
105
144
|
|
|
106
|
-
|
|
107
|
-
|
|
145
|
+
if (autowiredType) {
|
|
146
|
+
console.log(
|
|
147
|
+
` š @Autowired: ${target.name}.${prop} = ${autowiredType.name}`,
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
const isOptional = Reflect.getMetadata(
|
|
151
|
+
METADATA_KEYS.OPTIONAL,
|
|
152
|
+
currentProto,
|
|
153
|
+
prop,
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
instance[prop] = this.resolve(autowiredType);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
if (!isOptional) {
|
|
160
|
+
throw new Error(
|
|
161
|
+
`Failed to autowire ${autowiredType.name} into ${target.name}.${prop}: ${error}`,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
console.warn(
|
|
165
|
+
` ā ļø Optional autowired dependency ${autowiredType.name} not available`,
|
|
166
|
+
);
|
|
167
|
+
instance[prop] = undefined;
|
|
168
|
+
}
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
108
171
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
);
|
|
116
|
-
if (autowired) {
|
|
117
|
-
instance[prop] = this.resolve(autowired);
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
172
|
+
// Check @Inject - stores the TOKEN to inject
|
|
173
|
+
const injectToken = Reflect.getMetadata(
|
|
174
|
+
METADATA_KEYS.INJECT,
|
|
175
|
+
currentProto,
|
|
176
|
+
prop,
|
|
177
|
+
);
|
|
120
178
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
179
|
+
if (injectToken) {
|
|
180
|
+
const tokenName =
|
|
181
|
+
typeof injectToken === "string" ? injectToken : injectToken.name;
|
|
182
|
+
console.log(` š @Inject: ${target.name}.${prop} = ${tokenName}`);
|
|
183
|
+
|
|
184
|
+
const isOptional = Reflect.getMetadata(
|
|
185
|
+
METADATA_KEYS.OPTIONAL,
|
|
186
|
+
currentProto,
|
|
187
|
+
prop,
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
instance[prop] = this.resolve(injectToken);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
if (!isOptional) {
|
|
194
|
+
throw new Error(
|
|
195
|
+
`Failed to inject ${tokenName} into ${target.name}.${prop}: ${error}`,
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
console.warn(
|
|
199
|
+
` ā ļø Optional inject dependency ${tokenName} not available`,
|
|
200
|
+
);
|
|
201
|
+
instance[prop] = undefined;
|
|
202
|
+
}
|
|
203
|
+
continue;
|
|
204
|
+
}
|
|
127
205
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
206
|
+
// Check @Value
|
|
207
|
+
const valueExpression = Reflect.getMetadata(
|
|
208
|
+
METADATA_KEYS.VALUE,
|
|
209
|
+
currentProto,
|
|
210
|
+
prop,
|
|
211
|
+
);
|
|
134
212
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
instance[prop] = this.resolveRepository(repositoryEntity);
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
}
|
|
213
|
+
if (valueExpression !== undefined) {
|
|
214
|
+
console.log(
|
|
215
|
+
` š§ @Value: ${target.name}.${prop} = ${valueExpression}`,
|
|
216
|
+
);
|
|
217
|
+
instance[prop] = this.resolveValue(valueExpression);
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
147
220
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
221
|
+
// Check @InjectRepository
|
|
222
|
+
const repositoryEntity = Reflect.getMetadata(
|
|
223
|
+
METADATA_KEYS.INJECT_REPOSITORY,
|
|
224
|
+
currentProto,
|
|
225
|
+
prop,
|
|
226
|
+
);
|
|
151
227
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
228
|
+
if (repositoryEntity) {
|
|
229
|
+
console.log(
|
|
230
|
+
` š¾ @InjectRepository: ${target.name}.${prop} = Repository<${repositoryEntity.name}>`,
|
|
231
|
+
);
|
|
232
|
+
instance[prop] = this.resolveRepository(repositoryEntity);
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Check @Lazy
|
|
237
|
+
const isLazy = Reflect.getMetadata(
|
|
238
|
+
METADATA_KEYS.LAZY,
|
|
239
|
+
currentProto,
|
|
240
|
+
prop,
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
if (isLazy) {
|
|
244
|
+
const type = Reflect.getMetadata("design:type", currentProto, prop);
|
|
245
|
+
console.log(
|
|
246
|
+
` ā³ @Lazy: ${target.name}.${prop} (will resolve on access)`,
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
let cached: any = null;
|
|
250
|
+
let resolved = false;
|
|
251
|
+
|
|
252
|
+
Object.defineProperty(instance, prop, {
|
|
253
|
+
get: () => {
|
|
254
|
+
if (!resolved) {
|
|
255
|
+
console.log(
|
|
256
|
+
` š Lazy-loading ${type.name} for ${target.name}.${prop}`,
|
|
257
|
+
);
|
|
258
|
+
cached = this.resolve(type);
|
|
259
|
+
resolved = true;
|
|
260
|
+
}
|
|
261
|
+
return cached;
|
|
262
|
+
},
|
|
263
|
+
enumerable: true,
|
|
264
|
+
configurable: true,
|
|
265
|
+
});
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
156
269
|
|
|
157
|
-
|
|
270
|
+
currentProto = Object.getPrototypeOf(currentProto);
|
|
271
|
+
}
|
|
158
272
|
}
|
|
159
273
|
|
|
160
274
|
private resolveValue(expression: string): any {
|
|
161
|
-
|
|
162
|
-
|
|
275
|
+
const match = expression.match(
|
|
276
|
+
/\$\{([^:}]+)(?::([^}]*))?\}|\$([A-Z_][A-Z0-9_]*)/i,
|
|
277
|
+
);
|
|
163
278
|
if (match) {
|
|
164
|
-
const key = match[1] || match[
|
|
279
|
+
const key = match[1] || match[3];
|
|
280
|
+
const defaultValue = match[2];
|
|
165
281
|
const value = process.env[key];
|
|
166
282
|
|
|
167
283
|
if (value === undefined) {
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
284
|
+
if (defaultValue !== undefined) {
|
|
285
|
+
return defaultValue;
|
|
286
|
+
}
|
|
287
|
+
console.warn(`ā ļø Environment variable "${key}" not defined`);
|
|
171
288
|
return "";
|
|
172
289
|
}
|
|
173
290
|
|
|
174
|
-
//
|
|
291
|
+
// Parse JSON
|
|
175
292
|
if (value.startsWith("{") || value.startsWith("[")) {
|
|
176
293
|
try {
|
|
177
294
|
return JSON.parse(value);
|
|
@@ -181,8 +298,8 @@ export class DIContainer {
|
|
|
181
298
|
}
|
|
182
299
|
|
|
183
300
|
// Parse numbers
|
|
184
|
-
if (/^\d
|
|
185
|
-
return
|
|
301
|
+
if (/^\d+(\.\d+)?$/.test(value)) {
|
|
302
|
+
return parseFloat(value);
|
|
186
303
|
}
|
|
187
304
|
|
|
188
305
|
// Parse booleans
|
|
@@ -197,24 +314,23 @@ export class DIContainer {
|
|
|
197
314
|
|
|
198
315
|
private resolveRepository(entity: any): any {
|
|
199
316
|
try {
|
|
200
|
-
// Import TypeORM module dynamically to avoid circular dependencies
|
|
201
317
|
const { TypeORMModule } = require("../../typeorm/typeorm-module");
|
|
202
318
|
const dataSource = TypeORMModule.getDataSource();
|
|
319
|
+
|
|
320
|
+
if (!dataSource || !dataSource.isInitialized) {
|
|
321
|
+
throw new Error("TypeORM DataSource not initialized");
|
|
322
|
+
}
|
|
323
|
+
|
|
203
324
|
return dataSource.getRepository(entity);
|
|
204
325
|
} catch (error) {
|
|
205
326
|
throw new Error(
|
|
206
|
-
`Failed to resolve repository for
|
|
207
|
-
`Make sure TypeORM is initialized before using @InjectRepository.`,
|
|
327
|
+
`Failed to resolve repository for ${entity.name}: ${(error as Error)?.message}`,
|
|
208
328
|
);
|
|
209
329
|
}
|
|
210
330
|
}
|
|
211
331
|
|
|
212
332
|
has(token: any): boolean {
|
|
213
|
-
return (
|
|
214
|
-
this.singletons.has(token) ||
|
|
215
|
-
this.factories.has(token) ||
|
|
216
|
-
typeof token === "function"
|
|
217
|
-
);
|
|
333
|
+
return this.registered.has(token);
|
|
218
334
|
}
|
|
219
335
|
|
|
220
336
|
getAllInstances(): any[] {
|
|
@@ -226,9 +342,9 @@ export class DIContainer {
|
|
|
226
342
|
this.transients.clear();
|
|
227
343
|
this.factories.clear();
|
|
228
344
|
this.constructing.clear();
|
|
345
|
+
this.registered.clear();
|
|
229
346
|
}
|
|
230
347
|
|
|
231
|
-
// For testing purposes
|
|
232
348
|
reset(): void {
|
|
233
349
|
this.clear();
|
|
234
350
|
}
|
package/src/web/application.ts
CHANGED
|
@@ -20,7 +20,7 @@ export class FragmentWebApplication {
|
|
|
20
20
|
this.container = DIContainer.getInstance();
|
|
21
21
|
this.metadataStorage = MetadataStorage.getInstance();
|
|
22
22
|
this.setupMiddleware();
|
|
23
|
-
this
|
|
23
|
+
this;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
private setupMiddleware(): void {
|
|
@@ -122,7 +122,9 @@ export class FragmentWebApplication {
|
|
|
122
122
|
private discoverAndRegisterComponents(): void {
|
|
123
123
|
const classes = this.metadataStorage.getAllClasses();
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
console.log(`\nš¦ Discovered ${classes.length} component(s)`);
|
|
126
|
+
|
|
127
|
+
// Group by type for display
|
|
126
128
|
const grouped = classes.reduce(
|
|
127
129
|
(acc, cls) => {
|
|
128
130
|
if (!acc[cls.type]) acc[cls.type] = [];
|
|
@@ -132,29 +134,37 @@ export class FragmentWebApplication {
|
|
|
132
134
|
{} as Record<string, any[]>,
|
|
133
135
|
);
|
|
134
136
|
|
|
135
|
-
const total = classes.length;
|
|
136
|
-
const registered = classes.filter((m) =>
|
|
137
|
-
this.shouldRegister(m.target),
|
|
138
|
-
).length;
|
|
139
|
-
|
|
140
|
-
console.log(`\nš¦ Discovered ${total} component(s)`);
|
|
141
|
-
|
|
142
137
|
Object.entries(grouped).forEach(([type, items]) => {
|
|
143
138
|
const icon = this.getTypeIcon(type);
|
|
144
139
|
console.log(` ${icon} ${items.length} ${type}(s)`);
|
|
145
140
|
});
|
|
146
141
|
|
|
147
|
-
let
|
|
142
|
+
let registered = 0;
|
|
143
|
+
let skipped = 0;
|
|
144
|
+
|
|
148
145
|
classes.forEach((metadata) => {
|
|
149
146
|
if (this.shouldRegister(metadata.target)) {
|
|
147
|
+
// CRITICAL: Register with container
|
|
150
148
|
if (!this.container.has(metadata.target)) {
|
|
151
149
|
this.container.register(metadata.target);
|
|
152
|
-
|
|
150
|
+
registered++;
|
|
151
|
+
console.log(` ā Registered: ${metadata.target.name}`);
|
|
153
152
|
}
|
|
153
|
+
} else {
|
|
154
|
+
skipped++;
|
|
155
|
+
console.log(
|
|
156
|
+
` ā Skipped: ${metadata.target.name} (conditional check failed)`,
|
|
157
|
+
);
|
|
154
158
|
}
|
|
155
159
|
});
|
|
156
160
|
|
|
157
|
-
console.log(
|
|
161
|
+
console.log(
|
|
162
|
+
`\n ā Registered ${registered}/${classes.length} component(s)`,
|
|
163
|
+
);
|
|
164
|
+
if (skipped > 0) {
|
|
165
|
+
console.log(` ā Skipped ${skipped} (conditions not met)`);
|
|
166
|
+
}
|
|
167
|
+
console.log("");
|
|
158
168
|
}
|
|
159
169
|
|
|
160
170
|
private getTypeIcon(type: string): string {
|