ts-ioc-container 56.3.0 → 57.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
|
@@ -708,7 +708,7 @@ The `lazy()` registerPipe can be used in two ways: with the `@register` decorato
|
|
|
708
708
|
import 'reflect-metadata';
|
|
709
709
|
import {
|
|
710
710
|
appendArgs,
|
|
711
|
-
|
|
711
|
+
arg,
|
|
712
712
|
bindTo,
|
|
713
713
|
Container,
|
|
714
714
|
inject,
|
|
@@ -1017,8 +1017,8 @@ describe('lazy registerPipe', () => {
|
|
|
1017
1017
|
@register(bindTo('Config'))
|
|
1018
1018
|
class ConfigService {
|
|
1019
1019
|
constructor(
|
|
1020
|
-
@inject(
|
|
1021
|
-
@inject(
|
|
1020
|
+
@inject(arg(0)) public apiUrl: string,
|
|
1021
|
+
@inject(arg(1)) public timeout: number,
|
|
1022
1022
|
) {
|
|
1023
1023
|
initLog.push(`ConfigService initialized with ${apiUrl}`);
|
|
1024
1024
|
}
|
|
@@ -1391,7 +1391,7 @@ Provider is dependency factory which creates dependency.
|
|
|
1391
1391
|
- `new Provider((container, options) => container.resolve(Logger, options))`
|
|
1392
1392
|
|
|
1393
1393
|
```typescript
|
|
1394
|
-
import {
|
|
1394
|
+
import { arg, bindTo, Container, inject, lazy, Provider, register, Registration as R } from 'ts-ioc-container';
|
|
1395
1395
|
|
|
1396
1396
|
/**
|
|
1397
1397
|
* Data Processing Pipeline - Provider Patterns
|
|
@@ -1458,7 +1458,7 @@ describe('Provider', () => {
|
|
|
1458
1458
|
|
|
1459
1459
|
it('supports args decorator for providing extra arguments', () => {
|
|
1460
1460
|
class FileService {
|
|
1461
|
-
constructor(@inject(
|
|
1461
|
+
constructor(@inject(arg(0)) readonly basePath: string) {}
|
|
1462
1462
|
}
|
|
1463
1463
|
|
|
1464
1464
|
const container = new Container().register(
|
|
@@ -1472,7 +1472,7 @@ describe('Provider', () => {
|
|
|
1472
1472
|
|
|
1473
1473
|
it('supports argsFn decorator for dynamic arguments', () => {
|
|
1474
1474
|
class Database {
|
|
1475
|
-
constructor(@inject(
|
|
1475
|
+
constructor(@inject(arg(0)) readonly connectionString: string) {}
|
|
1476
1476
|
}
|
|
1477
1477
|
|
|
1478
1478
|
const container = new Container().register('DbPath', Provider.fromValue('localhost:5432')).register(
|
|
@@ -1632,14 +1632,15 @@ When you pass an `InjectionToken` via `token.args(...)`, the container resolves
|
|
|
1632
1632
|
- `ServiceToken.args(new ClassToken(SomeService))` — `SomeService` is constructed by the container
|
|
1633
1633
|
- `ServiceToken.args('literal')` — literal value passed directly
|
|
1634
1634
|
|
|
1635
|
-
### Positional arg injection with `
|
|
1635
|
+
### Positional arg injection with `arg(index)`, `args`, and `argsFn`
|
|
1636
1636
|
|
|
1637
|
-
Constructor parameters that should pick up positional args from `ProviderOptions` must be annotated with `@inject(
|
|
1637
|
+
Constructor parameters that should pick up positional args from `ProviderOptions` must be annotated with `@inject(arg(index))`. Parameters without `@inject` resolve to `undefined`.
|
|
1638
1638
|
|
|
1639
|
-
- `@inject(
|
|
1639
|
+
- `@inject(arg(0))` — resolves the first element of the `args` array passed at resolution time
|
|
1640
|
+
- `@inject(args)` — resolves the whole runtime `args` array
|
|
1640
1641
|
- Works together with `token.args(...)` to pass typed dependencies through the args context
|
|
1641
1642
|
|
|
1642
|
-
`argsFn(predicate)` is the general form: it iterates the runtime `args` array and returns the **first argument matching** `predicate(value, index)` — think `args.find(predicate)`. `
|
|
1643
|
+
`argsFn(predicate)` is the general form: it iterates the runtime `args` array and returns the **first argument matching** `predicate(value, index)` — think `args.find(predicate)`. `arg(index)` is just a shortcut for matching by position: `arg(0)` is `argsFn((value, index) => index === 0)`. `args` is `(scope, options) => options.args`, i.e. it returns the runtime args array as-is. Every `InjectFn` receives `(scope, options)`, where `options.args` is the runtime args array.
|
|
1643
1644
|
|
|
1644
1645
|
### Immutable token chaining
|
|
1645
1646
|
|
|
@@ -1654,7 +1655,7 @@ const userToken = ApiToken.args('https://users.api.com', 1000);
|
|
|
1654
1655
|
|
|
1655
1656
|
```typescript
|
|
1656
1657
|
import {
|
|
1657
|
-
|
|
1658
|
+
arg,
|
|
1658
1659
|
appendArgs,
|
|
1659
1660
|
appendArgsFn,
|
|
1660
1661
|
bindTo,
|
|
@@ -1686,7 +1687,7 @@ describe('IProvider', function () {
|
|
|
1686
1687
|
// Pre-configure the logger with a filename
|
|
1687
1688
|
@register(appendArgs('/var/log/app.log'))
|
|
1688
1689
|
class FileLogger {
|
|
1689
|
-
constructor(@inject(
|
|
1690
|
+
constructor(@inject(arg(0)) public filename: string) {}
|
|
1690
1691
|
}
|
|
1691
1692
|
|
|
1692
1693
|
const root = createContainer().addRegistration(R.fromClass(FileLogger));
|
|
@@ -1700,8 +1701,8 @@ describe('IProvider', function () {
|
|
|
1700
1701
|
@register(appendArgs('ConfiguredContext'))
|
|
1701
1702
|
class Logger {
|
|
1702
1703
|
constructor(
|
|
1703
|
-
@inject(
|
|
1704
|
-
@inject(
|
|
1704
|
+
@inject(arg(0)) public runtimeContext: string,
|
|
1705
|
+
@inject(arg(1)) public configuredContext: string,
|
|
1705
1706
|
) {}
|
|
1706
1707
|
}
|
|
1707
1708
|
|
|
@@ -1723,7 +1724,7 @@ describe('IProvider', function () {
|
|
|
1723
1724
|
// Extract 'env' from Config service dynamically
|
|
1724
1725
|
@register(appendArgsFn((scope) => [scope.resolve<Config>('Config').env]))
|
|
1725
1726
|
class Service {
|
|
1726
|
-
constructor(@inject(
|
|
1727
|
+
constructor(@inject(arg(0)) public env: string) {}
|
|
1727
1728
|
}
|
|
1728
1729
|
|
|
1729
1730
|
const root = createContainer()
|
|
@@ -1740,8 +1741,8 @@ describe('IProvider', function () {
|
|
|
1740
1741
|
@register(appendArgs('configured'))
|
|
1741
1742
|
class Service {
|
|
1742
1743
|
constructor(
|
|
1743
|
-
@inject(
|
|
1744
|
-
@inject(
|
|
1744
|
+
@inject(arg(0)) public runtime: string,
|
|
1745
|
+
@inject(arg(1)) public configured: string,
|
|
1745
1746
|
) {}
|
|
1746
1747
|
}
|
|
1747
1748
|
|
|
@@ -1760,9 +1761,9 @@ describe('IProvider', function () {
|
|
|
1760
1761
|
@register(appendArgs('fixed'), appendArgsFn((scope) => [scope.resolve<Config>('Config').tenant]))
|
|
1761
1762
|
class Service {
|
|
1762
1763
|
constructor(
|
|
1763
|
-
@inject(
|
|
1764
|
-
@inject(
|
|
1765
|
-
@inject(
|
|
1764
|
+
@inject(arg(0)) public runtime: string,
|
|
1765
|
+
@inject(arg(1)) public fixed: string,
|
|
1766
|
+
@inject(arg(2)) public tenant: string,
|
|
1766
1767
|
) {}
|
|
1767
1768
|
}
|
|
1768
1769
|
|
|
@@ -1799,7 +1800,7 @@ describe('IProvider', function () {
|
|
|
1799
1800
|
|
|
1800
1801
|
// EntityManager is generic - it works with ANY repository.
|
|
1801
1802
|
// The repository is the first arg passed via `EntityManagerToken.args(...)`.
|
|
1802
|
-
// `@inject(
|
|
1803
|
+
// `@inject(arg(0))` reads it; the container auto-resolves InjectionToken args
|
|
1803
1804
|
// before they reach the constructor.
|
|
1804
1805
|
const EntityManagerToken = new SingleToken<EntityManager>('EntityManager');
|
|
1805
1806
|
|
|
@@ -1808,7 +1809,7 @@ describe('IProvider', function () {
|
|
|
1808
1809
|
singleton((arg1) => (arg1 as SingleToken).token), // Cache unique instance per repository type
|
|
1809
1810
|
)
|
|
1810
1811
|
class EntityManager {
|
|
1811
|
-
constructor(@inject(
|
|
1812
|
+
constructor(@inject(arg(0)) public repository: IRepository) {}
|
|
1812
1813
|
}
|
|
1813
1814
|
|
|
1814
1815
|
class App {
|
|
@@ -2117,7 +2118,7 @@ Sometimes you want to decorate you class with some logic. Use the `decorate(...)
|
|
|
2117
2118
|
|
|
2118
2119
|
```typescript
|
|
2119
2120
|
import {
|
|
2120
|
-
|
|
2121
|
+
arg,
|
|
2121
2122
|
bindTo,
|
|
2122
2123
|
Container,
|
|
2123
2124
|
decorate,
|
|
@@ -2171,7 +2172,7 @@ describe('Decorator Pattern', () => {
|
|
|
2171
2172
|
// Decorator: Wraps any IRepository with logging behavior
|
|
2172
2173
|
class LoggingRepository implements IRepository {
|
|
2173
2174
|
constructor(
|
|
2174
|
-
@inject(
|
|
2175
|
+
@inject(arg(0)) private repository: IRepository,
|
|
2175
2176
|
@inject(s.token('Logger').lazy()) private logger: Logger,
|
|
2176
2177
|
) {}
|
|
2177
2178
|
|
package/cjm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.resolveConstructor = exports.Is = exports.pipe = exports.select = exports.once = exports.shallowCache = exports.debounce = exports.throttle = exports.handleAsyncError = exports.handleError = exports.getMethodTags = exports.addMethodTag = exports.getMethodLabels = exports.addMethodLabel = exports.getMethodMeta = exports.addMethodMeta = exports.getParamTags = exports.addParamTag = exports.getParamLabels = exports.addParamLabel = exports.getParamMeta = exports.addParamMeta = exports.getClassTags = exports.addClassTag = exports.getClassLabels = exports.addClassLabel = exports.getClassMeta = exports.addClassMeta = exports.GroupInstanceToken = exports.ConstantToken = exports.FunctionToken = exports.SingleToken = exports.ClassToken = exports.toSingleAlias = exports.SingleAliasToken = exports.toGroupAlias = exports.GroupAliasToken = exports.argToToken = exports.toMappedToken = exports.toToken = exports.InjectionToken = exports.HooksRunner = exports.AddOnDisposeHookModule = exports.onContainerDisposed = void 0;
|
|
3
|
+
exports.AddOnConstructAsyncHookModule = exports.onConstructAsync = exports.onConstructAsyncHooksRunner = exports.AddOnConstructHookModule = exports.onConstruct = exports.onConstructHooksRunner = exports.injectProp = exports.createHookContext = exports.createHookContextFactory = exports.HookContext = exports.prepend = exports.append = exports.prependHooks = exports.appendHooks = exports.hasHooks = exports.hook = exports.getHooks = exports.UnsupportedTokenTypeError = exports.CannonSingletonApplyTwiceError = exports.UnexpectedHookResultError = exports.ProviderDisposedError = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyMissingKeyError = exports.ContainerNotFoundError = exports.DependencyNotFoundError = exports.ContainerError = exports.Registration = exports.appendArgsFn = exports.appendArgs = exports.decorate = exports.singleton = exports.lazy = exports.scopeAccess = exports.scope = exports.bindTo = exports.register = exports.Provider = exports.ProxyInjector = exports.SimpleInjector = exports.resolveArgs = exports.argsFn = exports.args = exports.arg = exports.inject = exports.MetadataInjector = exports.Injector = exports.EmptyContainer = exports.Container = exports.isDependencyKey = void 0;
|
|
4
|
+
exports.resolveConstructor = exports.Is = exports.pipe = exports.select = exports.once = exports.shallowCache = exports.debounce = exports.throttle = exports.handleAsyncError = exports.handleError = exports.getMethodTags = exports.addMethodTag = exports.getMethodLabels = exports.addMethodLabel = exports.getMethodMeta = exports.addMethodMeta = exports.getParamTags = exports.addParamTag = exports.getParamLabels = exports.addParamLabel = exports.getParamMeta = exports.addParamMeta = exports.getClassTags = exports.addClassTag = exports.getClassLabels = exports.addClassLabel = exports.getClassMeta = exports.addClassMeta = exports.GroupInstanceToken = exports.ConstantToken = exports.FunctionToken = exports.SingleToken = exports.ClassToken = exports.toSingleAlias = exports.SingleAliasToken = exports.toGroupAlias = exports.GroupAliasToken = exports.argToToken = exports.toMappedToken = exports.toToken = exports.InjectionToken = exports.HooksRunner = exports.AddOnDisposeHookModule = exports.onContainerDisposed = exports.onContainerDisposedHooksRunner = void 0;
|
|
5
5
|
var IContainer_1 = require("./container/IContainer");
|
|
6
6
|
Object.defineProperty(exports, "isDependencyKey", { enumerable: true, get: function () { return IContainer_1.isDependencyKey; } });
|
|
7
7
|
var Container_1 = require("./container/Container");
|
|
@@ -13,6 +13,7 @@ Object.defineProperty(exports, "Injector", { enumerable: true, get: function ()
|
|
|
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, "arg", { enumerable: true, get: function () { return MetadataInjector_1.arg; } });
|
|
16
17
|
Object.defineProperty(exports, "args", { enumerable: true, get: function () { return MetadataInjector_1.args; } });
|
|
17
18
|
Object.defineProperty(exports, "argsFn", { enumerable: true, get: function () { return MetadataInjector_1.argsFn; } });
|
|
18
19
|
Object.defineProperty(exports, "resolveArgs", { enumerable: true, get: function () { return MetadataInjector_1.resolveArgs; } });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveArgs = exports.args = exports.argsFn = exports.MetadataInjector = void 0;
|
|
3
|
+
exports.resolveArgs = exports.args = exports.arg = exports.argsFn = exports.MetadataInjector = void 0;
|
|
4
4
|
exports.inject = inject;
|
|
5
5
|
const IInjector_1 = require("./IInjector");
|
|
6
6
|
const basic_1 = require("../utils/basic");
|
|
@@ -21,7 +21,9 @@ function inject(fn, ...mappers) {
|
|
|
21
21
|
}
|
|
22
22
|
const argsFn = (predicate) => (c, { args = [] }) => args.find((value, index) => predicate(value, index));
|
|
23
23
|
exports.argsFn = argsFn;
|
|
24
|
-
const
|
|
24
|
+
const arg = (index) => (0, exports.argsFn)((value, i) => i === index);
|
|
25
|
+
exports.arg = arg;
|
|
26
|
+
const args = (c, { args = [] }) => args;
|
|
25
27
|
exports.args = args;
|
|
26
28
|
const resolveArgs = (Target, methodName) => {
|
|
27
29
|
const tokens = (0, parameter_1.getParamMeta)(hookMetaKey(methodName), Target);
|
package/esm/index.js
CHANGED
|
@@ -2,7 +2,7 @@ export { isDependencyKey, } from './container/IContainer.js';
|
|
|
2
2
|
export { Container } from './container/Container.js';
|
|
3
3
|
export { EmptyContainer } from './container/EmptyContainer.js';
|
|
4
4
|
export { Injector } from './injector/IInjector.js';
|
|
5
|
-
export { MetadataInjector, inject, args, argsFn, resolveArgs } from './injector/MetadataInjector.js';
|
|
5
|
+
export { MetadataInjector, inject, arg, args, argsFn, resolveArgs } from './injector/MetadataInjector.js';
|
|
6
6
|
export { SimpleInjector } from './injector/SimpleInjector.js';
|
|
7
7
|
export { ProxyInjector } from './injector/ProxyInjector.js';
|
|
8
8
|
export { Provider } from './provider/Provider.js';
|
|
@@ -15,7 +15,8 @@ export function inject(fn, ...mappers) {
|
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
17
|
export const argsFn = (predicate) => (c, { args = [] }) => args.find((value, index) => predicate(value, index));
|
|
18
|
-
export const
|
|
18
|
+
export const arg = (index) => argsFn((value, i) => i === index);
|
|
19
|
+
export const args = (c, { args = [] }) => args;
|
|
19
20
|
export const resolveArgs = (Target, methodName) => {
|
|
20
21
|
const tokens = getParamMeta(hookMetaKey(methodName), Target);
|
|
21
22
|
return (scope, { args = [], lazy }) => tokens.map((fn) => fn.resolve(scope, { args: args.map(argToToken).map((t) => t.resolve(scope)), lazy }));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-ioc-container",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "57.0.0",
|
|
4
4
|
"description": "Fast, lightweight TypeScript dependency injection container with a clean API, scoped lifecycles, decorators, tokens, hooks, lazy injection, customizable providers, and no global container objects.",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
package/typings/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { type IContainer, type Resolvable, type IContainerModule, type Dependenc
|
|
|
2
2
|
export { Container } from './container/Container.js';
|
|
3
3
|
export { EmptyContainer } from './container/EmptyContainer.js';
|
|
4
4
|
export { type IInjector, type InjectOptions, type IInjectFnResolver, Injector } from './injector/IInjector.js';
|
|
5
|
-
export { MetadataInjector, inject, args, argsFn, resolveArgs } from './injector/MetadataInjector.js';
|
|
5
|
+
export { MetadataInjector, inject, arg, args, argsFn, resolveArgs } from './injector/MetadataInjector.js';
|
|
6
6
|
export { SimpleInjector } from './injector/SimpleInjector.js';
|
|
7
7
|
export { ProxyInjector } from './injector/ProxyInjector.js';
|
|
8
8
|
export { type ResolveDependency, type IProvider, type DecorateFn, type ArgsFn, type ProviderOptions, type GetCacheKey, type ScopeAccessOptions, type ScopeAccessRule, } from './provider/IProvider.js';
|
|
@@ -20,5 +20,6 @@ export declare function inject<T, B, C, D, E, F, G, H, I, J>(fn: Injectable<T>,
|
|
|
20
20
|
export declare function inject<T, B, C, D, E, F, G, H, I, J, K>(fn: Injectable<T>, fn1: MapFn<T, B>, fn2: MapFn<B, C>, fn3: MapFn<C, D>, fn4: MapFn<D, E>, fn5: MapFn<E, F>, fn6: MapFn<F, G>, fn7: MapFn<G, H>, fn8: MapFn<H, I>, fn9: MapFn<I, J>, fn10: MapFn<J, K>): ParameterDecorator;
|
|
21
21
|
export declare function inject<T>(fn: Injectable<T>, ...mappers: MapFn<T>[]): ParameterDecorator;
|
|
22
22
|
export declare const argsFn: <T = unknown>(predicate: (value: unknown, index: number) => boolean) => InjectFn<T>;
|
|
23
|
-
export declare const
|
|
23
|
+
export declare const arg: <T = unknown>(index: number) => InjectFn<T>;
|
|
24
|
+
export declare const args: InjectFn<unknown[]>;
|
|
24
25
|
export declare const resolveArgs: (Target: constructor<unknown>, methodName?: string) => (scope: IContainer, { args, lazy }: ProviderOptions) => unknown[];
|