@tsed/di 8.18.1 → 8.19.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.
Files changed (89) hide show
  1. package/lib/esm/common/decorators/autoInjectable.js +28 -9
  2. package/lib/esm/common/decorators/constant.js +26 -22
  3. package/lib/esm/common/decorators/controller.js +40 -20
  4. package/lib/esm/common/decorators/injectable.js +30 -10
  5. package/lib/esm/common/decorators/intercept.js +41 -3
  6. package/lib/esm/common/decorators/interceptor.js +31 -4
  7. package/lib/esm/common/decorators/module.js +36 -5
  8. package/lib/esm/common/decorators/opts.js +20 -12
  9. package/lib/esm/common/decorators/overrideProvider.js +38 -4
  10. package/lib/esm/common/decorators/scope.js +32 -3
  11. package/lib/esm/common/decorators/service.js +24 -4
  12. package/lib/esm/common/decorators/useOpts.js +21 -13
  13. package/lib/esm/common/decorators/value.js +28 -22
  14. package/lib/esm/common/domain/Container.js +20 -0
  15. package/lib/esm/common/domain/ContextLogger.js +21 -0
  16. package/lib/esm/common/domain/ControllerProvider.js +22 -0
  17. package/lib/esm/common/domain/DIContext.js +22 -0
  18. package/lib/esm/common/domain/InjectablePropertyType.js +16 -0
  19. package/lib/esm/common/domain/LocalsContainer.js +21 -0
  20. package/lib/esm/common/domain/Provider.js +19 -0
  21. package/lib/esm/common/domain/ProviderScope.js +25 -0
  22. package/lib/esm/common/domain/ProviderType.js +25 -0
  23. package/lib/esm/common/errors/InjectionError.js +24 -0
  24. package/lib/esm/common/errors/InvalidPropertyTokenError.js +15 -0
  25. package/lib/esm/common/fn/inject.js +19 -6
  26. package/lib/esm/common/fn/injectMany.js +24 -6
  27. package/lib/esm/common/fn/injectable.js +57 -0
  28. package/lib/esm/common/fn/injector.js +21 -2
  29. package/lib/esm/common/fn/lazyInject.js +48 -1
  30. package/lib/esm/common/fn/localsContainer.js +31 -2
  31. package/lib/esm/common/fn/logger.js +15 -1
  32. package/lib/esm/common/services/DIConfiguration.js +24 -0
  33. package/lib/esm/common/services/DILogger.js +23 -0
  34. package/lib/esm/common/services/InjectorService.js +89 -43
  35. package/lib/types/common/decorators/autoInjectable.d.ts +31 -10
  36. package/lib/types/common/decorators/configuration.d.ts +32 -2
  37. package/lib/types/common/decorators/constant.d.ts +26 -22
  38. package/lib/types/common/decorators/controller.d.ts +40 -20
  39. package/lib/types/common/decorators/inject.d.ts +29 -7
  40. package/lib/types/common/decorators/injectable.d.ts +30 -10
  41. package/lib/types/common/decorators/intercept.d.ts +41 -3
  42. package/lib/types/common/decorators/interceptor.d.ts +31 -4
  43. package/lib/types/common/decorators/lazyInject.d.ts +43 -9
  44. package/lib/types/common/decorators/module.d.ts +36 -5
  45. package/lib/types/common/decorators/opts.d.ts +20 -12
  46. package/lib/types/common/decorators/overrideProvider.d.ts +38 -4
  47. package/lib/types/common/decorators/scope.d.ts +32 -3
  48. package/lib/types/common/decorators/service.d.ts +24 -4
  49. package/lib/types/common/decorators/useOpts.d.ts +21 -13
  50. package/lib/types/common/decorators/value.d.ts +28 -22
  51. package/lib/types/common/domain/Container.d.ts +20 -0
  52. package/lib/types/common/domain/ContextLogger.d.ts +26 -0
  53. package/lib/types/common/domain/ControllerProvider.d.ts +29 -0
  54. package/lib/types/common/domain/DIContext.d.ts +27 -0
  55. package/lib/types/common/domain/InjectablePropertyType.d.ts +16 -0
  56. package/lib/types/common/domain/LocalsContainer.d.ts +21 -0
  57. package/lib/types/common/domain/Provider.d.ts +25 -0
  58. package/lib/types/common/domain/ProviderScope.d.ts +25 -0
  59. package/lib/types/common/domain/ProviderType.d.ts +25 -0
  60. package/lib/types/common/errors/InjectionError.d.ts +24 -0
  61. package/lib/types/common/errors/InvalidPropertyTokenError.d.ts +15 -0
  62. package/lib/types/common/fn/configuration.d.ts +31 -0
  63. package/lib/types/common/fn/constant.d.ts +22 -0
  64. package/lib/types/common/fn/inject.d.ts +19 -6
  65. package/lib/types/common/fn/injectMany.d.ts +24 -6
  66. package/lib/types/common/fn/injectable.d.ts +57 -0
  67. package/lib/types/common/fn/injector.d.ts +21 -2
  68. package/lib/types/common/fn/lazyInject.d.ts +48 -1
  69. package/lib/types/common/fn/localsContainer.d.ts +31 -2
  70. package/lib/types/common/fn/logger.d.ts +15 -1
  71. package/lib/types/common/fn/refValue.d.ts +15 -6
  72. package/lib/types/common/interfaces/AlterRunInContext.d.ts +26 -0
  73. package/lib/types/common/interfaces/DILogger.d.ts +36 -0
  74. package/lib/types/common/interfaces/DILoggerOptions.d.ts +23 -0
  75. package/lib/types/common/interfaces/ImportTokenProviderOpts.d.ts +43 -0
  76. package/lib/types/common/interfaces/InterceptorContext.d.ts +35 -0
  77. package/lib/types/common/interfaces/InterceptorMethods.d.ts +27 -0
  78. package/lib/types/common/interfaces/InvokeOptions.d.ts +8 -0
  79. package/lib/types/common/interfaces/OnDestroy.d.ts +22 -0
  80. package/lib/types/common/interfaces/OnInit.d.ts +22 -0
  81. package/lib/types/common/interfaces/ProviderOpts.d.ts +31 -0
  82. package/lib/types/common/interfaces/ResolvedInvokeOptions.d.ts +9 -0
  83. package/lib/types/common/interfaces/TokenProvider.d.ts +32 -2
  84. package/lib/types/common/interfaces/TokenRoute.d.ts +16 -0
  85. package/lib/types/common/services/DIConfiguration.d.ts +24 -0
  86. package/lib/types/common/services/DILogger.d.ts +28 -0
  87. package/lib/types/common/services/InjectorService.d.ts +89 -43
  88. package/lib/types/node/utils/asyncHookContext.d.ts +0 -1
  89. package/package.json +6 -6
