ts-ioc-container 33.2.0 → 33.4.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
@@ -1083,6 +1083,17 @@ describe('Registration module', function () {
1083
1083
 
1084
1084
  expect(root.resolve('FileLogger')).toBeInstanceOf(FileLogger);
1085
1085
  });
1086
+
1087
+ it('should assign additional key which redirects to original one', function () {
1088
+ @register(key('ILogger', 'Logger'))
1089
+ @provider(singleton())
1090
+ class Logger {}
1091
+
1092
+ const root = createContainer().add(R.fromClass(Logger));
1093
+
1094
+ expect(root.resolve('Logger')).toBeInstanceOf(Logger);
1095
+ expect(root.resolve('Logger')).toBe(root.resolve('ILogger'));
1096
+ });
1086
1097
  });
1087
1098
 
1088
1099
  ```
package/cjm/hooks/hook.js CHANGED
@@ -3,6 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.injectProp = exports.runHooksAsync = exports.runHooks = exports.hasHooks = exports.getHooks = exports.hook = void 0;
4
4
  const HookContext_1 = require("./HookContext");
5
5
  const utils_1 = require("../utils");
6
+ const isHookClassConstructor = (execute) => {
7
+ return (0, utils_1.isConstructor)(execute) && execute.prototype.execute;
8
+ };
6
9
  const hook = (key, ...fns) => (target, propertyKey) => {
7
10
  const hooks = Reflect.hasMetadata(key, target.constructor)
8
11
  ? Reflect.getMetadata(key, target.constructor)
@@ -23,14 +26,22 @@ const runHooks = (target, key, { scope, createContext = HookContext_1.createHook
23
26
  const hooks = Array.from(getHooks(target, key).entries()).filter(([methodName]) => predicate(methodName));
24
27
  for (const [methodName, executions] of hooks) {
25
28
  for (const execute of executions) {
26
- execute(createContext(target, scope, methodName));
29
+ const context = createContext(target, scope, methodName);
30
+ if (isHookClassConstructor(execute)) {
31
+ scope.resolve(execute).execute(context);
32
+ }
33
+ else {
34
+ execute(context);
35
+ }
27
36
  }
28
37
  }
29
38
  };
30
39
  exports.runHooks = runHooks;
31
40
  const runHooksAsync = (target, key, { scope, createContext = HookContext_1.createHookContext, predicate = () => true, }) => {
32
41
  const hooks = Array.from(getHooks(target, key).entries()).filter(([methodName]) => predicate(methodName));
33
- const runExecution = (execute, context) => (0, utils_1.promisify)(execute(context));
42
+ const runExecution = (execute, context) => isHookClassConstructor(execute)
43
+ ? (0, utils_1.promisify)(context.scope.resolve(execute).execute(context))
44
+ : (0, utils_1.promisify)(execute(context));
34
45
  return Promise.all(hooks.flatMap(([methodName, executions]) => {
35
46
  const context = createContext(target, scope, methodName);
36
47
  return executions.map((execute) => runExecution(execute, context));
@@ -2,7 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.register = exports.getTransformers = exports.scope = exports.key = void 0;
4
4
  const metadata_1 = require("../metadata");
5
- const key = (key) => (r) => r.to(key);
5
+ const key = (...keys) => (r) => {
6
+ const [originalKey, ...redirectKeys] = keys;
7
+ let registration = r.to(originalKey);
8
+ for (const key of redirectKeys) {
9
+ registration = registration.redirectFrom(key);
10
+ }
11
+ return registration;
12
+ };
6
13
  exports.key = key;
7
14
  const scope = (predicate) => (r) => r.when(predicate);
8
15
  exports.scope = scope;
@@ -24,12 +24,17 @@ class Registration {
24
24
  this.createProvider = createProvider;
25
25
  this.key = key;
26
26
  this.matchScope = matchScope;
27
+ this.redirectKeys = new Set();
27
28
  this.mappers = [];
28
29
  }
29
30
  to(key) {
30
31
  this.key = key;
31
32
  return this;
32
33
  }
34
+ redirectFrom(key) {
35
+ this.redirectKeys.add(key);
36
+ return this;
37
+ }
33
38
  pipe(...mappers) {
34
39
  this.mappers.push(...mappers);
35
40
  return this;
@@ -45,7 +50,11 @@ class Registration {
45
50
  if (!this.key) {
46
51
  throw new DependencyMissingKeyError_1.DependencyMissingKeyError('No key provided for registration');
47
52
  }
48
- container.register(this.key, this.createProvider(this.key).pipe(...this.mappers));
53
+ const key = this.key;
54
+ container.register(key, this.createProvider(key).pipe(...this.mappers));
55
+ for (const redirectKey of this.redirectKeys) {
56
+ container.register(redirectKey, new Provider_1.Provider((s) => s.resolve(key)));
57
+ }
49
58
  }
50
59
  }
51
60
  exports.Registration = Registration;
package/esm/hooks/hook.js CHANGED
@@ -1,5 +1,8 @@
1
1
  import { createHookContext } from './HookContext';
2
- import { promisify } from '../utils';
2
+ import { isConstructor, promisify } from '../utils';
3
+ const isHookClassConstructor = (execute) => {
4
+ return isConstructor(execute) && execute.prototype.execute;
5
+ };
3
6
  export const hook = (key, ...fns) => (target, propertyKey) => {
4
7
  const hooks = Reflect.hasMetadata(key, target.constructor)
5
8
  ? Reflect.getMetadata(key, target.constructor)
@@ -17,13 +20,21 @@ export const runHooks = (target, key, { scope, createContext = createHookContext
17
20
  const hooks = Array.from(getHooks(target, key).entries()).filter(([methodName]) => predicate(methodName));
18
21
  for (const [methodName, executions] of hooks) {
19
22
  for (const execute of executions) {
20
- execute(createContext(target, scope, methodName));
23
+ const context = createContext(target, scope, methodName);
24
+ if (isHookClassConstructor(execute)) {
25
+ scope.resolve(execute).execute(context);
26
+ }
27
+ else {
28
+ execute(context);
29
+ }
21
30
  }
22
31
  }
23
32
  };
24
33
  export const runHooksAsync = (target, key, { scope, createContext = createHookContext, predicate = () => true, }) => {
25
34
  const hooks = Array.from(getHooks(target, key).entries()).filter(([methodName]) => predicate(methodName));
26
- const runExecution = (execute, context) => promisify(execute(context));
35
+ const runExecution = (execute, context) => isHookClassConstructor(execute)
36
+ ? promisify(context.scope.resolve(execute).execute(context))
37
+ : promisify(execute(context));
27
38
  return Promise.all(hooks.flatMap(([methodName, executions]) => {
28
39
  const context = createContext(target, scope, methodName);
29
40
  return executions.map((execute) => runExecution(execute, context));
@@ -1,5 +1,12 @@
1
1
  import { getMetadata, setMetadata } from '../metadata';
2
- export const key = (key) => (r) => r.to(key);
2
+ export const key = (...keys) => (r) => {
3
+ const [originalKey, ...redirectKeys] = keys;
4
+ let registration = r.to(originalKey);
5
+ for (const key of redirectKeys) {
6
+ registration = registration.redirectFrom(key);
7
+ }
8
+ return registration;
9
+ };
3
10
  export const scope = (predicate) => (r) => r.when(predicate);
4
11
  const METADATA_KEY = 'registration';
5
12
  export const getTransformers = (Target) => getMetadata(Target, METADATA_KEY) ?? [];
@@ -21,12 +21,17 @@ export class Registration {
21
21
  this.createProvider = createProvider;
22
22
  this.key = key;
23
23
  this.matchScope = matchScope;
24
+ this.redirectKeys = new Set();
24
25
  this.mappers = [];
25
26
  }
26
27
  to(key) {
27
28
  this.key = key;
28
29
  return this;
29
30
  }
31
+ redirectFrom(key) {
32
+ this.redirectKeys.add(key);
33
+ return this;
34
+ }
30
35
  pipe(...mappers) {
31
36
  this.mappers.push(...mappers);
32
37
  return this;
@@ -42,6 +47,10 @@ export class Registration {
42
47
  if (!this.key) {
43
48
  throw new DependencyMissingKeyError('No key provided for registration');
44
49
  }
45
- container.register(this.key, this.createProvider(this.key).pipe(...this.mappers));
50
+ const key = this.key;
51
+ container.register(key, this.createProvider(key).pipe(...this.mappers));
52
+ for (const redirectKey of this.redirectKeys) {
53
+ container.register(redirectKey, new Provider((s) => s.resolve(key)));
54
+ }
46
55
  }
47
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "33.2.0",
3
+ "version": "33.4.0",
4
4
  "description": "Typescript IoC container",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -59,5 +59,5 @@
59
59
  "ts-node": "^10.9.1",
60
60
  "typescript": "5.4.3"
61
61
  },
62
- "gitHead": "f012d80a2d1e681d4babb127e35c6584620773d3"
62
+ "gitHead": "11b2d0ad78a1b6a6e800c94ac9439f6275c95342"
63
63
  }
@@ -23,5 +23,6 @@ export declare class HookContext implements IHookContext {
23
23
  setProperty(fn: InjectFn): void;
24
24
  getProperty(): unknown;
25
25
  }
26
- export declare const createHookContext: (Target: object, scope: IContainer, methodName?: string) => IHookContext;
26
+ export type CreateHookContext = (Target: object, scope: IContainer, methodName?: string) => IHookContext;
27
+ export declare const createHookContext: CreateHookContext;
27
28
  export declare const hookMetaKey: (methodName?: string) => string;
@@ -1,19 +1,23 @@
1
1
  import { IContainer } from '../container/IContainer';
2
- import { createHookContext, IHookContext, InjectFn } from './HookContext';
3
- export type Hook<T extends IHookContext = IHookContext> = (context: T) => void | Promise<void>;
4
- type HooksOfClass = Map<string, Hook[]>;
5
- export declare const hook: (key: string | symbol, ...fns: Hook[]) => (target: object, propertyKey: string | symbol) => void;
2
+ import { CreateHookContext, createHookContext, IHookContext, InjectFn } from './HookContext';
3
+ import { constructor } from '../utils';
4
+ export type HookFn<T extends IHookContext = IHookContext> = (context: T) => void | Promise<void>;
5
+ export interface HookClass<T extends IHookContext = IHookContext> {
6
+ execute(context: Omit<T, 'scope'>): void | Promise<void>;
7
+ }
8
+ type HooksOfClass = Map<string, (HookFn | constructor<HookClass>)[]>;
9
+ export declare const hook: (key: string | symbol, ...fns: (HookFn | constructor<HookClass>)[]) => (target: object, propertyKey: string | symbol) => void;
6
10
  export declare function getHooks(target: object, key: string | symbol): HooksOfClass;
7
11
  export declare function hasHooks(target: object, key: string | symbol): boolean;
8
12
  export declare const runHooks: (target: object, key: string | symbol, { scope, createContext, predicate, }: {
9
13
  scope: IContainer;
10
- createContext?: ((Target: object, scope: IContainer, methodName?: string) => IHookContext) | undefined;
14
+ createContext?: CreateHookContext | undefined;
11
15
  predicate?: ((methodName: string) => boolean) | undefined;
12
16
  }) => void;
13
17
  export declare const runHooksAsync: (target: object, key: string | symbol, { scope, createContext, predicate, }: {
14
18
  scope: IContainer;
15
- createContext?: ((Target: object, scope: IContainer, methodName?: string) => IHookContext) | undefined;
19
+ createContext?: CreateHookContext | undefined;
16
20
  predicate?: ((methodName: string) => boolean) | undefined;
17
21
  }) => Promise<void[]>;
18
- export declare const injectProp: (fn: InjectFn) => Hook;
22
+ export declare const injectProp: (fn: InjectFn) => HookFn;
19
23
  export {};
@@ -18,7 +18,7 @@ export { Registration } from './registration/Registration';
18
18
  export { DependencyNotFoundError } from './errors/DependencyNotFoundError';
19
19
  export { MethodNotImplementedError } from './errors/MethodNotImplementedError';
20
20
  export { ContainerDisposedError } from './errors/ContainerDisposedError';
21
- export { getHooks, hook, hasHooks, Hook, runHooks, runHooksAsync, injectProp } from './hooks/hook';
21
+ export { getHooks, hook, hasHooks, HookFn, HookClass, runHooks, runHooksAsync, injectProp } from './hooks/hook';
22
22
  export { HookContext, InjectFn, IHookContext } from './hooks/HookContext';
23
23
  export { by, InstancePredicate, IMemo, IMemoKey, byAlias, byAliases, depKey } from './by';
24
24
  export { constructor } from './utils';
@@ -6,9 +6,10 @@ export interface IRegistration<T = any> extends IContainerModule {
6
6
  when(isValidWhen: ScopePredicate): this;
7
7
  to(key: DependencyKey): this;
8
8
  pipe(...mappers: MapFn<IProvider<T>>[]): this;
9
+ redirectFrom(key: DependencyKey): this;
9
10
  }
10
11
  export type ReturnTypeOfRegistration<T> = T extends IRegistration<infer R> ? R : never;
11
- export declare const key: (key: DependencyKey) => MapFn<IRegistration>;
12
+ export declare const key: (...keys: DependencyKey[]) => MapFn<IRegistration>;
12
13
  export declare const scope: (predicate: ScopePredicate) => MapFn<IRegistration>;
13
14
  export declare const getTransformers: (Target: constructor<unknown>) => MapFn<IRegistration<any>>[];
14
15
  export declare const register: (...mappers: MapFn<IRegistration>[]) => ClassDecorator;
@@ -6,12 +6,14 @@ export declare class Registration<T = any> implements IRegistration<T> {
6
6
  private createProvider;
7
7
  private key?;
8
8
  private matchScope;
9
+ private redirectKeys;
9
10
  static fromClass<T>(Target: constructor<T>): IRegistration<any>;
10
11
  static fromValue<T>(value: T): IRegistration<any>;
11
12
  static fromFn<T>(fn: ResolveDependency<T>): Registration<T>;
12
13
  private mappers;
13
14
  constructor(createProvider: (key: DependencyKey) => IProvider<T>, key?: DependencyKey | undefined, matchScope?: ScopePredicate);
14
15
  to(key: DependencyKey): this;
16
+ redirectFrom(key: DependencyKey): this;
15
17
  pipe(...mappers: MapFn<IProvider<T>>[]): this;
16
18
  when(isValidWhen: ScopePredicate): this;
17
19
  applyTo(container: IContainer): void;