@velajs/vela 1.9.0 → 1.12.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 (161) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/dist/__tests__/workers-als/entry-als.d.ts +9 -0
  3. package/dist/application.d.ts +18 -0
  4. package/dist/application.js +45 -0
  5. package/dist/cache/cache.module.d.ts +5 -7
  6. package/dist/cache/cache.module.js +44 -66
  7. package/dist/cache/cache.types.d.ts +26 -0
  8. package/dist/cache/cache.types.js +1 -1
  9. package/dist/cache/index.d.ts +2 -1
  10. package/dist/cache/index.js +1 -0
  11. package/dist/cache/tiered-cache.store.d.ts +19 -0
  12. package/dist/cache/tiered-cache.store.js +40 -0
  13. package/dist/config/config.module.d.ts +6 -5
  14. package/dist/config/config.module.js +46 -49
  15. package/dist/container/container.d.ts +58 -0
  16. package/dist/container/container.js +223 -18
  17. package/dist/container/disposable.d.ts +5 -0
  18. package/dist/container/disposable.js +33 -0
  19. package/dist/container/types.d.ts +8 -0
  20. package/dist/cors/cors.module.d.ts +5 -5
  21. package/dist/cors/cors.module.js +26 -25
  22. package/dist/discovery/discoverable.decorator.d.ts +38 -0
  23. package/dist/discovery/discoverable.decorator.js +42 -0
  24. package/dist/discovery/discovery.service.d.ts +94 -0
  25. package/dist/discovery/discovery.service.js +166 -0
  26. package/dist/discovery/index.d.ts +2 -0
  27. package/dist/discovery/index.js +2 -0
  28. package/dist/entrypoint/entrypoint.registry.d.ts +40 -0
  29. package/dist/entrypoint/entrypoint.registry.js +106 -0
  30. package/dist/entrypoint/entrypoint.types.d.ts +41 -0
  31. package/dist/entrypoint/entrypoint.types.js +3 -0
  32. package/dist/entrypoint/execution-context.d.ts +15 -0
  33. package/dist/entrypoint/execution-context.js +21 -0
  34. package/dist/entrypoint/execution-scope.d.ts +21 -0
  35. package/dist/entrypoint/execution-scope.js +28 -0
  36. package/dist/entrypoint/index.d.ts +4 -0
  37. package/dist/entrypoint/index.js +4 -0
  38. package/dist/event-emitter/event-emitter.subscriber.d.ts +3 -3
  39. package/dist/event-emitter/event-emitter.subscriber.js +12 -29
  40. package/dist/factory/adapter.d.ts +36 -0
  41. package/dist/factory/adapter.js +18 -0
  42. package/dist/factory/bootstrap.js +20 -2
  43. package/dist/factory.d.ts +11 -1
  44. package/dist/factory.js +23 -2
  45. package/dist/fetch/fetch.module.d.ts +5 -6
  46. package/dist/fetch/fetch.module.js +9 -42
  47. package/dist/http/ambient.d.ts +17 -0
  48. package/dist/http/ambient.js +44 -0
  49. package/dist/http/execution-context.js +4 -1
  50. package/dist/http/handler-executor.js +22 -19
  51. package/dist/http/index.d.ts +1 -0
  52. package/dist/http/index.js +1 -0
  53. package/dist/http/route-contributor.d.ts +68 -0
  54. package/dist/http/route-contributor.js +22 -0
  55. package/dist/http/route.manager.d.ts +19 -0
  56. package/dist/http/route.manager.js +112 -19
  57. package/dist/i18n/deep-merge.d.ts +2 -0
  58. package/dist/i18n/deep-merge.js +15 -0
  59. package/dist/i18n/i18n.middleware.d.ts +15 -0
  60. package/dist/i18n/i18n.middleware.js +94 -0
  61. package/dist/i18n/i18n.module.d.ts +13 -0
  62. package/dist/i18n/i18n.module.js +64 -0
  63. package/dist/i18n/i18n.options.d.ts +30 -0
  64. package/dist/i18n/i18n.options.js +16 -0
  65. package/dist/i18n/i18n.service.d.ts +20 -0
  66. package/dist/i18n/i18n.service.js +49 -0
  67. package/dist/i18n/i18n.tokens.d.ts +6 -0
  68. package/dist/i18n/i18n.tokens.js +3 -0
  69. package/dist/i18n/i18n.types.d.ts +6 -0
  70. package/dist/i18n/i18n.types.js +1 -0
  71. package/dist/i18n/index.d.ts +10 -0
  72. package/dist/i18n/index.js +8 -0
  73. package/dist/i18n/message-loader.service.d.ts +21 -0
  74. package/dist/i18n/message-loader.service.js +90 -0
  75. package/dist/i18n/message-registry.d.ts +16 -0
  76. package/dist/i18n/message-registry.js +49 -0
  77. package/dist/index.d.ts +17 -5
  78. package/dist/index.js +14 -3
  79. package/dist/internal.d.ts +0 -2
  80. package/dist/internal.js +0 -7
  81. package/dist/module/configurable-module.builder.d.ts +56 -0
  82. package/dist/module/configurable-module.builder.js +84 -0
  83. package/dist/module/configurable-module.types.d.ts +93 -0
  84. package/dist/module/configurable-module.types.js +5 -0
  85. package/dist/module/define-module.d.ts +105 -0
  86. package/dist/module/define-module.js +227 -0
  87. package/dist/module/index.d.ts +4 -0
  88. package/dist/module/index.js +3 -0
  89. package/dist/module/lazy-provider.d.ts +65 -0
  90. package/dist/module/lazy-provider.js +111 -0
  91. package/dist/openapi/document.js +16 -15
  92. package/dist/pipeline/component.manager.d.ts +15 -9
  93. package/dist/pipeline/component.manager.js +32 -46
  94. package/dist/pipeline/index.d.ts +2 -0
  95. package/dist/pipeline/index.js +1 -0
  96. package/dist/pipeline/pipeline-runner.d.ts +31 -0
  97. package/dist/pipeline/pipeline-runner.js +40 -0
  98. package/dist/pipeline/types.d.ts +21 -4
  99. package/dist/registry/metadata.registry.d.ts +24 -18
  100. package/dist/registry/metadata.registry.js +137 -49
  101. package/dist/schedule/schedule.module.d.ts +5 -0
  102. package/dist/schedule/schedule.module.js +18 -8
  103. package/dist/schedule/schedule.registry.d.ts +3 -3
  104. package/dist/schedule/schedule.registry.js +23 -44
  105. package/dist/schedule-node/schedule-node.module.d.ts +5 -0
  106. package/dist/schedule-node/schedule-node.module.js +20 -10
  107. package/dist/seeder/index.d.ts +5 -0
  108. package/dist/seeder/index.js +4 -0
  109. package/dist/seeder/seeder.decorator.d.ts +7 -0
  110. package/dist/seeder/seeder.decorator.js +15 -0
  111. package/dist/seeder/seeder.module.d.ts +16 -0
  112. package/dist/seeder/seeder.module.js +41 -0
  113. package/dist/seeder/seeder.registry.d.ts +23 -0
  114. package/dist/seeder/seeder.registry.js +83 -0
  115. package/dist/seeder/seeder.tokens.d.ts +2 -0
  116. package/dist/seeder/seeder.tokens.js +1 -0
  117. package/dist/seeder/seeder.types.d.ts +20 -0
  118. package/dist/seeder/seeder.types.js +1 -0
  119. package/dist/storage/index.d.ts +4 -0
  120. package/dist/storage/index.js +2 -0
  121. package/dist/storage/path-template.d.ts +9 -0
  122. package/dist/storage/path-template.js +20 -0
  123. package/dist/storage/signed-url.d.ts +12 -0
  124. package/dist/storage/signed-url.js +55 -0
  125. package/dist/storage/storage.types.d.ts +41 -0
  126. package/dist/storage/storage.types.js +5 -0
  127. package/dist/throttler/throttler.module.d.ts +5 -8
  128. package/dist/throttler/throttler.module.js +27 -55
  129. package/dist/websocket/index.d.ts +12 -0
  130. package/dist/websocket/index.js +16 -0
  131. package/dist/websocket/websocket.decorators.d.ts +33 -0
  132. package/dist/websocket/websocket.decorators.js +58 -0
  133. package/dist/websocket/websocket.module.d.ts +35 -0
  134. package/dist/websocket/websocket.module.js +63 -0
  135. package/dist/websocket/websocket.tokens.d.ts +23 -0
  136. package/dist/websocket/websocket.tokens.js +21 -0
  137. package/dist/websocket/websocket.types.d.ts +86 -0
  138. package/dist/websocket/websocket.types.js +4 -0
  139. package/dist/websocket/ws-argument-resolver.d.ts +13 -0
  140. package/dist/websocket/ws-argument-resolver.js +40 -0
  141. package/dist/websocket/ws-dispatcher.d.ts +45 -0
  142. package/dist/websocket/ws-dispatcher.js +259 -0
  143. package/dist/websocket/ws-exception.d.ts +16 -0
  144. package/dist/websocket/ws-exception.js +32 -0
  145. package/dist/websocket/ws-execution-context.d.ts +9 -0
  146. package/dist/websocket/ws-execution-context.js +24 -0
  147. package/dist/websocket/ws-server.d.ts +31 -0
  148. package/dist/websocket/ws-server.js +74 -0
  149. package/dist/websocket/ws-sync.d.ts +47 -0
  150. package/dist/websocket/ws-sync.js +74 -0
  151. package/dist/websocket-node/index.d.ts +4 -0
  152. package/dist/websocket-node/index.js +5 -0
  153. package/dist/websocket-node/node-ws-client.d.ts +24 -0
  154. package/dist/websocket-node/node-ws-client.js +49 -0
  155. package/dist/websocket-node/redis-sync.d.ts +33 -0
  156. package/dist/websocket-node/redis-sync.js +56 -0
  157. package/dist/websocket-node/register-gateways.d.ts +20 -0
  158. package/dist/websocket-node/register-gateways.js +61 -0
  159. package/package.json +31 -1
  160. package/dist/http/crud-bridge.d.ts +0 -90
  161. package/dist/http/crud-bridge.js +0 -25
