@art-ws/di 2.0.8 → 2.0.9

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.
@@ -1,4 +1,4 @@
1
- import type { Func, Provider, Token } from "./types.js";
1
+ import type { DIModuleDef, Func, Provider, Token } from "./types.js";
2
2
  export type InjectorInstance = InstanceType<typeof Injector>;
3
3
  export declare class Injector {
4
4
  #private;
@@ -7,6 +7,9 @@ export declare class Injector {
7
7
  parent: Injector | null;
8
8
  addFactory<T>(token: Token<T>, factory?: Func<T>): void;
9
9
  addValue<T>(token: Token<T>, value: T): void;
10
+ private addModuleInner;
11
+ addModule(...modules: DIModuleDef[]): void;
12
+ addProvider(p: Provider): void;
10
13
  addProviders(...providers: Provider[]): this;
11
14
  get<T>(token: Token<T>): T;
12
15
  runScope<T>(fn: Func<T>, options?: Partial<{
@@ -14,7 +14,7 @@ export class Injector {
14
14
  }
15
15
  }
16
16
  else {
17
- if (!factory && typeof token === "function") {
17
+ if (!factory && isClass(token)) {
18
18
  factory = () => new token();
19
19
  }
20
20
  }
@@ -23,36 +23,60 @@ export class Injector {
23
23
  addValue(token, value) {
24
24
  this.addFactory(token, () => value);
25
25
  }
26
+ addModuleInner(set, ...modules) {
27
+ for (const module of modules) {
28
+ for (const imp of module.imports) {
29
+ if (set.has(imp))
30
+ throw new Error(`Circular dependency detected: ${imp}`);
31
+ set.add(imp);
32
+ this.addModuleInner(set, imp);
33
+ }
34
+ this.addProviders(...module.providers);
35
+ }
36
+ }
37
+ addModule(...modules) {
38
+ const set = new Set();
39
+ this.addModuleInner(set, ...modules);
40
+ }
41
+ addProvider(p) {
42
+ const p1 = p;
43
+ const p2 = p;
44
+ const p3 = p;
45
+ if (isClass(p1)) {
46
+ this.addFactory(p1);
47
+ }
48
+ else if (p2.token && p2.factory) {
49
+ this.addFactory(p2.token, p2.factory);
50
+ }
51
+ else if (p3.provide || p3.useClass) {
52
+ const provide = p3.provide || p3.useClass;
53
+ if (!provide)
54
+ throw new Error(`provide|useClass is not defined`);
55
+ const factory = () => {
56
+ if (p3.useFactory || p3.useClass) {
57
+ const deps = (p3.deps || []).map((dep) => inject(dep));
58
+ if (p3.useClass)
59
+ return new p3.useClass(...deps);
60
+ else
61
+ return p3.useFactory(...deps);
62
+ }
63
+ else if (p3.useValue) {
64
+ return p3.useValue;
65
+ }
66
+ else if (p3.useExisting) {
67
+ return inject(p3.useExisting);
68
+ }
69
+ else {
70
+ throw new Error(`useClass|useFactory|useValue|useExisting is not defined`);
71
+ }
72
+ };
73
+ this.addFactory(provide, factory);
74
+ }
75
+ }
26
76
  addProviders(...providers) {
27
77
  if (Array.isArray(providers)) {
28
78
  for (const p of providers) {
29
- if (p.token && p.factory) {
30
- this.addFactory(p.token, p.factory);
31
- }
32
- else if (p.provide || p.useClass) {
33
- const provide = p.provide || p.useClass;
34
- if (!provide)
35
- throw new Error(`provide|useClass is not defined`);
36
- const factory = () => {
37
- if (p.useFactory || p.useClass) {
38
- const deps = (p.deps || []).map((dep) => inject(dep));
39
- if (p.useClass)
40
- return new p.useClass(...deps);
41
- else
42
- return p.useFactory(...deps);
43
- }
44
- else if (p.useValue) {
45
- return p.useValue;
46
- }
47
- else if (p.useExisting) {
48
- return inject(p.useExisting);
49
- }
50
- else {
51
- throw new Error(`useClass|useFactory|useValue|useExisting is not defined`);
52
- }
53
- };
54
- this.addFactory(provide, factory);
55
- }
79
+ this.addProvider(p);
56
80
  }
57
81
  }
58
82
  return this;
@@ -95,3 +119,6 @@ export function inject(token) {
95
119
  throw new Error(`No injector found`);
96
120
  return injector.get(token);
97
121
  }
122
+ function isClass(value) {
123
+ return typeof value === "function" && !!value.prototype;
124
+ }
@@ -12,9 +12,11 @@ export interface Type<T> extends Function {
12
12
  new (...args: any[]): T;
13
13
  }
14
14
  export type Token<T = unknown> = string | Symbol | Type<T> | AbstractType<T> | InjectionToken<T>;
15
- export type Provider<T = unknown> = {
15
+ export type ProviderCoreDef<T = unknown> = {
16
16
  token?: Token<T>;
17
17
  factory?: Func<T>;
18
+ };
19
+ export type ProviderAngularLikeDef<T = unknown> = {
18
20
  provide?: Token<T>;
19
21
  multi?: boolean;
20
22
  deps?: Token[];
@@ -23,3 +25,8 @@ export type Provider<T = unknown> = {
23
25
  useValue?: T;
24
26
  useFactory?: FuncArgs<T>;
25
27
  };
28
+ export type Provider<T = unknown> = Type<T> | ProviderCoreDef<T> | ProviderAngularLikeDef<T>;
29
+ export type DIModuleDef = {
30
+ imports: DIModuleDef[];
31
+ providers: Provider[];
32
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@art-ws/di",
3
- "version": "2.0.8",
3
+ "version": "2.0.9",
4
4
  "description": "Dependency injection for TypeScript",
5
5
  "license": "UNLICENSED",
6
6
  "author": "art-ws Team",