@@ -15,38 +15,44 @@ export function bindValue(target, propertyKey, expression, defaultValue) {
15
15
  catchError(() => Reflect.defineProperty(target, propertyKey, descriptor));
16
16
  }
17
17
  /**
18
- * Return value from Configuration.
18
+ * Inject a reactive configuration value into a property.
19
19
  *
20
- * ## Example
20
+ * Creates a getter/setter that always reflects the current configuration value.
21
+ * Unlike `@Constant()`, the value is not frozen and can change at runtime.
21
22
  *
22
- * ```typescript
23
- * import {Env} from "@tsed/core/domain/Env.js";
24
- * import {Constant, Value} from "@tsed/di";
25
- *
26
- * export class MyClass {
23
+ * ### Usage
27
24
  *
28
- * @Constant("env")
29
- * env: Env;
25
+ * ```typescript
26
+ * import {Injectable, Value} from "@tsed/di";
30
27
  *
31
- * @Value("swagger.path")
32
- * swaggerPath: string;
28
+ * @Injectable()
29
+ * export class MyService {
30
+ * @Value("swagger.path")
31
+ * swaggerPath: string;
33
32
  *
34
- * @Value("swagger.path", "defaultValue")
35
- * swaggerPath: string;
33
+ * @Value("api.port", 3000)
34
+ * port: number;
36
35
  *
37
- * constructor() {
38
- * console.log(this.swaggerPath) // undefined. Not available on constructor
39
- * }
36
+ * constructor() {
37
+ * // Not available yet - undefined
38
+ * }
40
39
  *
41
- * $onInit() {
42
- * console.log(this.swaggerPath) // something
43
- * }
40
+ * $onInit() {
41
+ * console.log(this.swaggerPath); // Current value
42
+ * this.swaggerPath = "/new-path"; // Can be modified
43
+ * }
44
44
  * }
45
45
  * ```
46
46
  *
47
- * @param expression
48
- * @param defaultValue
49
- * @returns {(targetClass: any, attributeName: string) => any}
47
+ * ### Difference from @Constant
48
+ *
49
+ * - `@Constant`: Frozen immutable value (deep clone)
50
+ * - `@Value`: Reactive value (always reads current config)
51
+ *
52
+ * @param expression Dot-notation path to the configuration value
53
+ * @param defaultValue Optional default value if not found
54
+ * @returns Property decorator function
55
+ * @public
50
56
  * @decorator
51
57
  */
