@nextrush/di 3.0.0

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/index.js ADDED
@@ -0,0 +1,449 @@
1
+ import 'reflect-metadata';
2
+ import { container as container$1, singleton, injectable, inject as inject$1, delay as delay$1 } from 'tsyringe';
3
+
4
+ var __defProp = Object.defineProperty;
5
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
+
7
+ // src/errors.ts
8
+ var V8Error = Error;
9
+ var DIError = class extends Error {
10
+ static {
11
+ __name(this, "DIError");
12
+ }
13
+ constructor(message) {
14
+ super(message);
15
+ this.name = "DIError";
16
+ V8Error.captureStackTrace?.(this, this.constructor);
17
+ }
18
+ };
19
+ var DependencyResolutionError = class extends DIError {
20
+ static {
21
+ __name(this, "DependencyResolutionError");
22
+ }
23
+ chain;
24
+ missingDependency;
25
+ constructor(chain, missing) {
26
+ const chainStr = chain.length > 0 ? chain.join(" \u2192 ") + " \u2192 " : "";
27
+ super(`
28
+ \u274C Dependency Resolution Failed
29
+
30
+ ${chainStr}${missing}
31
+
32
+ "${missing}" is not registered in the container.
33
+
34
+ Possible fixes:
35
+ \u2022 Add @Service(), @Repository(), or @Config() decorator to ${missing}
36
+ \u2022 Ensure ${missing} is imported before container.resolve() is called
37
+ \u2022 Register manually: container.register(${missing}, { useClass: ${missing} })
38
+ \u2022 Check for typos in the class name or import path
39
+ `);
40
+ this.name = "DependencyResolutionError";
41
+ this.chain = chain;
42
+ this.missingDependency = missing;
43
+ }
44
+ };
45
+ var CircularDependencyError = class extends DIError {
46
+ static {
47
+ __name(this, "CircularDependencyError");
48
+ }
49
+ cycle;
50
+ constructor(cycle) {
51
+ const cycleStr = cycle.join(" \u2192 ") + " \u2192 " + cycle[0];
52
+ super(`
53
+ \u274C Circular Dependency Detected
54
+
55
+ ${cycleStr}
56
+
57
+ This creates an infinite loop during resolution.
58
+
59
+ Strategies to break the cycle:
60
+ 1. Extract shared logic into a third service
61
+ 2. Use @inject(delay(() => ServiceClass)) for lazy resolution
62
+ 3. Refactor to use event-driven communication
63
+ 4. Consider if the circular dependency indicates a design issue
64
+ `);
65
+ this.name = "CircularDependencyError";
66
+ this.cycle = cycle;
67
+ }
68
+ };
69
+ var TypeInferenceError = class extends DIError {
70
+ static {
71
+ __name(this, "TypeInferenceError");
72
+ }
73
+ className;
74
+ parameterIndex;
75
+ constructor(className, parameterIndex) {
76
+ super(`
77
+ \u274C Cannot Resolve Constructor Parameter
78
+
79
+ ${className} constructor parameter at index ${parameterIndex} has no type information.
80
+
81
+ This usually means:
82
+ 1. Missing type annotation on the parameter
83
+ 2. emitDecoratorMetadata is not enabled in tsconfig.json
84
+
85
+ Fix option 1 - Add explicit type annotation:
86
+ constructor(private service: ServiceClass) {}
87
+ ^^^^^^^^^^^^
88
+
89
+ Fix option 2 - Update tsconfig.json:
90
+ {
91
+ "compilerOptions": {
92
+ "experimentalDecorators": true,
93
+ "emitDecoratorMetadata": true
94
+ }
95
+ }
96
+
97
+ Fix option 3 - Use explicit @inject():
98
+ constructor(@inject(ServiceClass) private service: ServiceClass) {}
99
+ `);
100
+ this.name = "TypeInferenceError";
101
+ this.className = className;
102
+ this.parameterIndex = parameterIndex;
103
+ }
104
+ };
105
+ var InvalidProviderError = class extends DIError {
106
+ static {
107
+ __name(this, "InvalidProviderError");
108
+ }
109
+ token;
110
+ constructor(token) {
111
+ super(`
112
+ \u274C Invalid Provider Configuration
113
+
114
+ Token: "${token}"
115
+
116
+ A provider must have one of:
117
+ \u2022 useClass: Constructor function
118
+ \u2022 useValue: Any value
119
+ \u2022 useFactory: Factory function
120
+
121
+ Example:
122
+ container.register(MyService, { useClass: MyService });
123
+ container.register('CONFIG', { useValue: { port: 3000 } });
124
+ container.register(Logger, { useFactory: () => new Logger() });
125
+ `);
126
+ this.name = "InvalidProviderError";
127
+ this.token = token;
128
+ }
129
+ };
130
+ var ContainerDisposedError = class extends DIError {
131
+ static {
132
+ __name(this, "ContainerDisposedError");
133
+ }
134
+ constructor() {
135
+ super(`
136
+ \u274C Container Has Been Disposed
137
+
138
+ The container has been reset or disposed and cannot resolve dependencies.
139
+
140
+ If you're in a test environment, ensure you're creating a fresh container
141
+ for each test or using container.clearInstances() between tests.
142
+ `);
143
+ this.name = "ContainerDisposedError";
144
+ }
145
+ };
146
+ var MissingDependencyError = class extends DIError {
147
+ static {
148
+ __name(this, "MissingDependencyError");
149
+ }
150
+ token;
151
+ constructor(token) {
152
+ super(`
153
+ \u274C Missing Required Dependency
154
+
155
+ Token: "${token}"
156
+
157
+ The requested dependency is not registered in the container.
158
+
159
+ Make sure to:
160
+ 1. Register the dependency before resolving
161
+ 2. Check spelling of the token
162
+ 3. Verify the service has @Service() or @Repository() decorator
163
+ `);
164
+ this.name = "MissingDependencyError";
165
+ this.token = token;
166
+ }
167
+ };
168
+
169
+ // src/container.ts
170
+ function getTokenName(token) {
171
+ if (typeof token === "string") return token;
172
+ if (typeof token === "symbol") return token.toString();
173
+ if (typeof token === "function") return token.name || "Anonymous";
174
+ return String(token);
175
+ }
176
+ __name(getTokenName, "getTokenName");
177
+ function isClassProvider(provider) {
178
+ return "useClass" in provider && typeof provider.useClass === "function";
179
+ }
180
+ __name(isClassProvider, "isClassProvider");
181
+ function isValueProvider(provider) {
182
+ return "useValue" in provider;
183
+ }
184
+ __name(isValueProvider, "isValueProvider");
185
+ function isFactoryProvider(provider) {
186
+ return "useFactory" in provider && typeof provider.useFactory === "function";
187
+ }
188
+ __name(isFactoryProvider, "isFactoryProvider");
189
+ function createContainerWrapper(tsyInstance) {
190
+ const resolutionStack = /* @__PURE__ */ new Set();
191
+ const factoryTokens = /* @__PURE__ */ new Set();
192
+ const bootstrappedValues = /* @__PURE__ */ new Map();
193
+ const wrapper = {
194
+ register(token, provider, options) {
195
+ const tokenName = getTokenName(token);
196
+ const tsyToken = token;
197
+ bootstrappedValues.delete(token);
198
+ if (isClassProvider(provider)) {
199
+ if (options?.scope === "singleton") {
200
+ tsyInstance.registerSingleton(tsyToken, provider.useClass);
201
+ } else {
202
+ tsyInstance.register(tsyToken, {
203
+ useClass: provider.useClass
204
+ });
205
+ }
206
+ } else if (isValueProvider(provider)) {
207
+ tsyInstance.register(tsyToken, {
208
+ useValue: provider.useValue
209
+ });
210
+ } else if (isFactoryProvider(provider)) {
211
+ const { inject: injectTokens } = provider;
212
+ factoryTokens.add(token);
213
+ if (injectTokens && injectTokens.length > 0) {
214
+ tsyInstance.register(tsyToken, {
215
+ useFactory: /* @__PURE__ */ __name(() => {
216
+ const deps = injectTokens.map((depToken) => wrapper.resolve(depToken));
217
+ const hasAsyncDep = deps.some((d) => d instanceof Promise);
218
+ if (hasAsyncDep) {
219
+ return Promise.all(deps).then((resolved) => provider.useFactory(...resolved));
220
+ }
221
+ return provider.useFactory(...deps);
222
+ }, "useFactory")
223
+ });
224
+ } else {
225
+ tsyInstance.register(tsyToken, {
226
+ useFactory: /* @__PURE__ */ __name(() => provider.useFactory(wrapper), "useFactory")
227
+ });
228
+ }
229
+ } else {
230
+ throw new InvalidProviderError(tokenName);
231
+ }
232
+ },
233
+ resolve(token) {
234
+ if (bootstrappedValues.has(token)) {
235
+ return bootstrappedValues.get(token);
236
+ }
237
+ const tokenName = getTokenName(token);
238
+ const tsyToken = token;
239
+ if (resolutionStack.has(tokenName)) {
240
+ const cycle = [
241
+ ...resolutionStack,
242
+ tokenName
243
+ ];
244
+ throw new CircularDependencyError(cycle);
245
+ }
246
+ resolutionStack.add(tokenName);
247
+ try {
248
+ const instance = tsyInstance.resolve(tsyToken);
249
+ resolutionStack.delete(tokenName);
250
+ return instance;
251
+ } catch (error) {
252
+ resolutionStack.delete(tokenName);
253
+ if (error instanceof CircularDependencyError) {
254
+ throw error;
255
+ }
256
+ if (error instanceof RangeError && error.message.includes("Maximum call stack")) {
257
+ const cycle = [
258
+ ...resolutionStack,
259
+ tokenName
260
+ ];
261
+ throw new CircularDependencyError(cycle);
262
+ }
263
+ if (error instanceof Error && error.message.includes("Cannot inject the dependency")) {
264
+ const cycle = [
265
+ ...resolutionStack,
266
+ tokenName
267
+ ];
268
+ throw new CircularDependencyError(cycle);
269
+ }
270
+ if (error instanceof Error) {
271
+ const message = error.message.toLowerCase();
272
+ if (message.includes("not registered") || message.includes("cannot resolve") || message.includes("unregistered dependency")) {
273
+ throw new DependencyResolutionError([
274
+ ...resolutionStack
275
+ ], tokenName);
276
+ }
277
+ }
278
+ throw error;
279
+ }
280
+ },
281
+ async resolveAsync(token) {
282
+ if (bootstrappedValues.has(token)) {
283
+ return bootstrappedValues.get(token);
284
+ }
285
+ const result = wrapper.resolve(token);
286
+ return result instanceof Promise ? result : result;
287
+ },
288
+ async bootstrap() {
289
+ for (const token of factoryTokens) {
290
+ if (bootstrappedValues.has(token)) continue;
291
+ const result = wrapper.resolve(token);
292
+ const value = result instanceof Promise ? await result : result;
293
+ bootstrappedValues.set(token, value);
294
+ }
295
+ factoryTokens.clear();
296
+ },
297
+ resolveAll(token) {
298
+ const tsyToken = token;
299
+ try {
300
+ return tsyInstance.resolveAll(tsyToken);
301
+ } catch (error) {
302
+ const message = error instanceof Error ? error.message : String(error);
303
+ if (message.includes("unregistered")) {
304
+ return [];
305
+ }
306
+ throw error;
307
+ }
308
+ },
309
+ isRegistered(token) {
310
+ const tsyToken = token;
311
+ return tsyInstance.isRegistered(tsyToken);
312
+ },
313
+ clearInstances() {
314
+ tsyInstance.clearInstances();
315
+ bootstrappedValues.clear();
316
+ },
317
+ reset() {
318
+ tsyInstance.reset();
319
+ bootstrappedValues.clear();
320
+ factoryTokens.clear();
321
+ },
322
+ createChild() {
323
+ const childTsy = tsyInstance.createChildContainer();
324
+ return createContainerWrapper(childTsy);
325
+ }
326
+ };
327
+ return wrapper;
328
+ }
329
+ __name(createContainerWrapper, "createContainerWrapper");
330
+ var container = createContainerWrapper(container$1);
331
+ function createContainer() {
332
+ const childTsy = container$1.createChildContainer();
333
+ childTsy.reset();
334
+ return createContainerWrapper(childTsy);
335
+ }
336
+ __name(createContainer, "createContainer");
337
+
338
+ // src/types.ts
339
+ var METADATA_KEYS = {
340
+ SERVICE_TYPE: "di:type",
341
+ SERVICE_SCOPE: "di:scope",
342
+ INJECT_TOKEN: "di:inject",
343
+ PARAM_TYPES: "design:paramtypes",
344
+ CONFIG_PREFIX: "di:config:prefix",
345
+ OPTIONAL_PARAMS: "di:optional"
346
+ };
347
+
348
+ // src/decorators.ts
349
+ function Service(options = {}) {
350
+ const scope = options.scope ?? "singleton";
351
+ return (target) => {
352
+ Reflect.defineMetadata(METADATA_KEYS.SERVICE_TYPE, "service", target);
353
+ Reflect.defineMetadata(METADATA_KEYS.SERVICE_SCOPE, scope, target);
354
+ if (scope === "singleton") {
355
+ singleton()(target);
356
+ } else {
357
+ injectable()(target);
358
+ }
359
+ };
360
+ }
361
+ __name(Service, "Service");
362
+ function Repository(options = {}) {
363
+ const scope = options.scope ?? "singleton";
364
+ return (target) => {
365
+ Reflect.defineMetadata(METADATA_KEYS.SERVICE_TYPE, "repository", target);
366
+ Reflect.defineMetadata(METADATA_KEYS.SERVICE_SCOPE, scope, target);
367
+ if (scope === "singleton") {
368
+ singleton()(target);
369
+ } else {
370
+ injectable()(target);
371
+ }
372
+ };
373
+ }
374
+ __name(Repository, "Repository");
375
+ function inject(token) {
376
+ return inject$1(token);
377
+ }
378
+ __name(inject, "inject");
379
+ function Injectable() {
380
+ return (target) => {
381
+ Reflect.defineMetadata(METADATA_KEYS.SERVICE_TYPE, "service", target);
382
+ injectable()(target);
383
+ };
384
+ }
385
+ __name(Injectable, "Injectable");
386
+ var AutoInjectable = Injectable;
387
+ function markInjectable(target) {
388
+ injectable()(target);
389
+ }
390
+ __name(markInjectable, "markInjectable");
391
+ function delay(tokenFactory) {
392
+ return delay$1(tokenFactory);
393
+ }
394
+ __name(delay, "delay");
395
+ function hasServiceMetadata(target) {
396
+ return Reflect.hasMetadata(METADATA_KEYS.SERVICE_TYPE, target);
397
+ }
398
+ __name(hasServiceMetadata, "hasServiceMetadata");
399
+ function getServiceType(target) {
400
+ return Reflect.getMetadata(METADATA_KEYS.SERVICE_TYPE, target);
401
+ }
402
+ __name(getServiceType, "getServiceType");
403
+ function getServiceScope(target) {
404
+ return Reflect.getMetadata(METADATA_KEYS.SERVICE_SCOPE, target);
405
+ }
406
+ __name(getServiceScope, "getServiceScope");
407
+ function Config(options = {}) {
408
+ return (target) => {
409
+ Reflect.defineMetadata(METADATA_KEYS.SERVICE_TYPE, "config", target);
410
+ Reflect.defineMetadata(METADATA_KEYS.SERVICE_SCOPE, "singleton", target);
411
+ if (options.prefix) {
412
+ Reflect.defineMetadata(METADATA_KEYS.CONFIG_PREFIX, options.prefix, target);
413
+ }
414
+ singleton()(target);
415
+ };
416
+ }
417
+ __name(Config, "Config");
418
+ function getConfigPrefix(target) {
419
+ return Reflect.getMetadata(METADATA_KEYS.CONFIG_PREFIX, target);
420
+ }
421
+ __name(getConfigPrefix, "getConfigPrefix");
422
+ function Optional() {
423
+ return (target, _propertyKey, parameterIndex) => {
424
+ const existing = Reflect.getOwnMetadata(METADATA_KEYS.OPTIONAL_PARAMS, target) ?? /* @__PURE__ */ new Set();
425
+ existing.add(parameterIndex);
426
+ Reflect.defineMetadata(METADATA_KEYS.OPTIONAL_PARAMS, existing, target);
427
+ const TSYRINGE_INJECTION_KEY = "injectionTokens";
428
+ const descriptors = Reflect.getOwnMetadata(TSYRINGE_INJECTION_KEY, target) ?? {};
429
+ const descriptor = descriptors[parameterIndex];
430
+ if (descriptor && typeof descriptor === "object" && "token" in descriptor) {
431
+ descriptor.isOptional = true;
432
+ }
433
+ Reflect.defineMetadata(TSYRINGE_INJECTION_KEY, descriptors, target);
434
+ };
435
+ }
436
+ __name(Optional, "Optional");
437
+ function isParameterOptional(target, parameterIndex) {
438
+ const optional = Reflect.getOwnMetadata(METADATA_KEYS.OPTIONAL_PARAMS, target);
439
+ return optional?.has(parameterIndex) ?? false;
440
+ }
441
+ __name(isParameterOptional, "isParameterOptional");
442
+ function getOptionalParams(target) {
443
+ return Reflect.getOwnMetadata(METADATA_KEYS.OPTIONAL_PARAMS, target) ?? /* @__PURE__ */ new Set();
444
+ }
445
+ __name(getOptionalParams, "getOptionalParams");
446
+
447
+ export { AutoInjectable, CircularDependencyError, Config, ContainerDisposedError, DIError, DependencyResolutionError, Injectable, InvalidProviderError, METADATA_KEYS, MissingDependencyError, Optional, Repository, Service, TypeInferenceError, container, createContainer, delay, getConfigPrefix, getOptionalParams, getServiceScope, getServiceType, hasServiceMetadata, inject, isParameterOptional, markInjectable };
448
+ //# sourceMappingURL=index.js.map
449
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/container.ts","../src/types.ts","../src/decorators.ts"],"names":["V8Error","Error","DIError","message","name","captureStackTrace","DependencyResolutionError","chain","missingDependency","missing","chainStr","length","join","CircularDependencyError","cycle","cycleStr","TypeInferenceError","className","parameterIndex","InvalidProviderError","token","ContainerDisposedError","MissingDependencyError","getTokenName","toString","String","isClassProvider","provider","useClass","isValueProvider","isFactoryProvider","useFactory","createContainerWrapper","tsyInstance","resolutionStack","Set","factoryTokens","bootstrappedValues","Map","wrapper","register","options","tokenName","tsyToken","delete","scope","registerSingleton","useValue","inject","injectTokens","add","deps","map","depToken","resolve","hasAsyncDep","some","d","Promise","all","then","resolved","has","get","instance","error","RangeError","includes","toLowerCase","resolveAsync","result","bootstrap","value","set","clear","resolveAll","isRegistered","clearInstances","reset","createChild","childTsy","createChildContainer","container","tsyContainer","createContainer","METADATA_KEYS","SERVICE_TYPE","SERVICE_SCOPE","INJECT_TOKEN","PARAM_TYPES","CONFIG_PREFIX","OPTIONAL_PARAMS","Service","target","Reflect","defineMetadata","tsySingleton","tsyInjectable","Repository","tsyInject","Injectable","AutoInjectable","markInjectable","delay","tokenFactory","tsyDelay","hasServiceMetadata","hasMetadata","getServiceType","getMetadata","getServiceScope","Config","prefix","getConfigPrefix","Optional","_propertyKey","existing","getOwnMetadata","TSYRINGE_INJECTION_KEY","descriptors","descriptor","isOptional","isParameterOptional","optional","getOptionalParams"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @nextrush/di - Errors\n *\n * Production-grade error classes with actionable messages.\n */\n\nconst V8Error = Error as ErrorConstructor & {\n captureStackTrace?: (targetObject: object, constructorOpt?: Function) => void;\n};\n\n/**\n * Base error class for all DI-related errors.\n */\nexport class DIError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'DIError';\n V8Error.captureStackTrace?.(this, this.constructor);\n }\n}\n\n/**\n * Error thrown when a dependency cannot be resolved.\n *\n * Provides clear guidance on how to fix the issue.\n */\nexport class DependencyResolutionError extends DIError {\n public readonly chain: string[];\n public readonly missingDependency: string;\n\n constructor(chain: string[], missing: string) {\n const chainStr = chain.length > 0 ? chain.join(' → ') + ' → ' : '';\n\n super(`\n❌ Dependency Resolution Failed\n\n${chainStr}${missing}\n\n\"${missing}\" is not registered in the container.\n\nPossible fixes:\n • Add @Service(), @Repository(), or @Config() decorator to ${missing}\n • Ensure ${missing} is imported before container.resolve() is called\n • Register manually: container.register(${missing}, { useClass: ${missing} })\n • Check for typos in the class name or import path\n`);\n\n this.name = 'DependencyResolutionError';\n this.chain = chain;\n this.missingDependency = missing;\n }\n}\n\n/**\n * Error thrown when a circular dependency is detected.\n *\n * Provides strategies to break the cycle.\n */\nexport class CircularDependencyError extends DIError {\n public readonly cycle: string[];\n\n constructor(cycle: string[]) {\n const cycleStr = cycle.join(' → ') + ' → ' + cycle[0];\n\n super(`\n❌ Circular Dependency Detected\n\n${cycleStr}\n\nThis creates an infinite loop during resolution.\n\nStrategies to break the cycle:\n 1. Extract shared logic into a third service\n 2. Use @inject(delay(() => ServiceClass)) for lazy resolution\n 3. Refactor to use event-driven communication\n 4. Consider if the circular dependency indicates a design issue\n`);\n\n this.name = 'CircularDependencyError';\n this.cycle = cycle;\n }\n}\n\n/**\n * Error thrown when TypeScript cannot infer constructor parameter types.\n *\n * Usually caused by missing type annotations or incorrect tsconfig.\n */\nexport class TypeInferenceError extends DIError {\n public readonly className: string;\n public readonly parameterIndex: number;\n\n constructor(className: string, parameterIndex: number) {\n super(`\n❌ Cannot Resolve Constructor Parameter\n\n${className} constructor parameter at index ${parameterIndex} has no type information.\n\nThis usually means:\n 1. Missing type annotation on the parameter\n 2. emitDecoratorMetadata is not enabled in tsconfig.json\n\nFix option 1 - Add explicit type annotation:\n constructor(private service: ServiceClass) {}\n ^^^^^^^^^^^^\n\nFix option 2 - Update tsconfig.json:\n {\n \"compilerOptions\": {\n \"experimentalDecorators\": true,\n \"emitDecoratorMetadata\": true\n }\n }\n\nFix option 3 - Use explicit @inject():\n constructor(@inject(ServiceClass) private service: ServiceClass) {}\n`);\n\n this.name = 'TypeInferenceError';\n this.className = className;\n this.parameterIndex = parameterIndex;\n }\n}\n\n/**\n * Error thrown when an invalid provider configuration is given.\n */\nexport class InvalidProviderError extends DIError {\n public readonly token: string;\n\n constructor(token: string) {\n super(`\n❌ Invalid Provider Configuration\n\nToken: \"${token}\"\n\nA provider must have one of:\n • useClass: Constructor function\n • useValue: Any value\n • useFactory: Factory function\n\nExample:\n container.register(MyService, { useClass: MyService });\n container.register('CONFIG', { useValue: { port: 3000 } });\n container.register(Logger, { useFactory: () => new Logger() });\n`);\n\n this.name = 'InvalidProviderError';\n this.token = token;\n }\n}\n\n/**\n * Error thrown when trying to resolve from a disposed container.\n */\nexport class ContainerDisposedError extends DIError {\n constructor() {\n super(`\n❌ Container Has Been Disposed\n\nThe container has been reset or disposed and cannot resolve dependencies.\n\nIf you're in a test environment, ensure you're creating a fresh container\nfor each test or using container.clearInstances() between tests.\n`);\n\n this.name = 'ContainerDisposedError';\n }\n}\n\n/**\n * Error thrown when a required dependency is not found.\n *\n * @deprecated Use {@link DependencyResolutionError} instead — it provides\n * the same information plus the resolution chain context.\n */\nexport class MissingDependencyError extends DIError {\n public readonly token: string;\n\n constructor(token: string) {\n super(`\n❌ Missing Required Dependency\n\nToken: \"${token}\"\n\nThe requested dependency is not registered in the container.\n\nMake sure to:\n 1. Register the dependency before resolving\n 2. Check spelling of the token\n 3. Verify the service has @Service() or @Repository() decorator\n`);\n\n this.name = 'MissingDependencyError';\n this.token = token;\n }\n}\n","/**\n * @nextrush/di - Container\n *\n * Lightweight wrapper around tsyringe with enhanced error handling.\n */\n\nimport 'reflect-metadata';\nimport type { DependencyContainer, InjectionToken } from 'tsyringe';\nimport { container as tsyContainer } from 'tsyringe';\n\nimport type {\n Constructor,\n ContainerInterface,\n FactoryProvider,\n Provider,\n RegisterOptions,\n Token,\n} from './types.js';\n\nimport {\n CircularDependencyError,\n DependencyResolutionError,\n InvalidProviderError,\n} from './errors.js';\n\n/**\n * Get a human-readable name for a token.\n */\nfunction getTokenName(token: Token): string {\n if (typeof token === 'string') return token;\n if (typeof token === 'symbol') return token.toString();\n if (typeof token === 'function') return token.name || 'Anonymous';\n return String(token);\n}\n\n/**\n * Check if a provider uses a class constructor.\n */\nfunction isClassProvider<T>(provider: Provider<T>): provider is { useClass: Constructor<T> } {\n return 'useClass' in provider && typeof provider.useClass === 'function';\n}\n\n/**\n * Check if a provider uses a value.\n */\nfunction isValueProvider<T>(provider: Provider<T>): provider is { useValue: T } {\n return 'useValue' in provider;\n}\n\n/**\n * Check if a provider uses a factory.\n */\nfunction isFactoryProvider<T>(provider: Provider<T>): provider is FactoryProvider<T> {\n return 'useFactory' in provider && typeof provider.useFactory === 'function';\n}\n\n/**\n * Create a container wrapper with enhanced error handling.\n */\nfunction createContainerWrapper(tsyInstance: DependencyContainer): ContainerInterface {\n const resolutionStack = new Set<string>();\n const factoryTokens = new Set<Token>();\n const bootstrappedValues = new Map<Token, unknown>();\n\n const wrapper: ContainerInterface = {\n register<T>(token: Token<T>, provider: Provider<T>, options?: RegisterOptions): void {\n const tokenName = getTokenName(token);\n const tsyToken = token as InjectionToken<T>;\n\n // Invalidate bootstrap cache if re-registering\n bootstrappedValues.delete(token);\n\n if (isClassProvider(provider)) {\n if (options?.scope === 'singleton') {\n tsyInstance.registerSingleton(tsyToken, provider.useClass);\n } else {\n tsyInstance.register(tsyToken, { useClass: provider.useClass });\n }\n } else if (isValueProvider(provider)) {\n tsyInstance.register(tsyToken, { useValue: provider.useValue });\n } else if (isFactoryProvider(provider)) {\n const { inject: injectTokens } = provider;\n factoryTokens.add(token);\n\n if (injectTokens && injectTokens.length > 0) {\n tsyInstance.register(tsyToken, {\n useFactory: () => {\n const deps = injectTokens.map((depToken) => wrapper.resolve(depToken));\n const hasAsyncDep = deps.some((d) => d instanceof Promise);\n if (hasAsyncDep) {\n return Promise.all(deps).then((resolved) => provider.useFactory(...resolved));\n }\n return provider.useFactory(...deps);\n },\n });\n } else {\n tsyInstance.register(tsyToken, {\n useFactory: () => provider.useFactory(wrapper),\n });\n }\n } else {\n throw new InvalidProviderError(tokenName);\n }\n },\n\n resolve<T>(token: Token<T>): T {\n // Return bootstrapped value if available (async factory already resolved)\n if (bootstrappedValues.has(token)) {\n return bootstrappedValues.get(token) as T;\n }\n\n const tokenName = getTokenName(token);\n const tsyToken = token as InjectionToken<T>;\n\n // Detect circular dependencies (O(1) lookup with Set)\n if (resolutionStack.has(tokenName)) {\n const cycle = [...resolutionStack, tokenName];\n throw new CircularDependencyError(cycle);\n }\n\n resolutionStack.add(tokenName);\n\n try {\n const instance = tsyInstance.resolve<T>(tsyToken);\n resolutionStack.delete(tokenName);\n return instance;\n } catch (error) {\n resolutionStack.delete(tokenName);\n\n // Re-throw our own errors as-is\n if (error instanceof CircularDependencyError) {\n throw error;\n }\n\n // Detect tsyringe-internal circular dependencies (stack overflow)\n if (error instanceof RangeError && error.message.includes('Maximum call stack')) {\n const cycle = [...resolutionStack, tokenName];\n throw new CircularDependencyError(cycle);\n }\n\n // Detect tsyringe \"Cannot inject\" errors (typically circular deps)\n if (error instanceof Error && error.message.includes('Cannot inject the dependency')) {\n const cycle = [...resolutionStack, tokenName];\n throw new CircularDependencyError(cycle);\n }\n\n // Enhance error message for missing registrations\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n\n if (\n message.includes('not registered') ||\n message.includes('cannot resolve') ||\n message.includes('unregistered dependency')\n ) {\n throw new DependencyResolutionError([...resolutionStack], tokenName);\n }\n }\n\n throw error;\n }\n },\n\n async resolveAsync<T>(token: Token<T>): Promise<T> {\n if (bootstrappedValues.has(token)) {\n return bootstrappedValues.get(token) as T;\n }\n const result = wrapper.resolve<T | Promise<T>>(token);\n return result instanceof Promise ? result : result;\n },\n\n async bootstrap(): Promise<void> {\n for (const token of factoryTokens) {\n if (bootstrappedValues.has(token)) continue;\n const result = wrapper.resolve<unknown>(token);\n const value = result instanceof Promise ? await result : result;\n bootstrappedValues.set(token, value);\n }\n factoryTokens.clear();\n },\n\n resolveAll<T>(token: Token<T>): T[] {\n const tsyToken = token as InjectionToken<T>;\n try {\n return tsyInstance.resolveAll<T>(tsyToken);\n } catch (error: unknown) {\n // Only swallow \"unregistered\" errors — token genuinely has no registrations\n const message = error instanceof Error ? error.message : String(error);\n if (message.includes('unregistered')) {\n return [];\n }\n throw error;\n }\n },\n\n isRegistered<T>(token: Token<T>): boolean {\n const tsyToken = token as InjectionToken<T>;\n return tsyInstance.isRegistered(tsyToken);\n },\n\n clearInstances(): void {\n tsyInstance.clearInstances();\n bootstrappedValues.clear();\n },\n\n reset(): void {\n tsyInstance.reset();\n bootstrappedValues.clear();\n factoryTokens.clear();\n },\n\n createChild(): ContainerInterface {\n const childTsy = tsyInstance.createChildContainer();\n return createContainerWrapper(childTsy);\n },\n };\n\n return wrapper;\n}\n\n/**\n * The global DI container instance.\n *\n * Use this for registering and resolving dependencies throughout your application.\n *\n * @example\n * ```typescript\n * // Register a service\n * container.register(UserService, { useClass: UserService });\n *\n * // Resolve a service\n * const userService = container.resolve(UserService);\n *\n * // Register with value\n * container.register('CONFIG', { useValue: { port: 3000 } });\n * ```\n */\nexport const container: ContainerInterface = createContainerWrapper(tsyContainer);\n\n/**\n * Create a new isolated container.\n *\n * Useful for testing or creating scoped containers.\n * Note: Creates a child container from the global tsyringe container.\n * For truly isolated containers, reset the child before use.\n *\n * @example\n * ```typescript\n * const testContainer = createContainer();\n * testContainer.register(UserService, { useClass: MockUserService });\n * ```\n */\nexport function createContainer(): ContainerInterface {\n const childTsy = tsyContainer.createChildContainer();\n childTsy.reset();\n return createContainerWrapper(childTsy);\n}\n","/**\n * @nextrush/di - Types\n *\n * Type definitions for the dependency injection container.\n */\n\n/**\n * Token used to identify a dependency in the container.\n * Can be a class constructor, string, or symbol.\n */\nexport type Token<T = unknown> = Constructor<T> | string | symbol;\n\n/**\n * Constructor type for class-based tokens.\n */\nexport type Constructor<T = unknown> = new (...args: unknown[]) => T;\n\n/**\n * Provider that uses a class constructor.\n */\nexport interface ClassProvider<T> {\n useClass: Constructor<T>;\n}\n\n/**\n * Provider that uses a factory function.\n *\n * Without `inject`: factory receives the container.\n * With `inject`: factory receives resolved dependencies in order.\n *\n * @example Without inject\n * ```typescript\n * container.register('DB', {\n * useFactory: (c) => new Database(c.resolve(ConfigService).dbUrl),\n * });\n * ```\n *\n * @example With inject\n * ```typescript\n * container.register('DB', {\n * useFactory: (config: ConfigService) => new Database(config.dbUrl),\n * inject: [ConfigService],\n * });\n * ```\n *\n * @example Async factory (auto-resolved by bootstrap)\n * ```typescript\n * container.register('DB', {\n * useFactory: async (config: ConfigService) => {\n * const db = new Database(config.dbUrl);\n * await db.connect();\n * return db;\n * },\n * inject: [ConfigService],\n * });\n * // Controllers plugin calls bootstrap() automatically.\n * // For functional mode: await container.bootstrap()\n * ```\n */\nexport interface FactoryProvider<T> {\n useFactory: (...args: unknown[]) => T | Promise<T>;\n inject?: Token[];\n}\n\n/**\n * Provider that uses a constant value.\n */\nexport interface ValueProvider<T> {\n useValue: T;\n}\n\n/**\n * Union of all provider types.\n */\nexport type Provider<T> = ClassProvider<T> | FactoryProvider<T> | ValueProvider<T>;\n\n/**\n * Lifecycle scope for registered services.\n */\nexport type Scope = 'singleton' | 'transient';\n\n/**\n * Options for service registration.\n */\nexport interface ServiceOptions {\n scope?: Scope;\n}\n\n/**\n * Container interface for dependency injection operations.\n */\nexport interface ContainerInterface {\n /**\n * Register a dependency with the container.\n *\n * @param token - The token to register\n * @param provider - The provider (class, value, or factory)\n * @param options - Optional registration options\n */\n register<T>(token: Token<T>, provider: Provider<T>, options?: RegisterOptions): void;\n\n /**\n * Resolve a dependency from the container (synchronous).\n */\n resolve<T>(token: Token<T>): T;\n\n /**\n * Resolve a dependency that may have been registered with an async factory.\n * Awaits the result if the factory returns a Promise.\n *\n * Prefer `bootstrap()` over calling this for each async provider.\n */\n resolveAsync<T>(token: Token<T>): Promise<T>;\n\n /**\n * Bootstrap all factory providers.\n *\n * Resolves every factory-registered provider, awaiting any Promises,\n * and caches results for synchronous access via `resolve()`.\n *\n * Called automatically by the controllers plugin during `install()`.\n * For functional mode, call once before handling requests.\n *\n * @example\n * ```typescript\n * container.register('DB', {\n * useFactory: async () => { const db = new Database(); await db.connect(); return db; },\n * });\n * await container.bootstrap(); // All async providers resolved\n * container.resolve('DB'); // Works synchronously now\n * ```\n */\n bootstrap(): Promise<void>;\n\n /**\n * Resolve all dependencies registered under a token.\n */\n resolveAll<T>(token: Token<T>): T[];\n\n /**\n * Check if a token is registered.\n */\n isRegistered<T>(token: Token<T>): boolean;\n\n /**\n * Clear all registered instances (useful for testing).\n */\n clearInstances(): void;\n\n /**\n * Reset the container completely (useful for testing).\n */\n reset(): void;\n\n /**\n * Create a child container with isolated scope.\n */\n createChild(): ContainerInterface;\n}\n\n/**\n * Metadata key constants.\n */\nexport const METADATA_KEYS = {\n SERVICE_TYPE: 'di:type',\n SERVICE_SCOPE: 'di:scope',\n INJECT_TOKEN: 'di:inject',\n PARAM_TYPES: 'design:paramtypes',\n CONFIG_PREFIX: 'di:config:prefix',\n OPTIONAL_PARAMS: 'di:optional',\n} as const;\n\n/**\n * Options for @Config decorator.\n */\nexport interface ConfigOptions {\n /**\n * Environment variable prefix.\n *\n * When set, the configuration class can be used with prefix-based env loading.\n *\n * @example\n * ```typescript\n * @Config({ prefix: 'DB' })\n * class DatabaseConfig {\n * readonly host = 'localhost'; // reads DB_HOST\n * readonly port = 5432; // reads DB_PORT\n * }\n * ```\n */\n prefix?: string;\n}\n\n/**\n * Service types for metadata.\n */\nexport type ServiceType = 'service' | 'repository' | 'controller' | 'config';\n\n/**\n * Registration options for container.register().\n */\nexport interface RegisterOptions {\n /** Lifecycle scope — defaults to 'transient' if not specified */\n scope?: Scope;\n}\n","/**\n * @nextrush/di - Decorators\n *\n * Injectable decorators for marking classes as DI-managed services.\n * Uses legacy TypeScript decorators for maximum compatibility with tsyringe.\n */\n\nimport 'reflect-metadata';\nimport {\n delay as tsyDelay,\n inject as tsyInject,\n injectable as tsyInjectable,\n singleton as tsySingleton,\n} from 'tsyringe';\n\nimport { METADATA_KEYS, type Constructor, type Scope, type ServiceOptions } from './types.js';\n\n/** Decorator-compatible constructor type. Uses `never[]` so any class is structurally assignable. */\ntype DecoratorTarget = new (...args: never[]) => unknown;\n\n/**\n * Mark a class as injectable service.\n *\n * Services are singletons by default - one instance shared across the application.\n *\n * @param options - Optional configuration for the service\n *\n * @example\n * ```typescript\n * @Service()\n * export class UserService {\n * async findAll() {\n * return [{ id: 1, name: 'Alice' }];\n * }\n * }\n *\n * // With transient scope (new instance each time)\n * @Service({ scope: 'transient' })\n * export class RequestLogger {\n * constructor() {\n * this.timestamp = Date.now();\n * }\n * }\n * ```\n */\nexport function Service(options: ServiceOptions = {}) {\n const scope: Scope = options.scope ?? 'singleton';\n\n return (target: DecoratorTarget): void => {\n // Store metadata for smart discovery\n Reflect.defineMetadata(METADATA_KEYS.SERVICE_TYPE, 'service', target);\n Reflect.defineMetadata(METADATA_KEYS.SERVICE_SCOPE, scope, target);\n\n // Apply tsyringe decorator based on scope\n if (scope === 'singleton') {\n tsySingleton()(target as unknown as Constructor);\n } else {\n tsyInjectable()(target as unknown as Constructor);\n }\n };\n}\n\n/**\n * Mark a class as a repository (data access layer).\n *\n * Semantically identical to @Service(), but indicates the class is for data access.\n * Repositories are singletons by default.\n *\n * @param options - Optional configuration for the repository\n *\n * @example\n * ```typescript\n * @Repository()\n * export class UserRepository {\n * async findById(id: string) {\n * return db.users.findUnique({ where: { id } });\n * }\n * }\n * ```\n */\nexport function Repository(options: ServiceOptions = {}) {\n const scope: Scope = options.scope ?? 'singleton';\n\n return (target: DecoratorTarget): void => {\n Reflect.defineMetadata(METADATA_KEYS.SERVICE_TYPE, 'repository', target);\n Reflect.defineMetadata(METADATA_KEYS.SERVICE_SCOPE, scope, target);\n\n if (scope === 'singleton') {\n tsySingleton()(target as unknown as Constructor);\n } else {\n tsyInjectable()(target as unknown as Constructor);\n }\n };\n}\n\n/**\n * Explicitly inject a dependency by token.\n *\n * Use this when:\n * - Injecting an interface (TypeScript can't infer interface types at runtime)\n * - Using string or symbol tokens\n * - The automatic type inference doesn't work\n *\n * @param token - The token to inject (class, string, or symbol)\n *\n * @example\n * ```typescript\n * @Service()\n * export class UserService {\n * constructor(\n * // Inject by interface token\n * @inject('IUserRepository') private repo: IUserRepository,\n *\n * // Inject by string token\n * @inject('DATABASE_URL') private dbUrl: string\n * ) {}\n * }\n * ```\n */\nexport function inject(token: unknown): ParameterDecorator {\n return tsyInject(token as never);\n}\n\n/**\n * Make a class injectable without singleton scope.\n *\n * Unlike @Service() which defaults to singleton, @Injectable() creates\n * a transient registration that can be resolved from the container.\n *\n * @example\n * ```typescript\n * @Injectable()\n * export class FeatureService {\n * constructor(private logger: Logger) {}\n * }\n *\n * // Resolve from container\n * const service = container.resolve(FeatureService);\n * ```\n */\nexport function Injectable() {\n return (target: DecoratorTarget): void => {\n Reflect.defineMetadata(METADATA_KEYS.SERVICE_TYPE, 'service', target);\n tsyInjectable()(target as unknown as Constructor);\n };\n}\n\n/**\n * @deprecated Use `@Injectable()` instead. Will be removed in v4.\n */\nexport const AutoInjectable = Injectable;\n\n/**\n * Make a class resolvable by the DI container without adding service metadata.\n *\n * Used internally by `@Controller()` to enable constructor injection\n * without marking the class as a service. This is the abstraction boundary\n * that prevents `@nextrush/decorators` from depending directly on tsyringe.\n *\n * @param target - The class constructor to make injectable\n *\n * @internal\n */\nexport function markInjectable(target: Constructor): void {\n tsyInjectable()(target);\n}\n\n/**\n * Delay resolution of a dependency.\n *\n * Use this to break circular dependencies by lazily resolving the dependency.\n *\n * @param token - Factory function returning the class to inject\n *\n * @example\n * ```typescript\n * @Service()\n * class UserService {\n * constructor(\n * @inject(delay(() => OrderService)) private orderService: OrderService\n * ) {}\n * }\n *\n * @Service()\n * class OrderService {\n * constructor(\n * @inject(delay(() => UserService)) private userService: UserService\n * ) {}\n * }\n * ```\n */\nexport function delay(tokenFactory: () => Constructor): unknown {\n return tsyDelay(tokenFactory);\n}\n\n/**\n * Check if a class has DI metadata (is decorated with @Service or @Repository).\n *\n * @param target - The class to check\n * @returns True if the class has DI metadata\n */\nexport function hasServiceMetadata(target: object): boolean {\n return Reflect.hasMetadata(METADATA_KEYS.SERVICE_TYPE, target);\n}\n\n/**\n * Get the service type from a decorated class.\n *\n * @param target - The class to check\n * @returns The service type ('service' | 'repository') or undefined\n */\nexport function getServiceType(target: object): string | undefined {\n return Reflect.getMetadata(METADATA_KEYS.SERVICE_TYPE, target) as string | undefined;\n}\n\n/**\n * Get the scope from a decorated class.\n *\n * @param target - The class to check\n * @returns The scope ('singleton' | 'transient') or undefined\n */\nexport function getServiceScope(target: object): Scope | undefined {\n return Reflect.getMetadata(METADATA_KEYS.SERVICE_SCOPE, target) as Scope | undefined;\n}\n\n/**\n * Mark a class as a configuration holder.\n *\n * Configuration classes are always singletons and serve as centralized\n * configuration containers for your application. Similar to Spring Boot's\n * `@Configuration` / `@ConfigurationProperties`.\n *\n * @param options - Optional configuration (e.g., env prefix)\n *\n * @example\n * ```typescript\n * // Simple configuration class\n * @Config()\n * export class AppConfig {\n * readonly port = Number(process.env.PORT ?? 3000);\n * readonly host = process.env.HOST ?? 'localhost';\n * }\n *\n * // With env prefix — documents that this config reads DB_* vars\n * @Config({ prefix: 'DB' })\n * export class DatabaseConfig {\n * readonly host = process.env.DB_HOST ?? 'localhost';\n * readonly port = Number(process.env.DB_PORT ?? 5432);\n * readonly name = process.env.DB_NAME ?? 'mydb';\n * }\n *\n * // Inject into services\n * @Service()\n * export class UserService {\n * constructor(private config: DatabaseConfig) {}\n *\n * getConnectionString() {\n * return `postgres://${this.config.host}:${this.config.port}/${this.config.name}`;\n * }\n * }\n * ```\n */\nexport function Config(options: import('./types.js').ConfigOptions = {}) {\n return (target: DecoratorTarget): void => {\n Reflect.defineMetadata(METADATA_KEYS.SERVICE_TYPE, 'config', target);\n Reflect.defineMetadata(METADATA_KEYS.SERVICE_SCOPE, 'singleton', target);\n\n if (options.prefix) {\n Reflect.defineMetadata(METADATA_KEYS.CONFIG_PREFIX, options.prefix, target);\n }\n\n // Configuration classes are always singletons\n tsySingleton()(target as unknown as Constructor);\n };\n}\n\n/**\n * Get the config prefix from a @Config-decorated class.\n *\n * @param target - The class to check\n * @returns The prefix string or undefined\n */\nexport function getConfigPrefix(target: object): string | undefined {\n return Reflect.getMetadata(METADATA_KEYS.CONFIG_PREFIX, target) as string | undefined;\n}\n\n/**\n * Mark a constructor parameter as optional.\n *\n * When a dependency marked `@Optional()` cannot be resolved, the container\n * injects `undefined` instead of throwing a `DependencyResolutionError`.\n *\n * @example\n * ```typescript\n * // Optional dependency - if 'MAILER' is not registered, `mailer` will be undefined\n * @Service()\n * class NotificationService {\n * constructor(\n * @Optional() @inject('MAILER') private mailer?: MailerService,\n * ) {}\n *\n * send(message: string) {\n * if (this.mailer) {\n * this.mailer.send(message);\n * } else {\n * console.log('No mailer configured, skipping:', message);\n * }\n * }\n * }\n * ```\n */\nexport function Optional(): ParameterDecorator {\n return (target: object, _propertyKey: string | symbol | undefined, parameterIndex: number) => {\n // Store in our own metadata for introspection via getOptionalParams / isParameterOptional\n const existing =\n (Reflect.getOwnMetadata(METADATA_KEYS.OPTIONAL_PARAMS, target) as Set<number> | undefined) ??\n new Set<number>();\n existing.add(parameterIndex);\n Reflect.defineMetadata(METADATA_KEYS.OPTIONAL_PARAMS, existing, target);\n\n // Set isOptional on tsyringe's injection token descriptor so that tsyringe\n // natively returns undefined for unregistered optional deps instead of throwing.\n // This works because @inject() runs before @Optional() (right-to-left param decorator order)\n // and @Service()/@injectable() runs after both (class decorator order).\n const TSYRINGE_INJECTION_KEY = 'injectionTokens';\n const descriptors =\n (Reflect.getOwnMetadata(TSYRINGE_INJECTION_KEY, target) as\n | Record<number, unknown>\n | undefined) ?? {};\n const descriptor = descriptors[parameterIndex];\n\n if (descriptor && typeof descriptor === 'object' && 'token' in descriptor) {\n // @inject() already created the descriptor — set isOptional flag\n (descriptor as Record<string, unknown>).isOptional = true;\n }\n\n Reflect.defineMetadata(TSYRINGE_INJECTION_KEY, descriptors, target);\n };\n}\n\n/**\n * Check whether a specific constructor parameter is marked `@Optional()`.\n */\nexport function isParameterOptional(target: object, parameterIndex: number): boolean {\n const optional = Reflect.getOwnMetadata(METADATA_KEYS.OPTIONAL_PARAMS, target) as\n | Set<number>\n | undefined;\n return optional?.has(parameterIndex) ?? false;\n}\n\n/**\n * Get the set of optional parameter indices for a class constructor.\n */\nexport function getOptionalParams(target: object): ReadonlySet<number> {\n return (\n (Reflect.getOwnMetadata(METADATA_KEYS.OPTIONAL_PARAMS, target) as Set<number> | undefined) ??\n new Set<number>()\n );\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@nextrush/di",
3
+ "version": "3.0.0",
4
+ "description": "Lightweight dependency injection container for NextRush",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "dependencies": {
20
+ "reflect-metadata": "^0.2.2",
21
+ "tsyringe": "^4.10.0"
22
+ },
23
+ "devDependencies": {
24
+ "rimraf": "^6.1.3",
25
+ "tsup": "^8.5.1",
26
+ "typescript": "^6.0.2",
27
+ "vitest": "^4.1.4",
28
+ "@nextrush/types": "3.0.0"
29
+ },
30
+ "peerDependencies": {
31
+ "typescript": ">=5.0.0"
32
+ },
33
+ "keywords": [
34
+ "nextrush",
35
+ "di",
36
+ "dependency-injection",
37
+ "ioc",
38
+ "container",
39
+ "typescript"
40
+ ],
41
+ "author": {
42
+ "name": "Tanzim Hossain",
43
+ "email": "tanzimhossain2@gmail.com",
44
+ "url": "https://github.com/0xTanzim"
45
+ },
46
+ "license": "MIT",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/0xTanzim/nextrush.git",
50
+ "directory": "packages/di"
51
+ },
52
+ "bugs": {
53
+ "url": "https://github.com/0xtanzim/nextrush/issues"
54
+ },
55
+ "homepage": "https://github.com/0xtanzim/nextrush/tree/main/packages/di#readme",
56
+ "publishConfig": {
57
+ "access": "public"
58
+ },
59
+ "engines": {
60
+ "node": ">=22.0.0"
61
+ },
62
+ "sideEffects": false,
63
+ "scripts": {
64
+ "build": "tsup",
65
+ "dev": "tsup --watch",
66
+ "test": "vitest run",
67
+ "test:watch": "vitest",
68
+ "test:coverage": "vitest run --coverage",
69
+ "typecheck": "tsc --noEmit",
70
+ "clean": "rimraf dist"
71
+ }
72
+ }