@@ -0,0 +1,90 @@
1
+ function _ts_decorate(decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ }
7
+ function _ts_metadata(k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ }
10
+ function _ts_param(paramIndex, decorator) {
11
+ return function(target, key) {
12
+ decorator(target, key, paramIndex);
13
+ };
14
+ }
15
+ import IntlMessageFormat from "intl-messageformat";
16
+ import { Inject, Injectable } from "../container/decorators.js";
17
+ import { I18N_OPTIONS } from "./i18n.tokens.js";
18
+ import { MessageRegistry } from "./message-registry.js";
19
+ export class MessageLoaderService {
20
+ cache = new Map();
21
+ compiledCache = new Map();
22
+ defaultLocale;
23
+ fallbackLocale;
24
+ constructor(registry, options){
25
+ this.defaultLocale = options?.defaultLocale ?? 'en';
26
+ this.fallbackLocale = options?.fallbackLocale ?? this.defaultLocale;
27
+ const merged = registry.getMergedMessages();
28
+ for (const locale of Object.keys(merged)){
29
+ this.cache.set(locale, merged[locale]);
30
+ }
31
+ }
32
+ translate(locale, key, params) {
33
+ const primary = this.getCompiledMessages(locale)[key];
34
+ if (primary) return primary(params);
35
+ // Per-key fallback: a supported locale missing an individual key falls back
36
+ // to fallbackLocale before giving up (returning the raw key).
37
+ if (this.fallbackLocale !== locale) {
38
+ const fallback = this.getCompiledMessages(this.fallbackLocale)[key];
39
+ if (fallback) return fallback(params);
40
+ }
41
+ return key; // missing everywhere → return the key (dev-friendly)
42
+ }
43
+ getAvailableLocales() {
44
+ return [
45
+ ...this.cache.keys()
46
+ ];
47
+ }
48
+ isLocaleSupported(locale) {
49
+ return this.cache.has(locale);
50
+ }
51
+ getDefaultLocale() {
52
+ return this.defaultLocale;
53
+ }
54
+ getCompiledMessages(locale) {
55
+ const effectiveLocale = this.cache.has(locale) ? locale : this.defaultLocale;
56
+ const cached = this.compiledCache.get(effectiveLocale);
57
+ if (cached) return cached;
58
+ const flattened = this.flattenMessages(this.cache.get(effectiveLocale) ?? {});
59
+ const compiled = {};
60
+ for (const [key, value] of Object.entries(flattened)){
61
+ const msg = new IntlMessageFormat(value, effectiveLocale);
62
+ compiled[key] = (params)=>String(msg.format(params));
63
+ }
64
+ this.compiledCache.set(effectiveLocale, compiled);
65
+ return compiled;
66
+ }
67
+ flattenMessages(messages, prefix = '') {
68
+ const result = {};
69
+ for (const key of Object.keys(messages)){
70
+ const value = messages[key];
71
+ const newKey = prefix ? `${prefix}.${key}` : key;
72
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
73
+ Object.assign(result, this.flattenMessages(value, newKey));
74
+ } else {
75
+ result[newKey] = String(value);
76
+ }
77
+ }
78
+ return result;
79
+ }
80
+ }
81
+ MessageLoaderService = _ts_decorate([
82
+ Injectable(),
83
+ _ts_param(0, Inject(MessageRegistry)),
84
+ _ts_param(1, Inject(I18N_OPTIONS)),
85
+ _ts_metadata("design:type", Function),
86
+ _ts_metadata("design:paramtypes", [
87
+ typeof MessageRegistry === "undefined" ? Object : MessageRegistry,
88
+ typeof I18nModuleOptions === "undefined" ? Object : I18nModuleOptions
89
+ ])
90
+ ], MessageLoaderService);
@@ -0,0 +1,16 @@
1
+ type Contribution = Record<string, Record<string, unknown>>;
2
+ /**
3
+ * Accumulates i18n messages from multiple `I18nModule.registerMessages()` calls
4
+ * (statically, at module import time), deep-merged on read by
5
+ * {@link MessageLoaderService}. Later registrations override earlier ones at the
6
+ * leaf level.
7
+ */
8
+ export declare class MessageRegistry {
9
+ /** Called by `I18nModule.registerMessages()`. */
10
+ static addMessages(messages: Contribution): void;
11
+ /** All contributions deep-merged, per locale, in registration order. */
12
+ getMergedMessages(): Record<string, Record<string, unknown>>;
13
+ /** @internal — testing */
14
+ static reset(): void;
15
+ }
16
+ export {};
@@ -0,0 +1,49 @@
1
+ function _ts_decorate(decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ }
7
+ import { Injectable } from "../container/decorators.js";
8
+ import { deepMerge } from "./deep-merge.js";
9
+ // Shared contributions store anchored on globalThis so bundler-inlined copies
10
+ // (portal/symlink) and Vite HMR re-eval share ONE store. Content-keyed so
11
+ // re-registering identical messages (HMR) dedups instead of accumulating.
12
+ const CONTRIBUTIONS_KEY = Symbol.for('vela:i18n:message-registry:contributions');
13
+ function getContributions() {
14
+ const g = globalThis;
15
+ return g[CONTRIBUTIONS_KEY] ??= new Map();
16
+ }
17
+ function contentKey(value) {
18
+ if (Array.isArray(value)) return `[${value.map(contentKey).join(',')}]`;
19
+ if (typeof value === 'object' && value !== null) {
20
+ const entries = Object.keys(value).sort().map((key)=>`${JSON.stringify(key)}:${contentKey(value[key])}`);
21
+ return `{${entries.join(',')}}`;
22
+ }
23
+ return JSON.stringify(value) ?? 'undefined';
24
+ }
25
+ export class MessageRegistry {
26
+ /** Called by `I18nModule.registerMessages()`. */ static addMessages(messages) {
27
+ if (messages && typeof messages === 'object' && Object.keys(messages).length > 0) {
28
+ // set() dedups by content-key AND preserves insertion order for an existing
29
+ // key. (A prior delete+set moved re-registered content to the end, flipping
30
+ // deep-merge precedence under HMR re-eval.)
31
+ getContributions().set(contentKey(messages), messages);
32
+ }
33
+ }
34
+ /** All contributions deep-merged, per locale, in registration order. */ getMergedMessages() {
35
+ const merged = {};
36
+ for (const contribution of getContributions().values()){
37
+ for (const locale of Object.keys(contribution)){
38
+ merged[locale] = deepMerge(merged[locale] ?? {}, contribution[locale]);
39
+ }
40
+ }
41
+ return merged;
42
+ }
43
+ /** @internal — testing */ static reset() {
44
+ globalThis[CONTRIBUTIONS_KEY] = new Map();
45
+ }
46
+ }
47
+ MessageRegistry = _ts_decorate([
48
+ Injectable()
49
+ ], MessageRegistry);
package/dist/index.d.ts CHANGED
@@ -12,6 +12,7 @@ export { METADATA_KEYS, HttpMethod, ParamType, Scope } from './constants';
12
12
  export { Controller, Version, Get, Post, Put, Patch, Delete, Options, Head, All, Sse, Param, Query, Body, Headers, Req, Res, Ip, Cookie, Cookies, RawBody, HttpCode, Header, Redirect, createParamDecorator, createLazyParamDecorator, applyDecorators, } from './http/index';
