ts-ioc-container 40.0.0 → 41.0.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
@@ -94,7 +94,7 @@ describe('Basic usage', function () {
94
94
 
95
95
  it('should inject dependencies', function () {
96
96
  class App {
97
- constructor(@inject(by.one('ILogger')) public logger: Logger) {}
97
+ constructor(@inject('ILogger') public logger: Logger) {}
98
98
  }
99
99
 
100
100
  const container = new Container().addRegistration(R.fromClass(Logger).bindToKey('ILogger'));
@@ -280,7 +280,7 @@ describe('lazy provider', () => {
280
280
  class Service {
281
281
  name = 'Service';
282
282
 
283
- constructor(@inject(by.one('Flag')) private flag: Flag) {
283
+ constructor(@inject('Flag') private flag: Flag) {
284
284
  this.flag.set();
285
285
  }
286
286
 
@@ -370,14 +370,14 @@ Also you can [inject property.](#inject-property)
370
370
 
371
371
  ```typescript
372
372
  import 'reflect-metadata';
373
- import { by, Container, inject, Registration as R } from 'ts-ioc-container';
373
+ import { Container, inject, Registration as R } from 'ts-ioc-container';
374
374
 
375
375
  class Logger {
376
376
  name = 'Logger';
377
377
  }
378
378
 
379
379
  class App {
380
- constructor(@inject(by.one('ILogger')) private logger: Logger) {}
380
+ constructor(@inject('ILogger') private logger: Logger) {}
381
381
 
382
382
  // OR
383
383
  // constructor(@inject((container, ...args) => container.resolve('ILogger', ...args)) private logger: ILogger) {
@@ -1025,8 +1025,8 @@ describe('alias', () => {
1025
1025
 
1026
1026
  const container = new Container().addRegistration(R.fromClass(FileLogger));
1027
1027
 
1028
- expect(by.one('ILogger').resolve(container)).toBeInstanceOf(FileLogger);
1029
- expect(() => by.one('logger').resolve(container)).toThrowError(DependencyNotFoundError);
1028
+ expect(container.resolveOne('ILogger')).toBeInstanceOf(FileLogger);
1029
+ expect(() => container.resolveOne('logger')).toThrowError(DependencyNotFoundError);
1030
1030
  });
1031
1031
 
1032
1032
  it('should resolve by alias', () => {
@@ -1040,9 +1040,9 @@ describe('alias', () => {
1040
1040
  .addRegistration(R.fromClass(FileLogger))
1041
1041
  .addRegistration(R.fromClass(DbLogger));
1042
1042
 
1043
- const result1 = by.one('ILogger').resolve(container);
1043
+ const result1 = container.resolveOne('ILogger');
1044
1044
  const child = container.createScope({ tags: ['child'] });
1045
- const result2 = by.one('ILogger').resolve(child);
1045
+ const result2 = child.resolveOne('ILogger');
1046
1046
 
1047
1047
  expect(result1).toBeInstanceOf(FileLogger);
1048
1048
  expect(result2).toBeInstanceOf(DbLogger);
@@ -1133,7 +1133,7 @@ describe('lazy provider', () => {
1133
1133
  }
1134
1134
 
1135
1135
  class App {
1136
- constructor(@inject(by.one('IRepository')) public repository: IRepository) {}
1136
+ constructor(@inject('IRepository') public repository: IRepository) {}
1137
1137
 
1138
1138
  async run() {
1139
1139
  await this.repository.save({ id: '1', text: 'Hello' });
@@ -1379,9 +1379,9 @@ class Logger {
1379
1379
  }) // <--- or extract it to @onDispose
1380
1380
  private messages: string[] = [];
1381
1381
 
1382
- constructor(@inject(by.one('logsRepo')) private logsRepo: LogsRepo) {}
1382
+ constructor(@inject('logsRepo') private logsRepo: LogsRepo) {}
1383
1383
 
1384
- log(@inject(by.one('logsRepo')) message: string): void {
1384
+ log(@inject('logsRepo') message: string): void {
1385
1385
  this.messages.push(message);
1386
1386
  }
1387
1387
 
@@ -1417,12 +1417,12 @@ describe('onDispose', function () {
1417
1417
  ### Inject property
1418
1418
 
1419
1419
  ```typescript
1420
- import { by, Container, hook, injectProp, Registration, runHooks } from 'ts-ioc-container';
1420
+ import { Container, hook, injectProp, Registration, runHooks } from 'ts-ioc-container';
1421
1421
 
1422
1422
  describe('inject property', () => {
1423
1423
  it('should inject property', () => {
1424
1424
  class App {
1425
- @hook('onInit', injectProp(by.one('greeting')))
1425
+ @hook('onInit', injectProp('greeting'))
1426
1426
  greeting!: string;
1427
1427
  }
1428
1428
  const expected = 'Hello world!';
package/cjm/index.js CHANGED
@@ -1,6 +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.scopeAccess = exports.ProxyInjector = exports.SimpleInjector = exports.MetadataInjector = exports.resolveArgs = exports.inject = exports.AutoMockedContainer = exports.EmptyContainer = exports.Container = exports.isDependencyKey = void 0;
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
4
  // Containers
5
5
  var IContainer_1 = require("./container/IContainer");
6
6
  Object.defineProperty(exports, "isDependencyKey", { enumerable: true, get: function () { return IContainer_1.isDependencyKey; } });
@@ -23,6 +23,7 @@ Object.defineProperty(exports, "ProxyInjector", { enumerable: true, get: functio
23
23
  // Providers
24
24
  var IProvider_1 = require("./provider/IProvider");
25
25
  Object.defineProperty(exports, "scopeAccess", { enumerable: true, get: function () { return IProvider_1.scopeAccess; } });
26
+ Object.defineProperty(exports, "lazy", { enumerable: true, get: function () { return IProvider_1.lazy; } });
26
27
  Object.defineProperty(exports, "argsFn", { enumerable: true, get: function () { return IProvider_1.argsFn; } });
27
28
  Object.defineProperty(exports, "args", { enumerable: true, get: function () { return IProvider_1.args; } });
28
29
  Object.defineProperty(exports, "ProviderDecorator", { enumerable: true, get: function () { return IProvider_1.ProviderDecorator; } });
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveArgs = exports.toInjectFn = exports.inject = void 0;
4
4
  const metadata_1 = require("../metadata");
5
5
  const utils_1 = require("../utils");
6
+ const IContainer_1 = require("../container/IContainer");
6
7
  const HookContext_1 = require("../hooks/HookContext");
7
8
  const inject = (fn) => (target, propertyKey, parameterIndex) => {
8
9
  (0, metadata_1.setParameterMetadata)((0, HookContext_1.hookMetaKey)(propertyKey), (0, exports.toInjectFn)(fn))((0, utils_1.isInstance)(target) ? target.constructor : target, propertyKey, parameterIndex);
@@ -11,7 +12,18 @@ exports.inject = inject;
11
12
  function isInjectBuilder(fn) {
12
13
  return 'resolve' in fn && typeof fn['resolve'] === 'function';
13
14
  }
14
- const toInjectFn = (fn) => isInjectBuilder(fn) ? (scope) => fn.resolve(scope) : fn;
15
+ const toInjectFn = (target) => {
16
+ if (typeof target === 'object' && isInjectBuilder(target)) {
17
+ return (s) => target.resolve(s);
18
+ }
19
+ if ((0, utils_1.isConstructor)(target)) {
20
+ return (scope) => scope.resolveByClass(target);
21
+ }
22
+ if ((0, IContainer_1.isDependencyKey)(target)) {
23
+ return (scope) => scope.resolveOne(target);
24
+ }
25
+ return target;
26
+ };
15
27
  exports.toInjectFn = toInjectFn;
16
28
  const resolveArgs = (Target, methodName) => {
17
29
  const argsFns = getInjectFns(Target, methodName);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ProviderDecorator = exports.scopeAccess = exports.argsFn = exports.args = void 0;
3
+ exports.ProviderDecorator = exports.lazy = exports.scopeAccess = exports.argsFn = exports.args = void 0;
4
4
  const ProviderPipe_1 = require("./ProviderPipe");
5
5
  const args = (...extraArgs) => (0, ProviderPipe_1.registerPipe)((p) => p.setArgs(() => extraArgs));
6
6
  exports.args = args;
@@ -8,6 +8,8 @@ const argsFn = (fn) => (0, ProviderPipe_1.registerPipe)((p) => p.setArgs(fn));
8
8
  exports.argsFn = argsFn;
9
9
  const scopeAccess = (predicate) => (0, ProviderPipe_1.registerPipe)((p) => p.setAccessPredicate(predicate));
10
10
  exports.scopeAccess = scopeAccess;
11
+ const lazy = () => (0, ProviderPipe_1.registerPipe)((p) => p.lazy());
12
+ exports.lazy = lazy;
11
13
  class ProviderDecorator {
12
14
  decorated;
13
15
  constructor(decorated) {
@@ -37,5 +39,9 @@ class ProviderDecorator {
37
39
  this.decorated.setArgs(argsFn);
38
40
  return this;
39
41
  }
42
+ lazy() {
43
+ this.decorated.lazy();
44
+ return this;
45
+ }
40
46
  }
41
47
  exports.ProviderDecorator = ProviderDecorator;
@@ -16,6 +16,7 @@ class Provider {
16
16
  }
17
17
  argsFn = () => [];
18
18
  checkAccess = () => true;
19
+ isLazy = false;
19
20
  constructor(resolveDependency) {
20
21
  this.resolveDependency = resolveDependency;
21
22
  }
@@ -23,14 +24,18 @@ class Provider {
23
24
  const fns = mappers.map((m) => ((0, ProviderPipe_1.isProviderPipe)(m) ? m.mapProvider.bind(m) : m));
24
25
  return (0, utils_1.pipe)(...fns)(this);
25
26
  }
26
- resolve(container, { args, lazy: isLazy }) {
27
+ resolve(container, { args, lazy }) {
27
28
  const resolveDependency = () => this.resolveDependency(container, { args: [...this.argsFn(container, ...args), ...args] });
28
- return isLazy ? (0, utils_1.lazyProxy)(resolveDependency) : resolveDependency();
29
+ return (lazy ?? this.isLazy) ? (0, utils_1.lazyProxy)(resolveDependency) : resolveDependency();
29
30
  }
30
31
  setAccessPredicate(predicate) {
31
32
  this.checkAccess = predicate;
32
33
  return this;
33
34
  }
35
+ lazy() {
36
+ this.isLazy = true;
37
+ return this;
38
+ }
34
39
  setArgs(argsFn) {
35
40
  this.argsFn = argsFn;
36
41
  return this;
package/esm/index.js CHANGED
@@ -9,7 +9,7 @@ export { MetadataInjector } from './injector/MetadataInjector';
9
9
  export { SimpleInjector } from './injector/SimpleInjector';
10
10
  export { ProxyInjector } from './injector/ProxyInjector';
11
11
  // Providers
12
- export { scopeAccess, argsFn, args, ProviderDecorator, } from './provider/IProvider';
12
+ export { scopeAccess, lazy, argsFn, args, ProviderDecorator, } from './provider/IProvider';
13
13
  export { Provider } from './provider/Provider';
14
14
  export { singleton, SingletonProvider } from './provider/SingletonProvider';
15
15
  export { multiCache, MultiCache } from './provider/Cache';
@@ -1,5 +1,6 @@
1
1
  import { getParameterMetadata, setParameterMetadata } from '../metadata';
2
- import { constant, fillEmptyIndexes, isInstance } from '../utils';
2
+ import { constant, fillEmptyIndexes, isConstructor, isInstance } from '../utils';
3
+ import { isDependencyKey } from '../container/IContainer';
3
4
  import { hookMetaKey } from '../hooks/HookContext';
4
5
  export const inject = (fn) => (target, propertyKey, parameterIndex) => {
5
6
  setParameterMetadata(hookMetaKey(propertyKey), toInjectFn(fn))(isInstance(target) ? target.constructor : target, propertyKey, parameterIndex);
@@ -7,7 +8,18 @@ export const inject = (fn) => (target, propertyKey, parameterIndex) => {
7
8
  function isInjectBuilder(fn) {
8
9
  return 'resolve' in fn && typeof fn['resolve'] === 'function';
9
10
  }
10
- export const toInjectFn = (fn) => isInjectBuilder(fn) ? (scope) => fn.resolve(scope) : fn;
11
+ export const toInjectFn = (target) => {
12
+ if (typeof target === 'object' && isInjectBuilder(target)) {
13
+ return (s) => target.resolve(s);
14
+ }
15
+ if (isConstructor(target)) {
16
+ return (scope) => scope.resolveByClass(target);
17
+ }
18
+ if (isDependencyKey(target)) {
19
+ return (scope) => scope.resolveOne(target);
20
+ }
21
+ return target;
22
+ };
11
23
  export const resolveArgs = (Target, methodName) => {
12
24
  const argsFns = getInjectFns(Target, methodName);
13
25
  return (scope, ...deps) => fillEmptyIndexes(argsFns, deps.map(constant)).map((fn) => fn(scope));
@@ -2,6 +2,7 @@ import { isProviderPipe, registerPipe } from './ProviderPipe';
2
2
  export const args = (...extraArgs) => registerPipe((p) => p.setArgs(() => extraArgs));
3
3
  export const argsFn = (fn) => registerPipe((p) => p.setArgs(fn));
4
4
  export const scopeAccess = (predicate) => registerPipe((p) => p.setAccessPredicate(predicate));
5
+ export const lazy = () => registerPipe((p) => p.lazy());
5
6
  export class ProviderDecorator {
6
7
  decorated;
7
8
  constructor(decorated) {
@@ -31,4 +32,8 @@ export class ProviderDecorator {
31
32
  this.decorated.setArgs(argsFn);
32
33
  return this;
33
34
  }
35
+ lazy() {
36
+ this.decorated.lazy();
37
+ return this;
38
+ }
34
39
  }
@@ -13,6 +13,7 @@ export class Provider {
13
13
  }
14
14
  argsFn = () => [];
15
15
  checkAccess = () => true;
16
+ isLazy = false;
16
17
  constructor(resolveDependency) {
17
18
  this.resolveDependency = resolveDependency;
18
19
  }
@@ -20,14 +21,18 @@ export class Provider {
20
21
  const fns = mappers.map((m) => (isProviderPipe(m) ? m.mapProvider.bind(m) : m));
21
22
  return pipe(...fns)(this);
22
23
  }
23
- resolve(container, { args, lazy: isLazy }) {
24
+ resolve(container, { args, lazy }) {
24
25
  const resolveDependency = () => this.resolveDependency(container, { args: [...this.argsFn(container, ...args), ...args] });
25
- return isLazy ? lazyProxy(resolveDependency) : resolveDependency();
26
+ return (lazy ?? this.isLazy) ? lazyProxy(resolveDependency) : resolveDependency();
26
27
  }
27
28
  setAccessPredicate(predicate) {
28
29
  this.checkAccess = predicate;
29
30
  return this;
30
31
  }
32
+ lazy() {
33
+ this.isLazy = true;
34
+ return this;
35
+ }
31
36
  setArgs(argsFn) {
32
37
  this.argsFn = argsFn;
33
38
  return this;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "40.0.0",
3
+ "version": "41.0.0",
4
4
  "description": "Typescript IoC container",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -46,7 +46,7 @@
46
46
  "test-coverage:update": "scripts/test-coverage/update-coverage-results.ts",
47
47
  "build": "npm run build:cjm && npm run build:esm && npm run build:types",
48
48
  "coverage": "coveralls",
49
- "test": "jest --coverage --coverageReporters='json-summary'",
49
+ "test": "jest --coverage",
50
50
  "type-check": "tsc --noEmit",
51
51
  "type-check:watch": "tsc --noEmit --watch",
52
52
  "commit": "cz",
@@ -1,4 +1,4 @@
1
- import { type IContainer } from '../container/IContainer';
1
+ import { DependencyKey, type IContainer } from '../container/IContainer';
2
2
  import { type CreateHookContext, createHookContext, type IHookContext, type InjectFn } from './HookContext';
3
3
  import { type constructor } from '../utils';
4
4
  import { type IInjectFnResolver } from '../injector/IInjector';
@@ -21,7 +21,7 @@ export declare const runHooksAsync: (target: object, key: string | symbol, { sco
21
21
  createContext?: typeof createHookContext;
22
22
  predicate?: (methodName: string) => boolean;
23
23
  }) => Promise<void[]>;
24
- export declare const injectProp: (fn: InjectFn | IInjectFnResolver<unknown>) => HookFn;
24
+ export declare const injectProp: (fn: InjectFn | IInjectFnResolver<unknown> | DependencyKey | constructor<unknown>) => HookFn;
25
25
  export declare const onConstruct: (fn: HookFn) => (target: object, propertyKey: string | symbol) => void;
26
26
  export declare const runOnConstructHooks: (target: object, scope: IContainer) => void;
27
27
  export declare const onDispose: (target: object, propertyKey: string | symbol) => void;
@@ -7,7 +7,7 @@ export { type IInjector, type InjectOptions } from './injector/IInjector';
7
7
  export { MetadataInjector } from './injector/MetadataInjector';
8
8
  export { SimpleInjector } from './injector/SimpleInjector';
9
9
  export { ProxyInjector } from './injector/ProxyInjector';
10
- export { type ResolveDependency, type IProvider, scopeAccess, argsFn, args, type ArgsFn, ProviderDecorator, type ProviderResolveOptions, type IMapper, } from './provider/IProvider';
10
+ export { type ResolveDependency, type IProvider, scopeAccess, lazy, argsFn, args, type ArgsFn, ProviderDecorator, type ProviderResolveOptions, type IMapper, } from './provider/IProvider';
11
11
  export { Provider } from './provider/Provider';
12
12
  export { singleton, SingletonProvider } from './provider/SingletonProvider';
13
13
  export { type Cache, multiCache, MultiCache } from './provider/Cache';
@@ -1,8 +1,7 @@
1
1
  import { type constructor } from '../utils';
2
- import { type IContainer } from '../container/IContainer';
2
+ import { DependencyKey, type IContainer } from '../container/IContainer';
3
3
  import { type InjectFn } from '../hooks/HookContext';
4
- import { type DepKey } from '../DepKey';
5
4
  import { type IInjectFnResolver } from './IInjector';
6
- export declare const inject: <T>(fn: InjectFn<T> | DepKey<T> | IInjectFnResolver<T>) => ParameterDecorator;
7
- export declare const toInjectFn: <T>(fn: InjectFn<T> | IInjectFnResolver<T>) => InjectFn<T>;
5
+ export declare const inject: <T>(fn: InjectFn<T> | IInjectFnResolver<T> | DependencyKey | constructor<T>) => ParameterDecorator;
6
+ export declare const toInjectFn: <T>(target: InjectFn<T> | IInjectFnResolver<T> | DependencyKey | constructor<T>) => InjectFn<T>;
8
7
  export declare const resolveArgs: (Target: constructor<unknown>, methodName?: string) => (scope: IContainer, ...deps: unknown[]) => unknown[];
@@ -21,10 +21,12 @@ export interface IProvider<T = any> {
21
21
  pipe(...mappers: (MapFn<IProvider<T>> | ProviderPipe<T>)[]): IProvider<T>;
22
22
  setAccessPredicate(hasAccessWhen: ScopeAccessFn): this;
23
23
  setArgs(argsFn: ArgsFn): this;
24
+ lazy(): this;
24
25
  }
25
26
  export declare const args: <T>(...extraArgs: unknown[]) => ProviderPipe<T>;
26
27
  export declare const argsFn: <T>(fn: ArgsFn) => ProviderPipe<T>;
27
28
  export declare const scopeAccess: <T>(predicate: ScopeAccessFn) => ProviderPipe<T>;
29
+ export declare const lazy: <T>() => ProviderPipe<T>;
28
30
  export declare abstract class ProviderDecorator<T> implements IProvider<T> {
29
31
  private decorated;
30
32
  protected constructor(decorated: IProvider<T>);
@@ -33,4 +35,5 @@ export declare abstract class ProviderDecorator<T> implements IProvider<T> {
33
35
  resolve(container: IContainer, options: ProviderResolveOptions): T;
34
36
  pipe(...mappers: (MapFn<IProvider<T>> | ProviderPipe<T>)[]): IProvider<T>;
35
37
  setArgs(argsFn: ArgsFn): this;
38
+ lazy(): this;
36
39
  }
@@ -9,10 +9,12 @@ export declare class Provider<T = any> implements IProvider<T> {
9
9
  static fromKey<T>(key: DependencyKey): Provider<T>;
10
10
  private argsFn;
11
11
  private checkAccess;
12
+ private isLazy;
12
13
  constructor(resolveDependency: ResolveDependency<T>);
13
14
  pipe(...mappers: (MapFn<IProvider<T>> | ProviderPipe<T>)[]): IProvider<T>;
14
- resolve(container: IContainer, { args, lazy: isLazy }: ProviderResolveOptions): T;
15
+ resolve(container: IContainer, { args, lazy }: ProviderResolveOptions): T;
15
16
  setAccessPredicate(predicate: ScopeAccessFn): this;
17
+ lazy(): this;
16
18
  setArgs(argsFn: ArgsFn): this;
17
19
  hasAccess(options: ScopeAccessOptions): boolean;
18
20
  }