@tsed/di 8.8.2 → 8.8.4

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,17 +1,19 @@
1
1
  import "../registries/ProviderRegistry.js";
2
2
  import { Store, type Type } from "@tsed/core";
3
3
  import type { ProviderOpts } from "../interfaces/ProviderOpts.js";
4
- import type { TokenProvider } from "../interfaces/TokenProvider.js";
5
- type ProviderBuilder<Token extends TokenProvider, BaseProvider, T extends object> = {
6
- [K in keyof T as T[K] extends (...args: any[]) => any ? never : K]: (value: T[K]) => ProviderBuilder<Token, BaseProvider, T>;
7
- } & {
4
+ import type { FactoryTokenProvider, TokenProvider } from "../interfaces/TokenProvider.js";
5
+ type BaseMethodsProvider<TypeOf, BaseProvider, T extends object> = {
6
+ [K in keyof T as T[K] extends (...args: any[]) => any ? never : K]: (value: T[K]) => ProviderBuilder<TypeOf, BaseProvider, T>;
7
+ };
8
+ type ProviderBuilder<TypeOf, BaseProvider, T extends object> = BaseMethodsProvider<TypeOf, BaseProvider, T> & {
8
9
  inspect(): BaseProvider;
9
10
  store(): Store;
10
- token(): Token;
11
- factory(f: (...args: unknown[]) => unknown): ProviderBuilder<Token, BaseProvider, T>;
12
- asyncFactory(f: (...args: unknown[]) => Promise<unknown>): ProviderBuilder<Token, BaseProvider, T>;
13
- value(v: unknown): ProviderBuilder<Token, BaseProvider, T>;
14
- class(c: Type): ProviderBuilder<Token, BaseProvider, T>;
11
+ token(): TypeOf;
12
+ factory<FactoryReturn>(f: (...args: unknown[]) => FactoryReturn): ProviderBuilder<FactoryTokenProvider<FactoryReturn>, BaseProvider, T>;
13
+ asyncFactory<FactoryReturn>(f: (...args: unknown[]) => Promise<FactoryReturn>): ProviderBuilder<FactoryTokenProvider<FactoryReturn>, BaseProvider, T>;
14
+ value<Value>(v: Value): ProviderBuilder<FactoryTokenProvider<Value>, BaseProvider, T>;
15
+ class<TokenKlass>(c: Type<TokenKlass>): ProviderBuilder<TokenKlass, BaseProvider, T>;
15
16
  };
16
- export declare function providerBuilder<Provider, Picked extends keyof Provider>(props: string[], baseOpts?: Partial<ProviderOpts<Provider>>): <Token extends TokenProvider>(token: Token, options?: Partial<ProviderOpts<Type>>) => ProviderBuilder<Token, Provider, Pick<Provider, Picked>>;
17
+ export type ProviderBuilderFn<Provider, Picked extends keyof Provider> = <TypeOf extends TokenProvider>(token: TypeOf, options?: Partial<ProviderOpts<Type>>) => ProviderBuilder<TypeOf, Provider, Pick<Provider, Picked>>;
18
+ export declare function providerBuilder<Provider, Picked extends keyof Provider>(props: string[], baseOpts?: Partial<ProviderOpts<Provider>>): ProviderBuilderFn<Provider, Picked>;
17
19
  export {};
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@tsed/di",
3
3
  "description": "DI module for Ts.ED Framework",
4
4
  "type": "module",
5
- "version": "8.8.2",
5
+ "version": "8.8.4",
6
6
  "source": "./src/index.ts",
7
7
  "main": "./lib/esm/index.js",
8
8
  "module": "./lib/esm/index.js",
@@ -30,12 +30,12 @@
30
30
  "uuid": "^10.0.0"
31
31
  },
32
32
  "devDependencies": {
33
- "@tsed/barrels": "8.8.2",
34
- "@tsed/core": "8.8.2",
35
- "@tsed/hooks": "8.8.2",
33
+ "@tsed/barrels": "8.8.4",
34
+ "@tsed/core": "8.8.4",
35
+ "@tsed/hooks": "8.8.4",
36
36
  "@tsed/logger": "^7.0.1",
37
- "@tsed/schema": "8.8.2",
38
- "@tsed/typescript": "8.8.2",
37
+ "@tsed/schema": "8.8.4",
38
+ "@tsed/typescript": "8.8.4",
39
39
  "cross-env": "7.0.3",
40
40
  "eslint": "9.12.0",
41
41
  "typescript": "5.4.5",
@@ -43,10 +43,10 @@
43
43
  "webpack": "^5.75.0"
44
44
  },
