@art-ws/di-node 2.0.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.
@@ -0,0 +1,7 @@
1
+ import "reflect-metadata";
2
+ import type { DIModuleOptions, DITypeOptions } from "./types";
3
+ export declare function DIModule(options?: Partial<DIModuleOptions>): ClassDecorator;
4
+ export declare function Autowire(options: DITypeOptions): ClassDecorator;
5
+ export declare function Singleton(options?: Partial<DITypeOptions>): ClassDecorator;
6
+ export declare function Service(options?: Partial<DITypeOptions>): ClassDecorator;
7
+ export declare function Transient(options?: Partial<DITypeOptions>): ClassDecorator;
@@ -0,0 +1,34 @@
1
+ import "reflect-metadata";
2
+ import { DIRegistry, METADATA_DI_MODULE_OPTIONS, METADATA_DI_TYPE_OPTIONS, } from "./registry";
3
+ import { DIScope as Scope } from "./types";
4
+ export function DIModule(options) {
5
+ const o = options ?? {};
6
+ o.scope = o.scope || Scope.SINGLETON;
7
+ return ((token) => {
8
+ Reflect.defineMetadata(METADATA_DI_MODULE_OPTIONS, o, token);
9
+ DIRegistry.current.registerModule(token);
10
+ return token;
11
+ });
12
+ }
13
+ export function Autowire(options) {
14
+ const o = (options ?? {});
15
+ return ((cls) => {
16
+ Reflect.defineMetadata(METADATA_DI_TYPE_OPTIONS, o, cls);
17
+ DIRegistry.current.registerProviders(o.scope, [cls]);
18
+ });
19
+ }
20
+ export function Singleton(options) {
21
+ const o = options ?? {};
22
+ o.scope = Scope.SINGLETON;
23
+ return Autowire(o);
24
+ }
25
+ export function Service(options) {
26
+ const o = options || {};
27
+ o.scope = o.scope ?? Scope.REQUEST;
28
+ return Autowire(options);
29
+ }
30
+ export function Transient(options) {
31
+ const o = options || {};
32
+ o.scope = o.scope ?? Scope.TRANSIENT;
33
+ return Autowire(options);
34
+ }
@@ -0,0 +1,7 @@
1
+ export * from "./utils";
2
+ export * from "./decorators";
3
+ export * from "./injector-ref";
4
+ export * from "./node-platform";
5
+ export * from "./re-export";
6
+ export * from "./registry";
7
+ export * from "./types";
@@ -0,0 +1,8 @@
1
+ // created from 'create-ts-index'
2
+ export * from "./utils";
3
+ export * from "./decorators";
4
+ export * from "./injector-ref";
5
+ export * from "./node-platform";
6
+ export * from "./re-export";
7
+ export * from "./registry";
8
+ export * from "./types";
@@ -0,0 +1,28 @@
1
+ import { Injector } from "injection-js";
2
+ import type { Provider } from "injection-js";
3
+ import { ReflectiveInjector_ } from "injection-js/reflective_injector";
4
+ import type { CreateChildOptions, InjectableType, InjectorRef, ScopeStrategy, TInjectableToken } from "./types";
5
+ export declare function getScopeForInjectorRef(parent: InjectorRef | null, scopeStrategyFn: ScopeStrategy): string | null;
6
+ export declare class InjectorRefImpl implements InjectorRef {
7
+ private parentInjector;
8
+ scopeStrategy: ScopeStrategy;
9
+ private readonly disposable;
10
+ private resolvedProvidersStore;
11
+ private reflectiveInjector;
12
+ private readonly injectorScope;
13
+ private readonly isTransient;
14
+ constructor(parentInjector: InjectorRefImpl | null, moduleToken: InjectableType | null, scopeStrategy: ScopeStrategy, staticProviders: Provider[], dynamicProviders: Provider[], disposable: boolean);
15
+ getByName<T>(tokenName: string): TInjectableToken<T> | undefined;
16
+ tryGet<T>(token: TInjectableToken<T>): T | undefined;
17
+ get<T>(token: TInjectableToken<T>): T;
18
+ get reflectiveInjector_(): ReflectiveInjector_;
19
+ getInstances(): any[];
20
+ dispose(cb: (ref?: unknown) => void): void;
21
+ injector(): Injector;
22
+ createChild(providers?: Provider[], opts?: Partial<CreateChildOptions>): InjectorRef;
23
+ parent(): InjectorRef | null;
24
+ scope(): string;
25
+ private _initEagerCalled;
26
+ initEager(cb?: (ref?: InjectableType) => Promise<void> | void, cached?: boolean): Promise<void>;
27
+ bootstrapModules(): Promise<void>;
28
+ }
@@ -0,0 +1,145 @@
1
+ import { Injector, ReflectiveInjector } from "injection-js";
2
+ import { ReflectiveInjector_ } from "injection-js/reflective_injector";
3
+ import { DIRegistry } from "./registry";
4
+ import { resolveAndBootstrapModule } from "./types";
5
+ export function getScopeForInjectorRef(parent, scopeStrategyFn) {
6
+ return scopeStrategyFn(parent ? parent.scope() : null);
7
+ }
8
+ const nil = null;
9
+ export class InjectorRefImpl {
10
+ parentInjector;
11
+ scopeStrategy;
12
+ disposable;
13
+ resolvedProvidersStore = nil;
14
+ reflectiveInjector;
15
+ injectorScope;
16
+ isTransient;
17
+ constructor(parentInjector, moduleToken, scopeStrategy, staticProviders, dynamicProviders, disposable) {
18
+ this.parentInjector = parentInjector;
19
+ this.scopeStrategy = scopeStrategy;
20
+ this.disposable = disposable;
21
+ if (!(typeof scopeStrategy === "function")) {
22
+ throw new Error("scopeStrategy not function");
23
+ }
24
+ this.injectorScope = getScopeForInjectorRef(parentInjector, scopeStrategy);
25
+ if (!this.injectorScope) {
26
+ throw new Error("Child injector for TRANSIENT scope not supported");
27
+ }
28
+ this.isTransient = !scopeStrategy(this.injectorScope);
29
+ if (staticProviders?.length) {
30
+ DIRegistry.current.registerProviders(this.injectorScope, staticProviders);
31
+ }
32
+ if (moduleToken) {
33
+ DIRegistry.current.registerModule(moduleToken, this.injectorScope);
34
+ }
35
+ let dynamicProvidersResolved = [];
36
+ if (dynamicProviders?.length) {
37
+ dynamicProvidersResolved =
38
+ ReflectiveInjector.resolve(dynamicProviders) || [];
39
+ }
40
+ const staticProvidersResolved = DIRegistry.current.getResolvedProvidersFor(this.injectorScope, moduleToken);
41
+ this.resolvedProvidersStore = [
42
+ ...staticProvidersResolved,
43
+ ...dynamicProvidersResolved,
44
+ ];
45
+ const resolvedProviders = this.isTransient
46
+ ? []
47
+ : this.resolvedProvidersStore || [];
48
+ this.reflectiveInjector = ReflectiveInjector.fromResolvedProviders(resolvedProviders, parentInjector?.injector());
49
+ }
50
+ getByName(tokenName) {
51
+ return DIRegistry.current.resolveTokenByName(tokenName);
52
+ }
53
+ tryGet(token) {
54
+ try {
55
+ return this.get(token);
56
+ }
57
+ catch (e) {
58
+ return undefined;
59
+ }
60
+ }
61
+ get(token) {
62
+ let result;
63
+ try {
64
+ if (this.isTransient) {
65
+ const tmp = this.reflectiveInjector.createChildFromResolved(this.resolvedProvidersStore || []);
66
+ result = tmp.get(token);
67
+ }
68
+ else {
69
+ result = this.reflectiveInjector.get(token);
70
+ }
71
+ }
72
+ catch (e) {
73
+ const err = e;
74
+ if (err.message?.startsWith("No provider")) {
75
+ const ex = new Error(`${err.message} (scope: ${this.injectorScope})`);
76
+ ex.stack = err.stack;
77
+ throw ex;
78
+ }
79
+ else {
80
+ throw e;
81
+ }
82
+ }
83
+ return result;
84
+ }
85
+ get reflectiveInjector_() {
86
+ return this.reflectiveInjector;
87
+ }
88
+ getInstances() {
89
+ return this.reflectiveInjector_?.objs ?? [];
90
+ }
91
+ dispose(cb) {
92
+ if (!this.reflectiveInjector)
93
+ return;
94
+ if (!this.disposable) {
95
+ throw new Error("disposable = false");
96
+ }
97
+ const isObject = (x) => {
98
+ const t = typeof x;
99
+ return t === "object" || t === "function";
100
+ };
101
+ this.getInstances()
102
+ .filter(isObject)
103
+ .forEach((x) => {
104
+ cb(x);
105
+ });
106
+ this.reflectiveInjector = nil;
107
+ this.resolvedProvidersStore = [];
108
+ this.parentInjector = nil;
109
+ }
110
+ injector() {
111
+ return this.reflectiveInjector;
112
+ }
113
+ createChild(providers, opts) {
114
+ const options = opts || { disposable: false };
115
+ return new InjectorRefImpl(this, null, this.scopeStrategy, [], providers ?? [], options.disposable ?? false);
116
+ }
117
+ parent() {
118
+ return this.parentInjector || null;
119
+ }
120
+ scope() {
121
+ return this.injectorScope ?? "";
122
+ }
123
+ _initEagerCalled = false;
124
+ async initEager(cb, cached) {
125
+ if (this._initEagerCalled)
126
+ throw new Error(`'initEager' already called for InjectorRef instance`);
127
+ this._initEagerCalled = true;
128
+ const tokens = DIRegistry.current.getEagerTokens(this.scope(), cached);
129
+ for (const token of tokens) {
130
+ const ref = this.get(token);
131
+ if (typeof cb === "function") {
132
+ const result = cb(ref);
133
+ if (typeof result?.then === "function") {
134
+ await result;
135
+ }
136
+ }
137
+ }
138
+ }
139
+ async bootstrapModules() {
140
+ const tokens = DIRegistry.current.getDIModules(this.scope());
141
+ for (const token of tokens) {
142
+ await resolveAndBootstrapModule(this, token);
143
+ }
144
+ }
145
+ }
@@ -0,0 +1,2 @@
1
+ import type { ModuleLoader } from "./types";
2
+ export declare function platform(): ModuleLoader;
@@ -0,0 +1,50 @@
1
+ import { InjectorRefImpl } from "./injector-ref";
2
+ import { APP_INITIALIZER, getDefaultScopeStrategy, ROOT_INJECTOR, } from "./types";
3
+ class NodeModuleLoader {
4
+ diProviders;
5
+ providers(providers) {
6
+ this.diProviders = providers;
7
+ return this;
8
+ }
9
+ async initAppInitializer(injector) {
10
+ let promises;
11
+ let p;
12
+ try {
13
+ p = injector.get(APP_INITIALIZER);
14
+ }
15
+ catch (e) {
16
+ const err = e;
17
+ if (!err.message.includes("No provider for InjectionToken APP_INITIALIZER")) {
18
+ throw e;
19
+ }
20
+ }
21
+ if (p) {
22
+ if (Array.isArray(p))
23
+ promises = p;
24
+ else
25
+ promises = [p];
26
+ await Promise.all(promises);
27
+ }
28
+ }
29
+ async bootstrapModule(token) {
30
+ let injector = null;
31
+ const providers = [
32
+ ...(this.diProviders ?? []),
33
+ {
34
+ provide: ROOT_INJECTOR,
35
+ useFactory: () => injector,
36
+ deps: [],
37
+ },
38
+ ];
39
+ injector = new InjectorRefImpl(null, token, getDefaultScopeStrategy, providers, [], false);
40
+ const instance = injector.get(token);
41
+ await this.initAppInitializer(injector);
42
+ return {
43
+ injector,
44
+ instance,
45
+ };
46
+ }
47
+ }
48
+ export function platform() {
49
+ return new NodeModuleLoader();
50
+ }
@@ -0,0 +1 @@
1
+ export * from "injection-js";
@@ -0,0 +1 @@
1
+ export * from "injection-js";
@@ -0,0 +1,37 @@
1
+ import type { Provider, ResolvedReflectiveProvider } from "injection-js";
2
+ import "reflect-metadata";
3
+ import type { DIModuleOptions, DITypeOptions, InjectableToken, InjectableType } from "./types";
4
+ export declare const METADATA_DI_ID: unique symbol;
5
+ export declare const METADATA_DI_MODULE_OPTIONS: unique symbol;
6
+ export declare const METADATA_DI_TYPE_OPTIONS: unique symbol;
7
+ type ProvidersStore = Map<string, Provider>;
8
+ type ScopesStore = Map<string, ProvidersStore>;
9
+ export declare function tokenToString(token: InjectableType): string | undefined;
10
+ export declare function isDITokenRegistered(token: InjectableType): boolean;
11
+ export declare function getDIModuleOptions(token: InjectableType): DIModuleOptions;
12
+ export declare function getDITypeOptions(token: InjectableType): DITypeOptions;
13
+ export declare class DIRegistry {
14
+ static current: DIRegistry;
15
+ parent: DIRegistry | null;
16
+ private nextId;
17
+ scopesStore: ScopesStore;
18
+ resolvedProvidersStore: Map<string, ResolvedReflectiveProvider[]>;
19
+ modulesStore: InjectableToken[];
20
+ resolvedEagerTokens: Map<string, InjectableType[]>;
21
+ tokensStore: Map<string, unknown>;
22
+ private getNexId;
23
+ private getProvidersStore;
24
+ registerProviders(scope: string, providers: Provider[]): void;
25
+ private registerProvider;
26
+ private injectRegisterTokenID;
27
+ private _registerModule;
28
+ registerModule(moduleToken: InjectableType, scope?: string): void;
29
+ getProvidersFor(scope: string, token: InjectableType | null): Provider[];
30
+ clear(): void;
31
+ getResolvedProvidersFor(scope: string, token: InjectableType | null): ResolvedReflectiveProvider[];
32
+ getDIModules(scope: string): InjectableType[];
33
+ resolveEagerTokens(scope: string): InjectableType[];
34
+ getEagerTokens(scope: string, cached?: boolean): InjectableType[];
35
+ resolveTokenByName(name: string): InjectableToken | undefined;
36
+ }
37
+ export {};
@@ -0,0 +1,171 @@
1
+ import { ReflectiveInjector } from "injection-js";
2
+ import "reflect-metadata";
3
+ export const METADATA_DI_ID = Symbol("art-ws:di:id");
4
+ export const METADATA_DI_MODULE_OPTIONS = Symbol("art-ws:di:module:options");
5
+ export const METADATA_DI_TYPE_OPTIONS = Symbol("art-ws:di:type:options");
6
+ function className(cls) {
7
+ const str = String(cls);
8
+ const [_type, _name] = str.split(" ");
9
+ if (_type != "class" || !_name)
10
+ return undefined;
11
+ return _name.trim();
12
+ }
13
+ export function tokenToString(token) {
14
+ const s = token.toString();
15
+ if (s === "[object Object]")
16
+ return undefined;
17
+ return className(token);
18
+ }
19
+ export function isDITokenRegistered(token) {
20
+ return Boolean(Reflect.getMetadata(METADATA_DI_ID, token));
21
+ }
22
+ export function getDIModuleOptions(token) {
23
+ const o = Reflect.getMetadata(METADATA_DI_MODULE_OPTIONS, token);
24
+ if (typeof o !== "object") {
25
+ throw new Error(`Module ${token} require @DIModule() decorator`);
26
+ }
27
+ return o;
28
+ }
29
+ export function getDITypeOptions(token) {
30
+ const o = Reflect.getMetadata(METADATA_DI_TYPE_OPTIONS, token);
31
+ if (typeof o !== "object") {
32
+ throw new Error(`Type ${`${token}`} require @Autowired() decorator`);
33
+ }
34
+ return o;
35
+ }
36
+ export class DIRegistry {
37
+ static current;
38
+ parent = null;
39
+ nextId = 1;
40
+ scopesStore = new Map();
41
+ resolvedProvidersStore = new Map();
42
+ modulesStore = [];
43
+ resolvedEagerTokens = new Map();
44
+ tokensStore = new Map();
45
+ getNexId() {
46
+ return this.nextId++;
47
+ }
48
+ getProvidersStore(scope) {
49
+ const { scopesStore } = this;
50
+ const providersStore = scopesStore.get(scope) ??
51
+ (() => {
52
+ const value = new Map();
53
+ scopesStore.set(scope, value);
54
+ return value;
55
+ })();
56
+ return providersStore;
57
+ }
58
+ registerProviders(scope, providers) {
59
+ const providersStore = this.getProvidersStore(scope);
60
+ providers.forEach((provider) => {
61
+ this.registerProvider(providersStore, provider);
62
+ });
63
+ }
64
+ registerProvider(store, provider) {
65
+ const o = Reflect.getMetadata(METADATA_DI_TYPE_OPTIONS, provider);
66
+ if (o && isDITokenRegistered(provider)) {
67
+ return;
68
+ }
69
+ const id = this.injectRegisterTokenID(provider);
70
+ store.set(`${id}`, provider);
71
+ const tokenName = tokenToString(provider);
72
+ if (tokenName) {
73
+ this.tokensStore.set(tokenName, provider);
74
+ }
75
+ }
76
+ injectRegisterTokenID(token) {
77
+ if (!token) {
78
+ throw new Error("token not defined");
79
+ }
80
+ const id = this.getNexId();
81
+ const metadataValue = `${id}`;
82
+ Reflect.defineMetadata(METADATA_DI_ID, metadataValue, token);
83
+ return metadataValue;
84
+ }
85
+ _registerModule(path, moduleToken, scope) {
86
+ if (isDITokenRegistered(moduleToken)) {
87
+ return;
88
+ }
89
+ const idMaybe = Reflect.getMetadata(METADATA_DI_ID, moduleToken);
90
+ if (idMaybe && path.includes(idMaybe)) {
91
+ throw new Error(`Circular dependency for type ${`${moduleToken}`}`);
92
+ }
93
+ this.modulesStore.push(moduleToken);
94
+ path.push(this.injectRegisterTokenID(moduleToken));
95
+ const o = getDIModuleOptions(moduleToken);
96
+ (o.imports ?? []).forEach((importedModuleToken) => {
97
+ this._registerModule(path, importedModuleToken, scope);
98
+ });
99
+ const s = scope ?? o.scope ?? "";
100
+ if (!s) {
101
+ throw new Error(`Scope not provided for ${moduleToken}`);
102
+ }
103
+ const providers = [...(o.providers ?? [])];
104
+ this.registerProviders(s, [
105
+ moduleToken,
106
+ ...providers,
107
+ ...(o.bootstrap ?? []),
108
+ ]);
109
+ }
110
+ registerModule(moduleToken, scope) {
111
+ this._registerModule([], moduleToken, scope);
112
+ }
113
+ getProvidersFor(scope, token) {
114
+ if (!scope) {
115
+ throw new Error(`Scope not defined.`);
116
+ }
117
+ if (token && !isDITokenRegistered(token)) {
118
+ throw new Error(`Token ${token} not registered.`);
119
+ }
120
+ const providersStore = this.getProvidersStore(scope);
121
+ const providers = [...providersStore.values()];
122
+ return providers;
123
+ }
124
+ clear() {
125
+ this.resolvedProvidersStore.clear();
126
+ this.resolvedEagerTokens.clear();
127
+ }
128
+ getResolvedProvidersFor(scope, token) {
129
+ if (!scope)
130
+ throw new Error("Scope not defined");
131
+ const { resolvedProvidersStore } = this;
132
+ if (resolvedProvidersStore.has(scope)) {
133
+ return resolvedProvidersStore.get(scope) ?? [];
134
+ }
135
+ const effectiveProviders = this.getProvidersFor(scope, token);
136
+ const result = ReflectiveInjector.resolve(effectiveProviders) ?? [];
137
+ resolvedProvidersStore.set(scope, result);
138
+ return result;
139
+ }
140
+ getDIModules(scope) {
141
+ return [...this.modulesStore]
142
+ .map((token) => ({ token, options: getDIModuleOptions(token) }))
143
+ .filter((x) => x.options?.scope === scope)
144
+ .map((x) => x.token);
145
+ }
146
+ resolveEagerTokens(scope) {
147
+ const providersStore = this.getProvidersStore(scope);
148
+ return [...providersStore.values()]
149
+ .map((token) => ({
150
+ token,
151
+ options: Reflect.getMetadata(METADATA_DI_TYPE_OPTIONS, token),
152
+ }))
153
+ .filter((x) => x.options?.eager)
154
+ .map((x) => x.token);
155
+ }
156
+ getEagerTokens(scope, cached) {
157
+ if (!cached)
158
+ return this.resolveEagerTokens(scope);
159
+ const { resolvedEagerTokens } = this;
160
+ return (resolvedEagerTokens.get(scope) ??
161
+ (() => {
162
+ const value = this.resolveEagerTokens(scope);
163
+ resolvedEagerTokens.set(scope, value);
164
+ return value;
165
+ })());
166
+ }
167
+ resolveTokenByName(name) {
168
+ return this.tokensStore.get(name);
169
+ }
170
+ }
171
+ DIRegistry.current = new DIRegistry();
@@ -0,0 +1,53 @@
1
+ import { InjectionToken, Injector } from "injection-js";
2
+ import type { Provider, Type } from "injection-js";
3
+ export type TInjectableType<T> = Type<T> | Object;
4
+ export type InjectableType = TInjectableType<any>;
5
+ export type TInjectableToken<T> = TInjectableType<T> | InjectionToken<T>;
6
+ export type InjectableToken = TInjectableToken<any>;
7
+ export declare const APP_INITIALIZER: InjectionToken<Promise<void>[]>;
8
+ export declare const ROOT_INJECTOR: InjectionToken<InjectorRef>;
9
+ export declare enum DIScope {
10
+ SINGLETON = "SINGLETON",
11
+ REQUEST = "REQUEST",
12
+ TRANSIENT = "TRANSIENT"
13
+ }
14
+ export interface DIModuleOptions {
15
+ scope: DIScope;
16
+ imports?: InjectableType[];
17
+ providers?: Provider[];
18
+ bootstrap?: InjectableType[];
19
+ }
20
+ export interface DITypeOptions {
21
+ scope: DIScope;
22
+ eager?: boolean;
23
+ }
24
+ export type ScopeStrategy = (parent: DIScope | null | string) => DIScope | null | string;
25
+ export declare function getDefaultScopeStrategy(parent: DIScope | null | string): DIScope | null | string;
26
+ export interface CreateChildOptions {
27
+ disposable: boolean;
28
+ }
29
+ export interface InjectorRef {
30
+ get: <T>(token: TInjectableToken<T>) => T;
31
+ parent: () => InjectorRef | null;
32
+ scope: () => string;
33
+ injector: () => Injector;
34
+ createChild: (providers?: Provider[], opts?: CreateChildOptions) => InjectorRef;
35
+ dispose?: (callback: (x?: unknown) => void) => void;
36
+ initEager: (cb?: (ref?: InjectableType) => void, cached?: boolean) => Promise<void>;
37
+ bootstrapModules: () => Promise<void> | void;
38
+ getByName: <T>(tokenName: string) => TInjectableToken<T> | undefined;
39
+ }
40
+ export interface ModuleRef<T = any> {
41
+ injector: InjectorRef;
42
+ instance: T;
43
+ }
44
+ export interface ModuleLoader {
45
+ providers: (providers?: Provider[]) => ModuleLoader;
46
+ bootstrapModule: (rootModule: InjectableType) => Promise<ModuleRef>;
47
+ }
48
+ export interface DoBootstrap {
49
+ doBootstrap: (injector?: InjectorRef) => Promise<void> | void;
50
+ }
51
+ export declare function tryInvokeDoBootstrap(ref: DoBootstrap, injector: InjectorRef): Promise<void>;
52
+ export declare function resolveAndInvokeDoBootstrap(injector: InjectorRef, token: InjectableToken): Promise<void>;
53
+ export declare function resolveAndBootstrapModule(injector: InjectorRef, token: InjectableToken): Promise<void>;
@@ -0,0 +1,45 @@
1
+ import { InjectionToken, Injector } from "injection-js";
2
+ import { getDIModuleOptions } from "./registry";
3
+ // https://angular.io/api/core/APP_INITIALIZER
4
+ // https://github.com/angular/angular/blob/master/packages/core/src/application_init.ts
5
+ export const APP_INITIALIZER = new InjectionToken("APP_INITIALIZER");
6
+ export const ROOT_INJECTOR = new InjectionToken("ROOT_INJECTOR");
7
+ export var DIScope;
8
+ (function (DIScope) {
9
+ DIScope["SINGLETON"] = "SINGLETON";
10
+ DIScope["REQUEST"] = "REQUEST";
11
+ DIScope["TRANSIENT"] = "TRANSIENT";
12
+ })(DIScope || (DIScope = {}));
13
+ export function getDefaultScopeStrategy(parent) {
14
+ if (!parent) {
15
+ return DIScope.SINGLETON;
16
+ }
17
+ else if (parent === DIScope.SINGLETON) {
18
+ return DIScope.REQUEST;
19
+ }
20
+ else if (parent === DIScope.REQUEST) {
21
+ return DIScope.TRANSIENT;
22
+ }
23
+ return "";
24
+ }
25
+ export async function tryInvokeDoBootstrap(ref, injector) {
26
+ if (typeof ref?.doBootstrap === "function") {
27
+ const result = ref.doBootstrap(injector);
28
+ if (typeof result?.then === "function") {
29
+ await result;
30
+ }
31
+ }
32
+ }
33
+ export async function resolveAndInvokeDoBootstrap(injector, token) {
34
+ const ref = injector.get(token);
35
+ await tryInvokeDoBootstrap(ref, injector);
36
+ }
37
+ export async function resolveAndBootstrapModule(injector, token) {
38
+ const ref = injector.get(token);
39
+ await tryInvokeDoBootstrap(ref, injector);
40
+ const o = getDIModuleOptions(token);
41
+ for (const moduleToken of o.bootstrap ?? []) {
42
+ const moduleRef = injector.get(moduleToken);
43
+ await tryInvokeDoBootstrap(moduleRef, injector);
44
+ }
45
+ }
@@ -0,0 +1,2 @@
1
+ import type { InjectorRef } from "../types";
2
+ export declare function getMultiInstances<T>(token: any, injector: InjectorRef): T[];
@@ -0,0 +1,7 @@
1
+ import { getInstanceSafe } from "./get-safe";
2
+ export function getMultiInstances(token, injector) {
3
+ const result = getInstanceSafe(token, injector);
4
+ if (!result)
5
+ return [];
6
+ return Array.isArray(result) ? result : [result];
7
+ }
@@ -0,0 +1,2 @@
1
+ import type { InjectorRef } from "../types";
2
+ export declare function getInstanceSafe<T>(token: any, injector: InjectorRef): T | null;
@@ -0,0 +1,11 @@
1
+ export function getInstanceSafe(token, injector) {
2
+ try {
3
+ return injector.get(token);
4
+ }
5
+ catch (e) {
6
+ const err = e;
7
+ if (err?.message?.startsWith("No provider for"))
8
+ return null;
9
+ throw err;
10
+ }
11
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./get-multi";
2
+ export * from "./get-safe";
@@ -0,0 +1,3 @@
1
+ // created from 'create-ts-index'
2
+ export * from "./get-multi";
3
+ export * from "./get-safe";
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@art-ws/di-node",
3
+ "version": "2.0.1",
4
+ "description": "Dependency Injection core",
5
+ "keywords": [
6
+ "lib"
7
+ ],
8
+ "license": "UNLICENSED",
9
+ "main": "dist/es/index.js",
10
+ "types": "dist/es/index.d.ts",
11
+ "files": [
12
+ "dist"
13
+ ],
14
+ "dependencies": {
15
+ "injection-js": "^2.5.0",
16
+ "reflect-metadata": "^0.2.2",
17
+ "tslib": "^2.8.1"
18
+ },
19
+ "devDependencies": {
20
+ "@types/node": "^24.3.0",
21
+ "eslint": "^9.34.0",
22
+ "typescript": "^5.9.2",
23
+ "vitest": "^3.2.4",
24
+ "@art-ws/config-ts": "2.0.6",
25
+ "@art-ws/config-eslint": "2.0.3"
26
+ },
27
+ "scripts": {
28
+ "build": "tsc",
29
+ "check": "pnpm clean && pnpm build && pnpm lint && pnpm test",
30
+ "clean": "rm -rf dist",
31
+ "clean:nm": "rm -rf node_modules",
32
+ "lint": "eslint .",
33
+ "test": "vitest run",
34
+ "test:watch": "vitest",
35
+ "watch": "tsc --watch"
36
+ }
37
+ }