ts-ioc-container 32.0.6 → 32.1.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
@@ -1149,12 +1149,13 @@ import {
1149
1149
  Registration as R,
1150
1150
  register,
1151
1151
  } from 'ts-ioc-container';
1152
+ import { InjectOptions } from '../lib/injector/IInjector.ts';
1152
1153
 
1153
1154
  class MyInjector implements IInjector {
1154
1155
  private injector = new MetadataInjector();
1155
1156
 
1156
- resolve<T>(container: IContainer, value: constructor<T>, ...deps: unknown[]): T {
1157
- const instance = this.injector.resolve(container, value, ...deps);
1157
+ resolve<T>(container: IContainer, value: constructor<T>, options: InjectOptions): T {
1158
+ const instance = this.injector.resolve(container, value, options);
1158
1159
  // eslint-disable-next-line @typescript-eslint/ban-types
1159
1160
  for (const [h] of getHooks(instance as object, 'onConstruct')) {
1160
1161
  // @ts-ignore
@@ -1206,7 +1207,6 @@ import {
1206
1207
  MetadataInjector,
1207
1208
  register,
1208
1209
  } from 'ts-ioc-container';
1209
- import * as console from 'node:console';
1210
1210
 
1211
1211
  @register(key('logsRepo'))
1212
1212
  @provider(singleton())
@@ -1224,7 +1224,7 @@ class Logger {
1224
1224
 
1225
1225
  constructor(@inject(by.key('logsRepo')) private logsRepo: LogsRepo) {}
1226
1226
 
1227
- log(message: string): void {
1227
+ log(@inject(by.key('logsRepo')) message: string): void {
1228
1228
  this.messages.push(message);
1229
1229
  }
1230
1230
 
package/cjm/autorun.js ADDED
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startAutorun = exports.getAutorunHooks = exports.autorun = exports.AutorunContext = void 0;
4
+ const MetadataInjector_1 = require("./injector/MetadataInjector");
5
+ const METADATA_KEY = 'autorun';
6
+ class AutorunContext {
7
+ constructor(instance, methodName, scope) {
8
+ this.instance = instance;
9
+ this.methodName = methodName;
10
+ this.scope = scope;
11
+ }
12
+ resolveArgs(...args) {
13
+ return (0, MetadataInjector_1.resolveArgs)(this.instance.constructor, this.methodName)(this.scope, ...args);
14
+ }
15
+ invokeMethod({ args = this.resolveArgs() }) {
16
+ // @ts-ignore
17
+ return this.instance[this.methodName](...args);
18
+ }
19
+ }
20
+ exports.AutorunContext = AutorunContext;
21
+ const createStore = () => new Map();
22
+ const autorun = (execute) => (target, propertyKey) => {
23
+ const hooks = Reflect.hasMetadata(METADATA_KEY, target.constructor)
24
+ ? Reflect.getMetadata(METADATA_KEY, target.constructor)
25
+ : createStore();
26
+ hooks.set(propertyKey, execute);
27
+ Reflect.defineMetadata(METADATA_KEY, hooks, target.constructor);
28
+ };
29
+ exports.autorun = autorun;
30
+ const getAutorunHooks = (target) => {
31
+ return Reflect.hasMetadata(METADATA_KEY, target.constructor)
32
+ ? Reflect.getMetadata(METADATA_KEY, target.constructor)
33
+ : new Map();
34
+ };
35
+ exports.getAutorunHooks = getAutorunHooks;
36
+ const startAutorun = (target, scope, createContext = (c) => c) => {
37
+ for (const [methodName, execute] of (0, exports.getAutorunHooks)(target)) {
38
+ execute(createContext(new AutorunContext(target, methodName, scope)));
39
+ }
40
+ };
41
+ exports.startAutorun = startAutorun;
package/cjm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getParameterMetadata = exports.getMethodMetadata = exports.setMethodMetadata = exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = exports.byAliases = exports.byAlias = exports.IMemoKey = exports.by = exports.hasHooks = exports.hook = exports.getHooks = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyNotFoundError = exports.Registration = exports.register = exports.scope = exports.key = exports.decorate = exports.multiCache = exports.MultiCache = exports.SingletonProvider = exports.singleton = exports.Provider = exports.ProviderDecorator = exports.args = exports.argsFn = exports.alias = exports.visible = exports.provider = exports.ProxyInjector = exports.SimpleInjector = exports.inject = exports.MetadataInjector = exports.AutoMockedContainer = exports.EmptyContainer = exports.Container = exports.isDependencyKey = void 0;
3
+ exports.getParameterMetadata = exports.getMethodMetadata = exports.setMethodMetadata = exports.setParameterMetadata = exports.getMetadata = exports.setMetadata = exports.AutorunContext = exports.startAutorun = exports.autorun = exports.byAliases = exports.byAlias = exports.IMemoKey = exports.by = exports.hasHooks = exports.hook = exports.getHooks = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyNotFoundError = exports.Registration = exports.register = exports.scope = exports.key = exports.decorate = exports.multiCache = exports.MultiCache = exports.SingletonProvider = exports.singleton = exports.Provider = exports.ProviderDecorator = exports.args = exports.argsFn = exports.alias = exports.visible = exports.provider = exports.ProxyInjector = exports.SimpleInjector = exports.getInjectFns = exports.resolveArgs = exports.inject = exports.MetadataInjector = 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; } });
@@ -13,6 +13,8 @@ Object.defineProperty(exports, "AutoMockedContainer", { enumerable: true, get: f
13
13
  var MetadataInjector_1 = require("./injector/MetadataInjector");
14
14
  Object.defineProperty(exports, "MetadataInjector", { enumerable: true, get: function () { return MetadataInjector_1.MetadataInjector; } });
15
15
  Object.defineProperty(exports, "inject", { enumerable: true, get: function () { return MetadataInjector_1.inject; } });
16
+ Object.defineProperty(exports, "resolveArgs", { enumerable: true, get: function () { return MetadataInjector_1.resolveArgs; } });
17
+ Object.defineProperty(exports, "getInjectFns", { enumerable: true, get: function () { return MetadataInjector_1.getInjectFns; } });
16
18
  var SimpleInjector_1 = require("./injector/SimpleInjector");
17
19
  Object.defineProperty(exports, "SimpleInjector", { enumerable: true, get: function () { return SimpleInjector_1.SimpleInjector; } });
18
20
  var ProxyInjector_1 = require("./injector/ProxyInjector");
@@ -59,6 +61,10 @@ Object.defineProperty(exports, "by", { enumerable: true, get: function () { retu
59
61
  Object.defineProperty(exports, "IMemoKey", { enumerable: true, get: function () { return by_1.IMemoKey; } });
60
62
  Object.defineProperty(exports, "byAlias", { enumerable: true, get: function () { return by_1.byAlias; } });
61
63
  Object.defineProperty(exports, "byAliases", { enumerable: true, get: function () { return by_1.byAliases; } });
64
+ var autorun_1 = require("./autorun");
65
+ Object.defineProperty(exports, "autorun", { enumerable: true, get: function () { return autorun_1.autorun; } });
66
+ Object.defineProperty(exports, "startAutorun", { enumerable: true, get: function () { return autorun_1.startAutorun; } });
67
+ Object.defineProperty(exports, "AutorunContext", { enumerable: true, get: function () { return autorun_1.AutorunContext; } });
62
68
  var metadata_1 = require("./metadata");
63
69
  Object.defineProperty(exports, "setMetadata", { enumerable: true, get: function () { return metadata_1.setMetadata; } });
64
70
  Object.defineProperty(exports, "getMetadata", { enumerable: true, get: function () { return metadata_1.getMetadata; } });
@@ -1,16 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MetadataInjector = exports.inject = void 0;
3
+ exports.MetadataInjector = exports.resolveArgs = exports.inject = exports.getInjectFns = void 0;
4
4
  const utils_1 = require("../utils");
5
5
  const metadata_1 = require("../metadata");
6
6
  const METADATA_KEY = 'inject';
7
- const getInjectFns = (Target) => (0, metadata_1.getParameterMetadata)(METADATA_KEY, Target);
8
- const inject = (fn) => (0, metadata_1.setParameterMetadata)(METADATA_KEY, fn);
7
+ const getInjectFns = (Target, methodName) => (0, metadata_1.getParameterMetadata)(metaKey(methodName), Target);
8
+ exports.getInjectFns = getInjectFns;
9
+ const metaKey = (methodName = 'constructor') => `${METADATA_KEY}:${methodName}`;
10
+ const inject = (fn) => (target, propertyKey, parameterIndex) => (0, metadata_1.setParameterMetadata)(metaKey(propertyKey), fn)(target, propertyKey, parameterIndex);
9
11
  exports.inject = inject;
12
+ const resolveArgs = (Target, methodName) => {
13
+ const argsFns = (0, exports.getInjectFns)(Target, methodName);
14
+ return (scope, ...deps) => (0, utils_1.fillEmptyIndexes)(argsFns, deps.map(utils_1.constant)).map((fn) => fn(scope));
15
+ };
16
+ exports.resolveArgs = resolveArgs;
10
17
  class MetadataInjector {
11
18
  resolve(container, Target, { args: deps }) {
12
- const injectionFns = getInjectFns(Target);
13
- const args = (0, utils_1.fillEmptyIndexes)(injectionFns, deps.map(utils_1.constant)).map((fn) => fn(container));
19
+ const args = (0, exports.resolveArgs)(Target)(container, ...deps);
14
20
  return new Target(...args);
15
21
  }
16
22
  }
@@ -34,6 +34,10 @@ class Registration {
34
34
  this.mappers.push(...mappers);
35
35
  return this;
36
36
  }
37
+ when(isValidWhen) {
38
+ this.matchScope = isValidWhen;
39
+ return this;
40
+ }
37
41
  applyTo(container) {
38
42
  if (!this.matchScope(container)) {
39
43
  return;
@@ -43,9 +47,5 @@ class Registration {
43
47
  }
44
48
  container.register(this.key, this.createProvider().pipe(...this.mappers));
45
49
  }
46
- when(isValidWhen) {
47
- this.matchScope = isValidWhen;
48
- return this;
49
- }
50
50
  }
51
51
  exports.Registration = Registration;
package/esm/autorun.js ADDED
@@ -0,0 +1,34 @@
1
+ import { resolveArgs } from './injector/MetadataInjector';
2
+ const METADATA_KEY = 'autorun';
3
+ export class AutorunContext {
4
+ constructor(instance, methodName, scope) {
5
+ this.instance = instance;
6
+ this.methodName = methodName;
7
+ this.scope = scope;
8
+ }
9
+ resolveArgs(...args) {
10
+ return resolveArgs(this.instance.constructor, this.methodName)(this.scope, ...args);
11
+ }
12
+ invokeMethod({ args = this.resolveArgs() }) {
13
+ // @ts-ignore
14
+ return this.instance[this.methodName](...args);
15
+ }
16
+ }
17
+ const createStore = () => new Map();
18
+ export const autorun = (execute) => (target, propertyKey) => {
19
+ const hooks = Reflect.hasMetadata(METADATA_KEY, target.constructor)
20
+ ? Reflect.getMetadata(METADATA_KEY, target.constructor)
21
+ : createStore();
22
+ hooks.set(propertyKey, execute);
23
+ Reflect.defineMetadata(METADATA_KEY, hooks, target.constructor);
24
+ };
25
+ export const getAutorunHooks = (target) => {
26
+ return Reflect.hasMetadata(METADATA_KEY, target.constructor)
27
+ ? Reflect.getMetadata(METADATA_KEY, target.constructor)
28
+ : new Map();
29
+ };
30
+ export const startAutorun = (target, scope, createContext = (c) => c) => {
31
+ for (const [methodName, execute] of getAutorunHooks(target)) {
32
+ execute(createContext(new AutorunContext(target, methodName, scope)));
33
+ }
34
+ };
package/esm/index.js CHANGED
@@ -3,7 +3,7 @@ export { isDependencyKey, } from './container/IContainer';
3
3
  export { Container } from './container/Container';
4
4
  export { EmptyContainer } from './container/EmptyContainer';
5
5
  export { AutoMockedContainer } from './container/AutoMockedContainer';
6
- export { MetadataInjector, inject } from './injector/MetadataInjector';
6
+ export { MetadataInjector, inject, resolveArgs, getInjectFns } from './injector/MetadataInjector';
7
7
  export { SimpleInjector } from './injector/SimpleInjector';
8
8
  export { ProxyInjector } from './injector/ProxyInjector';
9
9
  // Providers
@@ -22,4 +22,5 @@ export { ContainerDisposedError } from './errors/ContainerDisposedError';
22
22
  // Others
23
23
  export { getHooks, hook, hasHooks } from './hook';
24
24
  export { by, IMemoKey, byAlias, byAliases } from './by';
25
+ export { autorun, startAutorun, AutorunContext } from './autorun';
25
26
  export { setMetadata, getMetadata, setParameterMetadata, setMethodMetadata, getMethodMetadata, getParameterMetadata, } from './metadata';
@@ -1,12 +1,16 @@
1
1
  import { constant, fillEmptyIndexes } from '../utils';
2
2
  import { setParameterMetadata, getParameterMetadata } from '../metadata';
3
3
  const METADATA_KEY = 'inject';
4
- const getInjectFns = (Target) => getParameterMetadata(METADATA_KEY, Target);
5
- export const inject = (fn) => setParameterMetadata(METADATA_KEY, fn);
4
+ export const getInjectFns = (Target, methodName) => getParameterMetadata(metaKey(methodName), Target);
5
+ const metaKey = (methodName = 'constructor') => `${METADATA_KEY}:${methodName}`;
6
+ export const inject = (fn) => (target, propertyKey, parameterIndex) => setParameterMetadata(metaKey(propertyKey), fn)(target, propertyKey, parameterIndex);
7
+ export const resolveArgs = (Target, methodName) => {
8
+ const argsFns = getInjectFns(Target, methodName);
9
+ return (scope, ...deps) => fillEmptyIndexes(argsFns, deps.map(constant)).map((fn) => fn(scope));
10
+ };
6
11
  export class MetadataInjector {
7
12
  resolve(container, Target, { args: deps }) {
8
- const injectionFns = getInjectFns(Target);
9
- const args = fillEmptyIndexes(injectionFns, deps.map(constant)).map((fn) => fn(container));
13
+ const args = resolveArgs(Target)(container, ...deps);
10
14
  return new Target(...args);
11
15
  }
12
16
  }
@@ -31,6 +31,10 @@ export class Registration {
31
31
  this.mappers.push(...mappers);
32
32
  return this;
33
33
  }
34
+ when(isValidWhen) {
35
+ this.matchScope = isValidWhen;
36
+ return this;
37
+ }
34
38
  applyTo(container) {
35
39
  if (!this.matchScope(container)) {
36
40
  return;
@@ -40,8 +44,4 @@ export class Registration {
40
44
  }
41
45
  container.register(this.key, this.createProvider().pipe(...this.mappers));
42
46
  }
43
- when(isValidWhen) {
44
- this.matchScope = isValidWhen;
45
- return this;
46
- }
47
47
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-ioc-container",
3
- "version": "32.0.6",
3
+ "version": "32.1.0",
4
4
  "description": "Typescript IoC container",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -44,20 +44,20 @@
44
44
  "generate:docs": "ts-node scripts/generateReadme/generateReadme.ts && git add README.md",
45
45
  "build": "npm run build:cjm && npm run build:esm && npm run build:types",
46
46
  "coverage": "coveralls",
47
- "watch": "nodemon --watch ./lib --exec npm run build",
48
- "test": "jest --coverage"
47
+ "test": "jest --coverage",
48
+ "type-check": "tsc --noEmit",
49
+ "type-check:watch": "tsc --noEmit --watch"
49
50
  },
50
51
  "devDependencies": {
51
52
  "@types/jest": "27.0.2",
52
53
  "handlebars": "^4.7.7",
53
54
  "jest": "27.2.3",
54
55
  "moq.ts": "^7.3.4",
55
- "nodemon": "^2.0.13",
56
56
  "reflect-metadata": "^0.2.2",
57
57
  "rimraf": "3.0.2",
58
58
  "ts-jest": "27.0.5",
59
59
  "ts-node": "^10.9.1",
60
60
  "typescript": "5.4.3"
61
61
  },
62
- "gitHead": "a653a60236b043827d7f9d61b64b8380c4e3493e"
62
+ "gitHead": "79eba3d3a19747339a7b078592f719f00c869f59"
63
63
  }
@@ -0,0 +1,16 @@
1
+ import { IContainer } from './container/IContainer';
2
+ export declare class AutorunContext {
3
+ instance: object;
4
+ methodName: string;
5
+ private scope;
6
+ constructor(instance: object, methodName: string, scope: IContainer);
7
+ resolveArgs(...args: unknown[]): unknown[];
8
+ invokeMethod({ args }: {
9
+ args: unknown[];
10
+ }): unknown;
11
+ }
12
+ type AutorunHandler = <T extends AutorunContext>(context: T) => void;
13
+ export declare const autorun: (execute: AutorunHandler) => MethodDecorator;
14
+ export declare const getAutorunHooks: (target: object) => Map<string, AutorunHandler>;
15
+ export declare const startAutorun: <Context extends AutorunContext>(target: object, scope: IContainer, createContext?: (c: AutorunContext) => Context) => void;
16
+ export {};
@@ -3,7 +3,7 @@ export { Container } from './container/Container';
3
3
  export { EmptyContainer } from './container/EmptyContainer';
4
4
  export { AutoMockedContainer } from './container/AutoMockedContainer';
5
5
  export { IInjector } from './injector/IInjector';
6
- export { MetadataInjector, inject } from './injector/MetadataInjector';
6
+ export { MetadataInjector, inject, resolveArgs, getInjectFns, InjectFn } from './injector/MetadataInjector';
7
7
  export { SimpleInjector } from './injector/SimpleInjector';
8
8
  export { ProxyInjector } from './injector/ProxyInjector';
9
9
  export { ResolveDependency, IProvider, provider, visible, alias, argsFn, args, ArgsFn, ProviderDecorator, InstantDependencyOptions, ProviderResolveOptions, } from './provider/IProvider';
@@ -20,4 +20,5 @@ export { ContainerDisposedError } from './errors/ContainerDisposedError';
20
20
  export { getHooks, hook, hasHooks } from './hook';
21
21
  export { by, InstancePredicate, IMemo, IMemoKey, byAlias, byAliases } from './by';
22
22
  export { constructor } from './utils';
23
+ export { autorun, startAutorun, AutorunContext } from './autorun';
23
24
  export { setMetadata, getMetadata, setParameterMetadata, setMethodMetadata, getMethodMetadata, getParameterMetadata, } from './metadata';
@@ -2,7 +2,9 @@ import { IInjector, InjectOptions } from './IInjector';
2
2
  import { IContainer } from '../container/IContainer';
3
3
  import { constructor } from '../utils';
4
4
  export type InjectFn<T = unknown> = (l: IContainer) => T;
5
+ export declare const getInjectFns: (Target: constructor<unknown>, methodName?: string) => InjectFn<unknown>[];
5
6
  export declare const inject: (fn: InjectFn) => ParameterDecorator;
7
+ export declare const resolveArgs: (Target: constructor<unknown>, methodName?: string) => (scope: IContainer, ...deps: unknown[]) => unknown[];
6
8
  export declare class MetadataInjector implements IInjector {
7
9
  resolve<T>(container: IContainer, Target: constructor<T>, { args: deps }: InjectOptions): T;
8
10
  }
@@ -13,6 +13,6 @@ export declare class Registration<T = unknown> implements IRegistration<T> {
13
13
  constructor(createProvider: () => IProvider<T>, key?: DependencyKey | undefined, matchScope?: ScopePredicate);
14
14
  to(key: DependencyKey): this;
15
15
  pipe(...mappers: MapFn<IProvider<T>>[]): this;
16
- applyTo(container: IContainer): void;
17
16
  when(isValidWhen: ScopePredicate): this;
17
+ applyTo(container: IContainer): void;
18
18
  }