45
45
  "peerDependencies": {
46
- "@tsed/core": ">=8.8.2",
47
- "@tsed/hooks": ">=8.8.2",
46
+ "@tsed/core": ">=8.8.4",
47
+ "@tsed/hooks": ">=8.8.4",
48
48
  "@tsed/logger": ">=7.0.1",
49
- "@tsed/schema": ">=8.8.2"
49
+ "@tsed/schema": ">=8.8.4"
50
50
  },
51
51
  "peerDependenciesMeta": {
52
52
  "@tsed/core": {
@@ -14,7 +14,7 @@ describe("LazyInject", () => {
14
14
  lazy: Promise<MyLazyModule>;
15
15
  }
16
16
 
17
- const service = inject<MyInjectable>(MyInjectable);
17
+ const service = inject(MyInjectable);
18
18
  const nbProviders = injector().getProviders().length;
19
19
 
20
20
  const lazyService = await service.lazy;
@@ -202,4 +202,12 @@ export class Provider<T = any> implements ProviderOpts<T> {
202
202
  .filter(Boolean)
203
203
  .join(":");
204
204
  }
205
+
206
+ reset() {
207
+ this.useValue = undefined;
208
+ this.useFactory = undefined;
209
+ this.useAsyncFactory = undefined;
210
+
211
+ return this;
212
+ }
205
213
  }
@@ -20,7 +20,10 @@ import {invokeOptions, localsContainer} from "./localsContainer.js";
20
20
  * @returns {Function}
21
21
  * @decorator
22
22
  */
23
- export function inject<T>(token: TokenProvider<T>, opts?: Partial<Pick<InvokeOptions, "useOpts" | "rebuild" | "locals">>): T {
23
+ export function inject<TokenType>(
24
+ token: TokenProvider<TokenType>,
25
+ opts?: Partial<Pick<InvokeOptions, "useOpts" | "rebuild" | "locals">>
26
+ ): TokenType {
24
27
  return injector().resolve(token, {
25
28
  ...opts,
26
29
  ...invokeOptions(),
@@ -1,3 +1,8 @@
1
1
  import type {AbstractType, Type} from "@tsed/core";
2
2
 
3
- export type TokenProvider<T = any> = string | symbol | Type<T> | AbstractType<T> | Function;
3
+ /**
4
+ * A token is a unique identifier for a provider in the dependency injection system.
5
+ * It solves the inference problem when using `inject()` function.
6
+ */
7
+ export type FactoryTokenProvider<T = any> = T & {readonly __type: "token_factory"};
8
+ export type TokenProvider<T = any> = string | symbol | Type<T> | AbstractType<T> | FactoryTokenProvider<T>;
@@ -469,7 +469,7 @@ export class InjectorService extends Container {
469
469
  provider.useFactory = undefined;
470
470
 
471
471
  if ("useClass" in props) {
472
- provider.useClass = props.useClass;
472
+ provider.useClass = props.useClass as TokenProvider;
473
473
  return;
474
474
  }
475
475
 
@@ -484,7 +484,7 @@ export class InjectorService extends Container {
484
484
  }
485
485
 
486
486
  if ("use" in props) {
487
- provider.useValue = props.use;
487
+ provider.useValue = props.use as unknown;
488
488
  return;
489
489
  }
490
490
  }
@@ -5,26 +5,35 @@ import {Store, type Type} from "@tsed/core";
5
5
  import {ProviderType} from "../domain/ProviderType.js";
6
6
  import {injector} from "../fn/injector.js";
7
7
  import type {ProviderOpts} from "../interfaces/ProviderOpts.js";
8
- import type {TokenProvider} from "../interfaces/TokenProvider.js";
8
+ import type {FactoryTokenProvider, TokenProvider} from "../interfaces/TokenProvider.js";
9
9
  import {GlobalProviders} from "../registries/GlobalProviders.js";
10
10
 
11
- type ProviderBuilder<Token extends TokenProvider, BaseProvider, T extends object> = {
12
- [K in keyof T as T[K] extends (...args: any[]) => any ? never : K]: (value: T[K]) => ProviderBuilder<Token, BaseProvider, T>;
13
- } & {
11
+ type BaseMethodsProvider<TypeOf, BaseProvider, T extends object> = {
12
+ [K in keyof T as T[K] extends (...args: any[]) => any ? never : K]: (value: T[K]) => ProviderBuilder<TypeOf, BaseProvider, T>;
13
+ };
14
+
15
+ type ProviderBuilder<TypeOf, BaseProvider, T extends object> = BaseMethodsProvider<TypeOf, BaseProvider, T> & {
14
16
  inspect(): BaseProvider;
15
17
  store(): Store;
16
- token(): Token;
17
- factory(f: (...args: unknown[]) => unknown): ProviderBuilder<Token, BaseProvider, T>;
18
- asyncFactory(f: (...args: unknown[]) => Promise<unknown>): ProviderBuilder<Token, BaseProvider, T>;
19
- value(v: unknown): ProviderBuilder<Token, BaseProvider, T>;
20
- class(c: Type): ProviderBuilder<Token, BaseProvider, T>;
18
+ token(): TypeOf;
19
+ factory<FactoryReturn>(f: (...args: unknown[]) => FactoryReturn): ProviderBuilder<FactoryTokenProvider<FactoryReturn>, BaseProvider, T>;
20
+ asyncFactory<FactoryReturn>(
21
+ f: (...args: unknown[]) => Promise<FactoryReturn>
22
+ ): ProviderBuilder<FactoryTokenProvider<FactoryReturn>, BaseProvider, T>;
23
+ value<Value>(v: Value): ProviderBuilder<FactoryTokenProvider<Value>, BaseProvider, T>;
24
+ class<TokenKlass>(c: Type<TokenKlass>): ProviderBuilder<TokenKlass, BaseProvider, T>;
21
25
  };
22
26
 
23
- export function providerBuilder<Provider, Picked extends keyof Provider>(props: string[], baseOpts: Partial<ProviderOpts<Provider>> = {}) {
24
- return <Token extends TokenProvider>(
25
- token: Token,
26
- options: Partial<ProviderOpts<Type>> = {}
27
- ): ProviderBuilder<Token, Provider, Pick<Provider, Picked>> => {
27
+ export type ProviderBuilderFn<Provider, Picked extends keyof Provider> = <TypeOf extends TokenProvider>(
28
+ token: TypeOf,
29
+ options?: Partial<ProviderOpts<Type>>
30
+ ) => ProviderBuilder<TypeOf, Provider, Pick<Provider, Picked>>;
31
+
32
+ export function providerBuilder<Provider, Picked extends keyof Provider>(
33
+ props: string[],
34
+ baseOpts: Partial<ProviderOpts<Provider>> = {}
35
+ ): ProviderBuilderFn<Provider, Picked> {
36
+ return <TypeOf extends TokenProvider>(token: TypeOf, options: Partial<ProviderOpts<Type>> = {}) => {
28
37
  const merged = {
29
38
  global: !injector().isLoaded(),
30
39
  ...options,
@@ -49,20 +58,24 @@ export function providerBuilder<Provider, Picked extends keyof Provider>(props:
49
58
  };
50
59
  },
51
60
  {
52
- factory(factory: any) {
61
+ factory(factory: Function) {
62
+ provider.reset();
53
63
  provider.useFactory = factory;
54
64
  return this;
55
65
  },
56
- asyncFactory(asyncFactory: any) {
66
+ asyncFactory(asyncFactory: Function) {
67
+ provider.reset();
57
68
  provider.useAsyncFactory = asyncFactory;
58
69
  return this;
59
70
  },
60
71
  value(value: any) {
72
+ provider.reset();
61
73
  provider.useValue = value;
62
74
  provider.type = ProviderType.VALUE;
63
75
  return this;
64
76
  },
65
77
  class(k: any) {
78
+ provider.reset();
66
79
  provider.useClass = k;
67
80
  return this;
68
81
  },
@@ -73,9 +86,9 @@ export function providerBuilder<Provider, Picked extends keyof Provider>(props:
73
86
  return provider;
74
87
  },
75
88
  token() {
76
- return provider.token as Token;
89
+ return provider.token as TypeOf;
77
90
  }
78
- } as ProviderBuilder<Token, Provider, Pick<Provider, Picked>>
91
+ } as ProviderBuilder<TypeOf, Provider, Pick<Provider, Picked>>
79
92
  );
80
93
  };
81
94
  }
@@ -63,9 +63,9 @@ export class DITest {
63
63
  static async invoke<T = any>(target: TokenProvider<T>, providers: UseImportTokenProviderOpts[] = []): Promise<T> {
64
64
  const locals = localsContainer({providers, rebuild: true});
65
65
 
66
- const instance: T & OnInit = inject<T & OnInit>(target, {locals, rebuild: true});
66
+ const instance: T & Partial<OnInit> = inject(target as any, {locals, rebuild: true});
67
67
 
68
- if (instance && isObject(instance) && "$onInit" in instance) {
68
+ if (instance && isObject(instance) && instance?.$onInit) {
69
69
  const result = instance.$onInit();
70
70
 
71
71
  if (result instanceof Promise) {