13
13
  export { REQUEST_CONTEXT } from './http/request-context';
14
14
  export type { RequestContext } from './http/request-context';
15
+ export { enableAmbientContainer, getCurrentContainer, getCurrentRequestContext, } from './http/ambient';
15
16
  export { Logger, LogLevel } from './services/index';
16
17
  export type { LoggerService, ContextProvider, Writer, LoggerLevelName } from './services/index';
17
18
  export { ConfigModule, ConfigService, CONFIG_OPTIONS } from './config/index';
@@ -20,22 +21,33 @@ export { HttpModule, HttpService, HTTP_MODULE_OPTIONS, HttpRequestException } fr
20
21
  export type { HttpModuleOptions, HttpResponse, HttpRequestConfig } from './fetch/index';
21
22
  export { CorsModule, CORS_OPTIONS } from './cors/index';
22
23
  export type { CorsOptions } from './cors/index';
23
- export { CacheModule, CacheService, CacheInterceptor, MemoryCacheStore, CacheKey, CacheTTL, CACHE_MANAGER, CACHE_MODULE_OPTIONS, CACHE_KEY_METADATA, CACHE_TTL_METADATA, } from './cache/index';
24
- export type { CacheModuleOptions, CacheStore, CacheEntry } from './cache/index';
24
+ export { CacheModule, CacheService, CacheInterceptor, MemoryCacheStore, TieredCacheStore, CacheKey, CacheTTL, CACHE_MANAGER, CACHE_MODULE_OPTIONS, CACHE_KEY_METADATA, CACHE_TTL_METADATA, } from './cache/index';
25
+ export type { Awaitable, CacheModuleOptions, CacheStore, AsyncCacheStore, AnyCacheStore, CacheEntry, } from './cache/index';
25
26
  export { EventEmitterModule, EventEmitter, EventEmitterSubscriber, OnEvent, ON_EVENT_METADATA, } from './event-emitter/index';
