@lppedd/di-wise-neo 0.3.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/LICENSE +22 -0
- package/README.md +488 -0
- package/dist/cjs/index.d.ts +772 -0
- package/dist/cjs/index.js +1055 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/es/index.d.mts +772 -0
- package/dist/es/index.mjs +1037 -0
- package/dist/es/index.mjs.map +1 -0
- package/package.json +77 -0
- package/src/container.ts +292 -0
- package/src/decorators/autoRegister.ts +24 -0
- package/src/decorators/decorators.ts +47 -0
- package/src/decorators/index.ts +7 -0
- package/src/decorators/inject.ts +42 -0
- package/src/decorators/injectAll.ts +45 -0
- package/src/decorators/injectable.ts +61 -0
- package/src/decorators/optional.ts +39 -0
- package/src/decorators/optionalAll.ts +42 -0
- package/src/decorators/scoped.ts +32 -0
- package/src/defaultContainer.ts +519 -0
- package/src/errors.ts +47 -0
- package/src/index.ts +16 -0
- package/src/inject.ts +88 -0
- package/src/injectAll.ts +21 -0
- package/src/injectionContext.ts +46 -0
- package/src/injector.ts +117 -0
- package/src/metadata.ts +41 -0
- package/src/middleware.ts +85 -0
- package/src/optional.ts +65 -0
- package/src/optionalAll.ts +19 -0
- package/src/provider.ts +61 -0
- package/src/scope.ts +8 -0
- package/src/token.ts +84 -0
- package/src/tokenRegistry.ts +165 -0
- package/src/tokensRef.ts +46 -0
- package/src/utils/context.ts +19 -0
- package/src/utils/disposable.ts +10 -0
- package/src/utils/invariant.ts +6 -0
- package/src/utils/keyedStack.ts +26 -0
- package/src/utils/typeName.ts +28 -0
- package/src/utils/weakRefMap.ts +28 -0
- package/src/valueRef.ts +3 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
import { assert } from "../errors";
|
2
|
+
import { getMetadata } from "../metadata";
|
3
|
+
import type { Constructor, Token } from "../token";
|
4
|
+
import type { Decorator } from "../tokenRegistry";
|
5
|
+
import { forwardRef, isTokenRef, type TokenRef } from "../tokensRef";
|
6
|
+
|
7
|
+
export function processDecoratedParameter(
|
8
|
+
decorator: Decorator,
|
9
|
+
token: Token | TokenRef,
|
10
|
+
target: object,
|
11
|
+
propertyKey: string | symbol | undefined,
|
12
|
+
parameterIndex: number,
|
13
|
+
): void {
|
14
|
+
// Error out immediately if the decorator has been applied
|
15
|
+
// to a static property or a static method
|
16
|
+
if (propertyKey !== undefined && typeof target === "function") {
|
17
|
+
assert(false, `@${decorator} cannot be used on static member ${target.name}.${String(propertyKey)}`);
|
18
|
+
}
|
19
|
+
|
20
|
+
const tokenRef = isTokenRef(token) ? token : forwardRef(() => token);
|
21
|
+
|
22
|
+
if (propertyKey === undefined) {
|
23
|
+
// Constructor
|
24
|
+
const metadata = getMetadata(target as Constructor<any>);
|
25
|
+
metadata.dependencies.constructor.push({
|
26
|
+
decorator: decorator,
|
27
|
+
tokenRef: tokenRef,
|
28
|
+
index: parameterIndex,
|
29
|
+
});
|
30
|
+
} else {
|
31
|
+
// Normal instance method
|
32
|
+
const metadata = getMetadata(target.constructor as Constructor<any>);
|
33
|
+
const methods = metadata.dependencies.methods;
|
34
|
+
let dep = methods.get(propertyKey);
|
35
|
+
|
36
|
+
if (dep === undefined) {
|
37
|
+
dep = [];
|
38
|
+
methods.set(propertyKey, dep);
|
39
|
+
}
|
40
|
+
|
41
|
+
dep.push({
|
42
|
+
decorator: decorator,
|
43
|
+
tokenRef: tokenRef,
|
44
|
+
index: parameterIndex,
|
45
|
+
});
|
46
|
+
}
|
47
|
+
}
|
@@ -0,0 +1,7 @@
|
|
1
|
+
export { AutoRegister } from "./autoRegister";
|
2
|
+
export { Inject } from "./inject";
|
3
|
+
export { Injectable } from "./injectable";
|
4
|
+
export { InjectAll } from "./injectAll";
|
5
|
+
export { Optional } from "./optional";
|
6
|
+
export { OptionalAll } from "./optionalAll";
|
7
|
+
export { Scoped } from "./scoped";
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import type { Constructor, Token } from "../token";
|
2
|
+
import type { TokenRef } from "../tokensRef";
|
3
|
+
import { processDecoratedParameter } from "./decorators";
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Parameter decorator that injects the instance associated with the given class.
|
7
|
+
*
|
8
|
+
* Throws an error if the class is not registered in the container.
|
9
|
+
*/
|
10
|
+
export function Inject<Instance extends object>(Class: Constructor<Instance>): ParameterDecorator;
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Parameter decorator that injects the value associated with the given token.
|
14
|
+
*
|
15
|
+
* Throws an error if the token is not registered in the container.
|
16
|
+
*/
|
17
|
+
export function Inject<Value>(token: Token<Value>): ParameterDecorator;
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Parameter decorator that injects the value associated with the given token.
|
21
|
+
*
|
22
|
+
* Allows referencing a token that is declared later in the file by using
|
23
|
+
* the {@link forwardRef} helper function.
|
24
|
+
*
|
25
|
+
* Throws an error if the token is not registered in the container.
|
26
|
+
*
|
27
|
+
* @example
|
28
|
+
* ```ts
|
29
|
+
* class Wizard {
|
30
|
+
* constructor(@Inject(forwardRef(() => Wand)) readonly wand: Wand) {}
|
31
|
+
* }
|
32
|
+
* // Other code...
|
33
|
+
* class Wand {}
|
34
|
+
* ```
|
35
|
+
*/
|
36
|
+
export function Inject<Value>(tokens: TokenRef<Value>): ParameterDecorator;
|
37
|
+
|
38
|
+
export function Inject<T>(token: Token<T> | TokenRef<T>): ParameterDecorator {
|
39
|
+
return function (target, propertyKey, parameterIndex: number): void {
|
40
|
+
processDecoratedParameter("Inject", token, target, propertyKey, parameterIndex);
|
41
|
+
};
|
42
|
+
}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import type { Constructor, Token } from "../token";
|
2
|
+
import type { TokenRef } from "../tokensRef";
|
3
|
+
import { processDecoratedParameter } from "./decorators";
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Parameter decorator that injects all instances provided by the registrations
|
7
|
+
* associated with the given class.
|
8
|
+
*
|
9
|
+
* Throws an error if the class is not registered in the container.
|
10
|
+
*/
|
11
|
+
export function InjectAll<Instance extends object>(Class: Constructor<Instance>): ParameterDecorator;
|
12
|
+
|
13
|
+
/**
|
14
|
+
* Parameter decorator that injects all values provided by the registrations
|
15
|
+
* associated with the given token.
|
16
|
+
*
|
17
|
+
* Throws an error if the token is not registered in the container.
|
18
|
+
*/
|
19
|
+
export function InjectAll<Value>(token: Token<Value>): ParameterDecorator;
|
20
|
+
|
21
|
+
/**
|
22
|
+
* Parameter decorator that injects all values provided by the registrations
|
23
|
+
* associated with the given token.
|
24
|
+
*
|
25
|
+
* Allows referencing a token that is declared later in the file by using
|
26
|
+
* the {@link forwardRef} helper function.
|
27
|
+
*
|
28
|
+
* Throws an error if the token is not registered in the container.
|
29
|
+
*
|
30
|
+
* @example
|
31
|
+
* ```ts
|
32
|
+
* class Wizard {
|
33
|
+
* constructor(@InjectAll(forwardRef(() => Wand)) readonly wands: Wand[]) {}
|
34
|
+
* }
|
35
|
+
* // Other code...
|
36
|
+
* class Wand {}
|
37
|
+
* ```
|
38
|
+
*/
|
39
|
+
export function InjectAll<Value>(tokens: TokenRef<Value>): ParameterDecorator;
|
40
|
+
|
41
|
+
export function InjectAll<T>(token: Token<T> | TokenRef<T>): ParameterDecorator {
|
42
|
+
return function (target, propertyKey, parameterIndex: number): void {
|
43
|
+
processDecoratedParameter("InjectAll", token, target, propertyKey, parameterIndex);
|
44
|
+
};
|
45
|
+
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import { getMetadata } from "../metadata";
|
2
|
+
import type { Constructor, Tokens } from "../token";
|
3
|
+
import { forwardRef, isTokensRef, type TokenRef, type TokensRef } from "../tokensRef";
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Class decorator for registering additional aliasing tokens for the decorated type
|
7
|
+
* when registering it.
|
8
|
+
*
|
9
|
+
* The container uses {@link ExistingProvider} under the hood.
|
10
|
+
*
|
11
|
+
* @example
|
12
|
+
* ```ts
|
13
|
+
* @Injectable(Weapon)
|
14
|
+
* class Wand {}
|
15
|
+
* ```
|
16
|
+
*/
|
17
|
+
export function Injectable<This extends object, Value extends This>(...tokens: Tokens<Value>): ClassDecorator;
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Class decorator for registering additional aliasing tokens for the decorated type
|
21
|
+
* when registering it.
|
22
|
+
*
|
23
|
+
* The container uses {@link ExistingProvider} under the hood.
|
24
|
+
*
|
25
|
+
* Allows referencing tokens that are declared later in the file by using
|
26
|
+
* the {@link forwardRef} helper function.
|
27
|
+
*
|
28
|
+
* @example
|
29
|
+
* ```ts
|
30
|
+
* @Injectable(forwardRef() => Weapon) // Weapon is declared after Wand
|
31
|
+
* class Wizard {}
|
32
|
+
* // Other code...
|
33
|
+
* class Weapon {}
|
34
|
+
* ```
|
35
|
+
*/
|
36
|
+
export function Injectable<This extends object, Value extends This>(
|
37
|
+
tokens: TokenRef<Value> | TokensRef<Value>,
|
38
|
+
): ClassDecorator;
|
39
|
+
|
40
|
+
/**
|
41
|
+
* @__NO_SIDE_EFFECTS__
|
42
|
+
*/
|
43
|
+
export function Injectable(...args: unknown[]): ClassDecorator {
|
44
|
+
return function (Class): void {
|
45
|
+
const metadata = getMetadata(Class as any as Constructor<any>);
|
46
|
+
const arg0 = args[0];
|
47
|
+
const tokensRef = isTokensRef(arg0) ? arg0 : forwardRef(() => args as Tokens);
|
48
|
+
const existingTokensRef = metadata.tokensRef;
|
49
|
+
metadata.tokensRef = {
|
50
|
+
getRefTokens: () => {
|
51
|
+
const existingTokens = existingTokensRef.getRefTokens();
|
52
|
+
|
53
|
+
for (const token of tokensRef.getRefTokens()) {
|
54
|
+
existingTokens.add(token);
|
55
|
+
}
|
56
|
+
|
57
|
+
return existingTokens;
|
58
|
+
},
|
59
|
+
};
|
60
|
+
};
|
61
|
+
}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
import type { Constructor, Token } from "../token";
|
2
|
+
import type { TokenRef } from "../tokensRef";
|
3
|
+
import { processDecoratedParameter } from "./decorators";
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Parameter decorator that injects the instance associated with the given class,
|
7
|
+
* or `undefined` if the class is not registered in the container.
|
8
|
+
*/
|
9
|
+
export function Optional<Instance extends object>(Class: Constructor<Instance>): ParameterDecorator;
|
10
|
+
|
11
|
+
/**
|
12
|
+
* Parameter decorator that injects the value associated with the given token,
|
13
|
+
* or `undefined` if the token is not registered in the container.
|
14
|
+
*/
|
15
|
+
export function Optional<Value>(token: Token<Value>): ParameterDecorator;
|
16
|
+
|
17
|
+
/**
|
18
|
+
* Parameter decorator that injects the value associated with the given token,
|
19
|
+
* or `undefined` if the token is not registered in the container.
|
20
|
+
*
|
21
|
+
* Allows referencing a token that is declared later in the file by using
|
22
|
+
* the {@link forwardRef} helper function.
|
23
|
+
*
|
24
|
+
* @example
|
25
|
+
* ```ts
|
26
|
+
* class Wizard {
|
27
|
+
* constructor(@Optional(forwardRef(() => Wand)) readonly wand: Wand | undefined) {}
|
28
|
+
* }
|
29
|
+
* // Other code...
|
30
|
+
* class Wand {}
|
31
|
+
* ```
|
32
|
+
*/
|
33
|
+
export function Optional<Value>(tokens: TokenRef<Value>): ParameterDecorator;
|
34
|
+
|
35
|
+
export function Optional<T>(token: Token<T> | TokenRef<T>): ParameterDecorator {
|
36
|
+
return function (target, propertyKey, parameterIndex: number): void {
|
37
|
+
processDecoratedParameter("Optional", token, target, propertyKey, parameterIndex);
|
38
|
+
};
|
39
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import type { Constructor, Token } from "../token";
|
2
|
+
import type { TokenRef } from "../tokensRef";
|
3
|
+
import { processDecoratedParameter } from "./decorators";
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Parameter decorator that injects all instances provided by the registrations
|
7
|
+
* associated with the given class, or an empty array if the class is not registered
|
8
|
+
* in the container.
|
9
|
+
*/
|
10
|
+
export function OptionalAll<Instance extends object>(Class: Constructor<Instance>): ParameterDecorator;
|
11
|
+
|
12
|
+
/**
|
13
|
+
* Parameter decorator that injects all values provided by the registrations
|
14
|
+
* associated with the given token, or an empty array if the token is not registered
|
15
|
+
* in the container.
|
16
|
+
*/
|
17
|
+
export function OptionalAll<Value>(token: Token<Value>): ParameterDecorator;
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Parameter decorator that injects all values provided by the registrations
|
21
|
+
* associated with the given token, or an empty array if the token is not registered
|
22
|
+
* in the container.
|
23
|
+
*
|
24
|
+
* Allows referencing a token that is declared later in the file by using
|
25
|
+
* the {@link forwardRef} helper function.
|
26
|
+
*
|
27
|
+
* @example
|
28
|
+
* ```ts
|
29
|
+
* class Wizard {
|
30
|
+
* constructor(@OptionalAll(forwardRef(() => Wand)) readonly wands: Wand[]) {}
|
31
|
+
* }
|
32
|
+
* // Other code...
|
33
|
+
* class Wand {}
|
34
|
+
* ```
|
35
|
+
*/
|
36
|
+
export function OptionalAll<Value>(tokens: TokenRef<Value>): ParameterDecorator;
|
37
|
+
|
38
|
+
export function OptionalAll<T>(token: Token<T> | TokenRef<T>): ParameterDecorator {
|
39
|
+
return function (target, propertyKey, parameterIndex: number): void {
|
40
|
+
processDecoratedParameter("OptionalAll", token, target, propertyKey, parameterIndex);
|
41
|
+
};
|
42
|
+
}
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import { getMetadata } from "../metadata";
|
2
|
+
import type { Scope } from "../scope";
|
3
|
+
import type { Constructor } from "../token";
|
4
|
+
|
5
|
+
/**
|
6
|
+
* Class decorator for setting the scope of the decorated type when registering it.
|
7
|
+
*
|
8
|
+
* The scope set by this decorator can be overridden by explicit registration options, if provided.
|
9
|
+
*
|
10
|
+
* @example
|
11
|
+
* ```ts
|
12
|
+
* @Scoped(Scope.Container)
|
13
|
+
* class Wizard {}
|
14
|
+
*
|
15
|
+
* container.register(Wizard);
|
16
|
+
*
|
17
|
+
* // Under the hood
|
18
|
+
* container.register(
|
19
|
+
* Wizard,
|
20
|
+
* { useClass: Wizard },
|
21
|
+
* { scope: Scope.Container },
|
22
|
+
* );
|
23
|
+
* ```
|
24
|
+
*
|
25
|
+
* @__NO_SIDE_EFFECTS__
|
26
|
+
*/
|
27
|
+
export function Scoped(scope: Scope): ClassDecorator {
|
28
|
+
return function (Class): void {
|
29
|
+
const metadata = getMetadata(Class as any as Constructor<any>);
|
30
|
+
metadata.scope = scope;
|
31
|
+
};
|
32
|
+
}
|