ts-ioc-container 50.1.0 → 50.2.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/README.md +50 -80
- package/cjm/index.js +4 -6
- package/cjm/provider/IProvider.js +9 -17
- package/cjm/provider/Provider.js +2 -6
- package/cjm/token/InjectionToken.js +1 -3
- package/esm/index.js +1 -1
- package/esm/provider/IProvider.js +6 -12
- package/esm/provider/Provider.js +2 -6
- package/esm/token/InjectionToken.js +0 -1
- package/package.json +1 -1
- package/typings/index.d.ts +1 -1
- package/typings/provider/IProvider.d.ts +6 -10
- package/typings/provider/Provider.d.ts +2 -3
- package/typings/token/InjectionToken.d.ts +1 -2
package/README.md
CHANGED
|
@@ -29,16 +29,11 @@ no global container objects.
|
|
|
29
29
|
- can inject [lazy dependencies](#lazy)
|
|
30
30
|
- composable provider and registration pipelines
|
|
31
31
|
- custom injectors, hooks, and provider behavior
|
|
32
|
-
- product behavior covered by executable specs
|
|
33
|
-
|
|
34
32
|
## Content
|
|
35
33
|
|
|
36
34
|
- [Setup](#setup)
|
|
37
35
|
- [Quickstart](#quickstart)
|
|
38
36
|
- [Cheatsheet](#cheatsheet)
|
|
39
|
-
- [Specs-driven workflow](#specs-driven-workflow)
|
|
40
|
-
- [Product capability map](#product-capability-map)
|
|
41
|
-
- [Acceptance specs](#acceptance-specs)
|
|
42
37
|
- [tsyringe alternative](https://igorbabkin.github.io/ts-ioc-container/tsyringe-alternative)
|
|
43
38
|
- [Inversify and Awilix alternative](https://igorbabkin.github.io/ts-ioc-container/inversify-awilix-alternative)
|
|
44
39
|
- [Recipes](#recipes)
|
|
@@ -56,7 +51,7 @@ no global container objects.
|
|
|
56
51
|
- [Proxy](#proxy)
|
|
57
52
|
- [Provider](#provider) `provider`
|
|
58
53
|
- [Singleton](#singleton) `singleton`
|
|
59
|
-
- [Arguments](#arguments) `
|
|
54
|
+
- [Arguments](#arguments) `appendArgs` `appendArgsFn`
|
|
60
55
|
- [Visibility](#visibility) `visible`
|
|
61
56
|
- [Alias](#alias) `asAlias`
|
|
62
57
|
- [Decorator](#decorator) `decorate`
|
|
@@ -102,25 +97,39 @@ And `tsconfig.json` should have next options:
|
|
|
102
97
|
## Quickstart
|
|
103
98
|
|
|
104
99
|
```typescript
|
|
105
|
-
import '
|
|
106
|
-
import { Container, register, bindTo, singleton } from 'ts-ioc-container';
|
|
100
|
+
import { bindTo, Container, inject, register, Registration as R, singleton, SingleToken } from 'ts-ioc-container';
|
|
107
101
|
|
|
108
|
-
|
|
109
|
-
|
|
102
|
+
interface ILogger {
|
|
103
|
+
log(message: string): void;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const ILoggerToken = new SingleToken<ILogger>('ILogger');
|
|
107
|
+
|
|
108
|
+
@register(bindTo(ILoggerToken), singleton())
|
|
109
|
+
class Logger implements ILogger {
|
|
110
110
|
log(message: string) {
|
|
111
111
|
console.log(message);
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
class App {
|
|
116
|
-
constructor(private logger
|
|
116
|
+
constructor(@inject(ILoggerToken) private logger: ILogger) {}
|
|
117
117
|
start() {
|
|
118
118
|
this.logger.log('hello');
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
122
|
+
describe('Quickstart', function () {
|
|
123
|
+
it('should resolve App with injected Logger', function () {
|
|
124
|
+
const container = new Container({ tags: ['application'] }).addRegistration(R.fromClass(Logger));
|
|
125
|
+
|
|
126
|
+
const app = container.resolve(App);
|
|
127
|
+
app.start();
|
|
128
|
+
|
|
129
|
+
expect(app).toBeInstanceOf(App);
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
|
|
124
133
|
```
|
|
125
134
|
|
|
126
135
|
## Cheatsheet
|
|
@@ -140,46 +149,10 @@ container.resolve(App).start();
|
|
|
140
149
|
> For classes, prefer the `@register(bindTo('Key'))` decorator over the fluent
|
|
141
150
|
> `R.fromClass(Class).bindToKey('Key')` chain. The decorator co-locates the binding
|
|
142
151
|
> with the class and reads consistently with other registration pipes
|
|
143
|
-
> (`scope`, `singleton`, `
|
|
152
|
+
> (`scope`, `singleton`, `appendArgsFn`, ...). Use the fluent `bindToKey` chain only
|
|
144
153
|
> for `R.fromValue(...)` and `R.fromFn(...)` (which have no class to decorate)
|
|
145
154
|
> or for third-party classes you don't own.
|
|
146
155
|
|
|
147
|
-
## Specs-driven workflow
|
|
148
|
-
|
|
149
|
-
Public behavior is described as product capabilities before it is implemented.
|
|
150
|
-
The repository keeps the same chain visible in specs, tests, docs, and this
|
|
151
|
-
README:
|
|
152
|
-
|
|
153
|
-
```text
|
|
154
|
-
Business capability -> user story -> acceptance criteria -> executable spec test -> docs and ADRs
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
- ADRs in `docs/adr/` explain durable architecture and process decisions.
|
|
158
|
-
- Specs in `specs/` describe epics, stories, use cases, and acceptance criteria.
|
|
159
|
-
- Acceptance tests in `__tests__/specs/` execute the public contract.
|
|
160
|
-
- README examples in `__tests__/readme/` stay executable and are rendered from `.readme.hbs.md`.
|
|
161
|
-
|
|
162
|
-
### Product capability map
|
|
163
|
-
|
|
164
|
-
| Capability | User outcome | Spec | Acceptance test |
|
|
165
|
-
| ----------------------- | -------------------------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------- |
|
|
166
|
-
| Dependency resolution | Resolve dependencies by key, class, token, or constructor injection. | `specs/epics/dependency-resolution.md` | `__tests__/specs/dependency-resolution.spec.ts` |
|
|
167
|
-
| Scoped lifecycle | Isolate application, request, transaction, page, or widget lifecycles. | `specs/epics/scoped-lifecycle.md` | `__tests__/specs/scoped-lifecycle.spec.ts` |
|
|
168
|
-
| Dependency registration | Describe classes, values, factories, keys, aliases, and scoped services. | `specs/epics/dependency-registration.md` | `__tests__/specs/dependency-registration.spec.ts` |
|
|
169
|
-
| Provider behavior | Cache, decorate, delay, restrict, or parameterize dependency creation. | `specs/epics/provider-behavior.md` | `__tests__/specs/provider-behavior.spec.ts` |
|
|
170
|
-
| Token-based injection | Make dependency requests explicit, typed, reusable, and composable. | `specs/epics/token-based-injection.md` | `__tests__/specs/token-based-injection.spec.ts` |
|
|
171
|
-
| Injector strategies | Support metadata, simple container, proxy, and custom injection styles. | `specs/epics/injector-strategies.md` | `__tests__/specs/injector-strategies.spec.ts` |
|
|
172
|
-
| Lifecycle hooks | Run initialization, cleanup, property injection, and custom hook behavior. | `specs/epics/lifecycle-hooks.md` | `__tests__/specs/lifecycle-hooks.spec.ts` |
|
|
173
|
-
| Container modules | Package container configuration by feature, environment, or lifecycle. | `specs/epics/container-modules.md` | `__tests__/specs/container-modules.spec.ts` |
|
|
174
|
-
| Metadata utilities | Attach labels, tags, and reusable method behavior to application code. | `specs/epics/metadata-utilities.md` | `__tests__/specs/metadata-utilities.spec.ts` |
|
|
175
|
-
| Errors and boundaries | Make misconfiguration and unsupported usage diagnosable. | `specs/epics/errors-and-boundaries.md` | `__tests__/specs/errors-and-boundaries.spec.ts` |
|
|
176
|
-
|
|
177
|
-
### Acceptance specs
|
|
178
|
-
|
|
179
|
-
Use `pnpm run test:spec` to run only the executable acceptance specs. These
|
|
180
|
-
tests are intentionally product-facing; lower-level regression and implementation
|
|
181
|
-
tests stay in the feature folders under `__tests__/`.
|
|
182
|
-
|
|
183
156
|
## Recipes
|
|
184
157
|
|
|
185
158
|
### Express/Next handler (per-request scope)
|
|
@@ -1442,7 +1415,7 @@ describe('lazy registerPipe', () => {
|
|
|
1442
1415
|
const container = new Container().addRegistration(
|
|
1443
1416
|
R.fromClass(ConfigService)
|
|
1444
1417
|
.pipe(
|
|
1445
|
-
(p) => p.
|
|
1418
|
+
(p) => p.appendArgs('https://api.example.com', 5000),
|
|
1446
1419
|
(p) => p.lazy(),
|
|
1447
1420
|
)
|
|
1448
1421
|
.pipe(singleton()),
|
|
@@ -1740,8 +1713,8 @@ Provider is dependency factory which creates dependency.
|
|
|
1740
1713
|
```typescript
|
|
1741
1714
|
import {
|
|
1742
1715
|
args,
|
|
1743
|
-
|
|
1744
|
-
|
|
1716
|
+
appendArgs,
|
|
1717
|
+
appendArgsFn,
|
|
1745
1718
|
bindTo,
|
|
1746
1719
|
Container,
|
|
1747
1720
|
inject,
|
|
@@ -1823,7 +1796,7 @@ describe('Provider', () => {
|
|
|
1823
1796
|
|
|
1824
1797
|
const container = new Container().register(
|
|
1825
1798
|
'FileService',
|
|
1826
|
-
Provider.fromClass(FileService).pipe(
|
|
1799
|
+
Provider.fromClass(FileService).pipe(appendArgs('/var/data')),
|
|
1827
1800
|
);
|
|
1828
1801
|
|
|
1829
1802
|
const service = container.resolve<FileService>('FileService');
|
|
@@ -1839,7 +1812,7 @@ describe('Provider', () => {
|
|
|
1839
1812
|
'Database',
|
|
1840
1813
|
Provider.fromClass(Database).pipe(
|
|
1841
1814
|
// Dynamically resolve connection string at creation time
|
|
1842
|
-
|
|
1815
|
+
appendArgsFn((scope) => [`postgres://${scope.resolve('DbPath')}`]),
|
|
1843
1816
|
),
|
|
1844
1817
|
);
|
|
1845
1818
|
|
|
@@ -1982,9 +1955,9 @@ describe('Singleton', function () {
|
|
|
1982
1955
|
|
|
1983
1956
|
Sometimes you want to bind some arguments to provider.
|
|
1984
1957
|
|
|
1985
|
-
- `provider(
|
|
1986
|
-
- `provider(
|
|
1987
|
-
- `Provider.fromClass(Logger).pipe(
|
|
1958
|
+
- `provider(appendArgs('someArgument'))`
|
|
1959
|
+
- `provider(appendArgsFn((container) => [container.resolve(Logger), 'someValue']))`
|
|
1960
|
+
- `Provider.fromClass(Logger).pipe(appendArgs('someArgument'))`
|
|
1988
1961
|
|
|
1989
1962
|
### Token as argument
|
|
1990
1963
|
|
|
@@ -2016,16 +1989,14 @@ const userToken = ApiToken.args('https://users.api.com', 1000);
|
|
|
2016
1989
|
|
|
2017
1990
|
```typescript
|
|
2018
1991
|
import {
|
|
2019
|
-
addArgs,
|
|
2020
|
-
addArgsFn,
|
|
2021
1992
|
args,
|
|
1993
|
+
appendArgs,
|
|
1994
|
+
appendArgsFn,
|
|
2022
1995
|
bindTo,
|
|
2023
1996
|
Container,
|
|
2024
1997
|
inject,
|
|
2025
1998
|
register,
|
|
2026
1999
|
Registration as R,
|
|
2027
|
-
setArgs,
|
|
2028
|
-
setArgsFn,
|
|
2029
2000
|
SingleToken,
|
|
2030
2001
|
singleton,
|
|
2031
2002
|
} from 'ts-ioc-container';
|
|
@@ -2048,7 +2019,7 @@ describe('IProvider', function () {
|
|
|
2048
2019
|
describe('Static Arguments', () => {
|
|
2049
2020
|
it('can pass static arguments to constructor', function () {
|
|
2050
2021
|
// Pre-configure the logger with a filename
|
|
2051
|
-
@register(
|
|
2022
|
+
@register(appendArgs('/var/log/app.log'))
|
|
2052
2023
|
class FileLogger {
|
|
2053
2024
|
constructor(@inject(args(0)) public filename: string) {}
|
|
2054
2025
|
}
|
|
@@ -2060,19 +2031,21 @@ describe('IProvider', function () {
|
|
|
2060
2031
|
expect(logger.filename).toBe('/var/log/app.log');
|
|
2061
2032
|
});
|
|
2062
2033
|
|
|
2063
|
-
it('
|
|
2064
|
-
|
|
2065
|
-
@register(setArgs('FixedContext'))
|
|
2034
|
+
it('appends configured args after resolve args', function () {
|
|
2035
|
+
@register(appendArgs('ConfiguredContext'))
|
|
2066
2036
|
class Logger {
|
|
2067
|
-
constructor(
|
|
2037
|
+
constructor(
|
|
2038
|
+
@inject(args(0)) public runtimeContext: string,
|
|
2039
|
+
@inject(args(1)) public configuredContext: string,
|
|
2040
|
+
) {}
|
|
2068
2041
|
}
|
|
2069
2042
|
|
|
2070
2043
|
const root = createContainer().addRegistration(R.fromClass(Logger));
|
|
2071
2044
|
|
|
2072
|
-
// Even if we ask for 'RuntimeContext', we get 'FixedContext'
|
|
2073
2045
|
const logger = root.resolve<Logger>('Logger', { args: ['RuntimeContext'] });
|
|
2074
2046
|
|
|
2075
|
-
expect(logger.
|
|
2047
|
+
expect(logger.runtimeContext).toBe('RuntimeContext');
|
|
2048
|
+
expect(logger.configuredContext).toBe('ConfiguredContext');
|
|
2076
2049
|
});
|
|
2077
2050
|
});
|
|
2078
2051
|
|
|
@@ -2083,7 +2056,7 @@ describe('IProvider', function () {
|
|
|
2083
2056
|
}
|
|
2084
2057
|
|
|
2085
2058
|
// Extract 'env' from Config service dynamically
|
|
2086
|
-
@register(
|
|
2059
|
+
@register(appendArgsFn((scope) => [scope.resolve<Config>('Config').env]))
|
|
2087
2060
|
class Service {
|
|
2088
2061
|
constructor(@inject(args(0)) public env: string) {}
|
|
2089
2062
|
}
|
|
@@ -2099,7 +2072,7 @@ describe('IProvider', function () {
|
|
|
2099
2072
|
|
|
2100
2073
|
describe('Appending Arguments', () => {
|
|
2101
2074
|
it('can append static arguments after existing resolve arguments', function () {
|
|
2102
|
-
@register(
|
|
2075
|
+
@register(appendArgs('configured'))
|
|
2103
2076
|
class Service {
|
|
2104
2077
|
constructor(
|
|
2105
2078
|
@inject(args(0)) public runtime: string,
|
|
@@ -2114,29 +2087,26 @@ describe('IProvider', function () {
|
|
|
2114
2087
|
expect(service.configured).toBe('configured');
|
|
2115
2088
|
});
|
|
2116
2089
|
|
|
2117
|
-
it('can append dynamic arguments after
|
|
2090
|
+
it('can append dynamic arguments after runtime args', function () {
|
|
2118
2091
|
class Config {
|
|
2119
2092
|
tenant = 'tenant-a';
|
|
2120
2093
|
}
|
|
2121
2094
|
|
|
2122
|
-
@register(
|
|
2123
|
-
setArgs('fixed'),
|
|
2124
|
-
addArgsFn((scope, { args = [] } = {}) => [scope.resolve<Config>('Config').tenant, ...args]),
|
|
2125
|
-
)
|
|
2095
|
+
@register(appendArgs('fixed'), appendArgsFn((scope) => [scope.resolve<Config>('Config').tenant]))
|
|
2126
2096
|
class Service {
|
|
2127
2097
|
constructor(
|
|
2128
|
-
@inject(args(0)) public
|
|
2129
|
-
@inject(args(1)) public
|
|
2130
|
-
@inject(args(2)) public
|
|
2098
|
+
@inject(args(0)) public runtime: string,
|
|
2099
|
+
@inject(args(1)) public fixed: string,
|
|
2100
|
+
@inject(args(2)) public tenant: string,
|
|
2131
2101
|
) {}
|
|
2132
2102
|
}
|
|
2133
2103
|
|
|
2134
2104
|
const root = createContainer().addRegistration(R.fromClass(Config)).addRegistration(R.fromClass(Service));
|
|
2135
2105
|
|
|
2136
2106
|
const service = root.resolve<Service>('Service', { args: ['runtime'] });
|
|
2107
|
+
expect(service.runtime).toBe('runtime');
|
|
2137
2108
|
expect(service.fixed).toBe('fixed');
|
|
2138
2109
|
expect(service.tenant).toBe('tenant-a');
|
|
2139
|
-
expect(service.runtime).toBe('runtime');
|
|
2140
2110
|
});
|
|
2141
2111
|
});
|
|
2142
2112
|
|
package/cjm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.toSingleAlias = exports.SingleAliasToken = exports.toGroupAlias = exports.GroupAliasToken = exports.InjectionToken = exports.HooksRunner = exports.AddOnDisposeHookModule = exports.onDispose = exports.onDisposeHooksRunner = exports.AddOnConstructHookModule = exports.onConstruct = exports.onConstructHooksRunner = exports.injectProp = exports.createHookContext = exports.createHookContextFactory = exports.HookContext = exports.hasHooks = exports.hook = exports.getHooks = exports.UnexpectedHookResultError = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyMissingKeyError = exports.DependencyNotFoundError = exports.Registration = exports.bindTo = exports.register = exports.scope = exports.decorate = exports.SingletonProvider = exports.singleton = exports.Provider = exports.ProviderDecorator = 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.methodTag = exports.getMethodLabels = exports.methodLabel = exports.getMethodMeta = exports.methodMeta = exports.getParamTags = exports.paramTag = exports.getParamLabels = exports.paramLabel = exports.getParamMeta = exports.paramMeta = exports.getClassTags = exports.classTag = exports.getClassLabels = exports.classLabel = exports.getClassMeta = exports.classMeta = exports.GroupInstanceToken = exports.ConstantToken = exports.FunctionToken =
|
|
3
|
+
exports.SingleToken = exports.ClassToken = exports.toSingleAlias = exports.SingleAliasToken = exports.toGroupAlias = exports.GroupAliasToken = exports.InjectionToken = exports.HooksRunner = exports.AddOnDisposeHookModule = exports.onDispose = exports.onDisposeHooksRunner = exports.AddOnConstructHookModule = exports.onConstruct = exports.onConstructHooksRunner = exports.injectProp = exports.createHookContext = exports.createHookContextFactory = exports.HookContext = exports.hasHooks = exports.hook = exports.getHooks = exports.UnexpectedHookResultError = exports.ContainerDisposedError = exports.MethodNotImplementedError = exports.DependencyMissingKeyError = exports.DependencyNotFoundError = exports.Registration = exports.bindTo = exports.register = exports.scope = exports.decorate = exports.SingletonProvider = exports.singleton = exports.Provider = exports.ProviderDecorator = exports.appendArgsFn = exports.appendArgs = exports.lazy = exports.scopeAccess = exports.ProxyInjector = exports.SimpleInjector = exports.MetadataInjector = exports.Injector = exports.argsFn = exports.args = exports.resolveArgs = exports.inject = 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.methodTag = exports.getMethodLabels = exports.methodLabel = exports.getMethodMeta = exports.methodMeta = exports.getParamTags = exports.paramTag = exports.getParamLabels = exports.paramLabel = exports.getParamMeta = exports.paramMeta = exports.getClassTags = exports.classTag = exports.getClassLabels = exports.classLabel = exports.getClassMeta = exports.classMeta = exports.GroupInstanceToken = exports.ConstantToken = exports.FunctionToken = void 0;
|
|
5
5
|
// Containers
|
|
6
6
|
var IContainer_1 = require("./container/IContainer");
|
|
7
7
|
Object.defineProperty(exports, "isDependencyKey", { enumerable: true, get: function () { return IContainer_1.isDependencyKey; } });
|
|
@@ -27,10 +27,8 @@ Object.defineProperty(exports, "ProxyInjector", { enumerable: true, get: functio
|
|
|
27
27
|
var IProvider_1 = require("./provider/IProvider");
|
|
28
28
|
Object.defineProperty(exports, "scopeAccess", { enumerable: true, get: function () { return IProvider_1.scopeAccess; } });
|
|
29
29
|
Object.defineProperty(exports, "lazy", { enumerable: true, get: function () { return IProvider_1.lazy; } });
|
|
30
|
-
Object.defineProperty(exports, "
|
|
31
|
-
Object.defineProperty(exports, "
|
|
32
|
-
Object.defineProperty(exports, "setArgsFn", { enumerable: true, get: function () { return IProvider_1.setArgsFn; } });
|
|
33
|
-
Object.defineProperty(exports, "setArgs", { enumerable: true, get: function () { return IProvider_1.setArgs; } });
|
|
30
|
+
Object.defineProperty(exports, "appendArgs", { enumerable: true, get: function () { return IProvider_1.appendArgs; } });
|
|
31
|
+
Object.defineProperty(exports, "appendArgsFn", { enumerable: true, get: function () { return IProvider_1.appendArgsFn; } });
|
|
34
32
|
Object.defineProperty(exports, "ProviderDecorator", { enumerable: true, get: function () { return IProvider_1.ProviderDecorator; } });
|
|
35
33
|
var Provider_1 = require("./provider/Provider");
|
|
36
34
|
Object.defineProperty(exports, "Provider", { enumerable: true, get: function () { return Provider_1.Provider; } });
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ProviderDecorator = exports.lazy = exports.scopeAccess = exports.
|
|
3
|
+
exports.ProviderDecorator = exports.lazy = exports.scopeAccess = exports.appendArgsFn = exports.appendArgs = void 0;
|
|
4
4
|
const ProviderPipe_1 = require("./ProviderPipe");
|
|
5
|
-
const
|
|
6
|
-
exports.
|
|
7
|
-
const
|
|
8
|
-
exports.
|
|
9
|
-
const addArgs = (...extraArgs) => (0, ProviderPipe_1.registerPipe)((p) => p.addArgs(...extraArgs));
|
|
10
|
-
exports.addArgs = addArgs;
|
|
11
|
-
const addArgsFn = (fn) => (0, ProviderPipe_1.registerPipe)((p) => p.addArgsFn(fn));
|
|
12
|
-
exports.addArgsFn = addArgsFn;
|
|
5
|
+
const appendArgs = (...extraArgs) => (0, ProviderPipe_1.registerPipe)((p) => p.appendArgs(...extraArgs));
|
|
6
|
+
exports.appendArgs = appendArgs;
|
|
7
|
+
const appendArgsFn = (fn) => (0, ProviderPipe_1.registerPipe)((p) => p.appendArgsFn(fn));
|
|
8
|
+
exports.appendArgsFn = appendArgsFn;
|
|
13
9
|
const scopeAccess = (rule) => (0, ProviderPipe_1.registerPipe)((p) => p.setAccessRule(rule));
|
|
14
10
|
exports.scopeAccess = scopeAccess;
|
|
15
11
|
const lazy = () => (0, ProviderPipe_1.registerPipe)((p) => p.lazy());
|
|
@@ -39,16 +35,12 @@ class ProviderDecorator {
|
|
|
39
35
|
this.decorated = this.decorated.pipe(...fns);
|
|
40
36
|
return this;
|
|
41
37
|
}
|
|
42
|
-
|
|
43
|
-
this.decorated.
|
|
38
|
+
appendArgs(...extraArgs) {
|
|
39
|
+
this.decorated.appendArgs(...extraArgs);
|
|
44
40
|
return this;
|
|
45
41
|
}
|
|
46
|
-
|
|
47
|
-
this.decorated.
|
|
48
|
-
return this;
|
|
49
|
-
}
|
|
50
|
-
addArgsFn(argsFn) {
|
|
51
|
-
this.decorated.addArgsFn(argsFn);
|
|
42
|
+
appendArgsFn(argsFn) {
|
|
43
|
+
this.decorated.appendArgsFn(argsFn);
|
|
52
44
|
return this;
|
|
53
45
|
}
|
|
54
46
|
lazy() {
|
package/cjm/provider/Provider.js
CHANGED
|
@@ -38,16 +38,12 @@ class Provider {
|
|
|
38
38
|
this.isLazy = true;
|
|
39
39
|
return this;
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
this.argsFn = argsFn;
|
|
43
|
-
return this;
|
|
44
|
-
}
|
|
45
|
-
addArgs(...extraArgs) {
|
|
41
|
+
appendArgs(...extraArgs) {
|
|
46
42
|
const parentFn = this.argsFn;
|
|
47
43
|
this.argsFn = (container, options) => [...parentFn(container, options), ...extraArgs];
|
|
48
44
|
return this;
|
|
49
45
|
}
|
|
50
|
-
|
|
46
|
+
appendArgsFn(argsFn) {
|
|
51
47
|
const parentFn = this.argsFn;
|
|
52
48
|
this.argsFn = (container, options) => [...parentFn(container, options), ...argsFn(container, options)];
|
|
53
49
|
return this;
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.InjectionToken = void 0;
|
|
4
4
|
exports.isInjectionToken = isInjectionToken;
|
|
5
5
|
const basic_1 = require("../utils/basic");
|
|
6
6
|
class InjectionToken {
|
|
7
7
|
}
|
|
8
8
|
exports.InjectionToken = InjectionToken;
|
|
9
|
-
const setArgs = (...args) => (s) => args;
|
|
10
|
-
exports.setArgs = setArgs;
|
|
11
9
|
function isInjectionToken(target) {
|
|
12
10
|
return basic_1.Is.object(target) && 'resolve' in target && 'args' in target && 'argsFn' in target && 'lazy' in target;
|
|
13
11
|
}
|
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, lazy,
|
|
12
|
+
export { scopeAccess, lazy, appendArgs, appendArgsFn, ProviderDecorator, } from './provider/IProvider';
|
|
13
13
|
export { Provider } from './provider/Provider';
|
|
14
14
|
export { singleton, SingletonProvider } from './provider/SingletonProvider';
|
|
15
15
|
export { decorate } from './provider/DecoratorProvider';
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { isProviderPipe, registerPipe } from './ProviderPipe';
|
|
2
|
-
export const
|
|
3
|
-
export const
|
|
4
|
-
export const addArgs = (...extraArgs) => registerPipe((p) => p.addArgs(...extraArgs));
|
|
5
|
-
export const addArgsFn = (fn) => registerPipe((p) => p.addArgsFn(fn));
|
|
2
|
+
export const appendArgs = (...extraArgs) => registerPipe((p) => p.appendArgs(...extraArgs));
|
|
3
|
+
export const appendArgsFn = (fn) => registerPipe((p) => p.appendArgsFn(fn));
|
|
6
4
|
export const scopeAccess = (rule) => registerPipe((p) => p.setAccessRule(rule));
|
|
7
5
|
export const lazy = () => registerPipe((p) => p.lazy());
|
|
8
6
|
export class ProviderDecorator {
|
|
@@ -30,16 +28,12 @@ export class ProviderDecorator {
|
|
|
30
28
|
this.decorated = this.decorated.pipe(...fns);
|
|
31
29
|
return this;
|
|
32
30
|
}
|
|
33
|
-
|
|
34
|
-
this.decorated.
|
|
31
|
+
appendArgs(...extraArgs) {
|
|
32
|
+
this.decorated.appendArgs(...extraArgs);
|
|
35
33
|
return this;
|
|
36
34
|
}
|
|
37
|
-
|
|
38
|
-
this.decorated.
|
|
39
|
-
return this;
|
|
40
|
-
}
|
|
41
|
-
addArgsFn(argsFn) {
|
|
42
|
-
this.decorated.addArgsFn(argsFn);
|
|
35
|
+
appendArgsFn(argsFn) {
|
|
36
|
+
this.decorated.appendArgsFn(argsFn);
|
|
43
37
|
return this;
|
|
44
38
|
}
|
|
45
39
|
lazy() {
|
package/esm/provider/Provider.js
CHANGED
|
@@ -35,16 +35,12 @@ export class Provider {
|
|
|
35
35
|
this.isLazy = true;
|
|
36
36
|
return this;
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
this.argsFn = argsFn;
|
|
40
|
-
return this;
|
|
41
|
-
}
|
|
42
|
-
addArgs(...extraArgs) {
|
|
38
|
+
appendArgs(...extraArgs) {
|
|
43
39
|
const parentFn = this.argsFn;
|
|
44
40
|
this.argsFn = (container, options) => [...parentFn(container, options), ...extraArgs];
|
|
45
41
|
return this;
|
|
46
42
|
}
|
|
47
|
-
|
|
43
|
+
appendArgsFn(argsFn) {
|
|
48
44
|
const parentFn = this.argsFn;
|
|
49
45
|
this.argsFn = (container, options) => [...parentFn(container, options), ...argsFn(container, options)];
|
|
50
46
|
return this;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Is } from '../utils/basic';
|
|
2
2
|
export class InjectionToken {
|
|
3
3
|
}
|
|
4
|
-
export const setArgs = (...args) => (s) => args;
|
|
5
4
|
export function isInjectionToken(target) {
|
|
6
5
|
return Is.object(target) && 'resolve' in target && 'args' in target && 'argsFn' in target && 'lazy' in target;
|
|
7
6
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-ioc-container",
|
|
3
|
-
"version": "50.1
|
|
3
|
+
"version": "50.2.1",
|
|
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
|
"workspaces": [
|
|
6
6
|
"docs"
|
package/typings/index.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export { type IInjector, type InjectOptions, type IInjectFnResolver, Injector }
|
|
|
6
6
|
export { MetadataInjector } from './injector/MetadataInjector';
|
|
7
7
|
export { SimpleInjector } from './injector/SimpleInjector';
|
|
8
8
|
export { ProxyInjector } from './injector/ProxyInjector';
|
|
9
|
-
export { type ResolveDependency, type IProvider, scopeAccess, lazy,
|
|
9
|
+
export { type ResolveDependency, type IProvider, scopeAccess, lazy, appendArgs, appendArgsFn, type ArgsFn, ProviderDecorator, type IMapper, type ProviderOptions, } from './provider/IProvider';
|
|
10
10
|
export { Provider } from './provider/Provider';
|
|
11
11
|
export { singleton, SingletonProvider } from './provider/SingletonProvider';
|
|
12
12
|
export { decorate, type DecorateFn } from './provider/DecoratorProvider';
|
|
@@ -21,15 +21,12 @@ export interface IProvider<T = any> {
|
|
|
21
21
|
hasAccess(options: ScopeAccessOptions): boolean;
|
|
22
22
|
pipe(...mappers: (MapFn<IProvider<T>> | ProviderPipe<T>)[]): IProvider<T>;
|
|
23
23
|
setAccessRule(hasAccessWhen: ScopeAccessRule): this;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
addArgsFn(argsFn: ArgsFn): this;
|
|
24
|
+
appendArgs(...extraArgs: unknown[]): this;
|
|
25
|
+
appendArgsFn(argsFn: ArgsFn): this;
|
|
27
26
|
lazy(): this;
|
|
28
27
|
}
|
|
29
|
-
export declare const
|
|
30
|
-
export declare const
|
|
31
|
-
export declare const addArgs: <T>(...extraArgs: unknown[]) => ProviderPipe<T>;
|
|
32
|
-
export declare const addArgsFn: <T>(fn: ArgsFn) => ProviderPipe<T>;
|
|
28
|
+
export declare const appendArgs: <T>(...extraArgs: unknown[]) => ProviderPipe<T>;
|
|
29
|
+
export declare const appendArgsFn: <T>(fn: ArgsFn) => ProviderPipe<T>;
|
|
33
30
|
export declare const scopeAccess: <T>(rule: ScopeAccessRule) => ProviderPipe<T>;
|
|
34
31
|
export declare const lazy: <T>() => ProviderPipe<T>;
|
|
35
32
|
export declare abstract class ProviderDecorator<T> implements IProvider<T> {
|
|
@@ -39,8 +36,7 @@ export declare abstract class ProviderDecorator<T> implements IProvider<T> {
|
|
|
39
36
|
hasAccess(options: ScopeAccessOptions): boolean;
|
|
40
37
|
resolve(container: IContainer, options: ProviderOptions): T;
|
|
41
38
|
pipe(...mappers: (MapFn<IProvider<T>> | ProviderPipe<T>)[]): IProvider<T>;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
addArgsFn(argsFn: ArgsFn): this;
|
|
39
|
+
appendArgs(...extraArgs: unknown[]): this;
|
|
40
|
+
appendArgsFn(argsFn: ArgsFn): this;
|
|
45
41
|
lazy(): this;
|
|
46
42
|
}
|
|
@@ -16,8 +16,7 @@ export declare class Provider<T = any> implements IProvider<T> {
|
|
|
16
16
|
resolve(container: IContainer, { args, lazy }?: ProviderOptions): T;
|
|
17
17
|
setAccessRule(predicate: ScopeAccessRule): this;
|
|
18
18
|
lazy(): this;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
addArgsFn(argsFn: ArgsFn): this;
|
|
19
|
+
appendArgs(...extraArgs: unknown[]): this;
|
|
20
|
+
appendArgsFn(argsFn: ArgsFn): this;
|
|
22
21
|
hasAccess(options: ScopeAccessOptions): boolean;
|
|
23
22
|
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { type IContainer } from '../container/IContainer';
|
|
2
|
-
import {
|
|
2
|
+
import { ProviderOptions } from '../provider/IProvider';
|
|
3
3
|
export declare abstract class InjectionToken<T = any> {
|
|
4
4
|
abstract resolve(s: IContainer, options?: ProviderOptions): T;
|
|
5
5
|
abstract args(...deps: unknown[]): InjectionToken<T>;
|
|
6
6
|
abstract argsFn(getArgsFn: (s: IContainer) => unknown[]): InjectionToken<T>;
|
|
7
7
|
abstract lazy(): InjectionToken<T>;
|
|
8
8
|
}
|
|
9
|
-
export declare const setArgs: (...args: unknown[]) => ArgsFn;
|
|
10
9
|
export declare function isInjectionToken(target: unknown): target is InjectionToken;
|