26
27
  export type { EventHandler, OnEventMetadata } from './event-emitter/index';
27
28
  export { ScheduleModule, ScheduleRegistry, Cron, Interval, parseCron, CRON_METADATA, INTERVAL_METADATA, } from './schedule/index';
28
29
  export type { RegisteredCronJob, RegisteredIntervalJob, CronMetadata, IntervalMetadata, CronMatcher, } from './schedule/index';
30
+ export { WebSocketModule, WebSocketGateway, SubscribeMessage, MessageBody, ConnectedSocket, WebSocketServer, WsDispatcher, WsException, WS_SERVER, } from './websocket/index';
31
+ export type { WebSocketModuleOptions, WsClient, WsServer, WsMessage, WsResponse, WsExecutionContext, WsArgumentsHost, BroadcastCommand, SyncDriver, RoomRegistry, OnGatewayInit, OnGatewayConnection, OnGatewayDisconnect, } from './websocket/index';
29
32
  export { HealthModule, HealthCheckService, HealthIndicatorService, HttpHealthIndicator, } from './health/index';
30
33
  export type { HealthCheckResult, HealthCheckStatus, HealthIndicatorResult, HealthIndicatorFunction, ResponseCheckCallback, HttpPingOptions, } from './health/index';
31
34
  export { ThrottlerModule, ThrottlerGuard, ThrottlerStorage, Throttle, SkipThrottle, THROTTLER_OPTIONS, THROTTLER_STORAGE, THROTTLE_METADATA, SKIP_THROTTLE_METADATA, } from './throttler/index';
32
35
  export type { ThrottlerModuleOptions, ThrottleConfig, ThrottlerStore, ThrottlerStorageRecord, RateLimitInfo, } from './throttler/index';
33
- export { Global, Module, defineDynamicModule, stableHash, } from './module/index';
34
- export type { ModuleOptions, DynamicModule, AsyncModuleOptions, ModuleImport } from './module/index';
36
+ export { Global, Module, defineDynamicModule, stableHash, moduleKey, ConfigurableModuleBuilder, defineConfigurableModule, defineModule, buildAsyncOptionsProviders, lazyProvider, moduleToken, provideGlobal, sideEffectModule, } from './module/index';
37
+ export type { ModuleOptions, DynamicModule, AsyncModuleOptions, ModuleImport, ConfigurableModuleAsyncOptions, ConfigurableModuleBuilderOptions, ConfigurableModuleClassType, ConfigurableModuleExtras, ConfigurableModuleExtrasTransform, ConfigurableModuleHost, ConfigurableModuleOptionsFactory, DefineConfigurableModuleSpec, DefineModuleSpec, GlobalComponentSlot, ModuleContributions, ModuleSetupContext, LazyProviderSpec, } from './module/index';
35
38
  export type { MiddlewareConsumer, NestModule, RouteInfo } from './http/index';
39
+ export { DiscoveryService, createDiscoverableDecorator, } from './discovery/index';
40
+ export type { DiscoveredClass, DiscoveredMethodMeta, DiscoveryFilter, DiscoverableDecorator, CreateDiscoverableDecoratorOptions, } from './discovery/index';
41
+ export { EntrypointRegistry, registerEntrypointKind, getEntrypointKinds, contributesEntrypoints, runInEntrypointScope, buildEntrypointExecutionContext, } from './entrypoint/index';
42
+ export type { ContributesEntrypoints, Entrypoint, EntrypointKind, EntrypointExecutionContext, } from './entrypoint/index';
43
+ export { registerRouteContributor, getRouteContributors, } from './http/route-contributor';
44
+ export type { RouteContributor, RouteContributorContext, RouteContributorOpenApiContext, } from './http/route-contributor';
45
+ export type { AdapterContext, RuntimeAdapter } from './factory/adapter';
46
+ export type { VelaCreateOptions } from './factory';
36
47
  export { definePlugin, composePlugins, PluginRegistry, PluginRootModule, PLUGIN_REGISTRY_TOKEN, } from './plugin/plugin';
37
48
  export type { Plugin } from './plugin/plugin';
38
- export { UseMiddleware, UseGuards, UsePipes, UseInterceptors, UseFilters, Catch, SetMetadata, Reflector, APP_GUARD, APP_PIPE, APP_INTERCEPTOR, APP_FILTER, APP_MIDDLEWARE, } from './pipeline/index';
49
+ export { UseMiddleware, UseGuards, UsePipes, UseInterceptors, UseFilters, Catch, SetMetadata, Reflector, PipelineRunner, getCatchTypes, shouldFilterCatch, APP_GUARD, APP_PIPE, APP_INTERCEPTOR, APP_FILTER, APP_MIDDLEWARE, } from './pipeline/index';
50
+ export type { PipelineRunOptions } from './pipeline/index';
39
51
  export type { HttpArgumentsHost, ExecutionContext, CanActivate, CallHandler, NestInterceptor, NestMiddleware, PipeTransform, ExceptionFilter, ArgumentMetadata, ReflectableDecorator, CreateDecoratorOptions, } from './pipeline/index';
40
52
  export type { Constructor, MiddlewareType, GuardType, PipeType, InterceptorType, FilterType, } from './registry/index';
41
53
  export { ParseIntPipe, ParseFloatPipe, ParseBoolPipe, ParseUUIDPipe, ParseEnumPipe, ParseArrayPipe, DefaultValuePipe, RequiredPipe, ZodValidationPipe, } from './pipeline/index';
package/dist/index.js CHANGED
@@ -14,6 +14,8 @@ export { METADATA_KEYS, HttpMethod, ParamType, Scope } from "./constants.js";
14
14
  export { Controller, Version, Get, Post, Put, Patch, Delete, Options, Head, All, Sse, Param, Query, Body, Headers, Req, Res, Ip, Cookie, Cookies, RawBody, HttpCode, Header, Redirect, createParamDecorator, createLazyParamDecorator, applyDecorators } from "./http/index.js";
15
15
  // Request-scoped context primitive
16
16
  export { REQUEST_CONTEXT } from "./http/request-context.js";
17
+ // Opt-in ambient container access (ALS via hono/context-storage)
18
+ export { enableAmbientContainer, getCurrentContainer, getCurrentRequestContext } from "./http/ambient.js";
17
19
  // Services
18
20
  export { Logger, LogLevel } from "./services/index.js";
19
21
  // Config
@@ -23,21 +25,30 @@ export { HttpModule, HttpService, HTTP_MODULE_OPTIONS, HttpRequestException } fr
23
25
  // CORS
