@zudojs/container 1.1.2 → 1.2.1
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/README.md +32 -4
- package/dist/containerCore/containerCore.core.d.ts +9 -2
- package/dist/containerCore/containerCore.core.js +7 -0
- package/dist/containerProvider/containerProvider.core.d.ts +21 -2
- package/dist/containerProvider/containerProvider.core.js +13 -2
- package/dist/containerResolution/containerResolution.autoRegister.d.ts +42 -0
- package/dist/containerResolution/containerResolution.autoRegister.js +62 -0
- package/dist/containerResolution/containerResolution.core.js +5 -2
- package/dist/containerToken/containerToken.type.d.ts +8 -0
- package/dist/containerToken/containerToken.type.js +9 -3
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -47,6 +47,21 @@ container.registerFactory(API, (db) => new Api(db), [DB]); // deps via inject li
|
|
|
47
47
|
container.registerExisting("db-alias", DB); // alias to another token
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
A factory's parameters are typed from its `inject` list, in order: with
|
|
51
|
+
`DB = createToken<Db>("Db")`, `(db) => new Api(db)` receives `db: Db`, and a
|
|
52
|
+
factory whose parameters do not match the tokens is a compile error. Class
|
|
53
|
+
tokens type the same way; plain string and symbol tokens give `unknown`.
|
|
54
|
+
`factoryProvider(factory, inject)` and `provideFactory(token, factory,
|
|
55
|
+
inject)` infer the same way.
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
container.registerFactory(
|
|
59
|
+
REPORT,
|
|
60
|
+
(db, clock) => new Report(db, clock), // db: Db, clock: Clock
|
|
61
|
+
[DB, Clock],
|
|
62
|
+
);
|
|
63
|
+
```
|
|
64
|
+
|
|
50
65
|
## Tokens
|
|
51
66
|
|
|
52
67
|
Tokens can be strings, symbols, classes, or `InjectionToken`s from
|
|
@@ -58,6 +73,9 @@ Tokens can be strings, symbols, classes, or `InjectionToken`s from
|
|
|
58
73
|
- `createGlobalToken(key)` uses `Symbol.for(key)`: any other call with the
|
|
59
74
|
same key anywhere in the process yields the **same** token. That is by
|
|
60
75
|
design for cross-package sharing; namespace your keys (e.g. `"myapp:db"`).
|
|
76
|
+
- Error messages and default registration names show a symbol token by its
|
|
77
|
+
description: `createToken<Db>("Database")` appears as `Database`, not
|
|
78
|
+
`Symbol(Database)` (`describeToken(token)` returns the same string).
|
|
61
79
|
|
|
62
80
|
## Lifetimes (`scope` option)
|
|
63
81
|
|
|
@@ -144,9 +162,13 @@ container.register(API, {
|
|
|
144
162
|
});
|
|
145
163
|
```
|
|
146
164
|
|
|
147
|
-
Classes without an `inject` list are constructed with zero arguments
|
|
148
|
-
|
|
149
|
-
|
|
165
|
+
Classes without an `inject` list are constructed with zero arguments, so
|
|
166
|
+
only a constructor that declares no parameters may omit it (parameters with
|
|
167
|
+
a default value do not count). Registering such a class without `inject`
|
|
168
|
+
is allowed, but resolving it throws a `ProviderResolutionError` naming the
|
|
169
|
+
class and the `inject: [...]` fix, instead of building it with `undefined`
|
|
170
|
+
dependencies. There is no reflection/decorator magic — dependencies are
|
|
171
|
+
exactly the tokens you list, resolved in order.
|
|
150
172
|
|
|
151
173
|
## Duplicate registrations
|
|
152
174
|
|
|
@@ -185,7 +207,13 @@ const container = createContainer({
|
|
|
185
207
|
registers it on the fly as `TRANSIENT`. When registrations are frozen the
|
|
186
208
|
class is instantiated _ephemerally_ without being registered. Set to
|
|
187
209
|
`false` to require explicit registration (`canResolve`/`resolveOptional`
|
|
188
|
-
respect this).
|
|
210
|
+
respect this). Only a class whose constructor declares no required
|
|
211
|
+
parameters (`Class.length === 0`) is auto-registered: auto-registration
|
|
212
|
+
has no inject list, so `resolve(NeedsDep)` for
|
|
213
|
+
`constructor(dep: Dep)` throws `RegistrationNotFoundError` naming the
|
|
214
|
+
class and telling you to register it with an `inject` list, instead of
|
|
215
|
+
building it with `dep = undefined`. Parameters with defaults do not
|
|
216
|
+
count.
|
|
189
217
|
- `detectCircularDependencies` — circular chains throw
|
|
190
218
|
`CircularDependencyError` with the full chain. When disabled,
|
|
191
219
|
`maxResolutionDepth` still stops runaway recursion.
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* - TRANSIENT instances are never cached and never tracked — callers own
|
|
13
13
|
* their disposal.
|
|
14
14
|
*/
|
|
15
|
-
import type { ContainerProvider, ProviderToken } from "../containerProvider/containerProvider.core.js";
|
|
15
|
+
import type { ContainerProvider, InjectedFactory, ProviderToken } from "../containerProvider/containerProvider.core.js";
|
|
16
16
|
import type { ContainerRegistration, CreateRegistrationOptions, RegistrationToken, ResolvedTokens } from "../containerRegistration/containerRegistration.core.js";
|
|
17
17
|
import type { ResolutionCache, ResolutionResult } from "../containerResolution/containerResolution.type.js";
|
|
18
18
|
import type { ContainerOptions, ResolvedContainerOptions } from "../containerOptions/containerOptions.type.js";
|
|
@@ -51,7 +51,14 @@ export declare class Container implements ContainerLike {
|
|
|
51
51
|
* any other lifetime would be misleading.
|
|
52
52
|
*/
|
|
53
53
|
registerValue<T>(token: RegistrationToken<T>, value: T, options?: CreateRegistrationOptions): ContainerRegistration<T>;
|
|
54
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Registers a factory. Its parameters are typed from the `inject` tokens,
|
|
56
|
+
* in order: `registerFactory(API, (db) => new Api(db), [DB])` types `db`
|
|
57
|
+
* as `Db` when `DB` is a `createToken<Db>()` or class token, and rejects a
|
|
58
|
+
* factory whose parameters do not match. String/symbol tokens give
|
|
59
|
+
* `unknown`.
|
|
60
|
+
*/
|
|
61
|
+
registerFactory<T, const Deps extends readonly ProviderToken[] = readonly []>(token: RegistrationToken<T>, factory: InjectedFactory<T, Deps>, inject?: Deps, options?: CreateRegistrationOptions): ContainerRegistration<T>;
|
|
55
62
|
registerExisting<T>(token: RegistrationToken<T>, existing: ProviderToken<T>, options?: CreateRegistrationOptions): ContainerRegistration<T>;
|
|
56
63
|
/**
|
|
57
64
|
* Resolves a dependency at the container root.
|
|
@@ -87,6 +87,13 @@ export class Container {
|
|
|
87
87
|
scope: Scope.SINGLETON,
|
|
88
88
|
});
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Registers a factory. Its parameters are typed from the `inject` tokens,
|
|
92
|
+
* in order: `registerFactory(API, (db) => new Api(db), [DB])` types `db`
|
|
93
|
+
* as `Db` when `DB` is a `createToken<Db>()` or class token, and rejects a
|
|
94
|
+
* factory whose parameters do not match. String/symbol tokens give
|
|
95
|
+
* `unknown`.
|
|
96
|
+
*/
|
|
90
97
|
registerFactory(token, factory, inject = [], options = {}) {
|
|
91
98
|
return this.register(token, factoryProvider(factory, inject), options);
|
|
92
99
|
}
|
|
@@ -4,6 +4,17 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { Constructor, InjectionToken, Token } from "../containerToken/containerToken.type.js";
|
|
6
6
|
export type ProviderToken<T = unknown> = Token<T> | InjectionToken<T>;
|
|
7
|
+
/**
|
|
8
|
+
* The parameter list a factory receives for an `inject` list: each token is
|
|
9
|
+
* mapped to the type it resolves to, so `[DB, Clock]` gives `[Db, Clock]`.
|
|
10
|
+
* Untyped string/symbol tokens map to `unknown`, and a non-tuple
|
|
11
|
+
* `readonly ProviderToken[]` gives `unknown[]`, as before.
|
|
12
|
+
*/
|
|
13
|
+
export type InjectedDependencies<Deps extends readonly ProviderToken[]> = {
|
|
14
|
+
-readonly [K in keyof Deps]: Deps[K] extends ProviderToken<infer U> ? U : never;
|
|
15
|
+
};
|
|
16
|
+
/** A factory whose parameters are typed from its `inject` list. */
|
|
17
|
+
export type InjectedFactory<T, Deps extends readonly ProviderToken[]> = (...dependencies: InjectedDependencies<Deps>) => T;
|
|
7
18
|
export interface ClassProvider<T> {
|
|
8
19
|
readonly useClass: Constructor<T>;
|
|
9
20
|
/**
|
|
@@ -55,11 +66,19 @@ export declare function hasInjectedDependencies<T = unknown>(provider: Provider<
|
|
|
55
66
|
readonly inject: readonly ProviderToken[];
|
|
56
67
|
};
|
|
57
68
|
export declare function classProvider<T>(useClass: Constructor<T>, inject?: readonly ProviderToken[]): ClassProvider<T>;
|
|
58
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Builds a factory provider. The factory's parameters are inferred from the
|
|
71
|
+
* `inject` tokens, in order.
|
|
72
|
+
*/
|
|
73
|
+
export declare function factoryProvider<T, const Deps extends readonly ProviderToken[] = readonly []>(useFactory: InjectedFactory<T, Deps>, inject?: Deps): FactoryProvider<T>;
|
|
59
74
|
export declare function valueProvider<T>(useValue: T): ValueProvider<T>;
|
|
60
75
|
export declare function existingProvider<T>(useExisting: ProviderToken<T>): ExistingProvider<T>;
|
|
61
76
|
export declare function provideClass<T>(provide: ProviderToken<T>, useClass: Constructor<T>, inject?: readonly ProviderToken[]): ClassRegistration<T>;
|
|
62
|
-
|
|
77
|
+
/**
|
|
78
|
+
* Builds a factory registration. The factory's parameters are inferred from
|
|
79
|
+
* the `inject` tokens, in order.
|
|
80
|
+
*/
|
|
81
|
+
export declare function provideFactory<T, const Deps extends readonly ProviderToken[] = readonly []>(provide: ProviderToken<T>, useFactory: InjectedFactory<T, Deps>, inject?: Deps): FactoryRegistration<T>;
|
|
63
82
|
export declare function provideValue<T>(provide: ProviderToken<T>, useValue: T): ValueRegistration<T>;
|
|
64
83
|
export declare function provideExisting<T>(provide: ProviderToken<T>, useExisting: ProviderToken<T>): ExistingRegistration<T>;
|
|
65
84
|
export declare function getProviderToken<T>(provider: ContainerProvider<T>): ProviderToken<T> | undefined;
|
|
@@ -25,8 +25,15 @@ export function hasInjectedDependencies(provider) {
|
|
|
25
25
|
export function classProvider(useClass, inject = []) {
|
|
26
26
|
return Object.freeze({ useClass, inject: Object.freeze([...inject]) });
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Builds a factory provider. The factory's parameters are inferred from the
|
|
30
|
+
* `inject` tokens, in order.
|
|
31
|
+
*/
|
|
28
32
|
export function factoryProvider(useFactory, inject = []) {
|
|
29
|
-
return Object.freeze({
|
|
33
|
+
return Object.freeze({
|
|
34
|
+
useFactory: useFactory,
|
|
35
|
+
inject: Object.freeze([...inject]),
|
|
36
|
+
});
|
|
30
37
|
}
|
|
31
38
|
export function valueProvider(useValue) {
|
|
32
39
|
return Object.freeze({ useValue });
|
|
@@ -41,10 +48,14 @@ export function provideClass(provide, useClass, inject = []) {
|
|
|
41
48
|
inject: Object.freeze([...inject]),
|
|
42
49
|
});
|
|
43
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Builds a factory registration. The factory's parameters are inferred from
|
|
53
|
+
* the `inject` tokens, in order.
|
|
54
|
+
*/
|
|
44
55
|
export function provideFactory(provide, useFactory, inject = []) {
|
|
45
56
|
return Object.freeze({
|
|
46
57
|
provide,
|
|
47
|
-
useFactory,
|
|
58
|
+
useFactory: useFactory,
|
|
48
59
|
inject: Object.freeze([...inject]),
|
|
49
60
|
});
|
|
50
61
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zudojs/container/containerResolution/containerResolution.autoRegister
|
|
3
|
+
*
|
|
4
|
+
* Guards against building a class with no arguments when its constructor
|
|
5
|
+
* declares some: an unregistered class under `autoRegisterClasses`, and a
|
|
6
|
+
* class registration with no `inject` list.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Whether an unregistered token may be auto-registered: a class whose
|
|
10
|
+
* constructor declares no required parameters (`Class.length === 0`).
|
|
11
|
+
*
|
|
12
|
+
* Parameters with a default value do not count, so
|
|
13
|
+
* `constructor(value = 7)` still qualifies.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isAutoRegistrable(token: unknown): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Throws when a class cannot be auto-registered because its constructor
|
|
18
|
+
* declares parameters. Auto-registration has no inject list, so building
|
|
19
|
+
* it would pass `undefined` for every dependency.
|
|
20
|
+
*
|
|
21
|
+
* @throws {RegistrationNotFoundError} naming the class and how to
|
|
22
|
+
* register it.
|
|
23
|
+
*/
|
|
24
|
+
export declare function assertAutoRegistrable(token: {
|
|
25
|
+
readonly length: number;
|
|
26
|
+
}): void;
|
|
27
|
+
/**
|
|
28
|
+
* Throws when a class registration has no `inject` list but its constructor
|
|
29
|
+
* declares parameters. Without one the class is built with no arguments,
|
|
30
|
+
* so every dependency would be `undefined`. Registering it is allowed;
|
|
31
|
+
* resolving it is what fails.
|
|
32
|
+
*
|
|
33
|
+
* Parameters with a default value do not count (`Function.length` stops at
|
|
34
|
+
* the first one).
|
|
35
|
+
*
|
|
36
|
+
* @throws {ProviderResolutionError} naming the class and the `inject` fix.
|
|
37
|
+
*/
|
|
38
|
+
export declare function assertClassInjectable(token: string, ctor: {
|
|
39
|
+
readonly length: number;
|
|
40
|
+
readonly name: string;
|
|
41
|
+
}, inject: readonly unknown[]): void;
|
|
42
|
+
//# sourceMappingURL=containerResolution.autoRegister.d.ts.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zudojs/container/containerResolution/containerResolution.autoRegister
|
|
3
|
+
*
|
|
4
|
+
* Guards against building a class with no arguments when its constructor
|
|
5
|
+
* declares some: an unregistered class under `autoRegisterClasses`, and a
|
|
6
|
+
* class registration with no `inject` list.
|
|
7
|
+
*/
|
|
8
|
+
import { ProviderResolutionError, RegistrationNotFoundError, } from "@zudojs/errors";
|
|
9
|
+
import { describeToken } from "../containerToken/containerToken.type.js";
|
|
10
|
+
/**
|
|
11
|
+
* Whether an unregistered token may be auto-registered: a class whose
|
|
12
|
+
* constructor declares no required parameters (`Class.length === 0`).
|
|
13
|
+
*
|
|
14
|
+
* Parameters with a default value do not count, so
|
|
15
|
+
* `constructor(value = 7)` still qualifies.
|
|
16
|
+
*/
|
|
17
|
+
export function isAutoRegistrable(token) {
|
|
18
|
+
return typeof token === "function" && token.length === 0;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Throws when a class cannot be auto-registered because its constructor
|
|
22
|
+
* declares parameters. Auto-registration has no inject list, so building
|
|
23
|
+
* it would pass `undefined` for every dependency.
|
|
24
|
+
*
|
|
25
|
+
* @throws {RegistrationNotFoundError} naming the class and how to
|
|
26
|
+
* register it.
|
|
27
|
+
*/
|
|
28
|
+
export function assertAutoRegistrable(token) {
|
|
29
|
+
if (isAutoRegistrable(token))
|
|
30
|
+
return;
|
|
31
|
+
const name = describeToken(token);
|
|
32
|
+
const count = token.length;
|
|
33
|
+
throw new RegistrationNotFoundError(name, `Cannot auto-register class "${name}": its constructor declares ` +
|
|
34
|
+
`${count} parameter${count === 1 ? "" : "s"} and no inject list is ` +
|
|
35
|
+
`registered, so it would be built with undefined dependencies. ` +
|
|
36
|
+
`Register it with container.registerClass(${name}, ${name}, ` +
|
|
37
|
+
`{ inject: [/* one token per parameter */] }) or ` +
|
|
38
|
+
`container.registerFactory(${name}, (...deps) => new ${name}(...deps), [/* tokens */]).`);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Throws when a class registration has no `inject` list but its constructor
|
|
42
|
+
* declares parameters. Without one the class is built with no arguments,
|
|
43
|
+
* so every dependency would be `undefined`. Registering it is allowed;
|
|
44
|
+
* resolving it is what fails.
|
|
45
|
+
*
|
|
46
|
+
* Parameters with a default value do not count (`Function.length` stops at
|
|
47
|
+
* the first one).
|
|
48
|
+
*
|
|
49
|
+
* @throws {ProviderResolutionError} naming the class and the `inject` fix.
|
|
50
|
+
*/
|
|
51
|
+
export function assertClassInjectable(token, ctor, inject) {
|
|
52
|
+
const count = ctor.length;
|
|
53
|
+
if (inject.length > 0 || count === 0)
|
|
54
|
+
return;
|
|
55
|
+
const name = ctor.name || "anonymous class";
|
|
56
|
+
throw new ProviderResolutionError(token, `Cannot build class "${name}" for token "${token}": its constructor ` +
|
|
57
|
+
`declares ${count} parameter${count === 1 ? "" : "s"} and the ` +
|
|
58
|
+
`registration has no inject list, so it would be built with undefined ` +
|
|
59
|
+
`dependencies. Register it with container.registerClass(${token}, ` +
|
|
60
|
+
`${name}, { inject: [/* one token per parameter */] }).`);
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=containerResolution.autoRegister.js.map
|
|
@@ -35,6 +35,7 @@ import { unwrapToken } from "../containerToken/containerToken.type.js";
|
|
|
35
35
|
import { CircularDependencyError, ContainerError, ProviderResolutionError, RegistrationNotFoundError, } from "@zudojs/errors";
|
|
36
36
|
import { AsyncProviderError, CaptiveDependencyError, DependencyResolutionError, MaxResolutionDepthError, ScopedResolutionError, } from "./containerResolution.error.js";
|
|
37
37
|
import { describeToken } from "../containerToken/containerToken.type.js";
|
|
38
|
+
import { assertAutoRegistrable, assertClassInjectable, isAutoRegistrable, } from "./containerResolution.autoRegister.js";
|
|
38
39
|
import { DependentIndex } from "./containerResolution.dependents.js";
|
|
39
40
|
/**
|
|
40
41
|
* Scope cache that falls back to its parent scope's cache for lookups while
|
|
@@ -124,6 +125,7 @@ export class ContainerResolver {
|
|
|
124
125
|
let registration = this.registry.get(token);
|
|
125
126
|
if (!registration) {
|
|
126
127
|
if (state.autoRegisterClasses && typeof token === "function") {
|
|
128
|
+
assertAutoRegistrable(token);
|
|
127
129
|
if (state.allowRegistration) {
|
|
128
130
|
registration = this.registry.register(token, { useClass: token }, { scope: Scope.TRANSIENT });
|
|
129
131
|
}
|
|
@@ -214,7 +216,7 @@ export class ContainerResolver {
|
|
|
214
216
|
if (isExistingProvider(provider)) {
|
|
215
217
|
const target = unwrapToken(provider.useExisting);
|
|
216
218
|
if (!this.registry.has(target) &&
|
|
217
|
-
!(state.autoRegisterClasses &&
|
|
219
|
+
!(state.autoRegisterClasses && isAutoRegistrable(target))) {
|
|
218
220
|
throw new ContainerError(`useExisting target "${describeToken(target)}" for token ` +
|
|
219
221
|
`"${describeToken(token)}" is not registered.`, { token: describeToken(token) });
|
|
220
222
|
}
|
|
@@ -237,6 +239,7 @@ export class ContainerResolver {
|
|
|
237
239
|
}
|
|
238
240
|
if (isClassProvider(provider)) {
|
|
239
241
|
const deps = provider.inject ?? [];
|
|
242
|
+
assertClassInjectable(describeToken(token), provider.useClass, deps);
|
|
240
243
|
const args = deps.map((d) => this.resolveInternal(unwrapToken(d), state, singletonAncestor)
|
|
241
244
|
.value);
|
|
242
245
|
const ctor = provider.useClass;
|
|
@@ -283,7 +286,7 @@ export class ContainerResolver {
|
|
|
283
286
|
}
|
|
284
287
|
canResolve(token, autoRegisterClasses = true) {
|
|
285
288
|
const t = unwrapToken(token);
|
|
286
|
-
return (this.registry.has(t) || (autoRegisterClasses &&
|
|
289
|
+
return (this.registry.has(t) || (autoRegisterClasses && isAutoRegistrable(t)));
|
|
287
290
|
}
|
|
288
291
|
handleRegistryChange(event) {
|
|
289
292
|
switch (event.operation) {
|
|
@@ -44,5 +44,13 @@ export declare function isInjectionToken<T = unknown>(value: unknown): value is
|
|
|
44
44
|
export declare function isConstructorToken<T = unknown>(token: Token<T>): token is Constructor<T>;
|
|
45
45
|
export declare function isSymbolToken<T = unknown>(token: Token<T>): token is symbol;
|
|
46
46
|
export declare function isStringToken<T = unknown>(token: Token<T>): token is string;
|
|
47
|
+
/**
|
|
48
|
+
* Returns a human-readable name for a token, used in error messages and as
|
|
49
|
+
* the default registration name.
|
|
50
|
+
*
|
|
51
|
+
* A symbol token (including every `createToken`/`createGlobalToken` token)
|
|
52
|
+
* is shown by its description, so errors read `MissingService` rather than
|
|
53
|
+
* `Symbol(MissingService)`. A symbol without a description is `Symbol()`.
|
|
54
|
+
*/
|
|
47
55
|
export declare function describeToken<T>(token: Token<T> | InjectionToken<T>): string;
|
|
48
56
|
//# sourceMappingURL=containerToken.type.d.ts.map
|
|
@@ -48,14 +48,20 @@ export function isSymbolToken(token) {
|
|
|
48
48
|
export function isStringToken(token) {
|
|
49
49
|
return typeof token === "string";
|
|
50
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Returns a human-readable name for a token, used in error messages and as
|
|
53
|
+
* the default registration name.
|
|
54
|
+
*
|
|
55
|
+
* A symbol token (including every `createToken`/`createGlobalToken` token)
|
|
56
|
+
* is shown by its description, so errors read `MissingService` rather than
|
|
57
|
+
* `Symbol(MissingService)`. A symbol without a description is `Symbol()`.
|
|
58
|
+
*/
|
|
51
59
|
export function describeToken(token) {
|
|
52
60
|
const resolved = unwrapToken(token);
|
|
53
61
|
if (typeof resolved === "string")
|
|
54
62
|
return resolved;
|
|
55
63
|
if (typeof resolved === "symbol")
|
|
56
|
-
return resolved.description
|
|
57
|
-
? `Symbol(${resolved.description})`
|
|
58
|
-
: "Symbol()";
|
|
64
|
+
return resolved.description ? resolved.description : "Symbol()";
|
|
59
65
|
if (typeof resolved === "function")
|
|
60
66
|
return resolved.name || "AnonymousConstructor";
|
|
61
67
|
return "UnknownToken";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zudojs/container",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Token-based dependency injection container for managing application dependencies and service lifetimes.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
"!dist/.tsbuildinfo"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@zudojs/errors": "1.
|
|
21
|
+
"@zudojs/errors": "1.3.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"typescript": "7.0.2",
|
|
25
|
-
"vitest": "^
|
|
25
|
+
"vitest": "^5.0.1"
|
|
26
26
|
},
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"author": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"dependency-injection",
|
|
42
42
|
"container"
|
|
43
43
|
],
|
|
44
|
-
"homepage": "https://
|
|
44
|
+
"homepage": "https://zudojs.oyinlola.site/docs/packages-container",
|
|
45
45
|
"bugs": {
|
|
46
46
|
"url": "https://github.com/oyinlola-tech/zudo/issues"
|
|
47
47
|
},
|