52
58
  export function Value(expression, defaultValue) {
@@ -1,5 +1,25 @@
1
1
  import { GlobalProviders } from "../registries/GlobalProviders.js";
2
2
  import { Provider } from "./Provider.js";
3
+ /**
4
+ * Provider container managing registered providers and their metadata.
5
+ *
6
+ * Extends `Map` to provide specialized methods for adding, retrieving, and managing providers
7
+ * within the dependency injection system. Acts as a registry for all injectable classes and values.
8
+ *
9
+ * ### Usage
10
+ *
11
+ * ```typescript
12
+ * import {Container} from "@tsed/di";
13
+ *
14
+ * const container = new Container();
15
+ * container.add(MyService, {scope: ProviderScope.SINGLETON});
16
+ *
17
+ * const provider = container.getProvider(MyService);
18
+ * const controllers = container.getProviders(ProviderType.CONTROLLER);
19
+ * ```
20
+ *
21
+ * @public
22
+ */
3
23
  export class Container extends Map {
4
24
  /**
5
25
  *
@@ -2,6 +2,27 @@ import { Hooks } from "@tsed/hooks";
2
2
  import { levels } from "@tsed/logger";
3
3
  import { logger as injectLogger } from "../../common/index.js";
4
4
  const LEVELS = levels();
5
+ /**
6
+ * Context-aware logger for scoped logging within a request or execution context.
7
+ *
8
+ * Buffers log messages and associates them with a specific context (like an HTTP request).
9
+ * Supports log level filtering, buffering, and automatic flushing when the context ends.
10
+ *
11
+ * ### Usage
12
+ *
13
+ * ```typescript
14
+ * import {ContextLogger} from "@tsed/di";
15
+ *
16
+ * const logger = new ContextLogger({id: "req-123"});
17
+ *
18
+ * logger.info("Processing request");
19
+ * logger.debug("Debug info");
20
+ *
21
+ * await logger.flush(); // Write buffered logs
22
+ * ```
23
+ *
24
+ * @public
25
+ */
5
26
  export class ContextLogger {
6
27
  #additionalProps;
7
28
  #level;
@@ -1,5 +1,27 @@
1
1
  import { Provider } from "./Provider.js";
2
2
  import { ProviderType } from "./ProviderType.js";
3
+ /**
4
+ * Specialized provider for HTTP controllers.
5
+ *
6
+ * Extends the base `Provider` class with controller-specific metadata like middleware configuration
7
+ * and routing information. Used internally to manage HTTP route controllers in the DI system.
8
+ *
9
+ * ### Usage
10
+ *
11
+ * ```typescript
12
+ * import {ControllerProvider} from "@tsed/di";
13
+ *
14
+ * const provider = new ControllerProvider(MyController);
15
+ * provider.middlewares = {
16
+ * useBefore: [AuthMiddleware],
17
+ * use: [ValidationMiddleware],
18
+ * useAfter: [LoggingMiddleware]
19
+ * };
20
+ * ```
21
+ *
22
+ * @typeParam T - The type of controller class
23
+ * @public
24
+ */
3
25
  export class ControllerProvider extends Provider {
4
26
  constructor(token, options = {}) {
5
27
  super(token, options);
@@ -1,5 +1,27 @@
1
1
  import { injector, LocalsContainer } from "../index.js";
2
2
  import { ContextLogger } from "./ContextLogger.js";
3
+ /**
4
+ * Execution context for dependency injection operations.
5
+ *
6
+ * Represents a single execution scope (typically an HTTP request) with its own
7
+ * scoped provider instances, logger, and lifecycle management. Provides access to
8
+ * request-scoped services and context-specific data.
9
+ *
10
+ * ### Usage
11
+ *
12
+ * ```typescript
13
+ * import {DIContext} from "@tsed/di";
14
+ *
15
+ * const context = new DIContext({id: "req-123"});
16
+ *
17
+ * context.logger.info("Processing request");
18
+ * const service = await context.injector.invoke(MyService, context.container);
19
+ *
20
+ * await context.destroy(); // Cleanup when done
21
+ * ```
22
+ *
23
+ * @public
24
+ */
3
25
  export class DIContext {
4
26
  #container;
5
27
  #cache;
@@ -1,3 +1,19 @@
1
+ /**
2
+ * Enumeration defining types of injectable properties and decorators.
3
+ *
4
+ * Used internally to track and classify different kinds of injected dependencies
5
+ * and decorated members within a class.
6
+ *
7
+ * ### Types
8
+ *
9
+ * - `METHOD`: Injectable method parameter
10
+ * - `PROPERTY`: Injectable class property
11
+ * - `CONSTANT`: Injected constant value
12
+ * - `VALUE`: Injected configured value
13
+ * - `INTERCEPTOR`: Interceptor applied to a method
14
+ *
15
+ * @public
16
+ */
1
17
  export var InjectablePropertyType;
2
18
  (function (InjectablePropertyType) {
3
19
  InjectablePropertyType["METHOD"] = "method";
@@ -1,4 +1,25 @@
1
1
  import { Hooks } from "@tsed/hooks";
2
+ /**
3
+ * Container for request-scoped and instance-scoped provider instances.
4
+ *
5
+ * Stores instances created within a specific execution context (like an HTTP request).
6
+ * Manages lifecycle hooks and destruction of scoped instances when the context ends.
7
+ *
8
+ * ### Usage
9
+ *
10
+ * ```typescript
11
+ * import {LocalsContainer} from "@tsed/di";
12
+ *
13
+ * const locals = new LocalsContainer();
14
+ * locals.set(MyService, serviceInstance);
15
+ *
16
+ * const instance = locals.get(MyService);
17
+ *
18
+ * await locals.destroy(); // Cleanup when context ends
19
+ * ```
20
+ *
21
+ * @public
22
+ */
2
23
  export class LocalsContainer extends Map {
3
24
  constructor() {
4
25
  super(...arguments);
@@ -7,6 +7,25 @@ import { DI_USE_PARAM_OPTIONS } from "../constants/constants.js";
7
7
  import { discoverHooks } from "../utils/discoverHooks.js";
8
8
  import { ProviderScope } from "./ProviderScope.js";
9
9
  import { ProviderType } from "./ProviderType.js";
10
+ /**
11
+ * Provider metadata class managing dependency injection configuration.
12
+ *
13
+ * Encapsulates all information needed to create, configure, and manage a provider instance
14
+ * within the DI container. Tracks dependencies, lifecycle hooks, creation strategies, and metadata.
15
+ *
16
+ * ### Usage
17
+ *
18
+ * ```typescript
19
+ * import {Provider, ProviderType} from "@tsed/di";
20
+ *
21
+ * const provider = new Provider(MyService);
22
+ * provider.type = ProviderType.PROVIDER;
23
+ * provider.deps = [DatabaseService, LoggerService];
24
+ * ```
25
+ *
26
+ * @typeParam T - The type of instance this provider creates
27
+ * @public
28
+ */
10
29
  export class Provider {
11
30
  #useClass;
12
31
  #token;
@@ -1,3 +1,28 @@
1
+ /**
2
+ * Enumeration defining the lifecycle scopes for provider instances.
3
+ *
4
+ * Determines when and how provider instances are created and shared across the application.
5
+ *
6
+ * ### Scopes
7
+ *
8
+ * - `SINGLETON`: One instance shared across the entire application (default)
9
+ * - `REQUEST`: New instance created for each request/context
10
+ * - `INSTANCE`: New instance created on every injection
11
+ *
12
+ * ### Usage
13
+ *
14
+ * ```typescript
15
+ * import {Injectable, Scope, ProviderScope} from "@tsed/di";
16
+ *
17
+ * @Injectable()
18
+ * @Scope(ProviderScope.REQUEST)
19
+ * class RequestScopedService {
20
+ * // New instance per request
21
+ * }
22
+ * ```
23
+ *
24
+ * @public
25
+ */
1
26
  export var ProviderScope;
2
27
  (function (ProviderScope) {
3
28
  ProviderScope["SINGLETON"] = "singleton";
@@ -1,3 +1,28 @@
1
+ /**
2
+ * Enumeration categorizing different types of providers in the DI system.
3
+ *
4
+ * Used to classify and filter providers based on their role in the application architecture.
5
+ * Each type represents a distinct pattern or responsibility within the framework.
6
+ *
7
+ * ### Types
8
+ *
9
+ * - `VALUE`: Simple value providers (constants, configuration)
10
+ * - `PROVIDER`: Standard service providers
11
+ * - `MODULE`: Module providers organizing related functionality
12
+ * - `CONTROLLER`: HTTP route controllers
13
+ * - `INTERCEPTOR`: Method interceptors for cross-cutting concerns
14
+ * - `MIDDLEWARE`: Request/response middleware
15
+ *
16
+ * ### Usage
17
+ *
18
+ * ```typescript
19
+ * import {ProviderType} from "@tsed/di";
20
+ *
21
+ * const providers = container.getProviders(ProviderType.CONTROLLER);
22
+ * ```
23
+ *
24
+ * @public
25
+ */
1
26
  export var ProviderType;
2
27
  (function (ProviderType) {
3
28
  ProviderType["VALUE"] = "value";
@@ -3,6 +3,30 @@ import { isClass } from "@tsed/core/utils/isClass.js";
3
3
  import { isString } from "@tsed/core/utils/isString.js";
4
4
  import { nameOf } from "@tsed/core/utils/nameOf.js";
5
5
  import { colors } from "../utils/colors.js";
6
+ /**
7
+ * Error thrown when dependency injection fails.
8
+ *
9
+ * Provides detailed information about the failed injection including the dependency chain
10
+ * and the original error. Helps diagnose circular dependencies, missing providers, and
11
+ * configuration issues in the DI system.
12
+ *
13
+ * ### Usage
14
+ *
15
+ * ```typescript
16
+ * import {InjectionError} from "@tsed/di";
17
+ *
18
+ * try {
19
+ * injector.invoke(MyService);
20
+ * } catch (error) {
21
+ * if (error instanceof InjectionError) {
22
+ * console.log("Dependency chain:", error.tokens);
23
+ * console.log("Original error:", error.origin);
24
+ * }
25
+ * }
26
+ * ```
27
+ *
28
+ * @public
29
+ */
6
30
  export class InjectionError extends Error {
7
31
  constructor(token, origin) {
8
32
  super(isString(origin) ? origin : "");
@@ -1,5 +1,20 @@
1
1
  import { classOf } from "@tsed/core/utils/classOf.js";
2
2
  import { nameOf } from "@tsed/core/utils/nameOf.js";
3
+ /**
4
+ * Error thrown when an invalid token is used for property injection.
5
+ *
6
+ * Typically indicates a circular reference, missing import, or undefined token
7
+ * in property decorators like `@Inject()` or `@Constant()`.
8
+ *
9
+ * ### Common causes
10
+ *
11
+ * - Circular dependency between classes
12
+ * - Missing or incorrect import statement
13
+ * - Using `undefined` as a token
14
+ * - Forward reference not properly handled
15
+ *
16
+ * @public
17
+ */
3
18
  export class InvalidPropertyTokenError extends Error {
4
19
  constructor(target, propertyKey) {
5
20
  super(`Object isn't a valid token. Please check the token set on ${nameOf(classOf(target))}.${propertyKey}.\n- Check that it is not a circular reference.\n- Check that the token (class or symbol) exists`);
@@ -1,21 +1,34 @@
1
1
  import { injector } from "./injector.js";
2
2
  import { invokeOptions, localsContainer } from "./localsContainer.js";
3
3
  /**
4
- * Inject a provider to another provider.
4
+ * Programmatically inject a provider instance.
5
5
  *
6
- * Use this function to inject a custom provider on constructor parameter or property.
6
+ * Resolves and returns a provider instance using the global injector.
7
+ * Useful for injecting dependencies outside of decorators or in property initializers.
8
+ *
9
+ * ### Usage
7
10
  *
8
11
  * ```typescript
12
+ * import {inject, Injectable} from "@tsed/di";
13
+ *
9
14
  * @Injectable()
10
15
  * export class MyService {
16
+ * // Property injection
11
17
  * connection = inject(CONNECTION);
18
+ *
19
+ * // Function injection
20
+ * getData() {
21
+ * const api = inject(ApiService);
22
+ * return api.fetch();
23
+ * }
12
24
  * }
13
25
  * ```
14
26
  *
15
- * @param token A token provider or token provider group
16
- * @param opts
17
- * @returns {Function}
18
- * @decorator
27
+ * @typeParam TokenType The type of the injected provider
28
+ * @param token The provider token to resolve
29
+ * @param opts Optional invocation options (locals, rebuild, useOpts)
30
+ * @returns The resolved provider instance
31
+ * @public
19
32
  */
20
33
  export function inject(token, opts) {
21
34
  return injector().resolve(token, {
@@ -1,13 +1,31 @@
1
1
  import { injector } from "./injector.js";
2
2
  import { localsContainer } from "./localsContainer.js";
3
3
  /**
4
- * Injects multiple instances of a given token using the injector service.
5
- * @param token - The injection token to resolve
6
- * @param opts - Optional configuration for the injection
7
- * @param opts.useOpts - Options for instance creation
8
- * @param opts.rebuild - Whether to rebuild the instance
9
- * @param opts.locals - Local container overrides
4
+ * Inject all providers matching a given token type.
5
+ *
6
+ * Resolves multiple provider instances that share the same type or group token.
7
+ * Useful for getting all providers of a specific category (e.g., all controllers, all middleware).
8
+ *
9
+ * ### Usage
10
+ *
11
+ * ```typescript
12
+ * import {injectMany, ProviderType} from "@tsed/di";
13
+ *
14
+ * // Get all controllers
15
+ * const controllers = injectMany(ProviderType.CONTROLLER);
16
+ *
17
+ * // Get all providers of a custom type
18
+ * const plugins = injectMany(Symbol.for("PLUGIN"));
19
+ * ```
20
+ *
21
+ * @typeParam T The type of instances to return
22
+ * @param token The injection token or type to resolve
23
+ * @param opts Optional invocation options
24
+ * @param opts.useOpts Options passed to instance creation
25
+ * @param opts.rebuild Whether to rebuild instances
26
+ * @param opts.locals Local container overrides
10
27
  * @returns Array of resolved instances
28
+ * @public
11
29
  */
12
30
  export function injectMany(token, opts) {
13
31
  return injector().getMany(token, { ...opts, locals: opts?.locals || localsContainer() });
@@ -1,10 +1,67 @@
1
1
  import { ProviderType } from "../domain/ProviderType.js";
2
2
  import { providerBuilder } from "../utils/providerBuilder.js";
3
3
  const Props = ["type", "scope", "path", "alias", "hooks", "deps", "imports", "configuration", "priority"];
4
+ /**
5
+ * Fluent builder for registering providers programmatically.
6
+ *
7
+ * Creates or configures a provider with the specified options.
8
+ * Can be chained with additional configuration methods.
9
+ *
10
+ * ### Usage
11
+ *
12
+ * ```typescript
13
+ * import {injectable} from "@tsed/di";
14
+ *
15
+ * injectable(MyService)
16
+ * .scope(ProviderScope.REQUEST)
17
+ * .deps([DatabaseService])
18
+ * .build();
19
+ *
20
+ * // With factory
21
+ * injectable("CONFIG")
22
+ * .factory(() => loadConfig())
23
+ * .build();
24
+ * ```
25
+ *
26
+ * @public
27
+ */
4
28
  export const injectable = providerBuilder(Props);
29
+ /**
30
+ * Fluent builder for registering interceptor providers.
31
+ *
32
+ * Specialized version of `injectable` that automatically sets the provider type to `INTERCEPTOR`.
33
+ *
34
+ * ### Usage
35
+ *
36
+ * ```typescript
37
+ * import {interceptor} from "@tsed/di";
38
+ *
39
+ * interceptor(LogInterceptor).build();
40
+ * ```
41
+ *
42
+ * @public
43
+ */
5
44
  export const interceptor = providerBuilder(Props, {
6
45
  type: ProviderType.INTERCEPTOR
7
46
  });
47
+ /**
48
+ * Fluent builder for registering controller providers.
49
+ *
50
+ * Specialized version of `injectable` that automatically sets the provider type to `CONTROLLER`
51
+ * and supports controller-specific options like middlewares.
52
+ *
53
+ * ### Usage
54
+ *
55
+ * ```typescript
56
+ * import {controller} from "@tsed/di";
57
+ *
58
+ * controller(UsersController)
59
+ * .middlewares({useBefore: [AuthMiddleware]})
60
+ * .build();
61
+ * ```
62
+ *
63
+ * @public
64
+ */
8
65
  export const controller = providerBuilder([...Props, "middlewares"], {
9
66
  type: ProviderType.CONTROLLER
10
67
  });
@@ -1,9 +1,12 @@
1
1
  import { InjectorService } from "../services/InjectorService.js";
2
2
  let globalInjector = new InjectorService();
3
3
  /**
4
- * Return the existing injector service.
4
+ * Get the global injector service instance.
5
5
  *
6
- * Example:
6
+ * Returns the singleton instance of `InjectorService` managing all registered providers.
7
+ * Use this to access the DI container programmatically.
8
+ *
9
+ * ### Usage
7
10
  *
8
11
  * ```typescript
9
12
  * import {injector, Injectable} from "@tsed/di";
@@ -11,12 +14,28 @@ let globalInjector = new InjectorService();
11
14
  * @Injectable()
12
15
  * class MyService {
13
16
  * injector = injector();
17
+ *
18
+ * getService() {
19
+ * return injector().get(OtherService);
20
+ * }
14
21
  * }
15
22
  * ```
23
+ *
24
+ * @returns The global injector service instance
25
+ * @public
16
26
  */
17
27
  export function injector() {
18
28
  return globalInjector;
19
29
  }
30
+ /**
31
+ * Destroy the current injector and create a fresh instance.
32
+ *
33
+ * Calls the `destroy()` lifecycle hook on all providers and resets the global injector.
34
+ * Primarily used in testing to reset the DI container between tests.
35
+ *
36
+ * @returns Promise that resolves when destruction is complete
37
+ * @public
38
+ */
20
39
  export async function destroyInjector() {
21
40
  await globalInjector.destroy();
22
41
  globalInjector = new InjectorService();
@@ -2,7 +2,30 @@ import { isFunction } from "@tsed/core/utils/isFunction.js";
2
2
  import { inject } from "./inject.js";
3
3
  import { injector } from "./injector.js";
4
4
  /**
5
- * Lazy load a provider from his package and invoke only when the provider is used.
5
+ * Lazily load and inject a provider from a dynamic import.
6
+ *
7
+ * Loads the provider module asynchronously, registers it if needed, calls `$onInit` if present,
8
+ * and returns the resolved instance. Useful for code splitting and lazy loading dependencies.
9
+ *
10
+ * ### Usage
11
+ *
12
+ * ```typescript
13
+ * import {lazyInject} from "@tsed/di";
14
+ *
15
+ * // Lazy load a service
16
+ * const service = await lazyInject(() => import("./HeavyService"));
17
+ *
18
+ * // Use in a method
19
+ * async loadPlugin() {
20
+ * const plugin = await lazyInject(() => import("./plugins/MyPlugin"));
21
+ * return plugin.initialize();
22
+ * }
23
+ * ```
24
+ *
25
+ * @typeParam Token The type of the provider to inject
26
+ * @param factory Function returning a dynamic import promise with a default export
27
+ * @returns Promise resolving to the provider instance
28
+ * @public
6
29
  */
7
30
  export async function lazyInject(factory) {
8
31
  const { default: token } = await factory();
@@ -15,6 +38,30 @@ export async function lazyInject(factory) {
15
38
  }
16
39
  return injector().get(token);
17
40
  }
41
+ /**
42
+ * Attempt to lazily load and inject a provider, returning undefined on failure.
43
+ *
44
+ * Similar to `lazyInject` but catches errors and returns undefined instead of throwing.
45
+ * Useful for optional dependencies that may not be available.
46
+ *
47
+ * ### Usage
48
+ *
49
+ * ```typescript
50
+ * import {optionalLazyInject} from "@tsed/di";
51
+ *
52
+ * // Try to load optional plugin
53
+ * const plugin = await optionalLazyInject(() => import("./optional/Plugin"));
54
+ *
55
+ * if (plugin) {
56
+ * plugin.activate();
57
+ * }
58
+ * ```
59
+ *
60
+ * @typeParam Token The type of the provider to inject
61
+ * @param factory Function returning a dynamic import promise with a default export
62
+ * @returns Promise resolving to the provider instance or undefined if loading fails
63
+ * @public
64
+ */
18
65
  export async function optionalLazyInject(factory) {
19
66
  try {
20
67
  return await lazyInject(factory);
@@ -5,7 +5,31 @@ let globalLocals;
5
5
  let globalInvOpts = {};
6
6
  const stagedLocals = [];
7
7
  /**
8
- * Get the locals container initiated by DITest or .bootstrap() method.
8
+ * Get or create the current locals container for request-scoped providers.
9
+ *
10
+ * Returns the global locals container used for storing request-scoped provider instances.
11
+ * Can optionally create a new container with custom providers.
12
+ *
13
+ * ### Usage
14
+ *
15
+ * ```typescript
16
+ * import {localsContainer} from "@tsed/di";
17
+ *
18
+ * // Get current locals
19
+ * const locals = localsContainer();
20
+ *
21
+ * // Create with custom providers
22
+ * const locals = localsContainer({
23
+ * providers: [{token: MyService, use: mockInstance}],
24
+ * rebuild: true
25
+ * });
26
+ * ```
27
+ *
28
+ * @param options Configuration options
29
+ * @param options.providers Optional array of provider overrides
30
+ * @param options.rebuild Whether to mark providers for rebuilding
31
+ * @returns The locals container instance
32
+ * @public
9
33
  */
10
34
  export function localsContainer({ providers, rebuild } = {}) {
11
35
  if (!globalLocals || providers) {
@@ -26,7 +50,12 @@ export function invokeOptions() {
26
50
  return { ...globalInvOpts };
27
51
  }
28
52
  /**
29
- * Reset the locals container.
53
+ * Detach and stage the current locals container.
54
+ *
55
+ * Removes the global locals reference and saves it for cleanup.
56
+ * Used internally to manage request scope lifecycle.
57
+ *
58
+ * @public
30
59
  */
31
60
  export function detachLocalsContainer() {
32
61
  globalLocals && stagedLocals.push(globalLocals);