24
26
  export { CorsModule, CORS_OPTIONS } from "./cors/index.js";
25
27
  // Cache
26
- export { CacheModule, CacheService, CacheInterceptor, MemoryCacheStore, CacheKey, CacheTTL, CACHE_MANAGER, CACHE_MODULE_OPTIONS, CACHE_KEY_METADATA, CACHE_TTL_METADATA } from "./cache/index.js";
28
+ export { CacheModule, CacheService, CacheInterceptor, MemoryCacheStore, TieredCacheStore, CacheKey, CacheTTL, CACHE_MANAGER, CACHE_MODULE_OPTIONS, CACHE_KEY_METADATA, CACHE_TTL_METADATA } from "./cache/index.js";
27
29
  // Event Emitter
28
30
  export { EventEmitterModule, EventEmitter, EventEmitterSubscriber, OnEvent, ON_EVENT_METADATA } from "./event-emitter/index.js";
29
31
  // Schedule
30
32
  export { ScheduleModule, ScheduleRegistry, Cron, Interval, parseCron, CRON_METADATA, INTERVAL_METADATA } from "./schedule/index.js";
33
+ // WebSocket (edge-safe core; transport-facing internals live at @velajs/vela/websocket)
34
+ export { WebSocketModule, WebSocketGateway, SubscribeMessage, MessageBody, ConnectedSocket, WebSocketServer, WsDispatcher, WsException, WS_SERVER } from "./websocket/index.js";
31
35
  // Health
32
36
  export { HealthModule, HealthCheckService, HealthIndicatorService, HttpHealthIndicator } from "./health/index.js";
33
37
  // Throttler
34
38
  export { ThrottlerModule, ThrottlerGuard, ThrottlerStorage, Throttle, SkipThrottle, THROTTLER_OPTIONS, THROTTLER_STORAGE, THROTTLE_METADATA, SKIP_THROTTLE_METADATA } from "./throttler/index.js";
35
39
  // Module
36
- export { Global, Module, defineDynamicModule, stableHash } from "./module/index.js";
40
+ export { Global, Module, defineDynamicModule, stableHash, moduleKey, ConfigurableModuleBuilder, defineConfigurableModule, defineModule, buildAsyncOptionsProviders, lazyProvider, moduleToken, provideGlobal, sideEffectModule } from "./module/index.js";
41
+ // Discovery — decorator-driven provider discovery (the public replacement for
42
+ // hand-rolled bootstrap scans)
43
+ export { DiscoveryService, createDiscoverableDecorator } from "./discovery/index.js";
44
+ // Entrypoints — the open non-HTTP entry surface (websocket, queue, cron, …)
45
+ export { EntrypointRegistry, registerEntrypointKind, getEntrypointKinds, contributesEntrypoints, runInEntrypointScope, buildEntrypointExecutionContext } from "./entrypoint/index.js";
46
+ // Route contribution — metadata-claimed route generators (@Crud-style)
47
+ export { registerRouteContributor, getRouteContributors } from "./http/route-contributor.js";
37
48
  // Plugin manifest + composer
38
49
  export { definePlugin, composePlugins, PluginRegistry, PluginRootModule, PLUGIN_REGISTRY_TOKEN } from "./plugin/plugin.js";
39
50
  // Pipeline Decorators
40
- export { UseMiddleware, UseGuards, UsePipes, UseInterceptors, UseFilters, Catch, SetMetadata, Reflector, APP_GUARD, APP_PIPE, APP_INTERCEPTOR, APP_FILTER, APP_MIDDLEWARE } from "./pipeline/index.js";
51
+ export { UseMiddleware, UseGuards, UsePipes, UseInterceptors, UseFilters, Catch, SetMetadata, Reflector, PipelineRunner, getCatchTypes, shouldFilterCatch, APP_GUARD, APP_PIPE, APP_INTERCEPTOR, APP_FILTER, APP_MIDDLEWARE } from "./pipeline/index.js";
41
52
  // Built-in Pipes
42
53
  export { ParseIntPipe, ParseFloatPipe, ParseBoolPipe, ParseUUIDPipe, ParseEnumPipe, ParseArrayPipe, DefaultValuePipe, RequiredPipe, ZodValidationPipe } from "./pipeline/index.js";
43
54
  // Errors
@@ -5,8 +5,6 @@ export type { ModuleScope, ContainerOptions, Diagnostics, } from './container/ty
5
5
  export { bindAppProviders } from './pipeline/app-providers';
6
6
  export { RouteManager } from './http/route.manager';
7
7
  export type { RouteManagerOptions } from './http/route.manager';
8
- export { registerCrudBridge, getCrudBridge, } from './http/crud-bridge';
9
- export type { CrudBridge, CrudBridgeRouteContext, CrudBridgeOpenApiContext, } from './http/crud-bridge';
10
8
  export { ModuleLoader } from './module/module-loader';
11
9
  export { ComponentManager } from './pipeline/component.manager';
12
10
  export { VelaApplication } from './application';
package/dist/internal.js CHANGED
@@ -6,13 +6,6 @@ export { ModuleRef } from "./container/module-ref.js";
6
6
  export { ModuleVisibilityError } from "./container/types.js";
7
7
  export { bindAppProviders } from "./pipeline/app-providers.js";
8
8
  export { RouteManager } from "./http/route.manager.js";
9
- // CRUD bridge registry — the integration seam for `@velajs/crud` (and any
10
- // future CRUD route generator). `@velajs/crud` calls `registerCrudBridge`
11
- // once at import time; the framework consults `getCrudBridge` whenever it
12
- // encounters a controller carrying `vela:crud` metadata, both at route
13
- // build time and at OpenAPI document generation. The types are exposed so
14
- // integrators can write their own bridges or strongly-typed mocks in tests.
15
- export { registerCrudBridge, getCrudBridge } from "./http/crud-bridge.js";
16
9
  export { ModuleLoader } from "./module/module-loader.js";
17
10
  export { ComponentManager } from "./pipeline/component.manager.js";
18
11
  export { VelaApplication } from "./application.js";
