@velajs/vela 1.9.0 → 1.10.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 +20 -0
- package/dist/__tests__/workers-als/entry-als.d.ts +9 -0
- package/dist/application.d.ts +10 -0
- package/dist/application.js +25 -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 +33 -0
- package/dist/container/container.js +156 -7
- 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/factory/bootstrap.js +10 -0
- 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/index.d.ts +1 -0
- package/dist/http/index.js +1 -0
- package/dist/http/route.manager.d.ts +19 -0
- package/dist/http/route.manager.js +84 -0
- 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 +61 -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 +7 -4
- package/dist/index.js +6 -2
- package/dist/module/configurable-module.builder.d.ts +44 -0
- package/dist/module/configurable-module.builder.js +177 -0
- package/dist/module/configurable-module.types.d.ts +93 -0
- package/dist/module/configurable-module.types.js +5 -0
- package/dist/module/index.d.ts +2 -0
- package/dist/module/index.js +1 -0
- package/dist/pipeline/types.d.ts +21 -4
- package/dist/registry/metadata.registry.d.ts +16 -16
- package/dist/registry/metadata.registry.js +90 -32
- 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 +18 -0
- package/dist/seeder/seeder.module.js +40 -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 +18 -0
- package/dist/websocket/websocket.module.js +52 -0
- package/dist/websocket/websocket.tokens.d.ts +22 -0
- package/dist/websocket/websocket.tokens.js +20 -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 +33 -0
- package/dist/websocket/ws-dispatcher.js +253 -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
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { InjectionToken } from "../container/types.js";
|
|
2
|
+
import { stableHash } from "./stable-hash.js";
|
|
3
|
+
/** Default extra: `isGlobal` toggles `DynamicModule.global`, hiding the naming split. */ const DEFAULT_EXTRAS = {
|
|
4
|
+
isGlobal: false
|
|
5
|
+
};
|
|
6
|
+
const DEFAULT_TRANSFORM = (def, extras)=>extras.isGlobal ? {
|
|
7
|
+
...def,
|
|
8
|
+
global: true
|
|
9
|
+
} : def;
|
|
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
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN } =
|
|
19
|
+
* new ConfigurableModuleBuilder<FooOptions>({ moduleName: 'Foo' }).build();
|
|
20
|
+
*
|
|
21
|
+
* @Module({
|
|
22
|
+
* providers: [FooService], // derived providers inject MODULE_OPTIONS_TOKEN
|
|
23
|
+
* exports: [FooService],
|
|
24
|
+
* })
|
|
25
|
+
* export class FooModule extends ConfigurableModuleClass {}
|
|
26
|
+
* ```
|
|
27
|
+
*/ export class ConfigurableModuleBuilder {
|
|
28
|
+
options;
|
|
29
|
+
classMethodName = 'forRoot';
|
|
30
|
+
factoryMethodName = 'create';
|
|
31
|
+
extrasDefaults = DEFAULT_EXTRAS;
|
|
32
|
+
extrasTransform = DEFAULT_TRANSFORM;
|
|
33
|
+
constructor(options = {}){
|
|
34
|
+
this.options = options;
|
|
35
|
+
}
|
|
36
|
+
/** Declare extra call-site keys (e.g. `isGlobal`) + how they reshape the definition. */ setExtras(defaults, transform) {
|
|
37
|
+
this.extrasDefaults = defaults;
|
|
38
|
+
this.extrasTransform = transform;
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
/** Rename the sync static (default `forRoot`); the async static becomes `<name>Async`. */ setClassMethodName(name) {
|
|
42
|
+
this.classMethodName = name;
|
|
43
|
+
return this;
|
|
44
|
+
}
|
|
45
|
+
/** Rename the method a `useClass`/`useExisting` options factory must implement (default `create`). */ setFactoryMethodName(name) {
|
|
46
|
+
this.factoryMethodName = name;
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
build() {
|
|
50
|
+
const moduleName = this.options.moduleName ?? 'ConfigurableModule';
|
|
51
|
+
const optionsToken = this.options.optionsInjectionToken ?? new InjectionToken(`${moduleName}_MODULE_OPTIONS`);
|
|
52
|
+
const syncName = this.classMethodName;
|
|
53
|
+
const asyncName = `${this.classMethodName}Async`;
|
|
54
|
+
const factoryMethodName = this.factoryMethodName;
|
|
55
|
+
const extrasDefaults = this.extrasDefaults;
|
|
56
|
+
const transform = this.extrasTransform;
|
|
57
|
+
let ConfigurableModuleClass = class ConfigurableModuleClass {
|
|
58
|
+
};
|
|
59
|
+
Object.defineProperty(ConfigurableModuleClass, syncName, {
|
|
60
|
+
configurable: true,
|
|
61
|
+
writable: true,
|
|
62
|
+
enumerable: false,
|
|
63
|
+
value (options = {}) {
|
|
64
|
+
const { key, ...rest } = options;
|
|
65
|
+
const definition = {
|
|
66
|
+
module: this,
|
|
67
|
+
key: key ?? stableHash(rest),
|
|
68
|
+
providers: [
|
|
69
|
+
{
|
|
70
|
+
provide: optionsToken,
|
|
71
|
+
useValue: rest
|
|
72
|
+
}
|
|
73
|
+
]
|
|
74
|
+
};
|
|
75
|
+
return transform(definition, {
|
|
76
|
+
...extrasDefaults,
|
|
77
|
+
...rest
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
Object.defineProperty(ConfigurableModuleClass, asyncName, {
|
|
82
|
+
configurable: true,
|
|
83
|
+
writable: true,
|
|
84
|
+
enumerable: false,
|
|
85
|
+
value (options = {}) {
|
|
86
|
+
const { key, imports, inject, useFactory, useClass, useExisting, ...restExtras } = options;
|
|
87
|
+
const definition = {
|
|
88
|
+
module: this,
|
|
89
|
+
// Include extras (e.g. isGlobal) in the key — like forRoot — so two
|
|
90
|
+
// async instances differing only in an extra don't wrongly dedup.
|
|
91
|
+
key: key ?? stableHash({
|
|
92
|
+
inject,
|
|
93
|
+
useFactory,
|
|
94
|
+
useClass,
|
|
95
|
+
useExisting,
|
|
96
|
+
...restExtras
|
|
97
|
+
}),
|
|
98
|
+
imports: imports ?? [],
|
|
99
|
+
providers: buildAsyncOptionsProviders(optionsToken, factoryMethodName, {
|
|
100
|
+
inject,
|
|
101
|
+
useFactory,
|
|
102
|
+
useClass,
|
|
103
|
+
useExisting
|
|
104
|
+
})
|
|
105
|
+
};
|
|
106
|
+
return transform(definition, {
|
|
107
|
+
...extrasDefaults,
|
|
108
|
+
...restExtras
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
ConfigurableModuleClass: ConfigurableModuleClass,
|
|
114
|
+
MODULE_OPTIONS_TOKEN: optionsToken,
|
|
115
|
+
// Type-only sentinels — never read at runtime.
|
|
116
|
+
OPTIONS_TYPE: undefined,
|
|
117
|
+
ASYNC_OPTIONS_TYPE: undefined
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/** Lower `useFactory`/`useClass`/`useExisting` async options into provider registrations. */ function buildAsyncOptionsProviders(optionsToken, factoryMethodName, async) {
|
|
122
|
+
if (async.useFactory) {
|
|
123
|
+
return [
|
|
124
|
+
{
|
|
125
|
+
provide: optionsToken,
|
|
126
|
+
useFactory: async.useFactory,
|
|
127
|
+
inject: async.inject ?? []
|
|
128
|
+
}
|
|
129
|
+
];
|
|
130
|
+
}
|
|
131
|
+
if (async.useClass) {
|
|
132
|
+
const factoryClass = async.useClass;
|
|
133
|
+
return [
|
|
134
|
+
factoryClass,
|
|
135
|
+
{
|
|
136
|
+
provide: optionsToken,
|
|
137
|
+
useFactory: (instance)=>instance[factoryMethodName](),
|
|
138
|
+
inject: [
|
|
139
|
+
factoryClass
|
|
140
|
+
]
|
|
141
|
+
}
|
|
142
|
+
];
|
|
143
|
+
}
|
|
144
|
+
if (async.useExisting) {
|
|
145
|
+
return [
|
|
146
|
+
{
|
|
147
|
+
provide: optionsToken,
|
|
148
|
+
useFactory: (instance)=>instance[factoryMethodName](),
|
|
149
|
+
inject: [
|
|
150
|
+
async.useExisting
|
|
151
|
+
]
|
|
152
|
+
}
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
throw new Error('Async module options require one of `useFactory`, `useClass`, or `useExisting`.');
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Lower-level engine for cases a class-mixin can't express — chiefly a
|
|
159
|
+
* runtime-generated module class whose providers depend on a call-time arg
|
|
160
|
+
* (Cloudflare binding modules). Returns an object with a single static named by
|
|
161
|
+
* `spec.methodName` (default `forRoot`).
|
|
162
|
+
*/ export function defineConfigurableModule(spec) {
|
|
163
|
+
const methodName = spec.methodName ?? 'forRoot';
|
|
164
|
+
return {
|
|
165
|
+
[methodName] (args) {
|
|
166
|
+
const definition = {
|
|
167
|
+
module: spec.module,
|
|
168
|
+
key: spec.keyFrom(args),
|
|
169
|
+
providers: spec.providers(args)
|
|
170
|
+
};
|
|
171
|
+
if (spec.imports) definition.imports = spec.imports(args);
|
|
172
|
+
if (spec.exports) definition.exports = spec.exports;
|
|
173
|
+
if (spec.global) definition.global = true;
|
|
174
|
+
return definition;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
}
|
|
@@ -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
|
+
}
|
package/dist/module/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { Global, Module, isModule, getModuleMetadata, defineDynamicModule, } from './decorators';
|
|
2
2
|
export { stableHash } from './stable-hash';
|
|
3
|
+
export { ConfigurableModuleBuilder, defineConfigurableModule, } from './configurable-module.builder';
|
|
4
|
+
export type { ConfigurableModuleAsyncOptions, ConfigurableModuleBuilderOptions, ConfigurableModuleClassType, ConfigurableModuleExtras, ConfigurableModuleExtrasTransform, ConfigurableModuleHost, ConfigurableModuleOptionsFactory, DefineConfigurableModuleSpec, } from './configurable-module.types';
|
|
3
5
|
export { ModuleLoader } from './module-loader';
|
|
4
6
|
export { MiddlewareBuilder } from './middleware';
|
|
5
7
|
export type { MiddlewareConsumer, MiddlewareConfigProxy, MiddlewareRouteDefinition, NestModule, RouteInfo, } from './middleware';
|
package/dist/module/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { Global, Module, isModule, getModuleMetadata, defineDynamicModule } from "./decorators.js";
|
|
2
2
|
export { stableHash } from "./stable-hash.js";
|
|
3
|
+
export { ConfigurableModuleBuilder, defineConfigurableModule } from "./configurable-module.builder.js";
|
|
3
4
|
export { ModuleLoader } from "./module-loader.js";
|
|
4
5
|
export { MiddlewareBuilder } from "./middleware.js";
|
package/dist/pipeline/types.d.ts
CHANGED
|
@@ -11,16 +11,33 @@ export interface HttpArgumentsHost {
|
|
|
11
11
|
getRequest<T = Request>(): T;
|
|
12
12
|
getResponse<T = Context>(): T;
|
|
13
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* WebSocket-specific arguments host returned by `ExecutionContext.switchToWs()`.
|
|
16
|
+
* Populated by `@velajs/vela/websocket` when a gateway message is dispatched.
|
|
17
|
+
*
|
|
18
|
+
* - `getClient()` — the connected socket (`WsClient`)
|
|
19
|
+
* - `getData()` — the inbound message payload (the envelope's `data`)
|
|
20
|
+
* - `getPattern()` — the subscribed event name that matched
|
|
21
|
+
*/
|
|
22
|
+
export interface WsArgumentsHost {
|
|
23
|
+
getClient<T = unknown>(): T;
|
|
24
|
+
getData<T = unknown>(): T;
|
|
25
|
+
getPattern<T = string>(): T;
|
|
26
|
+
}
|
|
27
|
+
/** The transport a component is executing under. `'http'` for routes, `'ws'` for gateway messages. */
|
|
28
|
+
export type ContextType = 'http' | 'ws';
|
|
14
29
|
export interface ExecutionContext {
|
|
15
|
-
getType<T extends string =
|
|
30
|
+
getType<T extends string = ContextType>(): T;
|
|
16
31
|
getClass(): Type;
|
|
17
32
|
getHandler(): string | symbol;
|
|
18
|
-
/** Returns the Hono `Context` directly. */
|
|
33
|
+
/** Returns the Hono `Context` directly. Throws on a WebSocket context. */
|
|
19
34
|
getContext<T = Context>(): T;
|
|
20
|
-
/** Shorthand for `switchToHttp().getRequest()` — returns the Web `Request`. */
|
|
35
|
+
/** Shorthand for `switchToHttp().getRequest()` — returns the Web `Request`. Throws on a WebSocket context. */
|
|
21
36
|
getRequest(): Request;
|
|
22
|
-
/** Switch to the HTTP arguments host
|
|
37
|
+
/** Switch to the HTTP arguments host. Throws on a WebSocket context. */
|
|
23
38
|
switchToHttp(): HttpArgumentsHost;
|
|
39
|
+
/** Switch to the WebSocket arguments host. Throws on an HTTP context. */
|
|
40
|
+
switchToWs(): WsArgumentsHost;
|
|
24
41
|
}
|
|
25
42
|
export interface CanActivate {
|
|
26
43
|
canActivate(context: ExecutionContext): boolean | Promise<boolean>;
|
|
@@ -5,22 +5,22 @@ export interface ControllerOptions {
|
|
|
5
5
|
version?: number | number[];
|
|
6
6
|
}
|
|
7
7
|
export declare class MetadataRegistry {
|
|
8
|
-
private static
|
|
9
|
-
private static
|
|
10
|
-
private static
|
|
11
|
-
private static
|
|
12
|
-
private static
|
|
13
|
-
private static
|
|
14
|
-
private static
|
|
15
|
-
private static
|
|
16
|
-
private static
|
|
17
|
-
private static
|
|
18
|
-
private static
|
|
19
|
-
private static
|
|
20
|
-
private static
|
|
21
|
-
private static
|
|
22
|
-
private static
|
|
23
|
-
private static globalComponents;
|
|
8
|
+
private static get routes();
|
|
9
|
+
private static get controllers();
|
|
10
|
+
private static get controllerOptions();
|
|
11
|
+
private static get modules();
|
|
12
|
+
private static get parameters();
|
|
13
|
+
private static get injectables();
|
|
14
|
+
private static get scopes();
|
|
15
|
+
private static get injectTokens();
|
|
16
|
+
private static get handlerHttpMeta();
|
|
17
|
+
private static get catchTypes();
|
|
18
|
+
private static get routeVersions();
|
|
19
|
+
private static get classMeta();
|
|
20
|
+
private static get handlerMeta();
|
|
21
|
+
private static get controllerComponents();
|
|
22
|
+
private static get handlerComponents();
|
|
23
|
+
private static get globalComponents();
|
|
24
24
|
static getRoutes(controller: Constructor): RouteDefinition[];
|
|
25
25
|
static addRoute(controller: Constructor, route: RouteDefinition): void;
|
|
26
26
|
static getControllerPath(controller: Constructor): string;
|
|
@@ -17,37 +17,95 @@ function emptyComponentByOwner() {
|
|
|
17
17
|
filter: new Map()
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
guard: new Map(),
|
|
45
|
-
pipe: new Map(),
|
|
46
|
-
interceptor: new Map(),
|
|
47
|
-
filter: new Map()
|
|
20
|
+
function createRegistryState() {
|
|
21
|
+
return {
|
|
22
|
+
routes: new Map(),
|
|
23
|
+
controllers: new Map(),
|
|
24
|
+
controllerOptions: new Map(),
|
|
25
|
+
modules: new Map(),
|
|
26
|
+
parameters: new Map(),
|
|
27
|
+
injectables: new Set(),
|
|
28
|
+
scopes: new Map(),
|
|
29
|
+
injectTokens: new Map(),
|
|
30
|
+
handlerHttpMeta: new Map(),
|
|
31
|
+
catchTypes: new Map(),
|
|
32
|
+
routeVersions: new Map(),
|
|
33
|
+
classMeta: new Map(),
|
|
34
|
+
handlerMeta: new Map(),
|
|
35
|
+
controllerComponents: emptyComponentByOwner(),
|
|
36
|
+
handlerComponents: {
|
|
37
|
+
middleware: new Map(),
|
|
38
|
+
guard: new Map(),
|
|
39
|
+
pipe: new Map(),
|
|
40
|
+
interceptor: new Map(),
|
|
41
|
+
filter: new Map()
|
|
42
|
+
},
|
|
43
|
+
globalComponents: emptyComponentStore()
|
|
48
44
|
};
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
}
|
|
46
|
+
// HMR-safe: anchor ALL backing state on `globalThis` so a Vite dev re-eval of
|
|
47
|
+
// this module reuses the SAME maps that classes were already decorated against.
|
|
48
|
+
// Without this, re-eval creates fresh empty statics → split-brain (lost routes,
|
|
49
|
+
// spurious "not @Injectable" warnings, duplicated global components). The
|
|
50
|
+
// versioned symbol avoids collisions across framework major versions in one
|
|
51
|
+
// process. `globalThis` + `Symbol.for` exist on every target runtime; no node:*.
|
|
52
|
+
const REGISTRY_STATE_KEY = Symbol.for('vela:registry:v1');
|
|
53
|
+
function registryState() {
|
|
54
|
+
const g = globalThis;
|
|
55
|
+
return g[REGISTRY_STATE_KEY] ??= createRegistryState();
|
|
56
|
+
}
|
|
57
|
+
export class MetadataRegistry {
|
|
58
|
+
// Every field is a getter over the globalThis-anchored state (registryState).
|
|
59
|
+
// Method bodies keep using `this.<field>`; the getter returns the live map so
|
|
60
|
+
// `.set`/`.get`/`.clear` mutate the shared state.
|
|
61
|
+
static get routes() {
|
|
62
|
+
return registryState().routes;
|
|
63
|
+
}
|
|
64
|
+
static get controllers() {
|
|
65
|
+
return registryState().controllers;
|
|
66
|
+
}
|
|
67
|
+
static get controllerOptions() {
|
|
68
|
+
return registryState().controllerOptions;
|
|
69
|
+
}
|
|
70
|
+
static get modules() {
|
|
71
|
+
return registryState().modules;
|
|
72
|
+
}
|
|
73
|
+
static get parameters() {
|
|
74
|
+
return registryState().parameters;
|
|
75
|
+
}
|
|
76
|
+
static get injectables() {
|
|
77
|
+
return registryState().injectables;
|
|
78
|
+
}
|
|
79
|
+
static get scopes() {
|
|
80
|
+
return registryState().scopes;
|
|
81
|
+
}
|
|
82
|
+
static get injectTokens() {
|
|
83
|
+
return registryState().injectTokens;
|
|
84
|
+
}
|
|
85
|
+
static get handlerHttpMeta() {
|
|
86
|
+
return registryState().handlerHttpMeta;
|
|
87
|
+
}
|
|
88
|
+
static get catchTypes() {
|
|
89
|
+
return registryState().catchTypes;
|
|
90
|
+
}
|
|
91
|
+
static get routeVersions() {
|
|
92
|
+
return registryState().routeVersions;
|
|
93
|
+
}
|
|
94
|
+
static get classMeta() {
|
|
95
|
+
return registryState().classMeta;
|
|
96
|
+
}
|
|
97
|
+
static get handlerMeta() {
|
|
98
|
+
return registryState().handlerMeta;
|
|
99
|
+
}
|
|
100
|
+
static get controllerComponents() {
|
|
101
|
+
return registryState().controllerComponents;
|
|
102
|
+
}
|
|
103
|
+
static get handlerComponents() {
|
|
104
|
+
return registryState().handlerComponents;
|
|
105
|
+
}
|
|
106
|
+
static get globalComponents() {
|
|
107
|
+
return registryState().globalComponents;
|
|
108
|
+
}
|
|
51
109
|
// Routes
|
|
52
110
|
static getRoutes(controller) {
|
|
53
111
|
return this.routes.get(controller) ?? [];
|
|
@@ -237,7 +295,7 @@ export class MetadataRegistry {
|
|
|
237
295
|
// Clear app-time state. Decoration metadata persists — once a class is
|
|
238
296
|
// decorated, that fact is permanent for the lifetime of the process.
|
|
239
297
|
static clear() {
|
|
240
|
-
|
|
298
|
+
registryState().globalComponents = emptyComponentStore();
|
|
241
299
|
}
|
|
242
300
|
// Full reset, including decoration metadata. Used in framework-internal scenarios.
|
|
243
301
|
static reset() {
|
|
@@ -264,6 +322,6 @@ export class MetadataRegistry {
|
|
|
264
322
|
this.controllerComponents[type].clear();
|
|
265
323
|
this.handlerComponents[type].clear();
|
|
266
324
|
}
|
|
267
|
-
|
|
325
|
+
registryState().globalComponents = emptyComponentStore();
|
|
268
326
|
}
|
|
269
327
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { Seeder } from './seeder.decorator';
|
|
2
|
+
export { SeederRegistry } from './seeder.registry';
|
|
3
|
+
export { SeederModule, runSeeders } from './seeder.module';
|
|
4
|
+
export { SEEDER_METADATA } from './seeder.tokens';
|
|
5
|
+
export type { Seeder as ISeeder, SeederMetadata, RegisteredSeeder, SeederResult, } from './seeder.types';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SeederMetadata } from './seeder.types';
|
|
2
|
+
/**
|
|
3
|
+
* Mark a class as a seeder. Also marks it `@Injectable()` (singleton) so it only
|
|
4
|
+
* needs to be listed in a module's providers (or `SeederModule.forRoot({ seeders })`)
|
|
5
|
+
* to be discovered by {@link SeederRegistry} at bootstrap.
|
|
6
|
+
*/
|
|
7
|
+
export declare function Seeder(options?: SeederMetadata): ClassDecorator;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Scope } from "../constants.js";
|
|
2
|
+
import { MetadataRegistry } from "../registry/metadata.registry.js";
|
|
3
|
+
import { SEEDER_METADATA } from "./seeder.tokens.js";
|
|
4
|
+
/**
|
|
5
|
+
* Mark a class as a seeder. Also marks it `@Injectable()` (singleton) so it only
|
|
6
|
+
* needs to be listed in a module's providers (or `SeederModule.forRoot({ seeders })`)
|
|
7
|
+
* to be discovered by {@link SeederRegistry} at bootstrap.
|
|
8
|
+
*/ export function Seeder(options = {}) {
|
|
9
|
+
return (target)=>{
|
|
10
|
+
const ctor = target;
|
|
11
|
+
MetadataRegistry.markInjectable(ctor);
|
|
12
|
+
MetadataRegistry.setScope(ctor, Scope.SINGLETON);
|
|
13
|
+
MetadataRegistry.setCustomClassMeta(target, SEEDER_METADATA, options);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { VelaApplication } from '../application';
|
|
2
|
+
import type { DynamicModule } from '../module/types';
|
|
3
|
+
import type { Type } from '../container/types';
|
|
4
|
+
import type { SeederResult } from './seeder.types';
|
|
5
|
+
export declare class SeederModule {
|
|
6
|
+
/**
|
|
7
|
+
* Register seeder classes as providers so they're discovered at bootstrap.
|
|
8
|
+
* (Seeders declared in other modules' providers are also discovered — this is
|
|
9
|
+
* just a convenience to co-locate them.)
|
|
10
|
+
*/
|
|
11
|
+
static forRoot(options?: {
|
|
12
|
+
seeders?: Type[];
|
|
13
|
+
}): DynamicModule;
|
|
14
|
+
}
|
|
15
|
+
/** Convenience runner: resolve the registry from a built app and run all seeders. */
|
|
16
|
+
export declare function runSeeders(app: VelaApplication, options?: {
|
|
17
|
+
stopOnError?: boolean;
|
|
18
|
+
}): Promise<SeederResult[]>;
|
|
@@ -0,0 +1,40 @@
|
|
|
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 { Module } from "../module/decorators.js";
|
|
8
|
+
import { stableHash } from "../module/stable-hash.js";
|
|
9
|
+
import { SeederRegistry } from "./seeder.registry.js";
|
|
10
|
+
export class SeederModule {
|
|
11
|
+
/**
|
|
12
|
+
* Register seeder classes as providers so they're discovered at bootstrap.
|
|
13
|
+
* (Seeders declared in other modules' providers are also discovered — this is
|
|
14
|
+
* just a convenience to co-locate them.)
|
|
15
|
+
*/ static forRoot(options = {}) {
|
|
16
|
+
const seeders = options.seeders ?? [];
|
|
17
|
+
return {
|
|
18
|
+
module: SeederModule,
|
|
19
|
+
key: stableHash({
|
|
20
|
+
seeders: seeders.map((s)=>s.name)
|
|
21
|
+
}),
|
|
22
|
+
providers: [
|
|
23
|
+
...seeders
|
|
24
|
+
]
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
SeederModule = _ts_decorate([
|
|
29
|
+
Module({
|
|
30
|
+
providers: [
|
|
31
|
+
SeederRegistry
|
|
32
|
+
],
|
|
33
|
+
exports: [
|
|
34
|
+
SeederRegistry
|
|
35
|
+
]
|
|
36
|
+
})
|
|
37
|
+
], SeederModule);
|
|
38
|
+
/** Convenience runner: resolve the registry from a built app and run all seeders. */ export function runSeeders(app, options) {
|
|
39
|
+
return app.get(SeederRegistry).runAll(options);
|
|
40
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Container } from '../container/container';
|
|
2
|
+
import type { OnApplicationBootstrap } from '../lifecycle/index';
|
|
3
|
+
import type { RegisteredSeeder, SeederResult } from './seeder.types';
|
|
4
|
+
/**
|
|
5
|
+
* Discovers `@Seeder()` providers at bootstrap and runs them on demand.
|
|
6
|
+
* Mirrors `ScheduleRegistry`'s discovery (scan container tokens → read metadata).
|
|
7
|
+
*/
|
|
8
|
+
export declare class SeederRegistry implements OnApplicationBootstrap {
|
|
9
|
+
private readonly container;
|
|
10
|
+
private seeders;
|
|
11
|
+
constructor(container: Container);
|
|
12
|
+
onApplicationBootstrap(): void;
|
|
13
|
+
/** Registered seeders in run order. */
|
|
14
|
+
list(): RegisteredSeeder[];
|
|
15
|
+
/**
|
|
16
|
+
* Run every seeder in order, each in its own request-scoped child container so
|
|
17
|
+
* request-scoped dependencies resolve. Returns a per-seeder result; when
|
|
18
|
+
* `stopOnError` is true (default) the run aborts on the first failure.
|
|
19
|
+
*/
|
|
20
|
+
runAll(options?: {
|
|
21
|
+
stopOnError?: boolean;
|
|
22
|
+
}): Promise<SeederResult[]>;
|
|
23
|
+
}
|