@lppedd/di-wise-neo 0.9.1 → 0.9.3

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/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 ${type} ${token.name}${spec}`));
14
+ throw new Error(tag(`unregistered token ${getTokenName(token)}${spec}`));
43
15
  }
44
16
  // @internal
45
- function throwExistingUnregisteredError(sourceToken, targetTokenOrError) {
46
- let message = tag(`token resolution error encountered while resolving ${sourceToken.name}`);
47
- message += isError(targetTokenOrError) ? `\n [cause] ${untag(targetTokenOrError.message)}` : `\n [cause] the aliased token ${targetTokenOrError.name} is not registered`;
48
- throw new Error(message);
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 token = dependency.tokenRef.getRefToken();
27
+ const message = tag(`failed to resolve dependency for ${location}(parameter #${dependency.index}: ${token.name})`);
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) {
@@ -80,7 +70,7 @@ class KeyedStack {
80
70
  };
81
71
  }
82
72
  constructor(){
83
- this.myEntries = new Array();
73
+ this.myEntries = [];
84
74
  this.myKeys = new WeakSet();
85
75
  }
86
76
  }
@@ -113,6 +103,7 @@ class WeakRefMap {
113
103
  // @internal
114
104
  function createResolution() {
115
105
  return {
106
+ tokenStack: [],
116
107
  stack: new KeyedStack(),
117
108
  values: new WeakRefMap(),
118
109
  dependents: new WeakRefMap()
@@ -173,7 +164,7 @@ function injectAll(token) {
173
164
  class Metadata {
174
165
  constructor(Class){
175
166
  this.dependencies = {
176
- constructor: [],
167
+ ctor: [],
177
168
  methods: new Map()
178
169
  };
179
170
  this.tokensRef = {
@@ -189,15 +180,15 @@ class Metadata {
189
180
  set name(name) {
190
181
  this.provider.name = name;
191
182
  }
192
- getConstructorDependency(index) {
193
- const i = this.dependencies.constructor.findIndex((d)=>d.index === index);
183
+ getCtorDependency(index) {
184
+ const i = this.dependencies.ctor.findIndex((d)=>d.index === index);
194
185
  if (i > -1) {
195
- return this.dependencies.constructor[i];
186
+ return this.dependencies.ctor[i];
196
187
  }
197
188
  const dependency = {
198
189
  index: index
199
190
  };
200
- this.dependencies.constructor.push(dependency);
191
+ this.dependencies.ctor.push(dependency);
201
192
  return dependency;
202
193
  }
203
194
  getMethodDependency(method, index) {
@@ -311,6 +302,33 @@ const Scope = {
311
302
  Container: "Container"
312
303
  };
313
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
+
314
332
  // @internal
315
333
  function getTypeName(value) {
316
334
  switch(typeof value){
@@ -325,9 +343,9 @@ function getTypeName(value) {
325
343
  }
326
344
  const proto = Object.getPrototypeOf(value);
327
345
  if (proto && proto !== Object.prototype) {
328
- const constructor = proto.constructor;
329
- if (typeof constructor === "function" && constructor.name) {
330
- return constructor.name;
346
+ const ctor = proto.constructor;
347
+ if (typeof ctor === "function" && ctor.name) {
348
+ return ctor.name;
331
349
  }
332
350
  }
333
351
  }
@@ -443,7 +461,6 @@ const builders = new WeakSet();
443
461
  // @internal
444
462
  // @internal
445
463
  function isDisposable(value) {
446
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
447
464
  return value && typeof value === "object" && typeof value.dispose === "function";
448
465
  }
449
466
 
@@ -548,13 +565,13 @@ function isDisposable(value) {
548
565
  }
549
566
  // Eager-instantiate only if the class is container-scoped
550
567
  if (metadata.eagerInstantiate && registration.options?.scope === Scope.Container) {
551
- this.resolveProviderValue(registration, registration.provider);
568
+ this.resolveProviderValue(Class, registration);
552
569
  }
553
570
  } else {
554
571
  const [token, provider, options] = args;
555
572
  const existingProvider = isExistingProvider(provider);
556
573
  const name = existingProvider ? undefined : provider.name;
557
- check(name === undefined || name.trim(), "the provider name qualifier cannot be empty or blank");
574
+ check(name === undefined || name.trim(), `the name qualifier for token ${getTokenName(token)} must not be empty`);
558
575
  if (isClassProvider(provider)) {
559
576
  const metadata = getMetadata(provider.useClass);
560
577
  const registration = {
@@ -571,7 +588,7 @@ function isDisposable(value) {
571
588
  this.myTokenRegistry.set(token, registration);
572
589
  // Eager-instantiate only if the provided class is container-scoped
573
590
  if (metadata.eagerInstantiate && registration.options?.scope === Scope.Container) {
574
- this.resolveProviderValue(registration, registration.provider);
591
+ this.resolveProviderValue(token, registration);
575
592
  }
576
593
  } else {
577
594
  if (existingProvider) {
@@ -661,17 +678,15 @@ function isDisposable(value) {
661
678
  }
662
679
  resolveRegistration(token, registration, name) {
663
680
  let currRegistration = registration;
664
- let currProvider = currRegistration.provider;
665
- while(isExistingProvider(currProvider)){
666
- const targetToken = currProvider.useExisting;
681
+ while(isExistingProvider(currRegistration.provider)){
682
+ const targetToken = currRegistration.provider.useExisting;
667
683
  currRegistration = this.myTokenRegistry.get(targetToken, name);
668
684
  if (!currRegistration) {
669
685
  throwExistingUnregisteredError(token, targetToken);
670
686
  }
671
- currProvider = currRegistration.provider;
672
687
  }
673
688
  try {
674
- return this.resolveProviderValue(currRegistration, currProvider);
689
+ return this.resolveProviderValue(token, currRegistration);
675
690
  } catch (e) {
676
691
  // If we were trying to resolve a token registered via ExistingProvider,
677
692
  // we must add the cause of the error to the message
@@ -698,16 +713,15 @@ function isDisposable(value) {
698
713
  }
699
714
  return undefined;
700
715
  }
701
- resolveProviderValue(registration, provider) {
702
- check(registration.provider === provider, "internal error: mismatching provider");
716
+ resolveProviderValue(token, registration) {
717
+ const provider = registration.provider;
703
718
  if (isClassProvider(provider)) {
704
719
  const Class = provider.useClass;
705
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
706
- return this.resolveScopedValue(registration, (args)=>new Class(...args));
720
+ return this.resolveScopedValue(token, registration, (args)=>new Class(...args));
707
721
  }
708
722
  if (isFactoryProvider(provider)) {
709
723
  const factory = provider.useFactory;
710
- return this.resolveScopedValue(registration, factory);
724
+ return this.resolveScopedValue(token, registration, factory);
711
725
  }
712
726
  if (isValueProvider(provider)) {
713
727
  return provider.useValue;
@@ -715,7 +729,7 @@ function isDisposable(value) {
715
729
  check(!isExistingProvider(provider), "internal error: unexpected ExistingProvider");
716
730
  expectNever(provider);
717
731
  }
718
- resolveScopedValue(registration, factory) {
732
+ resolveScopedValue(token, registration, factory) {
719
733
  let context = useInjectionContext();
720
734
  if (!context || context.container !== this) {
721
735
  context = {
@@ -728,12 +742,16 @@ function isDisposable(value) {
728
742
  const options = registration.options;
729
743
  if (resolution.stack.has(provider)) {
730
744
  const dependentRef = resolution.dependents.get(provider);
731
- check(dependentRef, "circular dependency detected");
745
+ check(dependentRef, ()=>{
746
+ const path = resolution.tokenStack.map((t)=>t.name).join(" → ");
747
+ return `circular dependency detected while resolving ${path} → ${token.name}`;
748
+ });
732
749
  return dependentRef.current;
733
750
  }
734
751
  const scope = this.resolveScope(options?.scope, context);
735
752
  const cleanups = [
736
753
  provideInjectionContext(context),
754
+ resolution.tokenStack.push(token) && (()=>resolution.tokenStack.pop()),
737
755
  !isBuilder(provider) && resolution.stack.push(provider, {
738
756
  provider,
739
757
  scope
@@ -747,8 +765,8 @@ function isDisposable(value) {
747
765
  if (valueRef) {
748
766
  return valueRef.current;
749
767
  }
750
- const args = this.resolveConstructorDependencies(registration);
751
- const value = this.injectDependencies(registration, factory(args));
768
+ const args = this.resolveCtorDependencies(registration);
769
+ const value = this.injectMethodDependencies(registration, factory(args));
752
770
  registration.value = {
753
771
  current: value
754
772
  };
@@ -760,8 +778,8 @@ function isDisposable(value) {
760
778
  if (valueRef) {
761
779
  return valueRef.current;
762
780
  }
763
- const args = this.resolveConstructorDependencies(registration);
764
- const value = this.injectDependencies(registration, factory(args));
781
+ const args = this.resolveCtorDependencies(registration);
782
+ const value = this.injectMethodDependencies(registration, factory(args));
765
783
  resolution.values.set(provider, {
766
784
  current: value
767
785
  });
@@ -769,8 +787,8 @@ function isDisposable(value) {
769
787
  }
770
788
  case Scope.Transient:
771
789
  {
772
- const args = this.resolveConstructorDependencies(registration);
773
- return this.injectDependencies(registration, factory(args));
790
+ const args = this.resolveCtorDependencies(registration);
791
+ return this.injectMethodDependencies(registration, factory(args));
774
792
  }
775
793
  }
776
794
  } finally{
@@ -784,72 +802,74 @@ function isDisposable(value) {
784
802
  }
785
803
  return scope;
786
804
  }
787
- resolveConstructorDependencies(registration) {
805
+ resolveCtorDependencies(registration) {
788
806
  const dependencies = registration.dependencies;
789
807
  if (dependencies) {
790
808
  check(isClassProvider(registration.provider), `internal error: not a ClassProvider`);
791
- const ctorDeps = dependencies.constructor.filter((d)=>d.appliedBy);
809
+ const ctorDeps = dependencies.ctor.filter((d)=>d.appliedBy);
792
810
  if (ctorDeps.length > 0) {
793
811
  // Let's check if all necessary constructor parameters are decorated.
794
812
  // If not, we cannot safely create an instance.
795
813
  const ctor = registration.provider.useClass;
796
814
  check(ctor.length === ctorDeps.length, ()=>{
797
- const msg = `expected ${ctor.length} decorated constructor parameters in ${ctor.name}`;
815
+ const location = getLocation(ctor);
816
+ const msg = `${location} expected ${ctor.length} decorated constructor parameters`;
798
817
  return msg + `, but found ${ctorDeps.length}`;
799
818
  });
800
- return ctorDeps.sort((a, b)=>a.index - b.index).map((dep)=>{
801
- const token = dep.tokenRef.getRefToken();
802
- switch(dep.appliedBy){
803
- case "Inject":
804
- return this.resolve(token, dep.name);
805
- case "InjectAll":
806
- return this.resolveAll(token);
807
- case "Optional":
808
- return this.resolve(token, true, dep.name);
809
- case "OptionalAll":
810
- return this.resolveAll(token, true);
811
- }
812
- });
819
+ return this.resolveArgs(ctorDeps, ctor);
813
820
  }
814
821
  }
815
822
  return [];
816
823
  }
817
- injectDependencies(registration, instance) {
824
+ injectMethodDependencies(registration, instance) {
818
825
  const dependencies = registration.dependencies;
819
826
  if (dependencies) {
820
827
  check(isClassProvider(registration.provider), `internal error: not a ClassProvider`);
821
828
  const ctor = registration.provider.useClass;
822
829
  // Perform method injection
823
830
  for (const entry of dependencies.methods){
824
- const key = entry[0];
831
+ const methodKey = entry[0];
825
832
  const methodDeps = entry[1].filter((d)=>d.appliedBy);
826
833
  // Let's check if all necessary method parameters are decorated.
827
834
  // If not, we cannot safely invoke the method.
828
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
829
- const method = instance[key];
835
+ const method = instance[methodKey];
830
836
  check(methodDeps.length === method.length, ()=>{
831
- const msg = `expected ${method.length} decorated method parameters`;
832
- return msg + ` in ${ctor.name}.${String(key)}, but found ${methodDeps.length}`;
833
- });
834
- const args = methodDeps.sort((a, b)=>a.index - b.index).map((dep)=>{
835
- const token = dep.tokenRef.getRefToken();
836
- switch(dep.appliedBy){
837
- case "Inject":
838
- return injectBy(instance, token, dep.name);
839
- case "InjectAll":
840
- return injectAll(token);
841
- case "Optional":
842
- return optionalBy(instance, token, dep.name);
843
- case "OptionalAll":
844
- return optionalAll(token);
845
- }
837
+ const location = getLocation(ctor, methodKey);
838
+ const msg = `${location} expected ${method.length} decorated method parameters`;
839
+ return msg + `, but found ${methodDeps.length}`;
846
840
  });
847
- // eslint-disable-next-line @typescript-eslint/no-unsafe-call
841
+ const args = this.resolveArgs(methodDeps, ctor, instance, methodKey);
848
842
  method.bind(instance)(...args);
849
843
  }
850
844
  }
851
845
  return instance;
852
846
  }
847
+ resolveArgs(deps, ctor, instance, methodKey) {
848
+ const sortedDeps = deps.sort((a, b)=>a.index - b.index);
849
+ const args = [];
850
+ for (const dep of sortedDeps){
851
+ try {
852
+ args.push(this.resolveDependency(dep, instance));
853
+ } catch (e) {
854
+ throwParameterResolutionError(ctor, methodKey, dep, e);
855
+ }
856
+ }
857
+ return args;
858
+ }
859
+ resolveDependency(dependency, instance) {
860
+ const token = dependency.tokenRef.getRefToken();
861
+ const name = dependency.name;
862
+ switch(dependency.appliedBy){
863
+ case "Inject":
864
+ return instance ? injectBy(instance, token, name) : this.resolve(token, name);
865
+ case "InjectAll":
866
+ return instance ? injectAll(token) : this.resolveAll(token);
867
+ case "Optional":
868
+ return instance ? optionalBy(instance, token, name) : this.resolve(token, true, name);
869
+ case "OptionalAll":
870
+ return instance ? optionalAll(token) : this.resolveAll(token, true);
871
+ }
872
+ }
853
873
  checkDisposed() {
854
874
  check(!this.myDisposed, "the container is disposed");
855
875
  }
@@ -905,11 +925,13 @@ function isDisposable(value) {
905
925
  * @__NO_SIDE_EFFECTS__
906
926
  */ function EagerInstantiate() {
907
927
  return function(Class) {
908
- const metadata = getMetadata(Class);
928
+ const ctor = Class;
929
+ const metadata = getMetadata(ctor);
909
930
  const currentScope = metadata.scope;
910
931
  check(!currentScope || currentScope.value === Scope.Container, ()=>{
911
932
  const { value, appliedBy } = currentScope;
912
- return `class ${Class.name}: 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.`;
933
+ const className = getTokenName(ctor);
934
+ 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.`;
913
935
  });
914
936
  metadata.eagerInstantiate = true;
915
937
  metadata.scope = {
@@ -939,30 +961,28 @@ function forwardRef(token) {
939
961
  }
940
962
  // @internal
941
963
  function isTokensRef(value) {
942
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
943
964
  return value && typeof value === "object" && typeof value.getRefTokens === "function";
944
965
  }
945
966
  // @internal
946
967
  function isTokenRef(value) {
947
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
948
968
  return value && typeof value === "object" && typeof value.getRefToken === "function";
949
969
  }
950
970
 
951
971
  // @internal
952
- function updateParameterMetadata(decorator, target, propertyKey, parameterIndex, updateFn) {
972
+ function updateParameterMetadata(decorator, target, methodKey, parameterIndex, updateFn) {
953
973
  // Error out immediately if the decorator has been applied to a static method
954
- if (propertyKey !== undefined && typeof target === "function") {
955
- check(false, `@${decorator} cannot be used on static method ${target.name}.${String(propertyKey)}`);
974
+ if (methodKey !== undefined && typeof target === "function") {
975
+ check(false, `@${decorator} cannot be used on static method ${target.name}.${String(methodKey)}`);
956
976
  }
957
- if (propertyKey === undefined) {
977
+ if (methodKey === undefined) {
958
978
  // Constructor
959
979
  const metadata = getMetadata(target);
960
- const dependency = metadata.getConstructorDependency(parameterIndex);
980
+ const dependency = metadata.getCtorDependency(parameterIndex);
961
981
  updateFn(dependency);
962
982
  } else {
963
983
  // Instance method
964
984
  const metadata = getMetadata(target.constructor);
965
- const dependency = metadata.getMethodDependency(propertyKey, parameterIndex);
985
+ const dependency = metadata.getMethodDependency(methodKey, parameterIndex);
966
986
  updateFn(dependency);
967
987
  }
968
988
  }
@@ -971,30 +991,30 @@ function updateParameterMetadata(decorator, target, propertyKey, parameterIndex,
971
991
  // understand which one "wins", unless the user is aware of the decorator evaluation order.
972
992
  //
973
993
  // @internal
974
- function checkSingleDecorator(dependency, target, propertyKey, parameterIndex) {
994
+ function checkSingleDecorator(dependency, target, methodKey, parameterIndex) {
975
995
  check(dependency.appliedBy === undefined, ()=>{
976
- const location = getLocation(target, propertyKey, parameterIndex);
977
- return `multiple injection decorators on ${location}, but only one is allowed`;
996
+ const param = describeParam(target, methodKey, parameterIndex);
997
+ return `multiple injection decorators on ${param}, but only one is allowed`;
978
998
  });
979
999
  }
980
1000
  // Checks that the `@Named` decorator is not used in combination with
981
1001
  // `@InjectAll` or `@OptionalAll`, which ignore the name qualification.
982
1002
  //
983
1003
  // @internal
984
- function checkNamedDecorator(dependency, target, propertyKey, parameterIndex) {
1004
+ function checkNamedDecorator(dependency, target, methodKey, parameterIndex) {
985
1005
  const { appliedBy, name } = dependency;
986
1006
  check(name === undefined || appliedBy !== "InjectAll" && appliedBy !== "OptionalAll", ()=>{
987
- const location = getLocation(target, propertyKey, parameterIndex);
988
- return `@Named has no effect on ${location} when used with @${appliedBy}`;
1007
+ const param = describeParam(target, methodKey, parameterIndex);
1008
+ return `@Named has no effect on ${param} when used with @${appliedBy}`;
989
1009
  });
990
1010
  }
991
1011
  // Returns a human-readable description of the parameter location.
992
1012
  // For example: "Wizard constructor parameter 2" or "Wizard.set parameter 0"
993
1013
  //
994
1014
  // @internal
995
- function getLocation(target, propertyKey, parameterIndex) {
996
- const location = propertyKey === undefined ? `${target.name} constructor` : `${target.constructor.name}.${String(propertyKey)}`;
997
- return `${location} parameter ${parameterIndex}`;
1015
+ function describeParam(target, methodKey, parameterIndex) {
1016
+ const location = methodKey === undefined ? target.name : `${target.constructor.name}.${String(methodKey)}`;
1017
+ return `${location}(parameter #${parameterIndex})`;
998
1018
  }
999
1019
 
1000
1020
  function Inject(token) {
@@ -1056,20 +1076,21 @@ function InjectAll(token) {
1056
1076
  *
1057
1077
  * @__NO_SIDE_EFFECTS__
1058
1078
  */ function Named(name) {
1059
- check(name.trim(), "the @Named qualifier cannot be empty or blank");
1079
+ check(name.trim(), "the @Named qualifier must not be empty");
1060
1080
  return function(target, propertyKey, parameterIndex) {
1061
1081
  if (parameterIndex === undefined) {
1062
1082
  // The decorator has been applied to the class
1063
1083
  const ctor = target;
1064
1084
  const metadata = getMetadata(ctor);
1065
- check(metadata.name === undefined, `multiple @Named decorators on class ${ctor.name}, but only one is allowed`);
1085
+ const className = getTokenName(ctor);
1086
+ check(metadata.name === undefined, `multiple @Named decorators on class ${className}, but only one is allowed`);
1066
1087
  metadata.name = name;
1067
1088
  } else {
1068
1089
  // The decorator has been applied to a method parameter
1069
1090
  updateParameterMetadata("Named", target, propertyKey, parameterIndex, (dependency)=>{
1070
1091
  check(dependency.name === undefined, ()=>{
1071
- const location = getLocation(target, propertyKey, parameterIndex);
1072
- return `multiple @Named decorators on ${location}, but only one is allowed`;
1092
+ const param = describeParam(target, propertyKey, parameterIndex);
1093
+ return `multiple @Named decorators on ${param}, but only one is allowed`;
1073
1094
  });
1074
1095
  dependency.name = name;
1075
1096
  checkNamedDecorator(dependency, target, propertyKey, parameterIndex);
@@ -1122,12 +1143,14 @@ function OptionalAll(token) {
1122
1143
  * @__NO_SIDE_EFFECTS__
1123
1144
  */ function Scoped(scope) {
1124
1145
  return function(Class) {
1125
- const metadata = getMetadata(Class);
1146
+ const ctor = Class;
1147
+ const metadata = getMetadata(ctor);
1126
1148
  const currentScope = metadata.scope;
1127
1149
  check(!currentScope || currentScope.value === scope, ()=>{
1128
1150
  const { value, appliedBy } = currentScope;
1129
1151
  const by = appliedBy === "Scoped" ? `another @${appliedBy} decorator` : `@${appliedBy}`;
1130
- return `class ${Class.name}: 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.`;
1152
+ const className = getTokenName(ctor);
1153
+ 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.`;
1131
1154
  });
1132
1155
  metadata.scope = {
1133
1156
  value: scope,
@@ -1209,10 +1232,7 @@ function OptionalAll(token) {
1209
1232
  use (key, wrap) {
1210
1233
  // We need to bind the 'this' context of the function to the container
1211
1234
  // before passing it to the middleware wrapper.
1212
- //
1213
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-call
1214
1235
  const fn = container[key].bind(container);
1215
- // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
1216
1236
  container[key] = wrap(fn);
1217
1237
  return composer;
1218
1238
  }