@@ -0,0 +1,56 @@
1
+ import type { DynamicModule } from '../registry/types';
2
+ import type { ConfigurableModuleBuilderOptions, ConfigurableModuleExtras, ConfigurableModuleExtrasTransform, ConfigurableModuleHost, DefineConfigurableModuleSpec } from './configurable-module.types';
3
+ /**
4
+ * Blessed key-derivation helper for hand-written `forRoot` statics: the one
5
+ * documented way to derive a `DynamicModule.key` from an options bag so
6
+ * identical configurations dedup (HMR-idempotent) and distinct ones coexist.
7
+ * Alias of {@link stableHash} with a module-authoring name.
8
+ */
9
+ export declare const moduleKey: (options: unknown) => string;
10
+ /**
11
+ * NestJS-parity builder that generates `forRoot`/`forRootAsync` (and `key`,
12
+ * `global`, factory-param inference) from a tiny spec — so a module is just its
13
+ * tokens + options type + service + a `@Module({...})` bag, while vela keeps its
14
+ * encapsulation (`exports`/visibility) and multi-instance `key` dedup.
15
+ *
16
+ * Since 1.11 this is a thin adapter over {@link defineModule} — the single
17
+ * authoring engine. Prefer `defineModule` for new modules: it additionally
18
+ * supports contributions (providers/controllers/imports/exports/global
19
+ * components) computed as functions of the options.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
24
+ * new ConfigurableModuleBuilder<FooOptions>({ moduleName: 'Foo' }).build();
25
+ *
26
+ * @Module({
27
+ * providers: [FooService], // derived providers inject MODULE_OPTIONS_TOKEN
28
+ * exports: [FooService],
29
+ * })
30
+ * export class FooModule extends ConfigurableModuleClass {}
31
+ * ```
32
+ */
33
+ export declare class ConfigurableModuleBuilder<Opts, MethodKey extends string = 'forRoot', FactoryMethodKey extends string = 'create', Extras extends ConfigurableModuleExtras = {
34
+ isGlobal?: boolean;
35
+ }> {
36
+ private readonly options;
37
+ private classMethodName;
38
+ private factoryMethodName;
39
+ private extrasDefaults;
40
+ private extrasTransform;
41
+ constructor(options?: ConfigurableModuleBuilderOptions);
42
+ /** Declare extra call-site keys (e.g. `isGlobal`) + how they reshape the definition. */
43
+ setExtras<NewExtras extends ConfigurableModuleExtras>(defaults: NewExtras, transform: ConfigurableModuleExtrasTransform<NewExtras>): ConfigurableModuleBuilder<Opts, MethodKey, FactoryMethodKey, NewExtras>;
44
+ /** Rename the sync static (default `forRoot`); the async static becomes `<name>Async`. */
45
+ setClassMethodName<NewMethodKey extends string>(name: NewMethodKey): ConfigurableModuleBuilder<Opts, NewMethodKey, FactoryMethodKey, Extras>;
46
+ /** Rename the method a `useClass`/`useExisting` options factory must implement (default `create`). */
47
+ setFactoryMethodName<NewFactoryMethodKey extends string>(name: NewFactoryMethodKey): ConfigurableModuleBuilder<Opts, MethodKey, NewFactoryMethodKey, Extras>;
48
+ build(): ConfigurableModuleHost<Opts, MethodKey, FactoryMethodKey, Extras>;
49
+ }
50
+ /**
51
+ * Lower-level engine for cases a class-mixin can't express — chiefly a
52
+ * runtime-generated module class whose providers depend on a call-time arg
53
+ * (Cloudflare binding modules). Returns an object with a single static named by
54
+ * `spec.methodName` (default `forRoot`).
55
+ */
56
+ export declare function defineConfigurableModule<Args>(spec: DefineConfigurableModuleSpec<Args>): Record<string, (args: Args) => DynamicModule>;
@@ -0,0 +1,84 @@
1
+ import { defineModule } from "./define-module.js";
2
+ import { stableHash } from "./stable-hash.js";
3
+ /**
4
+ * Blessed key-derivation helper for hand-written `forRoot` statics: the one
5
+ * documented way to derive a `DynamicModule.key` from an options bag so
6
+ * identical configurations dedup (HMR-idempotent) and distinct ones coexist.
7
+ * Alias of {@link stableHash} with a module-authoring name.
8
+ */ export const moduleKey = stableHash;
9
+ /**
10
+ * NestJS-parity builder that generates `forRoot`/`forRootAsync` (and `key`,
11
+ * `global`, factory-param inference) from a tiny spec — so a module is just its
12
+ * tokens + options type + service + a `@Module({...})` bag, while vela keeps its
13
+ * encapsulation (`exports`/visibility) and multi-instance `key` dedup.
14
+ *
15
+ * Since 1.11 this is a thin adapter over {@link defineModule} — the single
16
+ * authoring engine. Prefer `defineModule` for new modules: it additionally
17
+ * supports contributions (providers/controllers/imports/exports/global
18
+ * components) computed as functions of the options.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
23
+ * new ConfigurableModuleBuilder<FooOptions>({ moduleName: 'Foo' }).build();
24
+ *
25
+ * @Module({
26
+ * providers: [FooService], // derived providers inject MODULE_OPTIONS_TOKEN
27
+ * exports: [FooService],
28
+ * })
29
+ * export class FooModule extends ConfigurableModuleClass {}
30
+ * ```
31
+ */ export class ConfigurableModuleBuilder {
32
+ options;
33
+ classMethodName = 'forRoot';
34
+ factoryMethodName = 'create';
35
+ extrasDefaults;
36
+ extrasTransform;
37
+ constructor(options = {}){
38
+ this.options = options;
39
+ }
40
+ /** Declare extra call-site keys (e.g. `isGlobal`) + how they reshape the definition. */ setExtras(defaults, transform) {
41
+ this.extrasDefaults = defaults;
42
+ this.extrasTransform = transform;
43
+ return this;
44
+ }
45
+ /** Rename the sync static (default `forRoot`); the async static becomes `<name>Async`. */ setClassMethodName(name) {
46
+ this.classMethodName = name;
47
+ return this;
48
+ }
49
+ /** Rename the method a `useClass`/`useExisting` options factory must implement (default `create`). */ setFactoryMethodName(name) {
50
+ this.factoryMethodName = name;
51
+ return this;
52
+ }
53
+ build() {
54
+ return defineModule({
55
+ name: this.options.moduleName ?? 'ConfigurableModule',
56
+ optionsToken: this.options.optionsInjectionToken,
57
+ extras: this.extrasDefaults,
58
+ transform: this.extrasTransform,
59
+ methodName: this.classMethodName,
60
+ factoryMethodName: this.factoryMethodName
61
+ });
62
+ }
63
+ }
64
+ /**
65
+ * Lower-level engine for cases a class-mixin can't express — chiefly a
66
+ * runtime-generated module class whose providers depend on a call-time arg
67
+ * (Cloudflare binding modules). Returns an object with a single static named by
68
+ * `spec.methodName` (default `forRoot`).
69
+ */ export function defineConfigurableModule(spec) {
70
+ const methodName = spec.methodName ?? 'forRoot';
71
+ return {
72
+ [methodName] (args) {
73
+ const definition = {
74
+ module: spec.module,
75
+ key: spec.keyFrom(args),
76
+ providers: spec.providers(args)
77
+ };
78
+ if (spec.imports) definition.imports = spec.imports(args);
79
+ if (spec.exports) definition.exports = spec.exports;
80
+ if (spec.global) definition.global = true;
81
+ return definition;
82
+ }
83
+ };
84
+ }
@@ -0,0 +1,93 @@
1
+ import type { InferTokens, InjectionToken, Token, Type } from '../container/types';
2
+ import type { DynamicModule, ModuleImport } from '../registry/types';
3
+ /**
4
+ * Arbitrary extra keys a module accepts alongside its options bag (e.g.
5
+ * `isGlobal`). Kept separate from the options type so the extras-transform can
6
+ * reshape the generated {@link DynamicModule} without polluting `Opts`.
7
+ */
8
+ export type ConfigurableModuleExtras = Record<string, unknown>;
9
+ /**
10
+ * Reshape the generated definition based on the resolved extras. Runs after the
11
+ * options provider + `key` are computed; the return value is the final
12
+ * `DynamicModule`. Mirrors NestJS's `extras` transform.
13
+ */
14
+ export type ConfigurableModuleExtrasTransform<E extends ConfigurableModuleExtras> = (definition: DynamicModule, extras: E) => DynamicModule;
15
+ /**
16
+ * The contract a `useClass`/`useExisting` async-options factory must satisfy:
17
+ * a single method (default name `create`) returning the module options.
18
+ */
19
+ export type ConfigurableModuleOptionsFactory<Opts, MethodName extends string> = {
20
+ [K in MethodName]: () => Opts | Promise<Opts>;
21
+ };
22
+ /**
23
+ * Async configuration accepted by the generated `<method>Async` static.
24
+ *
25
+ * Superset of `AsyncModuleOptions` (`registry/types.ts`): adds NestJS's
26
+ * `useClass`/`useExisting` while preserving the headline `const Inject` tuple
27
+ * inference for `useFactory` params (no `as const` needed at the call site).
28
+ */
29
+ export interface ConfigurableModuleAsyncOptions<Opts, MethodName extends string = 'create', Inject extends readonly Token<unknown>[] = readonly Token<unknown>[]> {
30
+ imports?: ModuleImport[];
31
+ inject?: Inject;
32
+ useFactory?: (...args: InferTokens<Inject>) => Opts | Promise<Opts>;
33
+ useClass?: Type<ConfigurableModuleOptionsFactory<Opts, MethodName>>;
34
+ useExisting?: Token<ConfigurableModuleOptionsFactory<Opts, MethodName>>;
35
+ /** Explicit instance discriminator (see {@link DynamicModule.key}). */
36
+ key?: string;
37
+ }
38
+ export interface ConfigurableModuleBuilderOptions {
39
+ /** Names the generated base class + the auto-minted options token, and feeds diagnostics. */
40
+ moduleName?: string;
41
+ /**
42
+ * Reuse an existing options token instead of minting one. **Critical for
43
+ * migrations** so the module's public token keeps its identity.
44
+ */
45
+ optionsInjectionToken?: InjectionToken<unknown>;
46
+ }
47
+ /**
48
+ * The generated base class type, carrying dynamically-named `<method>` and
49
+ * `<method>Async` statics. A module does `class Foo extends ConfigurableModuleClass {}`
50
+ * and gets `Foo.forRoot(...)` / `Foo.forRootAsync(...)` for free.
51
+ */
52
+ export type ConfigurableModuleClassType<Opts, MethodKey extends string, FactoryMethodKey extends string, Extras extends ConfigurableModuleExtras> = (new () => object) & Record<MethodKey, (options: Opts & Partial<Extras> & {
53
+ key?: string;
54
+ }) => DynamicModule> & Record<`${MethodKey}Async`, <const Inject extends readonly Token<unknown>[]>(options: ConfigurableModuleAsyncOptions<Opts, FactoryMethodKey, Inject> & Partial<Extras> & {
55
+ key?: string;
56
+ }) => DynamicModule>;
57
+ export interface ConfigurableModuleHost<Opts, MethodKey extends string = 'forRoot', FactoryMethodKey extends string = 'create', Extras extends ConfigurableModuleExtras = {
58
+ isGlobal?: boolean;
59
+ }> {
60
+ /** Base class to `extends`. */
61
+ ConfigurableModuleClass: ConfigurableModuleClassType<Opts, MethodKey, FactoryMethodKey, Extras>;
62
+ /** The options token — inject it into derived providers (`inject: [MODULE_OPTIONS_TOKEN]`). */
63
+ MODULE_OPTIONS_TOKEN: InjectionToken<Opts>;
64
+ /** Type-only helper: the shape accepted by the sync `<method>` static. */
65
+ OPTIONS_TYPE: Opts & Partial<Extras> & {
66
+ key?: string;
67
+ };
68
+ /** Type-only helper: the shape accepted by the `<method>Async` static. */
69
+ ASYNC_OPTIONS_TYPE: ConfigurableModuleAsyncOptions<Opts, FactoryMethodKey> & Partial<Extras> & {
70
+ key?: string;
71
+ };
72
+ }
73
+ /**
74
+ * Low-level engine spec (see `defineConfigurableModule`). Used for the cases a
75
+ * class-mixin can't express — notably runtime-generated module classes whose
76
+ * providers depend on a call-time argument (e.g. Cloudflare binding modules).
77
+ */
78
+ export interface DefineConfigurableModuleSpec<Args> {
79
+ /** The module class to reference in `{ module }`. */
80
+ module: Type;
81
+ /** Static method name to generate (e.g. `forRoot`). */
82
+ methodName?: string;
83
+ /** Derive the instance `key` from the call args. */
84
+ keyFrom: (args: Args) => string;
85
+ /** Build the provider list from the call args. */
86
+ providers: (args: Args) => DynamicModule['providers'];
87
+ /** Optional exports (usually prefer declaring these on `@Module`). */
88
+ exports?: DynamicModule['exports'];
89
+ /** Optional imports. */
90
+ imports?: (args: Args) => DynamicModule['imports'];
91
+ /** Mark the produced module global. */
92
+ global?: boolean;
93
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Low-level engine spec (see `defineConfigurableModule`). Used for the cases a
3
+ * class-mixin can't express — notably runtime-generated module classes whose
4
+ * providers depend on a call-time argument (e.g. Cloudflare binding modules).
5
+ */ export { };
@@ -0,0 +1,105 @@
1
+ import { InjectionToken, type ProviderOptions, type Token, type Type } from '../container/types';
2
+ import type { ComponentInstance, ModuleImport } from '../registry/types';
3
+ import type { ConfigurableModuleAsyncOptions, ConfigurableModuleExtras, ConfigurableModuleExtrasTransform, ConfigurableModuleHost } from './configurable-module.types';
4
+ /** The `global:` slot's component groups, lowered to `APP_*` registrations. */
5
+ export interface GlobalComponentSlot {
6
+ guards?: Array<Type | ComponentInstance>;
7
+ pipes?: Array<Type | ComponentInstance>;
8
+ interceptors?: Array<Type | ComponentInstance>;
9
+ filters?: Array<Type | ComponentInstance>;
10
+ middleware?: Array<Type | ComponentInstance>;
11
+ }
12
+ /** What a module instance contributes, computed from its call-time options. */
13
+ export interface ModuleContributions {
14
+ providers?: Array<Type | ProviderOptions>;
15
+ controllers?: Type[];
16
+ imports?: ModuleImport[];
17
+ exports?: Array<Type | InjectionToken>;
18
+ /**
19
+ * Standardized global-component registration — the one idiom replacing both
20
+ * the `@Module({ providers: [{ provide: APP_GUARD, useExisting: X }] })`
21
+ * pattern and the conditional-push-into-forRoot pattern. Class entries are
22
+ * registered as providers and wired via `useExisting`; instances via `useValue`.
23
+ */
24
+ global?: GlobalComponentSlot;
25
+ }
26
+ export interface ModuleSetupContext<Opts> {
27
+ /** The options token — derived providers do `inject: [OPTIONS]`. */
28
+ readonly OPTIONS: InjectionToken<Opts>;
29
+ /**
30
+ * Structural options known at call time. For `forRoot` this is the full
31
+ * bag; for `forRootAsync` it is only the structural fields passed alongside
32
+ * the factory (the DI-resolved options exist only at resolution time —
33
+ * read them through `OPTIONS`, never here).
34
+ */
35
+ readonly options: Partial<Opts>;
36
+ /** The instance key in effect (for deriving per-instance token names). */
37
+ readonly key: string;
38
+ }
39
+ export interface DefineModuleSpec<Opts, Extras extends ConfigurableModuleExtras = {
40
+ isGlobal?: boolean;
41
+ }, MethodKey extends string = 'forRoot', FactoryMethodKey extends string = 'create'> {
42
+ /** Names the generated base class, the minted options token, and diagnostics. */
43
+ name: string;
44
+ /**
45
+ * Reuse an existing options token instead of minting one — critical for
46
+ * migrations so the module's public token keeps its identity.
47
+ */
48
+ optionsToken?: InjectionToken<Opts>;
49
+ /**
50
+ * Structural contributions as a function of the call-time options. Runs at
51
+ * `forRoot`/`forRootAsync` call time, once per module instance.
52
+ */
53
+ setup?: (ctx: ModuleSetupContext<Opts>) => ModuleContributions;
54
+ /**
55
+ * Dedup key from the structural options. Defaults to `stableHash(options)`.
56
+ * Modules whose options carry stateful instances (drivers, registries)
57
+ * should derive from the stable identifying subset — or document that
58
+ * callers pass an explicit `key` for multi-instance setups.
59
+ */
60
+ key?: (options: Partial<Opts>) => string;
61
+ /** Call-site extras defaults (default `{ isGlobal: false }`). */
62
+ extras?: Extras;
63
+ /** Reshape the definition from resolved extras (default: `isGlobal` → `global: true`). */
64
+ transform?: ConfigurableModuleExtrasTransform<Extras>;
65
+ /** Rename the sync static (default `forRoot`); the async static becomes `<name>Async`. */
66
+ methodName?: MethodKey;
67
+ /** Method a `useClass`/`useExisting` options factory must implement (default `create`). */
68
+ factoryMethodName?: FactoryMethodKey;
69
+ }
70
+ /**
71
+ * The one blessed module-authoring engine. Generates `forRoot` AND
72
+ * `forRootAsync` statics with: `stableHash` key derivation (multi-instance
73
+ * dedup that survives HMR), typed `inject` tuple inference on the async
74
+ * factory, an `isGlobal` extra, and — the piece `ConfigurableModuleBuilder`
75
+ * could not express — providers/controllers/imports/exports/global components
76
+ * computed **as functions of the options**.
77
+ *
78
+ * ```ts
79
+ * const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } = defineModule<CorsOptions>({
80
+ * name: 'Cors',
81
+ * setup: ({ OPTIONS }) => ({
82
+ * providers: [{
83
+ * provide: APP_MIDDLEWARE,
84
+ * useFactory: (o: CorsOptions) => buildCorsMiddleware(o),
85
+ * inject: [OPTIONS],
86
+ * }],
87
+ * exports: [OPTIONS],
88
+ * }),
89
+ * });
90
+ * export class CorsModule extends ConfigurableModuleClass {}
91
+ * ```
92
+ *
93
+ * `ConfigurableModuleBuilder` remains supported (NestJS parity) and is a thin
94
+ * adapter over this engine.
95
+ */
96
+ export declare function defineModule<Opts, Extras extends ConfigurableModuleExtras = {
97
+ isGlobal?: boolean;
98
+ }, MethodKey extends string = 'forRoot', FactoryMethodKey extends string = 'create'>(spec: DefineModuleSpec<Opts, Extras, MethodKey, FactoryMethodKey>): ConfigurableModuleHost<Opts, MethodKey, FactoryMethodKey, Extras>;
99
+ /**
100
+ * Lower `useFactory`/`useClass`/`useExisting` async options into provider
101
+ * registrations. Structural fields from the call site merge UNDER the resolved
102
+ * options (`{ ...structural, ...resolved }`) so sync-declared fields act as
103
+ * defaults and the factory stays authoritative.
104
+ */
105
+ export declare function buildAsyncOptionsProviders<Opts>(optionsToken: Token, factoryMethodName: string, async: Pick<ConfigurableModuleAsyncOptions<Opts>, 'inject' | 'useFactory' | 'useClass' | 'useExisting'>, structural?: Record<string, unknown>): Array<ProviderOptions>;