@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.
- package/CHANGELOG.md +122 -0
- package/dist/__tests__/workers-als/entry-als.d.ts +9 -0
- package/dist/application.d.ts +18 -0
- package/dist/application.js +45 -0
- package/dist/cache/cache.module.d.ts +5 -7
- package/dist/cache/cache.module.js +44 -66
- package/dist/cache/cache.types.d.ts +26 -0
- package/dist/cache/cache.types.js +1 -1
- package/dist/cache/index.d.ts +2 -1
- package/dist/cache/index.js +1 -0
- package/dist/cache/tiered-cache.store.d.ts +19 -0
- package/dist/cache/tiered-cache.store.js +40 -0
- package/dist/config/config.module.d.ts +6 -5
- package/dist/config/config.module.js +46 -49
- package/dist/container/container.d.ts +58 -0
- package/dist/container/container.js +223 -18
- package/dist/container/disposable.d.ts +5 -0
- package/dist/container/disposable.js +33 -0
- package/dist/container/types.d.ts +8 -0
- package/dist/cors/cors.module.d.ts +5 -5
- package/dist/cors/cors.module.js +26 -25
- package/dist/discovery/discoverable.decorator.d.ts +38 -0
- package/dist/discovery/discoverable.decorator.js +42 -0
- package/dist/discovery/discovery.service.d.ts +94 -0
- package/dist/discovery/discovery.service.js +166 -0
- package/dist/discovery/index.d.ts +2 -0
- package/dist/discovery/index.js +2 -0
- package/dist/entrypoint/entrypoint.registry.d.ts +40 -0
- package/dist/entrypoint/entrypoint.registry.js +106 -0
- package/dist/entrypoint/entrypoint.types.d.ts +41 -0
- package/dist/entrypoint/entrypoint.types.js +3 -0
- package/dist/entrypoint/execution-context.d.ts +15 -0
- package/dist/entrypoint/execution-context.js +21 -0
- package/dist/entrypoint/execution-scope.d.ts +21 -0
- package/dist/entrypoint/execution-scope.js +28 -0
- package/dist/entrypoint/index.d.ts +4 -0
- package/dist/entrypoint/index.js +4 -0
- package/dist/event-emitter/event-emitter.subscriber.d.ts +3 -3
- package/dist/event-emitter/event-emitter.subscriber.js +12 -29
- package/dist/factory/adapter.d.ts +36 -0
- package/dist/factory/adapter.js +18 -0
- package/dist/factory/bootstrap.js +20 -2
- package/dist/factory.d.ts +11 -1
- package/dist/factory.js +23 -2
- package/dist/fetch/fetch.module.d.ts +5 -6
- package/dist/fetch/fetch.module.js +9 -42
- package/dist/http/ambient.d.ts +17 -0
- package/dist/http/ambient.js +44 -0
- package/dist/http/execution-context.js +4 -1
- package/dist/http/handler-executor.js +22 -19
- package/dist/http/index.d.ts +1 -0
- package/dist/http/index.js +1 -0
- package/dist/http/route-contributor.d.ts +68 -0
- package/dist/http/route-contributor.js +22 -0
- package/dist/http/route.manager.d.ts +19 -0
- package/dist/http/route.manager.js +112 -19
- package/dist/i18n/deep-merge.d.ts +2 -0
- package/dist/i18n/deep-merge.js +15 -0
- package/dist/i18n/i18n.middleware.d.ts +15 -0
- package/dist/i18n/i18n.middleware.js +94 -0
- package/dist/i18n/i18n.module.d.ts +13 -0
- package/dist/i18n/i18n.module.js +64 -0
- package/dist/i18n/i18n.options.d.ts +30 -0
- package/dist/i18n/i18n.options.js +16 -0
- package/dist/i18n/i18n.service.d.ts +20 -0
- package/dist/i18n/i18n.service.js +49 -0
- package/dist/i18n/i18n.tokens.d.ts +6 -0
- package/dist/i18n/i18n.tokens.js +3 -0
- package/dist/i18n/i18n.types.d.ts +6 -0
- package/dist/i18n/i18n.types.js +1 -0
- package/dist/i18n/index.d.ts +10 -0
- package/dist/i18n/index.js +8 -0
- package/dist/i18n/message-loader.service.d.ts +21 -0
- package/dist/i18n/message-loader.service.js +90 -0
- package/dist/i18n/message-registry.d.ts +16 -0
- package/dist/i18n/message-registry.js +49 -0
- package/dist/index.d.ts +17 -5
- package/dist/index.js +14 -3
- package/dist/internal.d.ts +0 -2
- package/dist/internal.js +0 -7
- package/dist/module/configurable-module.builder.d.ts +56 -0
- package/dist/module/configurable-module.builder.js +84 -0
- package/dist/module/configurable-module.types.d.ts +93 -0
- package/dist/module/configurable-module.types.js +5 -0
- package/dist/module/define-module.d.ts +105 -0
- package/dist/module/define-module.js +227 -0
- package/dist/module/index.d.ts +4 -0
- package/dist/module/index.js +3 -0
- package/dist/module/lazy-provider.d.ts +65 -0
- package/dist/module/lazy-provider.js +111 -0
- package/dist/openapi/document.js +16 -15
- package/dist/pipeline/component.manager.d.ts +15 -9
- package/dist/pipeline/component.manager.js +32 -46
- package/dist/pipeline/index.d.ts +2 -0
- package/dist/pipeline/index.js +1 -0
- package/dist/pipeline/pipeline-runner.d.ts +31 -0
- package/dist/pipeline/pipeline-runner.js +40 -0
- package/dist/pipeline/types.d.ts +21 -4
- package/dist/registry/metadata.registry.d.ts +24 -18
- package/dist/registry/metadata.registry.js +137 -49
- package/dist/schedule/schedule.module.d.ts +5 -0
- package/dist/schedule/schedule.module.js +18 -8
- package/dist/schedule/schedule.registry.d.ts +3 -3
- package/dist/schedule/schedule.registry.js +23 -44
- package/dist/schedule-node/schedule-node.module.d.ts +5 -0
- package/dist/schedule-node/schedule-node.module.js +20 -10
- package/dist/seeder/index.d.ts +5 -0
- package/dist/seeder/index.js +4 -0
- package/dist/seeder/seeder.decorator.d.ts +7 -0
- package/dist/seeder/seeder.decorator.js +15 -0
- package/dist/seeder/seeder.module.d.ts +16 -0
- package/dist/seeder/seeder.module.js +41 -0
- package/dist/seeder/seeder.registry.d.ts +23 -0
- package/dist/seeder/seeder.registry.js +83 -0
- package/dist/seeder/seeder.tokens.d.ts +2 -0
- package/dist/seeder/seeder.tokens.js +1 -0
- package/dist/seeder/seeder.types.d.ts +20 -0
- package/dist/seeder/seeder.types.js +1 -0
- package/dist/storage/index.d.ts +4 -0
- package/dist/storage/index.js +2 -0
- package/dist/storage/path-template.d.ts +9 -0
- package/dist/storage/path-template.js +20 -0
- package/dist/storage/signed-url.d.ts +12 -0
- package/dist/storage/signed-url.js +55 -0
- package/dist/storage/storage.types.d.ts +41 -0
- package/dist/storage/storage.types.js +5 -0
- package/dist/throttler/throttler.module.d.ts +5 -8
- package/dist/throttler/throttler.module.js +27 -55
- package/dist/websocket/index.d.ts +12 -0
- package/dist/websocket/index.js +16 -0
- package/dist/websocket/websocket.decorators.d.ts +33 -0
- package/dist/websocket/websocket.decorators.js +58 -0
- package/dist/websocket/websocket.module.d.ts +35 -0
- package/dist/websocket/websocket.module.js +63 -0
- package/dist/websocket/websocket.tokens.d.ts +23 -0
- package/dist/websocket/websocket.tokens.js +21 -0
- package/dist/websocket/websocket.types.d.ts +86 -0
- package/dist/websocket/websocket.types.js +4 -0
- package/dist/websocket/ws-argument-resolver.d.ts +13 -0
- package/dist/websocket/ws-argument-resolver.js +40 -0
- package/dist/websocket/ws-dispatcher.d.ts +45 -0
- package/dist/websocket/ws-dispatcher.js +259 -0
- package/dist/websocket/ws-exception.d.ts +16 -0
- package/dist/websocket/ws-exception.js +32 -0
- package/dist/websocket/ws-execution-context.d.ts +9 -0
- package/dist/websocket/ws-execution-context.js +24 -0
- package/dist/websocket/ws-server.d.ts +31 -0
- package/dist/websocket/ws-server.js +74 -0
- package/dist/websocket/ws-sync.d.ts +47 -0
- package/dist/websocket/ws-sync.js +74 -0
- package/dist/websocket-node/index.d.ts +4 -0
- package/dist/websocket-node/index.js +5 -0
- package/dist/websocket-node/node-ws-client.d.ts +24 -0
- package/dist/websocket-node/node-ws-client.js +49 -0
- package/dist/websocket-node/redis-sync.d.ts +33 -0
- package/dist/websocket-node/redis-sync.js +56 -0
- package/dist/websocket-node/register-gateways.d.ts +20 -0
- package/dist/websocket-node/register-gateways.js +61 -0
- package/package.json +31 -1
- package/dist/http/crud-bridge.d.ts +0 -90
- 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
|
package/dist/internal.d.ts
CHANGED
|
@@ -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,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>;
|