ts-ioc-container 43.2.0 → 43.3.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 +18 -8
- package/cjm/container/AliasMap.js +2 -2
- package/cjm/container/Container.js +10 -2
- package/cjm/container/EmptyContainer.js +5 -2
- package/cjm/index.js +13 -10
- package/cjm/registration/IRegistration.js +2 -2
- package/cjm/registration/Registration.js +2 -2
- package/cjm/token/AliasUniqToken.js +43 -0
- package/cjm/token/{StringToken.js → UniqToken.js} +6 -6
- package/cjm/token/toToken.js +2 -2
- package/esm/container/AliasMap.js +2 -2
- package/esm/container/Container.js +10 -2
- package/esm/container/EmptyContainer.js +5 -2
- package/esm/index.js +5 -4
- package/esm/registration/IRegistration.js +2 -2
- package/esm/registration/Registration.js +2 -2
- package/esm/token/AliasUniqToken.js +38 -0
- package/esm/token/{StringToken.js → UniqToken.js} +4 -4
- package/esm/token/toToken.js +2 -2
- package/package.json +1 -1
- package/typings/container/AliasMap.d.ts +2 -2
- package/typings/container/AutoMockedContainer.d.ts +2 -1
- package/typings/container/Container.d.ts +1 -0
- package/typings/container/EmptyContainer.d.ts +2 -1
- package/typings/container/IContainer.d.ts +1 -0
- package/typings/index.d.ts +5 -4
- package/typings/token/AliasUniqToken.d.ts +15 -0
- package/typings/token/{StringToken.d.ts → UniqToken.d.ts} +4 -4
package/README.md
CHANGED
|
@@ -867,7 +867,7 @@ import {
|
|
|
867
867
|
Registration as R,
|
|
868
868
|
resolveByArgs,
|
|
869
869
|
singleton,
|
|
870
|
-
|
|
870
|
+
UniqToken,
|
|
871
871
|
} from 'ts-ioc-container';
|
|
872
872
|
|
|
873
873
|
@register(bindTo('logger'))
|
|
@@ -911,8 +911,8 @@ describe('ArgsProvider', function () {
|
|
|
911
911
|
name: string;
|
|
912
912
|
}
|
|
913
913
|
|
|
914
|
-
const IUserRepositoryKey = new
|
|
915
|
-
const ITodoRepositoryKey = new
|
|
914
|
+
const IUserRepositoryKey = new UniqToken<IRepository>('IUserRepository');
|
|
915
|
+
const ITodoRepositoryKey = new UniqToken<IRepository>('ITodoRepository');
|
|
916
916
|
|
|
917
917
|
@register(bindTo(IUserRepositoryKey))
|
|
918
918
|
class UserRepository implements IRepository {
|
|
@@ -928,7 +928,7 @@ describe('ArgsProvider', function () {
|
|
|
928
928
|
repository: IRepository;
|
|
929
929
|
}
|
|
930
930
|
|
|
931
|
-
const IEntityManagerKey = new
|
|
931
|
+
const IEntityManagerKey = new UniqToken<IEntityManager>('IEntityManager');
|
|
932
932
|
|
|
933
933
|
@register(bindTo(IEntityManagerKey), argsFn(resolveByArgs))
|
|
934
934
|
class EntityManager {
|
|
@@ -957,8 +957,8 @@ describe('ArgsProvider', function () {
|
|
|
957
957
|
name: string;
|
|
958
958
|
}
|
|
959
959
|
|
|
960
|
-
const IUserRepositoryKey = new
|
|
961
|
-
const ITodoRepositoryKey = new
|
|
960
|
+
const IUserRepositoryKey = new UniqToken<IRepository>('IUserRepository');
|
|
961
|
+
const ITodoRepositoryKey = new UniqToken<IRepository>('ITodoRepository');
|
|
962
962
|
|
|
963
963
|
@register(bindTo(IUserRepositoryKey))
|
|
964
964
|
class UserRepository implements IRepository {
|
|
@@ -974,7 +974,7 @@ describe('ArgsProvider', function () {
|
|
|
974
974
|
repository: IRepository;
|
|
975
975
|
}
|
|
976
976
|
|
|
977
|
-
const IEntityManagerKey = new
|
|
977
|
+
const IEntityManagerKey = new UniqToken<IEntityManager>('IEntityManager');
|
|
978
978
|
|
|
979
979
|
@register(bindTo(IEntityManagerKey), argsFn(resolveByArgs), singleton(MultiCache.fromFirstArg))
|
|
980
980
|
class EntityManager {
|
|
@@ -1540,7 +1540,13 @@ describe('inject property', () => {
|
|
|
1540
1540
|
Sometimes you need to automatically mock all dependencies in container. This is what `AutoMockedContainer` is for.
|
|
1541
1541
|
|
|
1542
1542
|
```typescript
|
|
1543
|
-
import {
|
|
1543
|
+
import {
|
|
1544
|
+
AutoMockedContainer,
|
|
1545
|
+
Container,
|
|
1546
|
+
type DependencyKey,
|
|
1547
|
+
MethodNotImplementedError,
|
|
1548
|
+
ResolveOneOptions,
|
|
1549
|
+
} from 'ts-ioc-container';
|
|
1544
1550
|
import { type IMock, Mock } from 'moq.ts';
|
|
1545
1551
|
|
|
1546
1552
|
export class MoqContainer extends AutoMockedContainer {
|
|
@@ -1550,6 +1556,10 @@ export class MoqContainer extends AutoMockedContainer {
|
|
|
1550
1556
|
return this.resolveMock<T>(key).object();
|
|
1551
1557
|
}
|
|
1552
1558
|
|
|
1559
|
+
resolveOneByAlias<T>(alias: DependencyKey, options?: ResolveOneOptions): T {
|
|
1560
|
+
throw new MethodNotImplementedError('resolveOneByAlias');
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1553
1563
|
resolveMock<T>(key: DependencyKey): IMock<T> {
|
|
1554
1564
|
if (!this.mocks.has(key)) {
|
|
1555
1565
|
this.mocks.set(key, new Mock());
|
|
@@ -11,10 +11,10 @@ class AliasMap {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
-
|
|
14
|
+
getKeysByAlias(alias) {
|
|
15
15
|
return [...(this.aliasToKeySet.get(alias) ?? [])];
|
|
16
16
|
}
|
|
17
|
-
|
|
17
|
+
setAliasesByKey(key, aliases) {
|
|
18
18
|
for (const alias of aliases) {
|
|
19
19
|
const dependencyKeySet = this.aliasToKeySet.get(alias) ?? new Set();
|
|
20
20
|
this.aliasToKeySet.set(alias, dependencyKeySet.add(key));
|
|
@@ -43,7 +43,7 @@ class Container {
|
|
|
43
43
|
this.validateContainer();
|
|
44
44
|
this.providers.set(key, provider);
|
|
45
45
|
this.aliases.deleteAliasesByKey(key);
|
|
46
|
-
this.aliases.
|
|
46
|
+
this.aliases.setAliasesByKey(key, aliases);
|
|
47
47
|
return this;
|
|
48
48
|
}
|
|
49
49
|
addRegistration(registration) {
|
|
@@ -69,7 +69,7 @@ class Container {
|
|
|
69
69
|
let left = takeFirst;
|
|
70
70
|
const keys = [];
|
|
71
71
|
const deps = [];
|
|
72
|
-
for (const key of this.aliases.
|
|
72
|
+
for (const key of this.aliases.getKeysByAlias(alias).filter(utils_1.Filter.exclude(excludedKeys))) {
|
|
73
73
|
const provider = this.findProviderByKeyOrFail(key);
|
|
74
74
|
if (!provider.hasAccess({ invocationScope: child, providerScope: this })) {
|
|
75
75
|
continue;
|
|
@@ -90,6 +90,14 @@ class Container {
|
|
|
90
90
|
});
|
|
91
91
|
return [...deps, ...parentDeps];
|
|
92
92
|
}
|
|
93
|
+
resolveOneByAlias(alias, { args = [], child = this, lazy } = {}) {
|
|
94
|
+
this.validateContainer();
|
|
95
|
+
const [key, ..._] = this.aliases.getKeysByAlias(alias);
|
|
96
|
+
const provider = key !== undefined ? this.findProviderByKeyOrFail(key) : undefined;
|
|
97
|
+
return provider?.hasAccess({ invocationScope: child, providerScope: this })
|
|
98
|
+
? provider.resolve(this, { args, lazy })
|
|
99
|
+
: this.parent.resolveOneByAlias(key, { args, child, lazy });
|
|
100
|
+
}
|
|
93
101
|
createScope({ tags = [] } = {}) {
|
|
94
102
|
this.validateContainer();
|
|
95
103
|
const scope = new Container({
|
|
@@ -39,11 +39,14 @@ class EmptyContainer {
|
|
|
39
39
|
addRegistration(registration) {
|
|
40
40
|
throw new MethodNotImplementedError_1.MethodNotImplementedError();
|
|
41
41
|
}
|
|
42
|
+
resolve(key, options) {
|
|
43
|
+
throw new DependencyNotFoundError_1.DependencyNotFoundError(`Cannot find ${key.toString()}`);
|
|
44
|
+
}
|
|
42
45
|
resolveByAlias(alias, options) {
|
|
43
46
|
return [];
|
|
44
47
|
}
|
|
45
|
-
|
|
46
|
-
throw new DependencyNotFoundError_1.DependencyNotFoundError(`Cannot find ${
|
|
48
|
+
resolveOneByAlias(alias, options) {
|
|
49
|
+
throw new DependencyNotFoundError_1.DependencyNotFoundError(`Cannot find alias ${alias.toString()}`);
|
|
47
50
|
}
|
|
48
51
|
}
|
|
49
52
|
exports.EmptyContainer = EmptyContainer;
|
package/cjm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.
|
|
3
|
+
exports.AliasUniqToken = exports.toAlias = exports.AliasToken = exports.InjectionToken = exports.getParameterMetadata = exports.getMethodMetadata = exports.setMethodMetadata = exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = exports.SyncHooksRunner = exports.AsyncHooksRunner = exports.onDispose = exports.onDisposeHooksRunner = exports.onConstruct = exports.onConstructHooksRunner = exports.injectProp = exports.HookContext = exports.hasHooks = exports.hook = exports.getHooks = exports.UnexpectedHookResultError = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyMissingKeyError = exports.DependencyNotFoundError = exports.Registration = exports.bindTo = exports.register = exports.scope = exports.decorate = exports.MultiCache = exports.multiCache = exports.SingletonProvider = exports.singleton = exports.Provider = exports.resolveByArgs = exports.ProviderDecorator = exports.args = exports.argsFn = exports.lazy = exports.scopeAccess = exports.ProxyInjector = exports.SimpleInjector = exports.MetadataInjector = exports.resolveArgs = exports.inject = exports.AutoMockedContainer = exports.EmptyContainer = exports.Container = void 0;
|
|
4
|
+
exports.Is = exports.select = exports.toToken = exports.InstanceListToken = exports.ConstantToken = exports.FunctionToken = exports.UniqToken = exports.ClassToken = exports.toAliasUniq = void 0;
|
|
5
5
|
var Container_1 = require("./container/Container");
|
|
6
6
|
Object.defineProperty(exports, "Container", { enumerable: true, get: function () { return Container_1.Container; } });
|
|
7
7
|
var EmptyContainer_1 = require("./container/EmptyContainer");
|
|
@@ -69,6 +69,10 @@ Object.defineProperty(exports, "onConstruct", { enumerable: true, get: function
|
|
|
69
69
|
var onDispose_1 = require("./hooks/onDispose");
|
|
70
70
|
Object.defineProperty(exports, "onDisposeHooksRunner", { enumerable: true, get: function () { return onDispose_1.onDisposeHooksRunner; } });
|
|
71
71
|
Object.defineProperty(exports, "onDispose", { enumerable: true, get: function () { return onDispose_1.onDispose; } });
|
|
72
|
+
var AsyncHooksRunner_1 = require("./hooks/runner/AsyncHooksRunner");
|
|
73
|
+
Object.defineProperty(exports, "AsyncHooksRunner", { enumerable: true, get: function () { return AsyncHooksRunner_1.AsyncHooksRunner; } });
|
|
74
|
+
var SyncHooksRunner_1 = require("./hooks/runner/SyncHooksRunner");
|
|
75
|
+
Object.defineProperty(exports, "SyncHooksRunner", { enumerable: true, get: function () { return SyncHooksRunner_1.SyncHooksRunner; } });
|
|
72
76
|
// Metadata
|
|
73
77
|
var metadata_1 = require("./metadata");
|
|
74
78
|
Object.defineProperty(exports, "setMetadata", { enumerable: true, get: function () { return metadata_1.setMetadata; } });
|
|
@@ -83,24 +87,23 @@ Object.defineProperty(exports, "InjectionToken", { enumerable: true, get: functi
|
|
|
83
87
|
var AliasToken_1 = require("./token/AliasToken");
|
|
84
88
|
Object.defineProperty(exports, "AliasToken", { enumerable: true, get: function () { return AliasToken_1.AliasToken; } });
|
|
85
89
|
Object.defineProperty(exports, "toAlias", { enumerable: true, get: function () { return AliasToken_1.toAlias; } });
|
|
90
|
+
var AliasUniqToken_1 = require("./token/AliasUniqToken");
|
|
91
|
+
Object.defineProperty(exports, "AliasUniqToken", { enumerable: true, get: function () { return AliasUniqToken_1.AliasUniqToken; } });
|
|
92
|
+
Object.defineProperty(exports, "toAliasUniq", { enumerable: true, get: function () { return AliasUniqToken_1.toAliasUniq; } });
|
|
86
93
|
var ClassToken_1 = require("./token/ClassToken");
|
|
87
94
|
Object.defineProperty(exports, "ClassToken", { enumerable: true, get: function () { return ClassToken_1.ClassToken; } });
|
|
88
|
-
var
|
|
89
|
-
Object.defineProperty(exports, "
|
|
95
|
+
var UniqToken_1 = require("./token/UniqToken");
|
|
96
|
+
Object.defineProperty(exports, "UniqToken", { enumerable: true, get: function () { return UniqToken_1.UniqToken; } });
|
|
90
97
|
var FunctionToken_1 = require("./token/FunctionToken");
|
|
91
98
|
Object.defineProperty(exports, "FunctionToken", { enumerable: true, get: function () { return FunctionToken_1.FunctionToken; } });
|
|
92
99
|
var ConstantToken_1 = require("./token/ConstantToken");
|
|
93
100
|
Object.defineProperty(exports, "ConstantToken", { enumerable: true, get: function () { return ConstantToken_1.ConstantToken; } });
|
|
94
101
|
var InstanceListToken_1 = require("./token/InstanceListToken");
|
|
95
102
|
Object.defineProperty(exports, "InstanceListToken", { enumerable: true, get: function () { return InstanceListToken_1.InstanceListToken; } });
|
|
103
|
+
var toToken_1 = require("./token/toToken");
|
|
104
|
+
Object.defineProperty(exports, "toToken", { enumerable: true, get: function () { return toToken_1.toToken; } });
|
|
96
105
|
// Others
|
|
97
106
|
var select_1 = require("./select");
|
|
98
107
|
Object.defineProperty(exports, "select", { enumerable: true, get: function () { return select_1.select; } });
|
|
99
108
|
var utils_1 = require("./utils");
|
|
100
109
|
Object.defineProperty(exports, "Is", { enumerable: true, get: function () { return utils_1.Is; } });
|
|
101
|
-
var toToken_1 = require("./token/toToken");
|
|
102
|
-
Object.defineProperty(exports, "toToken", { enumerable: true, get: function () { return toToken_1.toToken; } });
|
|
103
|
-
var AsyncHooksRunner_1 = require("./hooks/runner/AsyncHooksRunner");
|
|
104
|
-
Object.defineProperty(exports, "AsyncHooksRunner", { enumerable: true, get: function () { return AsyncHooksRunner_1.AsyncHooksRunner; } });
|
|
105
|
-
var SyncHooksRunner_1 = require("./hooks/runner/SyncHooksRunner");
|
|
106
|
-
Object.defineProperty(exports, "SyncHooksRunner", { enumerable: true, get: function () { return SyncHooksRunner_1.SyncHooksRunner; } });
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.bindTo = exports.register = exports.getTransformers = exports.scope = void 0;
|
|
4
4
|
const metadata_1 = require("../metadata");
|
|
5
5
|
const ProviderPipe_1 = require("../provider/ProviderPipe");
|
|
6
|
-
const
|
|
6
|
+
const UniqToken_1 = require("../token/UniqToken");
|
|
7
7
|
const BindToken_1 = require("../token/BindToken");
|
|
8
8
|
const scope = (...predicates) => (r) => r.when(...predicates);
|
|
9
9
|
exports.scope = scope;
|
|
@@ -13,7 +13,7 @@ exports.getTransformers = getTransformers;
|
|
|
13
13
|
const register = (...mappers) => (0, metadata_1.setMetadata)(METADATA_KEY, mappers.map((m) => ((0, ProviderPipe_1.isProviderPipe)(m) ? (r) => m.mapRegistration(r) : m)));
|
|
14
14
|
exports.register = register;
|
|
15
15
|
const bindTo = (token) => (r) => {
|
|
16
|
-
const targetToken = (0, BindToken_1.isBindToken)(token) ? token : new
|
|
16
|
+
const targetToken = (0, BindToken_1.isBindToken)(token) ? token : new UniqToken_1.UniqToken(token);
|
|
17
17
|
targetToken.bindTo(r);
|
|
18
18
|
return r;
|
|
19
19
|
};
|
|
@@ -6,7 +6,7 @@ const Provider_1 = require("../provider/Provider");
|
|
|
6
6
|
const DependencyMissingKeyError_1 = require("../errors/DependencyMissingKeyError");
|
|
7
7
|
const IRegistration_1 = require("./IRegistration");
|
|
8
8
|
const ProviderPipe_1 = require("../provider/ProviderPipe");
|
|
9
|
-
const
|
|
9
|
+
const UniqToken_1 = require("../token/UniqToken");
|
|
10
10
|
class Registration {
|
|
11
11
|
createProvider;
|
|
12
12
|
key;
|
|
@@ -54,7 +54,7 @@ class Registration {
|
|
|
54
54
|
}
|
|
55
55
|
bindTo(key) {
|
|
56
56
|
if (utils_1.Is.dependencyKey(key)) {
|
|
57
|
-
new
|
|
57
|
+
new UniqToken_1.UniqToken(key).bindTo(this);
|
|
58
58
|
return this;
|
|
59
59
|
}
|
|
60
60
|
key.bindTo(this);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toAliasUniq = exports.AliasUniqToken = void 0;
|
|
4
|
+
const InjectionToken_1 = require("./InjectionToken");
|
|
5
|
+
class AliasUniqToken extends InjectionToken_1.InjectionToken {
|
|
6
|
+
token;
|
|
7
|
+
options;
|
|
8
|
+
constructor(token, options = {}) {
|
|
9
|
+
super();
|
|
10
|
+
this.token = token;
|
|
11
|
+
this.options = options;
|
|
12
|
+
}
|
|
13
|
+
resolve(s) {
|
|
14
|
+
const argsFn = this.options.argsFn ?? (0, InjectionToken_1.setArgs)();
|
|
15
|
+
return s.resolveOneByAlias(this.token, {
|
|
16
|
+
args: argsFn(s),
|
|
17
|
+
lazy: this.options.lazy,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
bindTo(r) {
|
|
21
|
+
r.bindToAlias(this.token);
|
|
22
|
+
}
|
|
23
|
+
args(...args) {
|
|
24
|
+
const argsFn = this.options.argsFn ?? (0, InjectionToken_1.setArgs)();
|
|
25
|
+
return new AliasUniqToken(this.token, {
|
|
26
|
+
...this.options,
|
|
27
|
+
argsFn: (s) => [...argsFn(s), ...args],
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
argsFn(getArgsFn) {
|
|
31
|
+
const argsFn = this.options.argsFn ?? (0, InjectionToken_1.setArgs)();
|
|
32
|
+
return new AliasUniqToken(this.token, {
|
|
33
|
+
...this.options,
|
|
34
|
+
argsFn: (s) => [...argsFn(s), ...getArgsFn(s)],
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
lazy() {
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.AliasUniqToken = AliasUniqToken;
|
|
42
|
+
const toAliasUniq = (token) => new AliasUniqToken(token);
|
|
43
|
+
exports.toAliasUniq = toAliasUniq;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.UniqToken = void 0;
|
|
4
4
|
const InjectionToken_1 = require("./InjectionToken");
|
|
5
|
-
class
|
|
5
|
+
class UniqToken extends InjectionToken_1.InjectionToken {
|
|
6
6
|
token;
|
|
7
7
|
options;
|
|
8
8
|
constructor(token, options = {}) {
|
|
@@ -22,20 +22,20 @@ class StringToken extends InjectionToken_1.InjectionToken {
|
|
|
22
22
|
}
|
|
23
23
|
args(...args) {
|
|
24
24
|
const argsFn = this.options.argsFn ?? (0, InjectionToken_1.setArgs)();
|
|
25
|
-
return new
|
|
25
|
+
return new UniqToken(this.token, {
|
|
26
26
|
...this.options,
|
|
27
27
|
argsFn: (s) => [...argsFn(s), ...args],
|
|
28
28
|
});
|
|
29
29
|
}
|
|
30
30
|
argsFn(getArgsFn) {
|
|
31
31
|
const argsFn = this.options.argsFn ?? (0, InjectionToken_1.setArgs)();
|
|
32
|
-
return new
|
|
32
|
+
return new UniqToken(this.token, {
|
|
33
33
|
...this.options,
|
|
34
34
|
argsFn: (s) => [...argsFn(s), ...getArgsFn(s)],
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
lazy() {
|
|
38
|
-
return new
|
|
38
|
+
return new UniqToken(this.token, { ...this.options, lazy: true });
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
exports.
|
|
41
|
+
exports.UniqToken = UniqToken;
|
package/cjm/token/toToken.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.toToken = void 0;
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
|
-
const
|
|
5
|
+
const UniqToken_1 = require("./UniqToken");
|
|
6
6
|
const ClassToken_1 = require("./ClassToken");
|
|
7
7
|
const FunctionToken_1 = require("./FunctionToken");
|
|
8
8
|
const UnsupportedTokenTypeError_1 = require("../errors/UnsupportedTokenTypeError");
|
|
@@ -12,7 +12,7 @@ const toToken = (token) => {
|
|
|
12
12
|
return token;
|
|
13
13
|
}
|
|
14
14
|
if (utils_1.Is.dependencyKey(token)) {
|
|
15
|
-
return new
|
|
15
|
+
return new UniqToken_1.UniqToken(token);
|
|
16
16
|
}
|
|
17
17
|
if (utils_1.Is.constructor(token)) {
|
|
18
18
|
return new ClassToken_1.ClassToken(token);
|
|
@@ -8,10 +8,10 @@ export class AliasMap {
|
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
getKeysByAlias(alias) {
|
|
12
12
|
return [...(this.aliasToKeySet.get(alias) ?? [])];
|
|
13
13
|
}
|
|
14
|
-
|
|
14
|
+
setAliasesByKey(key, aliases) {
|
|
15
15
|
for (const alias of aliases) {
|
|
16
16
|
const dependencyKeySet = this.aliasToKeySet.get(alias) ?? new Set();
|
|
17
17
|
this.aliasToKeySet.set(alias, dependencyKeySet.add(key));
|
|
@@ -40,7 +40,7 @@ export class Container {
|
|
|
40
40
|
this.validateContainer();
|
|
41
41
|
this.providers.set(key, provider);
|
|
42
42
|
this.aliases.deleteAliasesByKey(key);
|
|
43
|
-
this.aliases.
|
|
43
|
+
this.aliases.setAliasesByKey(key, aliases);
|
|
44
44
|
return this;
|
|
45
45
|
}
|
|
46
46
|
addRegistration(registration) {
|
|
@@ -66,7 +66,7 @@ export class Container {
|
|
|
66
66
|
let left = takeFirst;
|
|
67
67
|
const keys = [];
|
|
68
68
|
const deps = [];
|
|
69
|
-
for (const key of this.aliases.
|
|
69
|
+
for (const key of this.aliases.getKeysByAlias(alias).filter(F.exclude(excludedKeys))) {
|
|
70
70
|
const provider = this.findProviderByKeyOrFail(key);
|
|
71
71
|
if (!provider.hasAccess({ invocationScope: child, providerScope: this })) {
|
|
72
72
|
continue;
|
|
@@ -87,6 +87,14 @@ export class Container {
|
|
|
87
87
|
});
|
|
88
88
|
return [...deps, ...parentDeps];
|
|
89
89
|
}
|
|
90
|
+
resolveOneByAlias(alias, { args = [], child = this, lazy } = {}) {
|
|
91
|
+
this.validateContainer();
|
|
92
|
+
const [key, ..._] = this.aliases.getKeysByAlias(alias);
|
|
93
|
+
const provider = key !== undefined ? this.findProviderByKeyOrFail(key) : undefined;
|
|
94
|
+
return provider?.hasAccess({ invocationScope: child, providerScope: this })
|
|
95
|
+
? provider.resolve(this, { args, lazy })
|
|
96
|
+
: this.parent.resolveOneByAlias(key, { args, child, lazy });
|
|
97
|
+
}
|
|
90
98
|
createScope({ tags = [] } = {}) {
|
|
91
99
|
this.validateContainer();
|
|
92
100
|
const scope = new Container({
|
|
@@ -36,10 +36,13 @@ export class EmptyContainer {
|
|
|
36
36
|
addRegistration(registration) {
|
|
37
37
|
throw new MethodNotImplementedError();
|
|
38
38
|
}
|
|
39
|
+
resolve(key, options) {
|
|
40
|
+
throw new DependencyNotFoundError(`Cannot find ${key.toString()}`);
|
|
41
|
+
}
|
|
39
42
|
resolveByAlias(alias, options) {
|
|
40
43
|
return [];
|
|
41
44
|
}
|
|
42
|
-
|
|
43
|
-
throw new DependencyNotFoundError(`Cannot find ${
|
|
45
|
+
resolveOneByAlias(alias, options) {
|
|
46
|
+
throw new DependencyNotFoundError(`Cannot find alias ${alias.toString()}`);
|
|
44
47
|
}
|
|
45
48
|
}
|
package/esm/index.js
CHANGED
|
@@ -27,19 +27,20 @@ export { HookContext } from './hooks/HookContext';
|
|
|
27
27
|
export { injectProp } from './hooks/injectProp';
|
|
28
28
|
export { onConstructHooksRunner, onConstruct } from './hooks/onConstruct';
|
|
29
29
|
export { onDisposeHooksRunner, onDispose } from './hooks/onDispose';
|
|
30
|
+
export { AsyncHooksRunner } from './hooks/runner/AsyncHooksRunner';
|
|
31
|
+
export { SyncHooksRunner } from './hooks/runner/SyncHooksRunner';
|
|
30
32
|
// Metadata
|
|
31
33
|
export { setMetadata, getMetadata, setParameterMetadata, setMethodMetadata, getMethodMetadata, getParameterMetadata, } from './metadata';
|
|
32
34
|
// InjectionToken
|
|
33
35
|
export { InjectionToken } from './token/InjectionToken';
|
|
34
36
|
export { AliasToken, toAlias } from './token/AliasToken';
|
|
37
|
+
export { AliasUniqToken, toAliasUniq } from './token/AliasUniqToken';
|
|
35
38
|
export { ClassToken } from './token/ClassToken';
|
|
36
|
-
export {
|
|
39
|
+
export { UniqToken } from './token/UniqToken';
|
|
37
40
|
export { FunctionToken } from './token/FunctionToken';
|
|
38
41
|
export { ConstantToken } from './token/ConstantToken';
|
|
39
42
|
export { InstanceListToken } from './token/InstanceListToken';
|
|
43
|
+
export { toToken } from './token/toToken';
|
|
40
44
|
// Others
|
|
41
45
|
export { select } from './select';
|
|
42
46
|
export { Is } from './utils';
|
|
43
|
-
export { toToken } from './token/toToken';
|
|
44
|
-
export { AsyncHooksRunner } from './hooks/runner/AsyncHooksRunner';
|
|
45
|
-
export { SyncHooksRunner } from './hooks/runner/SyncHooksRunner';
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { getMetadata, setMetadata } from '../metadata';
|
|
2
2
|
import { isProviderPipe } from '../provider/ProviderPipe';
|
|
3
|
-
import {
|
|
3
|
+
import { UniqToken } from '../token/UniqToken';
|
|
4
4
|
import { isBindToken } from '../token/BindToken';
|
|
5
5
|
export const scope = (...predicates) => (r) => r.when(...predicates);
|
|
6
6
|
const METADATA_KEY = 'registration';
|
|
7
7
|
export const getTransformers = (Target) => getMetadata(Target, METADATA_KEY) ?? [];
|
|
8
8
|
export const register = (...mappers) => setMetadata(METADATA_KEY, mappers.map((m) => (isProviderPipe(m) ? (r) => m.mapRegistration(r) : m)));
|
|
9
9
|
export const bindTo = (token) => (r) => {
|
|
10
|
-
const targetToken = isBindToken(token) ? token : new
|
|
10
|
+
const targetToken = isBindToken(token) ? token : new UniqToken(token);
|
|
11
11
|
targetToken.bindTo(r);
|
|
12
12
|
return r;
|
|
13
13
|
};
|
|
@@ -3,7 +3,7 @@ import { Provider } from '../provider/Provider';
|
|
|
3
3
|
import { DependencyMissingKeyError } from '../errors/DependencyMissingKeyError';
|
|
4
4
|
import { getTransformers } from './IRegistration';
|
|
5
5
|
import { isProviderPipe } from '../provider/ProviderPipe';
|
|
6
|
-
import {
|
|
6
|
+
import { UniqToken } from '../token/UniqToken';
|
|
7
7
|
export class Registration {
|
|
8
8
|
createProvider;
|
|
9
9
|
key;
|
|
@@ -51,7 +51,7 @@ export class Registration {
|
|
|
51
51
|
}
|
|
52
52
|
bindTo(key) {
|
|
53
53
|
if (Is.dependencyKey(key)) {
|
|
54
|
-
new
|
|
54
|
+
new UniqToken(key).bindTo(this);
|
|
55
55
|
return this;
|
|
56
56
|
}
|
|
57
57
|
key.bindTo(this);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { InjectionToken, setArgs } from './InjectionToken';
|
|
2
|
+
export class AliasUniqToken extends InjectionToken {
|
|
3
|
+
token;
|
|
4
|
+
options;
|
|
5
|
+
constructor(token, options = {}) {
|
|
6
|
+
super();
|
|
7
|
+
this.token = token;
|
|
8
|
+
this.options = options;
|
|
9
|
+
}
|
|
10
|
+
resolve(s) {
|
|
11
|
+
const argsFn = this.options.argsFn ?? setArgs();
|
|
12
|
+
return s.resolveOneByAlias(this.token, {
|
|
13
|
+
args: argsFn(s),
|
|
14
|
+
lazy: this.options.lazy,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
bindTo(r) {
|
|
18
|
+
r.bindToAlias(this.token);
|
|
19
|
+
}
|
|
20
|
+
args(...args) {
|
|
21
|
+
const argsFn = this.options.argsFn ?? setArgs();
|
|
22
|
+
return new AliasUniqToken(this.token, {
|
|
23
|
+
...this.options,
|
|
24
|
+
argsFn: (s) => [...argsFn(s), ...args],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
argsFn(getArgsFn) {
|
|
28
|
+
const argsFn = this.options.argsFn ?? setArgs();
|
|
29
|
+
return new AliasUniqToken(this.token, {
|
|
30
|
+
...this.options,
|
|
31
|
+
argsFn: (s) => [...argsFn(s), ...getArgsFn(s)],
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
lazy() {
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export const toAliasUniq = (token) => new AliasUniqToken(token);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { InjectionToken, setArgs } from './InjectionToken';
|
|
2
|
-
export class
|
|
2
|
+
export class UniqToken extends InjectionToken {
|
|
3
3
|
token;
|
|
4
4
|
options;
|
|
5
5
|
constructor(token, options = {}) {
|
|
@@ -19,19 +19,19 @@ export class StringToken extends InjectionToken {
|
|
|
19
19
|
}
|
|
20
20
|
args(...args) {
|
|
21
21
|
const argsFn = this.options.argsFn ?? setArgs();
|
|
22
|
-
return new
|
|
22
|
+
return new UniqToken(this.token, {
|
|
23
23
|
...this.options,
|
|
24
24
|
argsFn: (s) => [...argsFn(s), ...args],
|
|
25
25
|
});
|
|
26
26
|
}
|
|
27
27
|
argsFn(getArgsFn) {
|
|
28
28
|
const argsFn = this.options.argsFn ?? setArgs();
|
|
29
|
-
return new
|
|
29
|
+
return new UniqToken(this.token, {
|
|
30
30
|
...this.options,
|
|
31
31
|
argsFn: (s) => [...argsFn(s), ...getArgsFn(s)],
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
lazy() {
|
|
35
|
-
return new
|
|
35
|
+
return new UniqToken(this.token, { ...this.options, lazy: true });
|
|
36
36
|
}
|
|
37
37
|
}
|
package/esm/token/toToken.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Is } from '../utils';
|
|
2
|
-
import {
|
|
2
|
+
import { UniqToken } from './UniqToken';
|
|
3
3
|
import { ClassToken } from './ClassToken';
|
|
4
4
|
import { FunctionToken } from './FunctionToken';
|
|
5
5
|
import { UnsupportedTokenTypeError } from '../errors/UnsupportedTokenTypeError';
|
|
@@ -9,7 +9,7 @@ export const toToken = (token) => {
|
|
|
9
9
|
return token;
|
|
10
10
|
}
|
|
11
11
|
if (Is.dependencyKey(token)) {
|
|
12
|
-
return new
|
|
12
|
+
return new UniqToken(token);
|
|
13
13
|
}
|
|
14
14
|
if (Is.constructor(token)) {
|
|
15
15
|
return new ClassToken(token);
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ export type Alias = DependencyKey;
|
|
|
3
3
|
export declare class AliasMap {
|
|
4
4
|
private readonly aliasToKeySet;
|
|
5
5
|
deleteAliasesByKey(key: DependencyKey): void;
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
getKeysByAlias(alias: DependencyKey): DependencyKey[];
|
|
7
|
+
setAliasesByKey(key: DependencyKey, aliases: DependencyKey[]): void;
|
|
8
8
|
destroy(): void;
|
|
9
9
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DependencyKey, type IContainer, type Instance, type ResolveManyOptions, type Tag } from './IContainer';
|
|
1
|
+
import { type DependencyKey, type IContainer, type Instance, type ResolveManyOptions, ResolveOneOptions, type Tag } from './IContainer';
|
|
2
2
|
import { type IRegistration } from '../registration/IRegistration';
|
|
3
3
|
import { type constructor } from '../utils';
|
|
4
4
|
export declare abstract class AutoMockedContainer implements IContainer {
|
|
@@ -17,4 +17,5 @@ export declare abstract class AutoMockedContainer implements IContainer {
|
|
|
17
17
|
addRegistration(registration: IRegistration): this;
|
|
18
18
|
abstract resolveByAlias<T>(alias: DependencyKey, options?: ResolveManyOptions): T[];
|
|
19
19
|
abstract resolve<T>(alias: constructor<T> | DependencyKey, options?: ResolveManyOptions): T;
|
|
20
|
+
abstract resolveOneByAlias<T>(alias: DependencyKey, options?: ResolveOneOptions): T;
|
|
20
21
|
}
|
|
@@ -30,6 +30,7 @@ export declare class Container implements IContainer {
|
|
|
30
30
|
getRegistrations(): IRegistration[];
|
|
31
31
|
resolve<T>(keyOrAlias: constructor<T> | DependencyKey, { args, child, lazy }?: ResolveOneOptions): T;
|
|
32
32
|
resolveByAlias<T>(alias: DependencyKey, { args, child, lazy, excludedKeys, takeFirst }?: ResolveManyOptions): T[];
|
|
33
|
+
resolveOneByAlias<T>(alias: DependencyKey, { args, child, lazy }?: ResolveOneOptions): T;
|
|
33
34
|
createScope({ tags }?: CreateScopeOptions): IContainer;
|
|
34
35
|
getScopes(): IContainer[];
|
|
35
36
|
removeScope(child: IContainer): void;
|
|
@@ -16,6 +16,7 @@ export declare class EmptyContainer implements IContainer {
|
|
|
16
16
|
removeScope(): void;
|
|
17
17
|
useModule(module: IContainerModule): this;
|
|
18
18
|
addRegistration(registration: IRegistration): this;
|
|
19
|
-
resolveByAlias<T>(alias: DependencyKey, options?: ResolveManyOptions): T[];
|
|
20
19
|
resolve<T>(key: constructor<T> | DependencyKey, options?: ResolveOneOptions): T;
|
|
20
|
+
resolveByAlias<T>(alias: DependencyKey, options?: ResolveManyOptions): T[];
|
|
21
|
+
resolveOneByAlias<T>(alias: DependencyKey, options?: ResolveOneOptions): T;
|
|
21
22
|
}
|
|
@@ -40,6 +40,7 @@ export interface IContainer extends Tagged {
|
|
|
40
40
|
getRegistrations(): IRegistration[];
|
|
41
41
|
resolve<T>(alias: constructor<T> | DependencyKey, options?: ResolveOneOptions): T;
|
|
42
42
|
resolveByAlias<T>(alias: DependencyKey, options?: ResolveManyOptions): T[];
|
|
43
|
+
resolveOneByAlias<T>(alias: DependencyKey, options?: ResolveOneOptions): T;
|
|
43
44
|
createScope(options?: CreateScopeOptions): IContainer;
|
|
44
45
|
getScopes(): IContainer[];
|
|
45
46
|
removeScope(child: IContainer): void;
|
package/typings/index.d.ts
CHANGED
|
@@ -26,16 +26,17 @@ export { injectProp } from './hooks/injectProp';
|
|
|
26
26
|
export { onConstructHooksRunner, onConstruct } from './hooks/onConstruct';
|
|
27
27
|
export { onDisposeHooksRunner, onDispose } from './hooks/onDispose';
|
|
28
28
|
export { HooksRunnerContext } from './hooks/runner/HooksRunner';
|
|
29
|
+
export { AsyncHooksRunner } from './hooks/runner/AsyncHooksRunner';
|
|
30
|
+
export { SyncHooksRunner } from './hooks/runner/SyncHooksRunner';
|
|
29
31
|
export { setMetadata, getMetadata, setParameterMetadata, setMethodMetadata, getMethodMetadata, getParameterMetadata, } from './metadata';
|
|
30
32
|
export { InjectionToken } from './token/InjectionToken';
|
|
31
33
|
export { AliasToken, toAlias } from './token/AliasToken';
|
|
34
|
+
export { AliasUniqToken, toAliasUniq } from './token/AliasUniqToken';
|
|
32
35
|
export { ClassToken } from './token/ClassToken';
|
|
33
|
-
export {
|
|
36
|
+
export { UniqToken } from './token/UniqToken';
|
|
34
37
|
export { FunctionToken } from './token/FunctionToken';
|
|
35
38
|
export { ConstantToken } from './token/ConstantToken';
|
|
36
39
|
export { type InstancePredicate, InstanceListToken } from './token/InstanceListToken';
|
|
40
|
+
export { toToken } from './token/toToken';
|
|
37
41
|
export { select } from './select';
|
|
38
42
|
export { type constructor, Is } from './utils';
|
|
39
|
-
export { toToken } from './token/toToken';
|
|
40
|
-
export { AsyncHooksRunner } from './hooks/runner/AsyncHooksRunner';
|
|
41
|
-
export { SyncHooksRunner } from './hooks/runner/SyncHooksRunner';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DependencyKey, IContainer } from '../container/IContainer';
|
|
2
|
+
import { InjectionToken, TokenOptions } from './InjectionToken';
|
|
3
|
+
import { IRegistration } from '../registration/IRegistration';
|
|
4
|
+
import { BindToken } from './BindToken';
|
|
5
|
+
export declare class AliasUniqToken<T = any> extends InjectionToken<T> implements BindToken<T> {
|
|
6
|
+
readonly token: string | symbol;
|
|
7
|
+
private options;
|
|
8
|
+
constructor(token: string | symbol, options?: TokenOptions);
|
|
9
|
+
resolve(s: IContainer): T;
|
|
10
|
+
bindTo(r: IRegistration<T>): void;
|
|
11
|
+
args(...args: unknown[]): InjectionToken<T>;
|
|
12
|
+
argsFn(getArgsFn: (s: IContainer) => unknown[]): InjectionToken<T>;
|
|
13
|
+
lazy(): InjectionToken<T>;
|
|
14
|
+
}
|
|
15
|
+
export declare const toAliasUniq: (token: DependencyKey) => AliasUniqToken<any>;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { IContainer } from '../container/IContainer';
|
|
2
2
|
import { InjectionToken, TokenOptions } from './InjectionToken';
|
|
3
3
|
import { IRegistration } from '../registration/IRegistration';
|
|
4
|
-
export declare class
|
|
4
|
+
export declare class UniqToken<T = any> extends InjectionToken {
|
|
5
5
|
token: string | symbol;
|
|
6
6
|
private options;
|
|
7
7
|
constructor(token: string | symbol, options?: TokenOptions);
|
|
8
8
|
resolve(s: IContainer): T;
|
|
9
9
|
bindTo(r: IRegistration<T>): void;
|
|
10
|
-
args(...args: unknown[]):
|
|
11
|
-
argsFn(getArgsFn: (s: IContainer) => unknown[]):
|
|
12
|
-
lazy():
|
|
10
|
+
args(...args: unknown[]): UniqToken<T>;
|
|
11
|
+
argsFn(getArgsFn: (s: IContainer) => unknown[]): UniqToken<T>;
|
|
12
|
+
lazy(): UniqToken<T>;
|
|
13
13
|
}
|