ts-ioc-container 41.1.1 → 41.2.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/README.md CHANGED
@@ -84,7 +84,6 @@ And `tsconfig.json` should have next options:
84
84
  ### Basic usage
85
85
 
86
86
  ```typescript
87
- import 'reflect-metadata';
88
87
  import { type IContainer, by, Container, inject, Registration as R } from 'ts-ioc-container';
89
88
 
90
89
  describe('Basic usage', function () {
@@ -125,7 +124,6 @@ Sometimes you need to create a scope of container. For example, when you want to
125
124
  - NOTICE: when you create a scope then we clone ONLY tags-matched providers.
126
125
 
127
126
  ```typescript
128
- import 'reflect-metadata';
129
127
  import {
130
128
  asKey,
131
129
  by,
@@ -173,7 +171,6 @@ Sometimes you want to get all instances from container and its scopes. For examp
173
171
  - you can get instances from container and scope which were created by injector
174
172
 
175
173
  ```typescript
176
- import 'reflect-metadata';
177
174
  import { asKey, by, Container, inject, register, Registration as R } from 'ts-ioc-container';
178
175
 
179
176
  describe('Instances', function () {
@@ -243,7 +240,6 @@ Sometimes you want to dispose container and all its scopes. For example, when yo
243
240
  - when container is disposed then it unregisters all providers and remove all instances
244
241
 
245
242
  ```typescript
246
- import 'reflect-metadata';
247
243
  import { by, Container, ContainerDisposedError, Registration as R } from 'ts-ioc-container';
248
244
 
249
245
  class Logger {}
@@ -369,7 +365,6 @@ This type of injector uses `@inject` decorator to mark where dependencies should
369
365
  Also you can [inject property.](#inject-property)
370
366
 
371
367
  ```typescript
372
- import 'reflect-metadata';
373
368
  import { Container, inject, Registration as R } from 'ts-ioc-container';
374
369
 
375
370
  class Logger {
@@ -404,7 +399,6 @@ describe('Reflection Injector', function () {
404
399
  This type of injector just passes container to constructor with others arguments.
405
400
 
406
401
  ```typescript
407
- import 'reflect-metadata';
408
402
  import { Container, type IContainer, Registration as R, SimpleInjector } from 'ts-ioc-container';
409
403
 
410
404
  describe('SimpleInjector', function () {
@@ -444,7 +438,6 @@ describe('SimpleInjector', function () {
444
438
  This type of injector injects dependencies as dictionary `Record<string, unknown>`.
445
439
 
446
440
  ```typescript
447
- import 'reflect-metadata';
448
441
  import { Container, ProxyInjector, args, Registration as R } from 'ts-ioc-container';
449
442
 
450
443
  describe('ProxyInjector', function () {
@@ -541,7 +534,6 @@ Provider is dependency factory which creates dependency.
541
534
  - `new Provider((container, ...args) => container.resolve(Logger, {args}))`
542
535
 
543
536
  ```typescript
544
- import 'reflect-metadata';
545
537
  import {
546
538
  args,
547
539
  argsFn,
@@ -823,7 +815,6 @@ Sometimes you need to create only one instance of dependency per scope. For exam
823
815
  - NOTICE: if you create a scope 'A' of container 'root' then Logger of A !== Logger of root.
824
816
 
825
817
  ```typescript
826
- import 'reflect-metadata';
827
818
  import { asKey, Container, register, Registration as R, singleton } from 'ts-ioc-container';
828
819
 
829
820
  @register(asKey('logger'), singleton())
@@ -865,19 +856,20 @@ Sometimes you want to bind some arguments to provider. This is what `ArgsProvide
865
856
  - NOTICE: args from this provider has higher priority than args from `resolve` method.
866
857
 
867
858
  ```typescript
868
- import 'reflect-metadata';
869
859
  import {
870
860
  args,
871
861
  argsFn,
872
862
  asKey,
863
+ by,
873
864
  Container,
874
- type DependencyKey,
865
+ depKey,
875
866
  inject,
876
867
  MultiCache,
877
868
  register,
878
869
  Registration as R,
879
870
  singleton,
880
871
  } from 'ts-ioc-container';
872
+ import { resolveByArgs } from '../lib/provider/IProvider';
881
873
 
882
874
  @register(asKey('logger'))
883
875
  class Logger {
@@ -893,7 +885,7 @@ describe('ArgsProvider', function () {
893
885
  }
894
886
 
895
887
  it('can assign argument function to provider', function () {
896
- const root = createContainer().addRegistration(R.fromClass(Logger).pipe(argsFn((container, ...args) => ['name'])));
888
+ const root = createContainer().addRegistration(R.fromClass(Logger).pipe(argsFn(() => ['name'])));
897
889
 
898
890
  const logger = root.createScope().resolveOne<Logger>('logger');
899
891
  expect(logger.name).toBe('name');
@@ -920,25 +912,34 @@ describe('ArgsProvider', function () {
920
912
  name: string;
921
913
  }
922
914
 
923
- @register(asKey('UserRepository'))
915
+ const IUserRepositoryKey = depKey<IRepository>('IUserRepository');
916
+ const ITodoRepositoryKey = depKey<IRepository>('ITodoRepository');
917
+
918
+ @register(IUserRepositoryKey.asKey)
924
919
  class UserRepository implements IRepository {
925
920
  name = 'UserRepository';
926
921
  }
927
922
 
928
- @register(asKey('TodoRepository'))
923
+ @register(ITodoRepositoryKey.asKey)
929
924
  class TodoRepository implements IRepository {
930
925
  name = 'TodoRepository';
931
926
  }
932
927
 
933
- @register(asKey('EntityManager'), argsFn((container, token) => [container.resolveOne(token as DependencyKey)]))
928
+ interface IEntityManager {
929
+ repository: IRepository;
930
+ }
931
+
932
+ const IEntityManagerKey = depKey<IEntityManager>('IEntityManager');
933
+
934
+ @register(IEntityManagerKey.asKey, argsFn(resolveByArgs))
934
935
  class EntityManager {
935
936
  constructor(public repository: IRepository) {}
936
937
  }
937
938
 
938
939
  class Main {
939
940
  constructor(
940
- @inject((s) => s.resolveOne('EntityManager', { args: ['UserRepository'] })) public userEntities: EntityManager,
941
- @inject((s) => s.resolveOne('EntityManager', { args: ['TodoRepository'] })) public todoEntities: EntityManager,
941
+ @inject(by.one(IEntityManagerKey).args(IUserRepositoryKey)) public userEntities: EntityManager,
942
+ @inject(by.one(IEntityManagerKey).args(ITodoRepositoryKey)) public todoEntities: EntityManager,
942
943
  ) {}
943
944
  }
944
945
 
@@ -957,29 +958,34 @@ describe('ArgsProvider', function () {
957
958
  name: string;
958
959
  }
959
960
 
960
- @register(asKey('UserRepository'))
961
+ const IUserRepositoryKey = depKey<IRepository>('IUserRepository');
962
+ const ITodoRepositoryKey = depKey<IRepository>('ITodoRepository');
963
+
964
+ @register(IUserRepositoryKey.asKey)
961
965
  class UserRepository implements IRepository {
962
966
  name = 'UserRepository';
963
967
  }
964
968
 
965
- @register(asKey('TodoRepository'))
969
+ @register(ITodoRepositoryKey.asKey)
966
970
  class TodoRepository implements IRepository {
967
971
  name = 'TodoRepository';
968
972
  }
969
973
 
970
- @register(
971
- asKey('EntityManager'),
972
- argsFn((container, token) => [container.resolveOne(token as DependencyKey)]),
973
- singleton(() => new MultiCache((...args: unknown[]) => args[0] as DependencyKey)),
974
- )
974
+ interface IEntityManager {
975
+ repository: IRepository;
976
+ }
977
+
978
+ const IEntityManagerKey = depKey<IEntityManager>('IEntityManager');
979
+
980
+ @register(IEntityManagerKey.asKey, argsFn(resolveByArgs), singleton(MultiCache.fromFirstArg))
975
981
  class EntityManager {
976
982
  constructor(public repository: IRepository) {}
977
983
  }
978
984
 
979
985
  class Main {
980
986
  constructor(
981
- @inject((s) => s.resolveOne('EntityManager', { args: ['UserRepository'] })) public userEntities: EntityManager,
982
- @inject((s) => s.resolveOne('EntityManager', { args: ['TodoRepository'] })) public todoEntities: EntityManager,
987
+ @inject(by.one(IEntityManagerKey).args(IUserRepositoryKey)) public userEntities: EntityManager,
988
+ @inject(by.one(IEntityManagerKey).args(ITodoRepositoryKey)) public todoEntities: EntityManager,
983
989
  ) {}
984
990
  }
985
991
 
@@ -989,11 +995,11 @@ describe('ArgsProvider', function () {
989
995
  .addRegistration(R.fromClass(TodoRepository));
990
996
  const main = root.resolveOne(Main);
991
997
 
992
- const userRepository = root.resolveOne<EntityManager>('EntityManager', { args: ['UserRepository'] }).repository;
998
+ const userRepository = IEntityManagerKey.resolve(root, { args: [IUserRepositoryKey] }).repository;
993
999
  expect(userRepository).toBeInstanceOf(UserRepository);
994
1000
  expect(main.userEntities.repository).toBe(userRepository);
995
1001
 
996
- const todoRepository = root.resolveOne<EntityManager>('EntityManager', { args: ['TodoRepository'] }).repository;
1002
+ const todoRepository = IEntityManagerKey.resolve(root, { args: [ITodoRepositoryKey] }).repository;
997
1003
  expect(todoRepository).toBeInstanceOf(TodoRepository);
998
1004
  expect(main.todoEntities.repository).toBe(todoRepository);
999
1005
  });
@@ -1007,7 +1013,6 @@ Sometimes you want to hide dependency if somebody wants to resolve it from certa
1007
1013
  - `Provider.fromClass(Logger).pipe(visible(({ isParent, child }) => isParent || child.hasTag('root')))`
1008
1014
 
1009
1015
  ```typescript
1010
- import 'reflect-metadata';
1011
1016
  import {
1012
1017
  asKey,
1013
1018
  Container,
@@ -1047,7 +1052,6 @@ Alias is needed to group keys
1047
1052
  - `Provider.fromClass(Logger).pipe(alias('logger'))`
1048
1053
 
1049
1054
  ```typescript
1050
- import 'reflect-metadata';
1051
1055
  import { asAlias, by, Container, DependencyNotFoundError, inject, register, Registration as R, scope } from 'ts-ioc-container';
1052
1056
 
1053
1057
  describe('alias', () => {
@@ -1271,7 +1275,6 @@ Sometimes you want to register provider with certain key. This is what `key` is
1271
1275
  - you can assign the same key to different registrations
1272
1276
 
1273
1277
  ```typescript
1274
- import 'reflect-metadata';
1275
1278
  import { asAlias, asKey, Container, register, Registration as R, scope, singleton } from 'ts-ioc-container';
1276
1279
  import { DependencyMissingKeyError } from '../../lib/errors/DependencyMissingKeyError';
1277
1280
 
@@ -1332,7 +1335,6 @@ Sometimes you need to register provider only in scope which matches to certain c
1332
1335
  - `Registration.fromClass(Logger).when((container) => container.hasTag('root'))`
1333
1336
 
1334
1337
  ```typescript
1335
- import 'reflect-metadata';
1336
1338
  import { singleton, Container, Registration as R, scope, register, asKey } from 'ts-ioc-container';
1337
1339
 
1338
1340
  @register(asKey('ILogger'), scope((s) => s.hasTag('root')), singleton())
@@ -1351,7 +1353,6 @@ describe('ScopeProvider', function () {
1351
1353
  Sometimes you want to encapsulate registration logic in separate module. This is what `IContainerModule` is for.
1352
1354
 
1353
1355
  ```typescript
1354
- import 'reflect-metadata';
1355
1356
  import { asKey, Container, type IContainer, type IContainerModule, register, Registration as R } from 'ts-ioc-container';
1356
1357
 
1357
1358
  @register(asKey('ILogger'))
@@ -1397,7 +1398,6 @@ Sometimes you need to invoke methods after construct or dispose of class. This i
1397
1398
 
1398
1399
  ### OnConstruct
1399
1400
  ```typescript
1400
- import 'reflect-metadata';
1401
1401
  import {
1402
1402
  asKey,
1403
1403
  type constructor,
@@ -1452,7 +1452,6 @@ describe('onConstruct', function () {
1452
1452
 
1453
1453
  ### OnDispose
1454
1454
  ```typescript
1455
- import 'reflect-metadata';
1456
1455
  import { asKey, by, Container, hook, inject, register, Registration as R, runHooks, singleton } from 'ts-ioc-container';
1457
1456
 
1458
1457
  @register(asKey('logsRepo'), singleton())
package/cjm/DepKey.js CHANGED
@@ -1,12 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.depKey = exports.isDepKey = void 0;
3
+ exports.depKey = void 0;
4
4
  const Registration_1 = require("./registration/Registration");
5
5
  const Provider_1 = require("./provider/Provider");
6
- const isDepKey = (key) => {
7
- return typeof key === 'object' && key !== null && 'key' in key;
8
- };
9
- exports.isDepKey = isDepKey;
10
6
  const depKey = (key) => {
11
7
  const scopePredicates = [];
12
8
  const mappers = [];
@@ -26,7 +22,7 @@ const depKey = (key) => {
26
22
  }
27
23
  return registration;
28
24
  },
29
- resolve: (s) => s.resolveOne(key),
25
+ resolve: (s, options) => s.resolveOne(key, options),
30
26
  pipe(...values) {
31
27
  mappers.push(...values);
32
28
  return this;
@@ -1,14 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DEFAULT_CONTAINER_RESOLVER = void 0;
4
- exports.isDependencyKey = isDependencyKey;
5
4
  const utils_1 = require("../utils");
6
5
  const DependencyNotFoundError_1 = require("../errors/DependencyNotFoundError");
7
- function isDependencyKey(token) {
8
- return ['string', 'symbol'].includes(typeof token);
9
- }
10
6
  const DEFAULT_CONTAINER_RESOLVER = (scope, keyOrAlias, options) => {
11
- if ((0, utils_1.isConstructor)(keyOrAlias)) {
7
+ if (utils_1.Is.constructor(keyOrAlias)) {
12
8
  return scope.resolveClass(keyOrAlias, options);
13
9
  }
14
10
  try {
package/cjm/hooks/hook.js CHANGED
@@ -8,7 +8,7 @@ const utils_1 = require("../utils");
8
8
  const UnexpectedHookResultError_1 = require("../errors/UnexpectedHookResultError");
9
9
  const inject_1 = require("../injector/inject");
10
10
  const isHookClassConstructor = (execute) => {
11
- return (0, utils_1.isConstructor)(execute) && execute.prototype.execute;
11
+ return utils_1.Is.constructor(execute) && execute.prototype.execute;
12
12
  };
13
13
  const toHookFn = (execute) => isHookClassConstructor(execute) ? (context) => context.scope.resolveOne(execute).execute(context) : execute;
14
14
  exports.toHookFn = toHookFn;
package/cjm/index.js CHANGED
@@ -1,9 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.depKey = exports.by = exports.getParameterMetadata = exports.getMethodMetadata = exports.setMethodMetadata = exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = exports.HookContext = exports.runOnDisposeHooks = exports.runOnConstructHooks = exports.onConstruct = exports.onDispose = exports.injectProp = exports.runHooksAsync = exports.runHooks = exports.hasHooks = exports.hook = exports.getHooks = exports.UnexpectedHookResultError = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyNotFoundError = exports.Registration = exports.register = exports.scope = exports.asAlias = exports.asKey = exports.decorate = exports.MultiCache = exports.multiCache = exports.SingletonProvider = exports.singleton = exports.Provider = 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 = exports.isDependencyKey = void 0;
4
- // Containers
5
- var IContainer_1 = require("./container/IContainer");
6
- Object.defineProperty(exports, "isDependencyKey", { enumerable: true, get: function () { return IContainer_1.isDependencyKey; } });
3
+ exports.depKey = exports.Is = exports.by = exports.getParameterMetadata = exports.getMethodMetadata = exports.setMethodMetadata = exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = exports.HookContext = exports.runOnDisposeHooks = exports.runOnConstructHooks = exports.onConstruct = exports.onDispose = exports.injectProp = exports.runHooksAsync = exports.runHooks = exports.hasHooks = exports.hook = exports.getHooks = exports.UnexpectedHookResultError = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyNotFoundError = exports.Registration = exports.register = exports.scope = exports.asAlias = exports.asKey = exports.decorate = exports.MultiCache = exports.multiCache = exports.SingletonProvider = exports.singleton = exports.Provider = 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;
7
4
  var Container_1 = require("./container/Container");
8
5
  Object.defineProperty(exports, "Container", { enumerable: true, get: function () { return Container_1.Container; } });
9
6
  var EmptyContainer_1 = require("./container/EmptyContainer");
@@ -79,5 +76,7 @@ Object.defineProperty(exports, "getParameterMetadata", { enumerable: true, get:
79
76
  // Others
80
77
  var resolve_1 = require("./resolve");
81
78
  Object.defineProperty(exports, "by", { enumerable: true, get: function () { return resolve_1.by; } });
79
+ var utils_1 = require("./utils");
80
+ Object.defineProperty(exports, "Is", { enumerable: true, get: function () { return utils_1.Is; } });
82
81
  var DepKey_1 = require("./DepKey");
83
82
  Object.defineProperty(exports, "depKey", { enumerable: true, get: function () { return DepKey_1.depKey; } });
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveArgs = exports.toInjectFn = exports.inject = void 0;
4
+ exports.isInjectBuilder = isInjectBuilder;
4
5
  const metadata_1 = require("../metadata");
5
6
  const utils_1 = require("../utils");
6
- const IContainer_1 = require("../container/IContainer");
7
7
  const HookContext_1 = require("../hooks/HookContext");
8
8
  const inject = (fn) => (target, propertyKey, parameterIndex) => {
9
- (0, metadata_1.setParameterMetadata)((0, HookContext_1.hookMetaKey)(propertyKey), (0, exports.toInjectFn)(fn))((0, utils_1.isInstance)(target) ? target.constructor : target, propertyKey, parameterIndex);
9
+ (0, metadata_1.setParameterMetadata)((0, HookContext_1.hookMetaKey)(propertyKey), (0, exports.toInjectFn)(fn))(utils_1.Is.instance(target) ? target.constructor : target, propertyKey, parameterIndex);
10
10
  };
11
11
  exports.inject = inject;
12
12
  function isInjectBuilder(fn) {
@@ -16,10 +16,10 @@ const toInjectFn = (target) => {
16
16
  if (typeof target === 'object' && isInjectBuilder(target)) {
17
17
  return (s) => target.resolve(s);
18
18
  }
19
- if ((0, utils_1.isConstructor)(target)) {
19
+ if (utils_1.Is.constructor(target)) {
20
20
  return (scope) => scope.resolveClass(target);
21
21
  }
22
- if ((0, IContainer_1.isDependencyKey)(target)) {
22
+ if (utils_1.Is.dependencyKey(target)) {
23
23
  return (scope) => scope.resolveOne(target);
24
24
  }
25
25
  return target;
@@ -4,6 +4,9 @@ exports.SingleCache = exports.multiCache = exports.MultiCache = void 0;
4
4
  class MultiCache {
5
5
  getKey;
6
6
  instances = new Map();
7
+ static fromFirstArg() {
8
+ return new MultiCache((key) => key);
9
+ }
7
10
  constructor(getKey = () => '1') {
8
11
  this.getKey = getKey;
9
12
  }
@@ -1,11 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ProviderDecorator = exports.lazy = exports.scopeAccess = exports.argsFn = exports.args = void 0;
3
+ exports.ProviderDecorator = exports.lazy = exports.scopeAccess = exports.resolveByArgs = exports.argsFn = exports.args = void 0;
4
+ const utils_1 = require("../utils");
4
5
  const ProviderPipe_1 = require("./ProviderPipe");
5
6
  const args = (...extraArgs) => (0, ProviderPipe_1.registerPipe)((p) => p.setArgs(() => extraArgs));
6
7
  exports.args = args;
7
8
  const argsFn = (fn) => (0, ProviderPipe_1.registerPipe)((p) => p.setArgs(fn));
8
9
  exports.argsFn = argsFn;
10
+ const resolveByArgs = (s, ...deps) => deps.map((d) => {
11
+ if (utils_1.Is.injectBuilder(d)) {
12
+ return d.resolve(s);
13
+ }
14
+ if (utils_1.Is.constructor(d)) {
15
+ return s.resolveClass(d);
16
+ }
17
+ return d;
18
+ });
19
+ exports.resolveByArgs = resolveByArgs;
9
20
  const scopeAccess = (predicate) => (0, ProviderPipe_1.registerPipe)((p) => p.setAccessPredicate(predicate));
10
21
  exports.scopeAccess = scopeAccess;
11
22
  const lazy = () => (0, ProviderPipe_1.registerPipe)((p) => p.lazy());
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.asKey = exports.asAlias = exports.register = exports.getTransformers = exports.scope = void 0;
4
- const IContainer_1 = require("../container/IContainer");
4
+ const utils_1 = require("../utils");
5
5
  const metadata_1 = require("../metadata");
6
6
  const ProviderPipe_1 = require("../provider/ProviderPipe");
7
7
  const scope = (...predicates) => (r) => r.when(...predicates);
@@ -11,7 +11,7 @@ const getTransformers = (Target) => (0, metadata_1.getMetadata)(Target, METADATA
11
11
  exports.getTransformers = getTransformers;
12
12
  const register = (...mappers) => (0, metadata_1.setMetadata)(METADATA_KEY, mappers.map((m) => ((0, ProviderPipe_1.isProviderPipe)(m) ? (r) => m.mapRegistration(r) : m)));
13
13
  exports.register = register;
14
- const asAlias = (target) => (r) => r.bindToAlias((0, IContainer_1.isDependencyKey)(target) ? target : target.key);
14
+ const asAlias = (target) => (r) => r.bindToAlias(utils_1.Is.dependencyKey(target) ? target : target.key);
15
15
  exports.asAlias = asAlias;
16
16
  const asKey = (key) => (r) => r.bindToKey(key);
17
17
  exports.asKey = asKey;
@@ -15,7 +15,7 @@ class Registration {
15
15
  return transform(new Registration(() => Provider_1.Provider.fromClass(Target), Target.name));
16
16
  }
17
17
  static fromValue(value) {
18
- if ((0, utils_1.isConstructor)(value)) {
18
+ if (utils_1.Is.constructor(value)) {
19
19
  const transform = (0, utils_1.pipe)(...(0, IRegistration_1.getTransformers)(value));
20
20
  return transform(new Registration(() => Provider_1.Provider.fromValue(value), value.name));
21
21
  }
package/cjm/resolve.js CHANGED
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.by = exports.InstancesResolver = exports.InjectionResolver = void 0;
4
- const IContainer_1 = require("./container/IContainer");
5
- const DepKey_1 = require("./DepKey");
4
+ const utils_1 = require("./utils");
6
5
  class InjectionResolver {
7
6
  resolveByOptions;
8
7
  isLazy = false;
@@ -55,18 +54,18 @@ class InstancesResolver {
55
54
  exports.InstancesResolver = InstancesResolver;
56
55
  exports.by = {
57
56
  many: (target) => {
58
- const alias = (0, IContainer_1.isDependencyKey)(target) ? target : target.key;
57
+ const alias = utils_1.Is.dependencyKey(target) ? target : target.key;
59
58
  return new InjectionResolver((s, options) => s.resolveMany(alias, options));
60
59
  },
61
60
  one: (target) => {
62
- const key = (0, DepKey_1.isDepKey)(target) ? target.key : target;
61
+ const key = utils_1.Is.DepKey(target) ? target.key : target;
63
62
  return new InjectionResolver((s, options) => s.resolveOne(key, options));
64
63
  },
65
64
  /**
66
65
  * Use it only for optimization. Otherwise, recommended to use `by.one`
67
66
  */
68
67
  aliasOne: (target) => {
69
- const alias = (0, DepKey_1.isDepKey)(target) ? target.key : target;
68
+ const alias = utils_1.Is.DepKey(target) ? target.key : target;
70
69
  return new InjectionResolver((s, options) => s.resolveOneByAlias(alias, options));
71
70
  },
72
71
  instances: (predicate = () => true) => new InstancesResolver(predicate),
package/cjm/utils.js CHANGED
@@ -1,14 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Filter = exports.List = exports.promisify = exports.constant = exports.pipe = exports.isConstructor = void 0;
4
- exports.isInstance = isInstance;
3
+ exports.Is = exports.Filter = exports.List = exports.promisify = exports.constant = exports.pipe = void 0;
5
4
  exports.fillEmptyIndexes = fillEmptyIndexes;
6
5
  exports.lazyProxy = lazyProxy;
7
- const isConstructor = (T) => typeof T === 'function' && !!T.prototype;
8
- exports.isConstructor = isConstructor;
9
- function isInstance(target) {
10
- return Object.prototype.hasOwnProperty.call(target, 'constructor');
11
- }
12
6
  const pipe = (...mappers) => (value) => mappers.reduce((acc, current) => current(acc), value);
13
7
  exports.pipe = pipe;
14
8
  function fillEmptyIndexes(baseArr, insertArr) {
@@ -44,3 +38,13 @@ exports.Filter = {
44
38
  return (v) => !excludeSet.has(v);
45
39
  },
46
40
  };
41
+ exports.Is = {
42
+ object: (target) => target !== null && typeof target === 'object',
43
+ instance: (target) => Object.prototype.hasOwnProperty.call(target, 'constructor'),
44
+ constructor: (target) => typeof target === 'function' && !!target.prototype,
45
+ dependencyKey: (target) => ['string', 'symbol'].includes(typeof target),
46
+ injectBuilder: (target) => exports.Is.object(target) && 'resolve' in target && typeof target['resolve'] === 'function',
47
+ DepKey: (key) => {
48
+ return typeof key === 'object' && key !== null && 'key' in key;
49
+ },
50
+ };
package/esm/DepKey.js CHANGED
@@ -1,8 +1,5 @@
1
1
  import { Registration } from './registration/Registration';
2
2
  import { Provider } from './provider/Provider';
3
- export const isDepKey = (key) => {
4
- return typeof key === 'object' && key !== null && 'key' in key;
5
- };
6
3
  export const depKey = (key) => {
7
4
  const scopePredicates = [];
8
5
  const mappers = [];
@@ -22,7 +19,7 @@ export const depKey = (key) => {
22
19
  }
23
20
  return registration;
24
21
  },
25
- resolve: (s) => s.resolveOne(key),
22
+ resolve: (s, options) => s.resolveOne(key, options),
26
23
  pipe(...values) {
27
24
  mappers.push(...values);
28
25
  return this;
@@ -1,10 +1,7 @@
1
- import { isConstructor } from '../utils';
1
+ import { Is } from '../utils';
2
2
  import { DependencyNotFoundError } from '../errors/DependencyNotFoundError';
3
- export function isDependencyKey(token) {
4
- return ['string', 'symbol'].includes(typeof token);
5
- }
6
3
  export const DEFAULT_CONTAINER_RESOLVER = (scope, keyOrAlias, options) => {
7
- if (isConstructor(keyOrAlias)) {
4
+ if (Is.constructor(keyOrAlias)) {
8
5
  return scope.resolveClass(keyOrAlias, options);
9
6
  }
10
7
  try {
package/esm/hooks/hook.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { createHookContext } from './HookContext';
2
- import { isConstructor, promisify } from '../utils';
2
+ import { Is, promisify } from '../utils';
3
3
  import { UnexpectedHookResultError } from '../errors/UnexpectedHookResultError';
4
4
  import { toInjectFn } from '../injector/inject';
5
5
  const isHookClassConstructor = (execute) => {
6
- return isConstructor(execute) && execute.prototype.execute;
6
+ return Is.constructor(execute) && execute.prototype.execute;
7
7
  };
8
8
  export const toHookFn = (execute) => isHookClassConstructor(execute) ? (context) => context.scope.resolveOne(execute).execute(context) : execute;
9
9
  export const hook = (key, ...fns) => (target, propertyKey) => {
package/esm/index.js CHANGED
@@ -1,5 +1,3 @@
1
- // Containers
2
- export { isDependencyKey, } from './container/IContainer';
3
1
  export { Container } from './container/Container';
4
2
  export { EmptyContainer } from './container/EmptyContainer';
5
3
  export { AutoMockedContainer } from './container/AutoMockedContainer';
@@ -29,4 +27,5 @@ export { HookContext } from './hooks/HookContext';
29
27
  export { setMetadata, getMetadata, setParameterMetadata, setMethodMetadata, getMethodMetadata, getParameterMetadata, } from './metadata';
30
28
  // Others
31
29
  export { by } from './resolve';
30
+ export { Is } from './utils';
32
31
  export { depKey } from './DepKey';
@@ -1,21 +1,20 @@
1
1
  import { getParameterMetadata, setParameterMetadata } from '../metadata';
2
- import { constant, fillEmptyIndexes, isConstructor, isInstance } from '../utils';
3
- import { isDependencyKey } from '../container/IContainer';
2
+ import { constant, fillEmptyIndexes, Is } from '../utils';
4
3
  import { hookMetaKey } from '../hooks/HookContext';
5
4
  export const inject = (fn) => (target, propertyKey, parameterIndex) => {
6
- setParameterMetadata(hookMetaKey(propertyKey), toInjectFn(fn))(isInstance(target) ? target.constructor : target, propertyKey, parameterIndex);
5
+ setParameterMetadata(hookMetaKey(propertyKey), toInjectFn(fn))(Is.instance(target) ? target.constructor : target, propertyKey, parameterIndex);
7
6
  };
8
- function isInjectBuilder(fn) {
7
+ export function isInjectBuilder(fn) {
9
8
  return 'resolve' in fn && typeof fn['resolve'] === 'function';
10
9
  }
11
10
  export const toInjectFn = (target) => {
12
11
  if (typeof target === 'object' && isInjectBuilder(target)) {
13
12
  return (s) => target.resolve(s);
14
13
  }
15
- if (isConstructor(target)) {
14
+ if (Is.constructor(target)) {
16
15
  return (scope) => scope.resolveClass(target);
17
16
  }
18
- if (isDependencyKey(target)) {
17
+ if (Is.dependencyKey(target)) {
19
18
  return (scope) => scope.resolveOne(target);
20
19
  }
21
20
  return target;
@@ -1,6 +1,9 @@
1
1
  export class MultiCache {
2
2
  getKey;
3
3
  instances = new Map();
4
+ static fromFirstArg() {
5
+ return new MultiCache((key) => key);
6
+ }
4
7
  constructor(getKey = () => '1') {
5
8
  this.getKey = getKey;
6
9
  }
@@ -1,6 +1,16 @@
1
+ import { Is } from '../utils';
1
2
  import { isProviderPipe, registerPipe } from './ProviderPipe';
2
3
  export const args = (...extraArgs) => registerPipe((p) => p.setArgs(() => extraArgs));
3
4
  export const argsFn = (fn) => registerPipe((p) => p.setArgs(fn));
5
+ export const resolveByArgs = (s, ...deps) => deps.map((d) => {
6
+ if (Is.injectBuilder(d)) {
7
+ return d.resolve(s);
8
+ }
9
+ if (Is.constructor(d)) {
10
+ return s.resolveClass(d);
11
+ }
12
+ return d;
13
+ });
4
14
  export const scopeAccess = (predicate) => registerPipe((p) => p.setAccessPredicate(predicate));
5
15
  export const lazy = () => registerPipe((p) => p.lazy());
6
16
  export class ProviderDecorator {
@@ -1,9 +1,9 @@
1
- import { isDependencyKey } from '../container/IContainer';
1
+ import { Is } from '../utils';
2
2
  import { getMetadata, setMetadata } from '../metadata';
3
3
  import { isProviderPipe } from '../provider/ProviderPipe';
4
4
  export const scope = (...predicates) => (r) => r.when(...predicates);
5
5
  const METADATA_KEY = 'registration';
6
6
  export const getTransformers = (Target) => getMetadata(Target, METADATA_KEY) ?? [];
7
7
  export const register = (...mappers) => setMetadata(METADATA_KEY, mappers.map((m) => (isProviderPipe(m) ? (r) => m.mapRegistration(r) : m)));
8
- export const asAlias = (target) => (r) => r.bindToAlias(isDependencyKey(target) ? target : target.key);
8
+ export const asAlias = (target) => (r) => r.bindToAlias(Is.dependencyKey(target) ? target : target.key);
9
9
  export const asKey = (key) => (r) => r.bindToKey(key);
@@ -1,4 +1,4 @@
1
- import { isConstructor, pipe } from '../utils';
1
+ import { Is, pipe } from '../utils';
2
2
  import { Provider } from '../provider/Provider';
3
3
  import { DependencyMissingKeyError } from '../errors/DependencyMissingKeyError';
4
4
  import { getTransformers } from './IRegistration';
@@ -12,7 +12,7 @@ export class Registration {
12
12
  return transform(new Registration(() => Provider.fromClass(Target), Target.name));
13
13
  }
14
14
  static fromValue(value) {
15
- if (isConstructor(value)) {
15
+ if (Is.constructor(value)) {
16
16
  const transform = pipe(...getTransformers(value));
17
17
  return transform(new Registration(() => Provider.fromValue(value), value.name));
18
18
  }
package/esm/resolve.js CHANGED
@@ -1,5 +1,4 @@
1
- import { isDependencyKey, } from './container/IContainer';
2
- import { isDepKey } from './DepKey';
1
+ import { Is } from './utils';
3
2
  export class InjectionResolver {
4
3
  resolveByOptions;
5
4
  isLazy = false;
@@ -50,18 +49,18 @@ export class InstancesResolver {
50
49
  }
51
50
  export const by = {
52
51
  many: (target) => {
53
- const alias = isDependencyKey(target) ? target : target.key;
52
+ const alias = Is.dependencyKey(target) ? target : target.key;
54
53
  return new InjectionResolver((s, options) => s.resolveMany(alias, options));
55
54
  },
56
55
  one: (target) => {
57
- const key = isDepKey(target) ? target.key : target;
56
+ const key = Is.DepKey(target) ? target.key : target;
58
57
  return new InjectionResolver((s, options) => s.resolveOne(key, options));
59
58
  },
60
59
  /**
61
60
  * Use it only for optimization. Otherwise, recommended to use `by.one`
62
61
  */
63
62
  aliasOne: (target) => {
64
- const alias = isDepKey(target) ? target.key : target;
63
+ const alias = Is.DepKey(target) ? target.key : target;
65
64
  return new InjectionResolver((s, options) => s.resolveOneByAlias(alias, options));
66
65
  },
67
66
  instances: (predicate = () => true) => new InstancesResolver(predicate),
package/esm/utils.js CHANGED
@@ -1,7 +1,3 @@
1
- export const isConstructor = (T) => typeof T === 'function' && !!T.prototype;
2
- export function isInstance(target) {
3
- return Object.prototype.hasOwnProperty.call(target, 'constructor');
4
- }
5
1
  export const pipe = (...mappers) => (value) => mappers.reduce((acc, current) => current(acc), value);
6
2
  export function fillEmptyIndexes(baseArr, insertArr) {
7
3
  const a = [...baseArr];
@@ -34,3 +30,13 @@ export const Filter = {
34
30
  return (v) => !excludeSet.has(v);
35
31
  },
36
32
  };
33
+ export const Is = {
34
+ object: (target) => target !== null && typeof target === 'object',
35
+ instance: (target) => Object.prototype.hasOwnProperty.call(target, 'constructor'),
36
+ constructor: (target) => typeof target === 'function' && !!target.prototype,
37
+ dependencyKey: (target) => ['string', 'symbol'].includes(typeof target),
38
+ injectBuilder: (target) => Is.object(target) && 'resolve' in target && typeof target['resolve'] === 'function',
39
+ DepKey: (key) => {
40
+ return typeof key === 'object' && key !== null && 'key' in key;
41
+ },
42
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "41.1.1",
3
+ "version": "41.2.0",
4
4
  "description": "Typescript IoC container",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -12,5 +12,4 @@ export type DepKey<T> = IInjectFnResolver<T> & {
12
12
  when(value: ScopePredicate): DepKey<T>;
13
13
  asAlias: (registration: IRegistration<T>) => IRegistration<T>;
14
14
  };
15
- export declare const isDepKey: <T>(key: unknown) => key is DepKey<T>;
16
15
  export declare const depKey: <T>(key: DependencyKey) => DepKey<T>;
@@ -3,7 +3,6 @@ import { type constructor } from '../utils';
3
3
  import { type IRegistration } from '../registration/IRegistration';
4
4
  export type Tag = string;
5
5
  export type DependencyKey = string | symbol;
6
- export declare function isDependencyKey(token: unknown): token is DependencyKey;
7
6
  export type InjectionToken<T = unknown> = constructor<T> | DependencyKey;
8
7
  export type ResolveOneOptions = {
9
8
  args?: unknown[];
@@ -39,7 +38,7 @@ export interface IContainer extends Tagged {
39
38
  resolveClass<T>(target: constructor<T>, options?: {
40
39
  args?: unknown[];
41
40
  }): T;
42
- resolveOne<T>(alias: constructor<T> | DependencyKey, options?: ResolveManyOptions): T;
41
+ resolveOne<T>(alias: constructor<T> | DependencyKey, options?: ResolveOneOptions): T;
43
42
  resolveOneByKey<T>(key: DependencyKey, options?: ResolveOneOptions): T;
44
43
  resolveOneByAlias<T>(key: DependencyKey, options?: ResolveOneOptions): T;
45
44
  resolveMany<T>(alias: DependencyKey, options?: ResolveManyOptions): T[];
@@ -1,4 +1,4 @@
1
- export { type IContainer, type Resolvable, type IContainerModule, isDependencyKey, type DependencyKey, type InjectionToken, type Tag, type Tagged, type Instance, } from './container/IContainer';
1
+ export { type IContainer, type Resolvable, type IContainerModule, type DependencyKey, type InjectionToken, type Tag, type Tagged, type Instance, } from './container/IContainer';
2
2
  export { Container } from './container/Container';
3
3
  export { EmptyContainer } from './container/EmptyContainer';
4
4
  export { AutoMockedContainer } from './container/AutoMockedContainer';
@@ -23,6 +23,6 @@ export { getHooks, hook, hasHooks, type HookFn, type HookClass, runHooks, runHoo
23
23
  export { HookContext, type InjectFn, type IHookContext } from './hooks/HookContext';
24
24
  export { setMetadata, getMetadata, setParameterMetadata, setMethodMetadata, getMethodMetadata, getParameterMetadata, } from './metadata';
25
25
  export { by } from './resolve';
26
- export { type constructor } from './utils';
26
+ export { type constructor, Is } from './utils';
27
27
  export { depKey, type DepKey } from './DepKey';
28
28
  export { type InstancePredicate } from './resolve';
@@ -1,5 +1,5 @@
1
1
  import { type constructor } from '../utils';
2
- import { type IContainer } from '../container/IContainer';
2
+ import { type IContainer, ResolveOneOptions } from '../container/IContainer';
3
3
  export type InjectOptions = {
4
4
  args: unknown[];
5
5
  };
@@ -7,5 +7,5 @@ export interface IInjector {
7
7
  resolve<T>(container: IContainer, value: constructor<T>, options: InjectOptions): T;
8
8
  }
9
9
  export interface IInjectFnResolver<T> {
10
- resolve(s: IContainer): T;
10
+ resolve(s: IContainer, options?: ResolveOneOptions): T;
11
11
  }
@@ -3,5 +3,6 @@ import { DependencyKey, type IContainer } from '../container/IContainer';
3
3
  import { type InjectFn } from '../hooks/HookContext';
4
4
  import { type IInjectFnResolver } from './IInjector';
5
5
  export declare const inject: <T>(fn: InjectFn<T> | IInjectFnResolver<T> | DependencyKey | constructor<T>) => ParameterDecorator;
6
+ export declare function isInjectBuilder<T>(fn: object): fn is IInjectFnResolver<T>;
6
7
  export declare const toInjectFn: <T>(target: InjectFn<T> | IInjectFnResolver<T> | DependencyKey | constructor<T>) => InjectFn<T>;
7
8
  export declare const resolveArgs: (Target: constructor<unknown>, methodName?: string) => (scope: IContainer, ...deps: unknown[]) => unknown[];
@@ -1,3 +1,4 @@
1
+ import type { DependencyKey } from '../container/IContainer';
1
2
  export interface Cache<K, V> {
2
3
  getKey(...args: unknown[]): K;
3
4
  hasValue(key: K): boolean;
@@ -7,6 +8,7 @@ export interface Cache<K, V> {
7
8
  export declare class MultiCache<K, V> implements Cache<K, V> {
8
9
  readonly getKey: (...args: unknown[]) => K;
9
10
  private instances;
11
+ static fromFirstArg(): MultiCache<DependencyKey, unknown>;
10
12
  constructor(getKey?: (...args: unknown[]) => K);
11
13
  hasValue(token: K): boolean;
12
14
  getValue(token: K): V;
@@ -1,5 +1,5 @@
1
- import type { IContainer, Tagged } from '../container/IContainer';
2
- import type { MapFn } from '../utils';
1
+ import { IContainer, Tagged } from '../container/IContainer';
2
+ import { MapFn } from '../utils';
3
3
  import { ProviderPipe } from './ProviderPipe';
4
4
  export type ProviderResolveOptions = {
5
5
  args: unknown[];
@@ -25,6 +25,7 @@ export interface IProvider<T = any> {
25
25
  }
26
26
  export declare const args: <T>(...extraArgs: unknown[]) => ProviderPipe<T>;
27
27
  export declare const argsFn: <T>(fn: ArgsFn) => ProviderPipe<T>;
28
+ export declare const resolveByArgs: (s: IContainer, ...deps: unknown[]) => unknown[];
28
29
  export declare const scopeAccess: <T>(predicate: ScopeAccessFn) => ProviderPipe<T>;
29
30
  export declare const lazy: <T>() => ProviderPipe<T>;
30
31
  export declare abstract class ProviderDecorator<T> implements IProvider<T> {
@@ -1,5 +1,5 @@
1
1
  import type { DependencyKey, IContainer, IContainerModule } from '../container/IContainer';
2
- import type { constructor, MapFn } from '../utils';
2
+ import { constructor, MapFn } from '../utils';
3
3
  import type { IProvider } from '../provider/IProvider';
4
4
  import type { DepKey } from '../DepKey';
5
5
  import { ProviderPipe } from '../provider/ProviderPipe';
@@ -1,5 +1,5 @@
1
1
  import type { DependencyKey, IContainer } from '../container/IContainer';
2
- import type { constructor, MapFn } from '../utils';
2
+ import { constructor, MapFn } from '../utils';
3
3
  import type { IProvider, ResolveDependency } from '../provider/IProvider';
4
4
  import type { IRegistration, ScopePredicate } from './IRegistration';
5
5
  import type { ProviderPipe } from '../provider/ProviderPipe';
@@ -1,9 +1,10 @@
1
+ import { DependencyKey } from './container/IContainer';
2
+ import { IInjectFnResolver } from './injector/IInjector';
3
+ import { DepKey } from './DepKey';
1
4
  export type constructor<T> = new (...args: any[]) => T;
2
- export declare const isConstructor: (T: unknown) => T is constructor<unknown>;
3
5
  export interface InstanceOfClass<T = unknown> {
4
6
  new (...args: unknown[]): T;
5
7
  }
6
- export declare function isInstance(target: object): target is InstanceOfClass;
7
8
  export type MapFn<T> = (value: T) => T;
8
9
  export declare const pipe: <T>(...mappers: MapFn<T>[]) => MapFn<T>;
9
10
  export declare function fillEmptyIndexes<T>(baseArr: (T | undefined)[], insertArr: T[]): T[];
@@ -16,3 +17,11 @@ export declare const List: {
16
17
  export declare const Filter: {
17
18
  exclude: <T>(arr: Set<T> | T[]) => (v: T) => boolean;
18
19
  };
20
+ export declare const Is: {
21
+ object: (target: unknown) => target is object;
22
+ instance: (target: unknown) => target is InstanceOfClass;
23
+ constructor: (target: unknown) => target is constructor<unknown>;
24
+ dependencyKey: (target: unknown) => target is DependencyKey;
25
+ injectBuilder: (target: unknown) => target is IInjectFnResolver<unknown>;
26
+ DepKey: <T>(key: unknown) => key is DepKey<T>;
27
+ };