@lppedd/di-wise-neo 0.9.2 → 0.9.4
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/cjs/index.js +142 -122
- package/dist/cjs/index.js.map +1 -1
- package/dist/es/index.mjs +142 -122
- package/dist/es/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/es/index.mjs
CHANGED
@@ -1,30 +1,3 @@
|
|
1
|
-
/**
|
2
|
-
* Type API.
|
3
|
-
*/ /**
|
4
|
-
* Creates a type token.
|
5
|
-
*
|
6
|
-
* @example
|
7
|
-
* ```ts
|
8
|
-
* const ISpell = createType<Spell>("Spell");
|
9
|
-
* ```
|
10
|
-
*
|
11
|
-
* @__NO_SIDE_EFFECTS__
|
12
|
-
*/ function createType(typeName) {
|
13
|
-
const type = {
|
14
|
-
name: `Type<${typeName}>`,
|
15
|
-
inter: createType,
|
16
|
-
union: createType,
|
17
|
-
toString () {
|
18
|
-
return type.name;
|
19
|
-
}
|
20
|
-
};
|
21
|
-
return type;
|
22
|
-
}
|
23
|
-
// @internal
|
24
|
-
function isConstructor(token) {
|
25
|
-
return typeof token === "function";
|
26
|
-
}
|
27
|
-
|
28
1
|
// @internal
|
29
2
|
function check(condition, message) {
|
30
3
|
if (!condition) {
|
@@ -37,18 +10,35 @@ function expectNever(value) {
|
|
37
10
|
}
|
38
11
|
// @internal
|
39
12
|
function throwUnregisteredError(token, name) {
|
40
|
-
const type = isConstructor(token) ? "class" : "token";
|
41
13
|
const spec = name !== undefined ? `[name=${name}]` : "";
|
42
|
-
throw new Error(tag(`unregistered
|
14
|
+
throw new Error(tag(`unregistered token ${getTokenName(token)}${spec}`));
|
43
15
|
}
|
44
16
|
// @internal
|
45
|
-
function throwExistingUnregisteredError(
|
46
|
-
|
47
|
-
|
48
|
-
|
17
|
+
function throwExistingUnregisteredError(token, cause) {
|
18
|
+
const message = tag(`failed to resolve token ${getTokenName(token)}`);
|
19
|
+
throw isError(cause) ? new Error(`${message}\n [cause] ${untag(cause.message)}`, {
|
20
|
+
cause
|
21
|
+
}) : new Error(`${message}\n [cause] the aliased token ${getTokenName(cause)} is not registered`);
|
22
|
+
}
|
23
|
+
// @internal
|
24
|
+
function throwParameterResolutionError(ctor, methodKey, dependency, cause) {
|
25
|
+
const location = getLocation(ctor, methodKey);
|
26
|
+
const tokenName = getTokenName(dependency.tokenRef.getRefToken());
|
27
|
+
const message = tag(`failed to resolve dependency for ${location}(parameter #${dependency.index}: ${tokenName})`);
|
28
|
+
throw new Error(`${message}\n [cause] ${untag(cause.message)}`, {
|
29
|
+
cause
|
30
|
+
});
|
31
|
+
}
|
32
|
+
// @internal
|
33
|
+
function getLocation(ctor, methodKey) {
|
34
|
+
const ctorName = ctor.name || "<unnamed>";
|
35
|
+
return methodKey ? `${ctorName}.${String(methodKey)}` : ctorName;
|
36
|
+
}
|
37
|
+
// @internal
|
38
|
+
function getTokenName(token) {
|
39
|
+
return token.name || "<unnamed>";
|
49
40
|
}
|
50
41
|
function isError(value) {
|
51
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
52
42
|
return value && value.stack && value.message && typeof value.message === "string";
|
53
43
|
}
|
54
44
|
function tag(message) {
|
@@ -174,7 +164,7 @@ function injectAll(token) {
|
|
174
164
|
class Metadata {
|
175
165
|
constructor(Class){
|
176
166
|
this.dependencies = {
|
177
|
-
|
167
|
+
ctor: [],
|
178
168
|
methods: new Map()
|
179
169
|
};
|
180
170
|
this.tokensRef = {
|
@@ -190,15 +180,15 @@ class Metadata {
|
|
190
180
|
set name(name) {
|
191
181
|
this.provider.name = name;
|
192
182
|
}
|
193
|
-
|
194
|
-
const i = this.dependencies.
|
183
|
+
getCtorDependency(index) {
|
184
|
+
const i = this.dependencies.ctor.findIndex((d)=>d.index === index);
|
195
185
|
if (i > -1) {
|
196
|
-
return this.dependencies.
|
186
|
+
return this.dependencies.ctor[i];
|
197
187
|
}
|
198
188
|
const dependency = {
|
199
189
|
index: index
|
200
190
|
};
|
201
|
-
this.dependencies.
|
191
|
+
this.dependencies.ctor.push(dependency);
|
202
192
|
return dependency;
|
203
193
|
}
|
204
194
|
getMethodDependency(method, index) {
|
@@ -312,6 +302,33 @@ const Scope = {
|
|
312
302
|
Container: "Container"
|
313
303
|
};
|
314
304
|
|
305
|
+
/**
|
306
|
+
* Type API.
|
307
|
+
*/ /**
|
308
|
+
* Creates a type token.
|
309
|
+
*
|
310
|
+
* @example
|
311
|
+
* ```ts
|
312
|
+
* const ISpell = createType<Spell>("Spell");
|
313
|
+
* ```
|
314
|
+
*
|
315
|
+
* @__NO_SIDE_EFFECTS__
|
316
|
+
*/ function createType(typeName) {
|
317
|
+
const type = {
|
318
|
+
name: `Type<${typeName}>`,
|
319
|
+
inter: createType,
|
320
|
+
union: createType,
|
321
|
+
toString () {
|
322
|
+
return type.name;
|
323
|
+
}
|
324
|
+
};
|
325
|
+
return type;
|
326
|
+
}
|
327
|
+
// @internal
|
328
|
+
function isConstructor(token) {
|
329
|
+
return typeof token === "function";
|
330
|
+
}
|
331
|
+
|
315
332
|
// @internal
|
316
333
|
function getTypeName(value) {
|
317
334
|
switch(typeof value){
|
@@ -326,9 +343,9 @@ function getTypeName(value) {
|
|
326
343
|
}
|
327
344
|
const proto = Object.getPrototypeOf(value);
|
328
345
|
if (proto && proto !== Object.prototype) {
|
329
|
-
const
|
330
|
-
if (typeof
|
331
|
-
return
|
346
|
+
const ctor = proto.constructor;
|
347
|
+
if (typeof ctor === "function" && ctor.name) {
|
348
|
+
return ctor.name;
|
332
349
|
}
|
333
350
|
}
|
334
351
|
}
|
@@ -356,11 +373,14 @@ class TokenRegistry {
|
|
356
373
|
set(token, registration) {
|
357
374
|
check(!internals.has(token), `cannot register reserved token ${token.name}`);
|
358
375
|
let registrations = this.myMap.get(token);
|
359
|
-
if (
|
376
|
+
if (registrations) {
|
377
|
+
const name = registration.name;
|
378
|
+
if (name !== undefined) {
|
379
|
+
const existing = registrations.filter((r)=>r.name === name);
|
380
|
+
check(existing.length === 0, `token ${getTokenName(token)} with name '${name}' is already registered`);
|
381
|
+
}
|
382
|
+
} else {
|
360
383
|
this.myMap.set(token, registrations = []);
|
361
|
-
} else if (registration.name !== undefined) {
|
362
|
-
const existing = registrations.filter((r)=>r.name === registration.name);
|
363
|
-
check(existing.length === 0, `a ${token.name} token named '${registration.name}' is already registered`);
|
364
384
|
}
|
365
385
|
registrations.push(registration);
|
366
386
|
}
|
@@ -444,7 +464,6 @@ const builders = new WeakSet();
|
|
444
464
|
// @internal
|
445
465
|
// @internal
|
446
466
|
function isDisposable(value) {
|
447
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
448
467
|
return value && typeof value === "object" && typeof value.dispose === "function";
|
449
468
|
}
|
450
469
|
|
@@ -555,7 +574,7 @@ function isDisposable(value) {
|
|
555
574
|
const [token, provider, options] = args;
|
556
575
|
const existingProvider = isExistingProvider(provider);
|
557
576
|
const name = existingProvider ? undefined : provider.name;
|
558
|
-
check(name === undefined || name.trim(),
|
577
|
+
check(name === undefined || name.trim(), `the name qualifier for token ${getTokenName(token)} must not be empty`);
|
559
578
|
if (isClassProvider(provider)) {
|
560
579
|
const metadata = getMetadata(provider.useClass);
|
561
580
|
const registration = {
|
@@ -576,7 +595,7 @@ function isDisposable(value) {
|
|
576
595
|
}
|
577
596
|
} else {
|
578
597
|
if (existingProvider) {
|
579
|
-
check(token !== provider.useExisting, `
|
598
|
+
check(token !== provider.useExisting, `token ${getTokenName(token)} cannot alias itself via useExisting`);
|
580
599
|
}
|
581
600
|
this.myTokenRegistry.set(token, {
|
582
601
|
name: name,
|
@@ -701,7 +720,6 @@ function isDisposable(value) {
|
|
701
720
|
const provider = registration.provider;
|
702
721
|
if (isClassProvider(provider)) {
|
703
722
|
const Class = provider.useClass;
|
704
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
705
723
|
return this.resolveScopedValue(token, registration, (args)=>new Class(...args));
|
706
724
|
}
|
707
725
|
if (isFactoryProvider(provider)) {
|
@@ -728,8 +746,8 @@ function isDisposable(value) {
|
|
728
746
|
if (resolution.stack.has(provider)) {
|
729
747
|
const dependentRef = resolution.dependents.get(provider);
|
730
748
|
check(dependentRef, ()=>{
|
731
|
-
const
|
732
|
-
return `circular dependency detected while resolving ${
|
749
|
+
const path = resolution.tokenStack.map(getTokenName).join(" → ");
|
750
|
+
return `circular dependency detected while resolving ${path} → ${getTokenName(token)}`;
|
733
751
|
});
|
734
752
|
return dependentRef.current;
|
735
753
|
}
|
@@ -750,8 +768,8 @@ function isDisposable(value) {
|
|
750
768
|
if (valueRef) {
|
751
769
|
return valueRef.current;
|
752
770
|
}
|
753
|
-
const args = this.
|
754
|
-
const value = this.
|
771
|
+
const args = this.resolveCtorDependencies(registration);
|
772
|
+
const value = this.injectMethodDependencies(registration, factory(args));
|
755
773
|
registration.value = {
|
756
774
|
current: value
|
757
775
|
};
|
@@ -763,8 +781,8 @@ function isDisposable(value) {
|
|
763
781
|
if (valueRef) {
|
764
782
|
return valueRef.current;
|
765
783
|
}
|
766
|
-
const args = this.
|
767
|
-
const value = this.
|
784
|
+
const args = this.resolveCtorDependencies(registration);
|
785
|
+
const value = this.injectMethodDependencies(registration, factory(args));
|
768
786
|
resolution.values.set(provider, {
|
769
787
|
current: value
|
770
788
|
});
|
@@ -772,8 +790,8 @@ function isDisposable(value) {
|
|
772
790
|
}
|
773
791
|
case Scope.Transient:
|
774
792
|
{
|
775
|
-
const args = this.
|
776
|
-
return this.
|
793
|
+
const args = this.resolveCtorDependencies(registration);
|
794
|
+
return this.injectMethodDependencies(registration, factory(args));
|
777
795
|
}
|
778
796
|
}
|
779
797
|
} finally{
|
@@ -787,72 +805,74 @@ function isDisposable(value) {
|
|
787
805
|
}
|
788
806
|
return scope;
|
789
807
|
}
|
790
|
-
|
808
|
+
resolveCtorDependencies(registration) {
|
791
809
|
const dependencies = registration.dependencies;
|
792
810
|
if (dependencies) {
|
793
811
|
check(isClassProvider(registration.provider), `internal error: not a ClassProvider`);
|
794
|
-
const ctorDeps = dependencies.
|
812
|
+
const ctorDeps = dependencies.ctor.filter((d)=>d.appliedBy);
|
795
813
|
if (ctorDeps.length > 0) {
|
796
814
|
// Let's check if all necessary constructor parameters are decorated.
|
797
815
|
// If not, we cannot safely create an instance.
|
798
816
|
const ctor = registration.provider.useClass;
|
799
817
|
check(ctor.length === ctorDeps.length, ()=>{
|
800
|
-
const
|
818
|
+
const location = getLocation(ctor);
|
819
|
+
const msg = `${location} expected ${ctor.length} decorated constructor parameters`;
|
801
820
|
return msg + `, but found ${ctorDeps.length}`;
|
802
821
|
});
|
803
|
-
return
|
804
|
-
const token = dep.tokenRef.getRefToken();
|
805
|
-
switch(dep.appliedBy){
|
806
|
-
case "Inject":
|
807
|
-
return this.resolve(token, dep.name);
|
808
|
-
case "InjectAll":
|
809
|
-
return this.resolveAll(token);
|
810
|
-
case "Optional":
|
811
|
-
return this.resolve(token, true, dep.name);
|
812
|
-
case "OptionalAll":
|
813
|
-
return this.resolveAll(token, true);
|
814
|
-
}
|
815
|
-
});
|
822
|
+
return this.resolveArgs(ctorDeps, ctor);
|
816
823
|
}
|
817
824
|
}
|
818
825
|
return [];
|
819
826
|
}
|
820
|
-
|
827
|
+
injectMethodDependencies(registration, instance) {
|
821
828
|
const dependencies = registration.dependencies;
|
822
829
|
if (dependencies) {
|
823
830
|
check(isClassProvider(registration.provider), `internal error: not a ClassProvider`);
|
824
831
|
const ctor = registration.provider.useClass;
|
825
832
|
// Perform method injection
|
826
833
|
for (const entry of dependencies.methods){
|
827
|
-
const
|
834
|
+
const methodKey = entry[0];
|
828
835
|
const methodDeps = entry[1].filter((d)=>d.appliedBy);
|
829
836
|
// Let's check if all necessary method parameters are decorated.
|
830
837
|
// If not, we cannot safely invoke the method.
|
831
|
-
|
832
|
-
const method = instance[key];
|
838
|
+
const method = instance[methodKey];
|
833
839
|
check(methodDeps.length === method.length, ()=>{
|
834
|
-
const
|
835
|
-
|
840
|
+
const location = getLocation(ctor, methodKey);
|
841
|
+
const msg = `${location} expected ${method.length} decorated method parameters`;
|
842
|
+
return msg + `, but found ${methodDeps.length}`;
|
836
843
|
});
|
837
|
-
const args =
|
838
|
-
const token = dep.tokenRef.getRefToken();
|
839
|
-
switch(dep.appliedBy){
|
840
|
-
case "Inject":
|
841
|
-
return injectBy(instance, token, dep.name);
|
842
|
-
case "InjectAll":
|
843
|
-
return injectAll(token);
|
844
|
-
case "Optional":
|
845
|
-
return optionalBy(instance, token, dep.name);
|
846
|
-
case "OptionalAll":
|
847
|
-
return optionalAll(token);
|
848
|
-
}
|
849
|
-
});
|
850
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
844
|
+
const args = this.resolveArgs(methodDeps, ctor, instance, methodKey);
|
851
845
|
method.bind(instance)(...args);
|
852
846
|
}
|
853
847
|
}
|
854
848
|
return instance;
|
855
849
|
}
|
850
|
+
resolveArgs(deps, ctor, instance, methodKey) {
|
851
|
+
const sortedDeps = deps.sort((a, b)=>a.index - b.index);
|
852
|
+
const args = [];
|
853
|
+
for (const dep of sortedDeps){
|
854
|
+
try {
|
855
|
+
args.push(this.resolveDependency(dep, instance));
|
856
|
+
} catch (e) {
|
857
|
+
throwParameterResolutionError(ctor, methodKey, dep, e);
|
858
|
+
}
|
859
|
+
}
|
860
|
+
return args;
|
861
|
+
}
|
862
|
+
resolveDependency(dependency, instance) {
|
863
|
+
const token = dependency.tokenRef.getRefToken();
|
864
|
+
const name = dependency.name;
|
865
|
+
switch(dependency.appliedBy){
|
866
|
+
case "Inject":
|
867
|
+
return instance ? injectBy(instance, token, name) : this.resolve(token, name);
|
868
|
+
case "InjectAll":
|
869
|
+
return instance ? injectAll(token) : this.resolveAll(token);
|
870
|
+
case "Optional":
|
871
|
+
return instance ? optionalBy(instance, token, name) : this.resolve(token, true, name);
|
872
|
+
case "OptionalAll":
|
873
|
+
return instance ? optionalAll(token) : this.resolveAll(token, true);
|
874
|
+
}
|
875
|
+
}
|
856
876
|
checkDisposed() {
|
857
877
|
check(!this.myDisposed, "the container is disposed");
|
858
878
|
}
|
@@ -908,11 +928,13 @@ function isDisposable(value) {
|
|
908
928
|
* @__NO_SIDE_EFFECTS__
|
909
929
|
*/ function EagerInstantiate() {
|
910
930
|
return function(Class) {
|
911
|
-
const
|
931
|
+
const ctor = Class;
|
932
|
+
const metadata = getMetadata(ctor);
|
912
933
|
const currentScope = metadata.scope;
|
913
934
|
check(!currentScope || currentScope.value === Scope.Container, ()=>{
|
914
935
|
const { value, appliedBy } = currentScope;
|
915
|
-
|
936
|
+
const className = getTokenName(ctor);
|
937
|
+
return `class ${className}: Scope.${value} was already set by @${appliedBy},\n ` + `but @EagerInstantiate is trying to set a conflicting Scope.Container.\n ` + `Only one decorator should set the class scope, or all must agree on the same value.`;
|
916
938
|
});
|
917
939
|
metadata.eagerInstantiate = true;
|
918
940
|
metadata.scope = {
|
@@ -942,30 +964,28 @@ function forwardRef(token) {
|
|
942
964
|
}
|
943
965
|
// @internal
|
944
966
|
function isTokensRef(value) {
|
945
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
946
967
|
return value && typeof value === "object" && typeof value.getRefTokens === "function";
|
947
968
|
}
|
948
969
|
// @internal
|
949
970
|
function isTokenRef(value) {
|
950
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
951
971
|
return value && typeof value === "object" && typeof value.getRefToken === "function";
|
952
972
|
}
|
953
973
|
|
954
974
|
// @internal
|
955
|
-
function updateParameterMetadata(decorator, target,
|
975
|
+
function updateParameterMetadata(decorator, target, methodKey, parameterIndex, updateFn) {
|
956
976
|
// Error out immediately if the decorator has been applied to a static method
|
957
|
-
if (
|
958
|
-
check(false, `@${decorator} cannot be used on static method ${target.name}.${String(
|
977
|
+
if (methodKey !== undefined && typeof target === "function") {
|
978
|
+
check(false, `@${decorator} cannot be used on static method ${target.name}.${String(methodKey)}`);
|
959
979
|
}
|
960
|
-
if (
|
980
|
+
if (methodKey === undefined) {
|
961
981
|
// Constructor
|
962
982
|
const metadata = getMetadata(target);
|
963
|
-
const dependency = metadata.
|
983
|
+
const dependency = metadata.getCtorDependency(parameterIndex);
|
964
984
|
updateFn(dependency);
|
965
985
|
} else {
|
966
986
|
// Instance method
|
967
987
|
const metadata = getMetadata(target.constructor);
|
968
|
-
const dependency = metadata.getMethodDependency(
|
988
|
+
const dependency = metadata.getMethodDependency(methodKey, parameterIndex);
|
969
989
|
updateFn(dependency);
|
970
990
|
}
|
971
991
|
}
|
@@ -974,30 +994,30 @@ function updateParameterMetadata(decorator, target, propertyKey, parameterIndex,
|
|
974
994
|
// understand which one "wins", unless the user is aware of the decorator evaluation order.
|
975
995
|
//
|
976
996
|
// @internal
|
977
|
-
function checkSingleDecorator(dependency, target,
|
997
|
+
function checkSingleDecorator(dependency, target, methodKey, parameterIndex) {
|
978
998
|
check(dependency.appliedBy === undefined, ()=>{
|
979
|
-
const
|
980
|
-
return `multiple injection decorators on ${
|
999
|
+
const param = describeParam(target, methodKey, parameterIndex);
|
1000
|
+
return `multiple injection decorators on ${param}, but only one is allowed`;
|
981
1001
|
});
|
982
1002
|
}
|
983
1003
|
// Checks that the `@Named` decorator is not used in combination with
|
984
1004
|
// `@InjectAll` or `@OptionalAll`, which ignore the name qualification.
|
985
1005
|
//
|
986
1006
|
// @internal
|
987
|
-
function checkNamedDecorator(dependency, target,
|
1007
|
+
function checkNamedDecorator(dependency, target, methodKey, parameterIndex) {
|
988
1008
|
const { appliedBy, name } = dependency;
|
989
1009
|
check(name === undefined || appliedBy !== "InjectAll" && appliedBy !== "OptionalAll", ()=>{
|
990
|
-
const
|
991
|
-
return `@Named has no effect on ${
|
1010
|
+
const param = describeParam(target, methodKey, parameterIndex);
|
1011
|
+
return `@Named has no effect on ${param} when used with @${appliedBy}`;
|
992
1012
|
});
|
993
1013
|
}
|
994
1014
|
// Returns a human-readable description of the parameter location.
|
995
1015
|
// For example: "Wizard constructor parameter 2" or "Wizard.set parameter 0"
|
996
1016
|
//
|
997
1017
|
// @internal
|
998
|
-
function
|
999
|
-
const location =
|
1000
|
-
return `${location}
|
1018
|
+
function describeParam(target, methodKey, parameterIndex) {
|
1019
|
+
const location = methodKey === undefined ? target.name : `${target.constructor.name}.${String(methodKey)}`;
|
1020
|
+
return `${location}(parameter #${parameterIndex})`;
|
1001
1021
|
}
|
1002
1022
|
|
1003
1023
|
function Inject(token) {
|
@@ -1059,20 +1079,21 @@ function InjectAll(token) {
|
|
1059
1079
|
*
|
1060
1080
|
* @__NO_SIDE_EFFECTS__
|
1061
1081
|
*/ function Named(name) {
|
1062
|
-
check(name.trim(), "the @Named qualifier
|
1082
|
+
check(name.trim(), "the @Named qualifier must not be empty");
|
1063
1083
|
return function(target, propertyKey, parameterIndex) {
|
1064
1084
|
if (parameterIndex === undefined) {
|
1065
1085
|
// The decorator has been applied to the class
|
1066
1086
|
const ctor = target;
|
1067
1087
|
const metadata = getMetadata(ctor);
|
1068
|
-
|
1088
|
+
const className = getTokenName(ctor);
|
1089
|
+
check(metadata.name === undefined, `multiple @Named decorators on class ${className}, but only one is allowed`);
|
1069
1090
|
metadata.name = name;
|
1070
1091
|
} else {
|
1071
1092
|
// The decorator has been applied to a method parameter
|
1072
1093
|
updateParameterMetadata("Named", target, propertyKey, parameterIndex, (dependency)=>{
|
1073
1094
|
check(dependency.name === undefined, ()=>{
|
1074
|
-
const
|
1075
|
-
return `multiple @Named decorators on ${
|
1095
|
+
const param = describeParam(target, propertyKey, parameterIndex);
|
1096
|
+
return `multiple @Named decorators on ${param}, but only one is allowed`;
|
1076
1097
|
});
|
1077
1098
|
dependency.name = name;
|
1078
1099
|
checkNamedDecorator(dependency, target, propertyKey, parameterIndex);
|
@@ -1125,12 +1146,14 @@ function OptionalAll(token) {
|
|
1125
1146
|
* @__NO_SIDE_EFFECTS__
|
1126
1147
|
*/ function Scoped(scope) {
|
1127
1148
|
return function(Class) {
|
1128
|
-
const
|
1149
|
+
const ctor = Class;
|
1150
|
+
const metadata = getMetadata(ctor);
|
1129
1151
|
const currentScope = metadata.scope;
|
1130
1152
|
check(!currentScope || currentScope.value === scope, ()=>{
|
1131
1153
|
const { value, appliedBy } = currentScope;
|
1132
1154
|
const by = appliedBy === "Scoped" ? `another @${appliedBy} decorator` : `@${appliedBy}`;
|
1133
|
-
|
1155
|
+
const className = getTokenName(ctor);
|
1156
|
+
return `class ${className}: Scope.${value} was already set by ${by},\n ` + `but @Scoped is trying to set a conflicting Scope.${scope}.\n ` + `Only one decorator should set the class scope, or all must agree on the same value.`;
|
1134
1157
|
});
|
1135
1158
|
metadata.scope = {
|
1136
1159
|
value: scope,
|
@@ -1212,10 +1235,7 @@ function OptionalAll(token) {
|
|
1212
1235
|
use (key, wrap) {
|
1213
1236
|
// We need to bind the 'this' context of the function to the container
|
1214
1237
|
// before passing it to the middleware wrapper.
|
1215
|
-
//
|
1216
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
|
1217
1238
|
const fn = container[key].bind(container);
|
1218
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
1219
1239
|
container[key] = wrap(fn);
|
1220
1240
|
return composer;
|
1221
1241
|
}
|