ts-ioc-container 46.8.1 → 46.9.1
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/cjm/container/Container.js +1 -1
- package/cjm/hooks/HookContext.js +10 -4
- package/cjm/hooks/hook.js +10 -2
- package/cjm/injector/IInjector.js +1 -0
- package/cjm/utils/proxy.js +23 -3
- package/esm/container/Container.js +1 -1
- package/esm/hooks/HookContext.js +10 -4
- package/esm/hooks/hook.js +10 -2
- package/esm/injector/IInjector.js +1 -0
- package/esm/utils/proxy.js +21 -3
- package/package.json +50 -12
- package/typings/hooks/HookContext.d.ts +6 -3
- package/typings/utils/proxy.d.ts +4 -2
|
@@ -63,7 +63,7 @@ class Container {
|
|
|
63
63
|
}
|
|
64
64
|
resolveOneByAlias(alias, { args, child = this, lazy } = {}) {
|
|
65
65
|
this.validateContainer();
|
|
66
|
-
const key = this.aliases.getKeysByAlias(alias)
|
|
66
|
+
const [key, ..._] = this.aliases.getKeysByAlias(alias);
|
|
67
67
|
const provider = key ? this.findProviderByKeyOrFail(key) : undefined;
|
|
68
68
|
return provider?.hasAccess({ invocationScope: child, providerScope: this })
|
|
69
69
|
? provider.resolve(this, { args, lazy })
|
package/cjm/hooks/HookContext.js
CHANGED
|
@@ -2,19 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createHookContext = exports.HookContext = void 0;
|
|
4
4
|
const inject_1 = require("../injector/inject");
|
|
5
|
+
const proxy_1 = require("../utils/proxy");
|
|
5
6
|
class HookContext {
|
|
6
|
-
instance;
|
|
7
7
|
scope;
|
|
8
8
|
methodName;
|
|
9
|
+
instance;
|
|
10
|
+
initialArgs = [];
|
|
9
11
|
constructor(instance, scope, methodName) {
|
|
10
|
-
this.instance = instance;
|
|
11
12
|
this.scope = scope;
|
|
12
13
|
this.methodName = methodName;
|
|
14
|
+
this.instance = (0, proxy_1.isProxy)(instance) ? (0, proxy_1.getProxyTarget)(instance) : instance;
|
|
13
15
|
}
|
|
14
16
|
resolveArgs(...args) {
|
|
15
|
-
return (0, inject_1.resolveArgs)(this.instance.constructor, this.methodName)(this.scope, ...args);
|
|
17
|
+
return (0, inject_1.resolveArgs)(this.instance.constructor, this.methodName)(this.scope, ...[...this.initialArgs, ...args]);
|
|
16
18
|
}
|
|
17
|
-
invokeMethod({ args = this.resolveArgs() }) {
|
|
19
|
+
invokeMethod({ args = this.resolveArgs() } = {}) {
|
|
18
20
|
// @ts-ignore
|
|
19
21
|
return this.instance[this.methodName](...args);
|
|
20
22
|
}
|
|
@@ -22,6 +24,10 @@ class HookContext {
|
|
|
22
24
|
// @ts-ignore
|
|
23
25
|
this.instance[this.methodName] = fn.resolve(this.scope);
|
|
24
26
|
}
|
|
27
|
+
setInitialArgs(...args) {
|
|
28
|
+
this.initialArgs = args;
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
25
31
|
}
|
|
26
32
|
exports.HookContext = HookContext;
|
|
27
33
|
const createHookContext = (Target, scope, methodName = 'constructor') => new HookContext(Target, scope, methodName);
|
package/cjm/hooks/hook.js
CHANGED
|
@@ -4,17 +4,25 @@ exports.hook = exports.toHookFn = void 0;
|
|
|
4
4
|
exports.getHooks = getHooks;
|
|
5
5
|
exports.hasHooks = hasHooks;
|
|
6
6
|
const basic_1 = require("../utils/basic");
|
|
7
|
+
const proxy_1 = require("../utils/proxy");
|
|
7
8
|
const isHookClassConstructor = (execute) => {
|
|
8
9
|
return basic_1.Is.constructor(execute) && execute.prototype.execute;
|
|
9
10
|
};
|
|
10
11
|
const toHookFn = (execute) => isHookClassConstructor(execute) ? (context) => context.scope.resolve(execute).execute(context) : execute;
|
|
11
12
|
exports.toHookFn = toHookFn;
|
|
13
|
+
const getReflectionTarget = (target) => {
|
|
14
|
+
return (0, proxy_1.isProxy)(target) ? (0, proxy_1.getProxyTarget)(target) : target;
|
|
15
|
+
};
|
|
12
16
|
// Get hooks metadata
|
|
13
17
|
function getHooks(target, key) {
|
|
14
|
-
|
|
18
|
+
const reflectionTarget = getReflectionTarget(target);
|
|
19
|
+
return Reflect.hasMetadata(key, reflectionTarget.constructor)
|
|
20
|
+
? Reflect.getMetadata(key, reflectionTarget.constructor)
|
|
21
|
+
: new Map();
|
|
15
22
|
}
|
|
16
23
|
function hasHooks(target, key) {
|
|
17
|
-
|
|
24
|
+
const reflectionTarget = getReflectionTarget(target);
|
|
25
|
+
return Reflect.hasMetadata(key, reflectionTarget.constructor);
|
|
18
26
|
}
|
|
19
27
|
// Hook decorator
|
|
20
28
|
const hook = (key, ...fns) => (target, propertyKey) => {
|
|
@@ -4,6 +4,7 @@ exports.Injector = void 0;
|
|
|
4
4
|
const proxy_1 = require("../utils/proxy");
|
|
5
5
|
class Injector {
|
|
6
6
|
resolve(scope, Target, { args, lazy } = {}) {
|
|
7
|
+
// @ts-ignore
|
|
7
8
|
return (0, proxy_1.toLazyIf)(() => {
|
|
8
9
|
const instance = this.createInstance(scope, Target, { args });
|
|
9
10
|
scope.addInstance(instance);
|
package/cjm/utils/proxy.js
CHANGED
|
@@ -1,16 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isProxy = isProxy;
|
|
4
|
+
exports.getProxyTarget = getProxyTarget;
|
|
3
5
|
exports.lazyProxy = lazyProxy;
|
|
4
6
|
exports.toLazyIf = toLazyIf;
|
|
7
|
+
const proxyStateMap = new WeakMap();
|
|
8
|
+
const unwrapProxyTarget = (value) => {
|
|
9
|
+
return isProxy(value) ? getProxyTarget(value) : value;
|
|
10
|
+
};
|
|
11
|
+
function isProxy(value) {
|
|
12
|
+
return proxyStateMap.has(value);
|
|
13
|
+
}
|
|
14
|
+
function getProxyTarget(value) {
|
|
15
|
+
return proxyStateMap.get(value).getTarget();
|
|
16
|
+
}
|
|
5
17
|
function lazyProxy(resolveInstance) {
|
|
6
18
|
let instance;
|
|
7
|
-
|
|
19
|
+
const state = {
|
|
20
|
+
getTarget: () => {
|
|
21
|
+
instance = instance ?? unwrapProxyTarget(resolveInstance());
|
|
22
|
+
return instance;
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
const proxy = new Proxy({}, {
|
|
8
26
|
get: (_, prop) => {
|
|
9
|
-
|
|
27
|
+
const target = state.getTarget();
|
|
10
28
|
// @ts-ignore
|
|
11
|
-
return
|
|
29
|
+
return target[prop];
|
|
12
30
|
},
|
|
13
31
|
});
|
|
32
|
+
proxyStateMap.set(proxy, state);
|
|
33
|
+
return proxy;
|
|
14
34
|
}
|
|
15
35
|
function toLazyIf(resolveInstance, isLazy = false) {
|
|
16
36
|
if (isLazy) {
|
|
@@ -60,7 +60,7 @@ export class Container {
|
|
|
60
60
|
}
|
|
61
61
|
resolveOneByAlias(alias, { args, child = this, lazy } = {}) {
|
|
62
62
|
this.validateContainer();
|
|
63
|
-
const key = this.aliases.getKeysByAlias(alias)
|
|
63
|
+
const [key, ..._] = this.aliases.getKeysByAlias(alias);
|
|
64
64
|
const provider = key ? this.findProviderByKeyOrFail(key) : undefined;
|
|
65
65
|
return provider?.hasAccess({ invocationScope: child, providerScope: this })
|
|
66
66
|
? provider.resolve(this, { args, lazy })
|
package/esm/hooks/HookContext.js
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
import { resolveArgs } from '../injector/inject';
|
|
2
|
+
import { getProxyTarget, isProxy } from '../utils/proxy';
|
|
2
3
|
export class HookContext {
|
|
3
|
-
instance;
|
|
4
4
|
scope;
|
|
5
5
|
methodName;
|
|
6
|
+
instance;
|
|
7
|
+
initialArgs = [];
|
|
6
8
|
constructor(instance, scope, methodName) {
|
|
7
|
-
this.instance = instance;
|
|
8
9
|
this.scope = scope;
|
|
9
10
|
this.methodName = methodName;
|
|
11
|
+
this.instance = isProxy(instance) ? getProxyTarget(instance) : instance;
|
|
10
12
|
}
|
|
11
13
|
resolveArgs(...args) {
|
|
12
|
-
return resolveArgs(this.instance.constructor, this.methodName)(this.scope, ...args);
|
|
14
|
+
return resolveArgs(this.instance.constructor, this.methodName)(this.scope, ...[...this.initialArgs, ...args]);
|
|
13
15
|
}
|
|
14
|
-
invokeMethod({ args = this.resolveArgs() }) {
|
|
16
|
+
invokeMethod({ args = this.resolveArgs() } = {}) {
|
|
15
17
|
// @ts-ignore
|
|
16
18
|
return this.instance[this.methodName](...args);
|
|
17
19
|
}
|
|
@@ -19,5 +21,9 @@ export class HookContext {
|
|
|
19
21
|
// @ts-ignore
|
|
20
22
|
this.instance[this.methodName] = fn.resolve(this.scope);
|
|
21
23
|
}
|
|
24
|
+
setInitialArgs(...args) {
|
|
25
|
+
this.initialArgs = args;
|
|
26
|
+
return this;
|
|
27
|
+
}
|
|
22
28
|
}
|
|
23
29
|
export const createHookContext = (Target, scope, methodName = 'constructor') => new HookContext(Target, scope, methodName);
|
package/esm/hooks/hook.js
CHANGED
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import { Is } from '../utils/basic';
|
|
2
|
+
import { getProxyTarget, isProxy } from '../utils/proxy';
|
|
2
3
|
const isHookClassConstructor = (execute) => {
|
|
3
4
|
return Is.constructor(execute) && execute.prototype.execute;
|
|
4
5
|
};
|
|
5
6
|
export const toHookFn = (execute) => isHookClassConstructor(execute) ? (context) => context.scope.resolve(execute).execute(context) : execute;
|
|
7
|
+
const getReflectionTarget = (target) => {
|
|
8
|
+
return isProxy(target) ? getProxyTarget(target) : target;
|
|
9
|
+
};
|
|
6
10
|
// Get hooks metadata
|
|
7
11
|
export function getHooks(target, key) {
|
|
8
|
-
|
|
12
|
+
const reflectionTarget = getReflectionTarget(target);
|
|
13
|
+
return Reflect.hasMetadata(key, reflectionTarget.constructor)
|
|
14
|
+
? Reflect.getMetadata(key, reflectionTarget.constructor)
|
|
15
|
+
: new Map();
|
|
9
16
|
}
|
|
10
17
|
export function hasHooks(target, key) {
|
|
11
|
-
|
|
18
|
+
const reflectionTarget = getReflectionTarget(target);
|
|
19
|
+
return Reflect.hasMetadata(key, reflectionTarget.constructor);
|
|
12
20
|
}
|
|
13
21
|
// Hook decorator
|
|
14
22
|
export const hook = (key, ...fns) => (target, propertyKey) => {
|
package/esm/utils/proxy.js
CHANGED
|
@@ -1,12 +1,30 @@
|
|
|
1
|
+
const proxyStateMap = new WeakMap();
|
|
2
|
+
const unwrapProxyTarget = (value) => {
|
|
3
|
+
return isProxy(value) ? getProxyTarget(value) : value;
|
|
4
|
+
};
|
|
5
|
+
export function isProxy(value) {
|
|
6
|
+
return proxyStateMap.has(value);
|
|
7
|
+
}
|
|
8
|
+
export function getProxyTarget(value) {
|
|
9
|
+
return proxyStateMap.get(value).getTarget();
|
|
10
|
+
}
|
|
1
11
|
export function lazyProxy(resolveInstance) {
|
|
2
12
|
let instance;
|
|
3
|
-
|
|
13
|
+
const state = {
|
|
14
|
+
getTarget: () => {
|
|
15
|
+
instance = instance ?? unwrapProxyTarget(resolveInstance());
|
|
16
|
+
return instance;
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
const proxy = new Proxy({}, {
|
|
4
20
|
get: (_, prop) => {
|
|
5
|
-
|
|
21
|
+
const target = state.getTarget();
|
|
6
22
|
// @ts-ignore
|
|
7
|
-
return
|
|
23
|
+
return target[prop];
|
|
8
24
|
},
|
|
9
25
|
});
|
|
26
|
+
proxyStateMap.set(proxy, state);
|
|
27
|
+
return proxy;
|
|
10
28
|
}
|
|
11
29
|
export function toLazyIf(resolveInstance, isLazy = false) {
|
|
12
30
|
if (isLazy) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-ioc-container",
|
|
3
|
-
"version": "46.
|
|
3
|
+
"version": "46.9.1",
|
|
4
4
|
"description": "Typescript IoC container",
|
|
5
|
+
"workspaces": [
|
|
6
|
+
"docs"
|
|
7
|
+
],
|
|
5
8
|
"publishConfig": {
|
|
6
9
|
"access": "public",
|
|
7
10
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -35,39 +38,74 @@
|
|
|
35
38
|
],
|
|
36
39
|
"repository": {
|
|
37
40
|
"type": "git",
|
|
38
|
-
"url": "git+https://github.com/IgorBabkin/ts-ioc-container"
|
|
39
|
-
"directory": "packages/ts-ioc-container"
|
|
41
|
+
"url": "git+https://github.com/IgorBabkin/ts-ioc-container"
|
|
40
42
|
},
|
|
41
43
|
"scripts": {
|
|
42
44
|
"build:cjm": "rimraf cjm && tsc -p tsconfig.production.json --outDir cjm --module CommonJS",
|
|
43
45
|
"build:esm": "rimraf esm && tsc -p tsconfig.production.json --outDir esm",
|
|
44
46
|
"build:types": "rimraf typings && tsc -p tsconfig.production.json --outDir typings --emitDeclarationOnly --declaration",
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"test
|
|
47
|
+
"generate:docs": "scripts/generate-readme/generate-readme.ts && git add README.md",
|
|
48
|
+
"build": "npm run build:cjm && npm run build:esm && npm run build:types",
|
|
49
|
+
"test": "jest",
|
|
50
|
+
"test:coverage": "jest --coverage --coverageReporters=lcov --coverageReporters=text-summary",
|
|
48
51
|
"type-check": "tsc --noEmit",
|
|
49
52
|
"type-check:watch": "tsc --noEmit --watch",
|
|
50
|
-
"
|
|
51
|
-
"lint:fix": "pnpm run lint -- --fix",
|
|
53
|
+
"commit": "cz",
|
|
52
54
|
"format": "prettier --write \"**/*.ts\"",
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
+
"lint": "eslint lib/**/*.ts __tests__/**/*.ts scripts/**/*.ts",
|
|
56
|
+
"lint:fix": "npm run lint --fix",
|
|
57
|
+
"audit": "npm audit",
|
|
58
|
+
"prepare": "husky",
|
|
59
|
+
"release": "npm run build && npm test && npm publish",
|
|
60
|
+
"docs:dev": "pnpm --filter ts-ioc-container-docs run dev",
|
|
61
|
+
"docs:serve": "pnpm --filter ts-ioc-container-docs run dev",
|
|
62
|
+
"docs:build": "pnpm --filter ts-ioc-container-docs run build",
|
|
63
|
+
"docs:preview": "pnpm --filter ts-ioc-container-docs run preview"
|
|
55
64
|
},
|
|
56
65
|
"devDependencies": {
|
|
66
|
+
"@commitlint/cli": "^20.2.0",
|
|
67
|
+
"@commitlint/config-conventional": "^20.2.0",
|
|
68
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
69
|
+
"@semantic-release/git": "^10.0.1",
|
|
70
|
+
"@semantic-release/github": "^12.0.2",
|
|
71
|
+
"@semantic-release/npm": "^13.1.2",
|
|
57
72
|
"@types/jest": "29.5.14",
|
|
58
|
-
"@types/node": "^25.1.0",
|
|
59
73
|
"@typescript-eslint/eslint-plugin": "8.29.1",
|
|
60
74
|
"@typescript-eslint/parser": "8.29.1",
|
|
75
|
+
"cz-conventional-changelog": "^3.3.0",
|
|
61
76
|
"eslint": "9.24.0",
|
|
62
77
|
"eslint-config-prettier": "10.1.1",
|
|
63
78
|
"eslint-plugin-prettier": "5.2.6",
|
|
64
79
|
"handlebars": "^4.7.8",
|
|
80
|
+
"husky": "^9.1.7",
|
|
65
81
|
"jest": "29.7.0",
|
|
82
|
+
"lint-staged": "^15.5.0",
|
|
66
83
|
"moq.ts": "^7.4.1",
|
|
67
84
|
"prettier": "3.5.3",
|
|
85
|
+
"prettier-plugin-astro": "^0.14.1",
|
|
68
86
|
"reflect-metadata": "^0.2.2",
|
|
69
87
|
"rimraf": "6.0.1",
|
|
88
|
+
"semantic-release": "^25.0.2",
|
|
70
89
|
"ts-jest": "29.3.1",
|
|
71
90
|
"typescript": "5.8.3"
|
|
72
|
-
}
|
|
91
|
+
},
|
|
92
|
+
"lint-staged": {
|
|
93
|
+
"*.{js,ts,tsx}": [
|
|
94
|
+
"eslint --fix",
|
|
95
|
+
"prettier --write"
|
|
96
|
+
],
|
|
97
|
+
"docs/**/*.{js,ts,tsx,mjs,astro}": [
|
|
98
|
+
"prettier --write"
|
|
99
|
+
],
|
|
100
|
+
"docs/**/*.astro": [
|
|
101
|
+
"eslint --fix"
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
"gitHead": "ae10f302c7e0f55196b42669040735112479a854",
|
|
105
|
+
"config": {
|
|
106
|
+
"commitizen": {
|
|
107
|
+
"path": "./node_modules/cz-conventional-changelog"
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"packageManager": "pnpm@10.20.0+sha512.cf9998222162dd85864d0a8102e7892e7ba4ceadebbf5a31f9c2fce48dfce317a9c53b9f6464d1ef9042cba2e02ae02a9f7c143a2b438cd93c91840f0192b9dd"
|
|
73
111
|
}
|
|
@@ -5,21 +5,24 @@ export interface IHookContext {
|
|
|
5
5
|
scope: IContainer;
|
|
6
6
|
methodName?: string;
|
|
7
7
|
resolveArgs(...args: unknown[]): unknown[];
|
|
8
|
-
invokeMethod(
|
|
8
|
+
invokeMethod(options?: {
|
|
9
9
|
args?: unknown[];
|
|
10
10
|
}): unknown;
|
|
11
11
|
setProperty(fn: InjectionToken): void;
|
|
12
|
+
setInitialArgs(...args: unknown[]): this;
|
|
12
13
|
}
|
|
13
14
|
export declare class HookContext implements IHookContext {
|
|
14
|
-
instance: object;
|
|
15
15
|
scope: IContainer;
|
|
16
16
|
methodName?: string | undefined;
|
|
17
|
+
readonly instance: object;
|
|
18
|
+
private initialArgs;
|
|
17
19
|
constructor(instance: object, scope: IContainer, methodName?: string | undefined);
|
|
18
20
|
resolveArgs(...args: unknown[]): unknown[];
|
|
19
|
-
invokeMethod({ args }
|
|
21
|
+
invokeMethod({ args }?: {
|
|
20
22
|
args?: unknown[];
|
|
21
23
|
}): unknown;
|
|
22
24
|
setProperty(fn: InjectionToken): void;
|
|
25
|
+
setInitialArgs(...args: unknown[]): this;
|
|
23
26
|
}
|
|
24
27
|
export type CreateHookContext = (Target: object, scope: IContainer, methodName?: string) => IHookContext;
|
|
25
28
|
export declare const createHookContext: CreateHookContext;
|
package/typings/utils/proxy.d.ts
CHANGED
|
@@ -1,2 +1,4 @@
|
|
|
1
|
-
export declare function
|
|
2
|
-
export declare function
|
|
1
|
+
export declare function isProxy(value: object): boolean;
|
|
2
|
+
export declare function getProxyTarget<T extends object>(value: T): T;
|
|
3
|
+
export declare function lazyProxy<T extends object>(resolveInstance: () => T): T;
|
|
4
|
+
export declare function toLazyIf<T extends object>(resolveInstance: () => T, isLazy?: boolean): T;
|