@velajs/vela 1.0.0 → 1.2.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 +80 -0
- package/README.md +36 -2
- package/dist/cache/cache.decorators.d.ts +2 -2
- package/dist/cache/cache.module.d.ts +1 -1
- package/dist/cache/cache.module.js +1 -1
- package/dist/constants.d.ts +8 -8
- package/dist/constants.js +8 -8
- package/dist/container/container.js +2 -2
- package/dist/container/decorators.js +8 -11
- package/dist/container/types.d.ts +1 -0
- package/dist/errors/http-exception.d.ts +21 -20
- package/dist/errors/http-exception.js +6 -6
- package/dist/event-emitter/event-emitter.decorators.js +2 -3
- package/dist/event-emitter/event-emitter.subscriber.js +2 -1
- package/dist/factory.d.ts +0 -1
- package/dist/factory.js +2 -32
- package/dist/fetch/fetch.module.d.ts +2 -2
- package/dist/fetch/fetch.module.js +2 -2
- package/dist/health/health.service.js +6 -2
- package/dist/http/decorators.d.ts +6 -5
- package/dist/http/decorators.js +28 -76
- package/dist/http/execution-context.d.ts +4 -0
- package/dist/http/execution-context.js +15 -0
- package/dist/http/index.d.ts +2 -2
- package/dist/http/index.js +1 -1
- package/dist/http/route.manager.d.ts +1 -2
- package/dist/http/route.manager.js +19 -25
- package/dist/http/types.d.ts +0 -1
- package/dist/index.d.ts +2 -8
- package/dist/index.js +6 -11
- package/dist/internal.d.ts +11 -0
- package/dist/internal.js +13 -0
- package/dist/metadata.js +6 -15
- package/dist/module/decorators.d.ts +1 -3
- package/dist/module/decorators.js +8 -20
- package/dist/module/graph.d.ts +10 -0
- package/dist/module/graph.js +35 -0
- package/dist/module/index.d.ts +2 -0
- package/dist/module/index.js +1 -0
- package/dist/{http/middleware-consumer.d.ts → module/middleware.d.ts} +4 -14
- package/dist/{http/middleware-consumer.js → module/middleware.js} +0 -12
- package/dist/module/module-loader.d.ts +1 -1
- package/dist/module/module-loader.js +17 -13
- package/dist/module/types.d.ts +1 -29
- package/dist/openapi/decorators.js +15 -10
- package/dist/openapi/document.js +7 -42
- package/dist/pipeline/app-providers.d.ts +10 -0
- package/dist/pipeline/app-providers.js +43 -0
- package/dist/pipeline/decorators.d.ts +5 -5
- package/dist/pipeline/decorators.js +1 -9
- package/dist/pipeline/reflector.d.ts +8 -24
- package/dist/pipeline/reflector.js +10 -55
- package/dist/registry/index.d.ts +1 -1
- package/dist/registry/metadata.registry.d.ts +18 -13
- package/dist/registry/metadata.registry.js +133 -159
- package/dist/registry/paths.d.ts +3 -0
- package/dist/registry/paths.js +15 -0
- package/dist/registry/types.d.ts +24 -14
- package/dist/registry/types.js +0 -1
- package/dist/registry/util.d.ts +3 -0
- package/dist/registry/util.js +8 -0
- package/dist/schedule/schedule.decorators.js +3 -6
- package/dist/schedule/schedule.registry.js +3 -2
- package/dist/schedule-node/index.d.ts +1 -0
- package/dist/schedule-node/index.js +1 -0
- package/dist/throttler/throttler.decorators.d.ts +2 -2
- package/package.json +5 -9
- package/dist/testing/index.d.ts +0 -2
- package/dist/testing/index.js +0 -2
- package/dist/testing/testing.builder.d.ts +0 -29
- package/dist/testing/testing.builder.js +0 -148
- package/dist/testing/testing.module.d.ts +0 -9
- package/dist/testing/testing.module.js +0 -15
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,85 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.1.0 (2026-04-30)
|
|
4
|
+
|
|
5
|
+
Architectural remodel: one metadata model, one storage, public surface trimmed, internal primitives exposed via a stable subpath.
|
|
6
|
+
|
|
7
|
+
### Breaking changes
|
|
8
|
+
|
|
9
|
+
- **`createApplication` removed.** Use `VelaFactory.create(AppModule)` directly.
|
|
10
|
+
|
|
11
|
+
```diff
|
|
12
|
+
- import { createApplication } from '@velajs/vela';
|
|
13
|
+
- const app = await createApplication(AppModule);
|
|
14
|
+
+ import { VelaFactory } from '@velajs/vela';
|
|
15
|
+
+ const app = await VelaFactory.create(AppModule);
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
- **`RequestMethod` removed; `HttpMethod` is canonical and now uppercase.** The two enums had the same purpose but different cases (`'get'` vs `'GET'`). Unified to uppercase to match HTTP spec and Hono's request `method` field.
|
|
19
|
+
|
|
20
|
+
```diff
|
|
21
|
+
- import { RequestMethod } from '@velajs/vela';
|
|
22
|
+
- .forRoutes({ path: '/api', method: RequestMethod.POST });
|
|
23
|
+
+ import { HttpMethod } from '@velajs/vela';
|
|
24
|
+
+ .forRoutes({ path: '/api', method: HttpMethod.POST });
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- **`@Controller({ prefix })` removed; `@Controller({ path })` only.** `prefix` was a non-canonical alias.
|
|
28
|
+
|
|
29
|
+
```diff
|
|
30
|
+
- @Controller({ prefix: '/users', version: 1 })
|
|
31
|
+
+ @Controller({ path: '/users', version: 1 })
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- **`HttpModule.register` / `registerAsync` renamed to `forRoot` / `forRootAsync`.** Same for `CacheModule.registerAsync` → `forRootAsync`. Matches NestJS canonical naming and aligns the rest of the framework's dynamic-module shape.
|
|
35
|
+
|
|
36
|
+
```diff
|
|
37
|
+
- HttpModule.register({ baseURL: '...' })
|
|
38
|
+
- HttpModule.registerAsync({ ... })
|
|
39
|
+
- CacheModule.registerAsync({ ... })
|
|
40
|
+
+ HttpModule.forRoot({ baseURL: '...' })
|
|
41
|
+
+ HttpModule.forRootAsync({ ... })
|
|
42
|
+
+ CacheModule.forRootAsync({ ... })
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- **`MetadataRegistry`, `RouteManager`, `ModuleLoader`, `ComponentManager`, `Container`, `VelaApplication` (the class), `bindAppProviders`, and the `APP_*` tokens moved to a stable internal subpath.** The public root barrel still re-exports `MetadataRegistry` (used by tests for `clear()`), but plugin authors should consume framework primitives from `/internal`:
|
|
46
|
+
|
|
47
|
+
```diff
|
|
48
|
+
- import { RouteManager, ModuleLoader, ComponentManager } from '@velajs/vela';
|
|
49
|
+
+ import { RouteManager, ModuleLoader, ComponentManager } from '@velajs/vela/internal';
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
- **`Test`, `TestingModule`, `TestingModuleBuilder` removed from `@velajs/vela`'s root barrel.** Use `@velajs/testing` (≥ 0.2.0) — it's the canonical home and was rewritten on top of `@velajs/vela/internal`.
|
|
53
|
+
|
|
54
|
+
- **`HttpException._response` typed as `string | Record<string, unknown>`** (was `string | object`). `getResponse()` now returns `Record<string, unknown>`.
|
|
55
|
+
|
|
56
|
+
- **`applyDecorators` return type** changed from the impossible-at-runtime `ClassDecorator & MethodDecorator & PropertyDecorator` intersection to a `ComposedDecorator` polymorphic shape that matches every decorator slot structurally.
|
|
57
|
+
|
|
58
|
+
- **`Reflector` API takes `ExecutionContext` directly.** Was a duck-typed `{ getClass(): Constructor; getHandler(): string|symbol }` parameter; now the real type. Existing call sites that already pass an `ExecutionContext` need no change.
|
|
59
|
+
|
|
60
|
+
- **Inverted peer dep removed**: `@velajs/vela` no longer declares `peerDependencies['@velajs/crud']`. Crud is the consumer; that line was reversed.
|
|
61
|
+
|
|
62
|
+
### New
|
|
63
|
+
|
|
64
|
+
- **`@velajs/vela/internal` subpath export.** Re-exports `MetadataRegistry`, `Container`, `ModuleRef`, `RouteManager`, `ModuleLoader`, `ComponentManager`, `VelaApplication`, `bindAppProviders`, `APP_GUARD`/`APP_PIPE`/`APP_INTERCEPTOR`/`APP_FILTER`/`APP_MIDDLEWARE`, `getModuleMetadata`, `isModule`. Stable target for plugins.
|
|
65
|
+
|
|
66
|
+
### Internal cleanup
|
|
67
|
+
|
|
68
|
+
- **One metadata storage.** Decorators no longer dual-write to a typed `MetadataRegistry` slot AND a parallel `WeakMap` polyfill. The `Reflect.metadata` polyfill now funnels into `MetadataRegistry.classMeta`/`handlerMeta`, which also backs `setCustomClassMeta`/`setCustomHandlerMeta` and the `appendCustomClassMeta`/`appendCustomHandlerMeta` helpers.
|
|
69
|
+
- **`MetadataRegistry.clear()`** now clears only app-time global components (the only mutable run-time slot). Decoration metadata persists across `clear()`, so tests no longer need a fallback path. Use `MetadataRegistry.reset()` for a full wipe.
|
|
70
|
+
- **No `!` non-null assertions** in `MetadataRegistry`. New `getOrCreate`/`getOrCreateMap`/`getOrCreateArray` helpers in `registry/util.ts`.
|
|
71
|
+
- **No `as unknown as` casts** in `MetadataRegistry`. Component stores are now mapped-typed instead of union-typed.
|
|
72
|
+
- **`Constructor` is now `abstract new (...args: any[]) => unknown`** (was the bare unsafe `Function`). Every decorator's `target` casts to `Constructor` consistently.
|
|
73
|
+
- **Single home for shared types**: `Type`, `Token`, `Constructor`, `ProviderOptions`, `InjectableOptions`, etc. canonical in `container/types.ts`. `ModuleOptions`, `DynamicModule`, `ModuleImport`, `AsyncModuleOptions`, `ModuleMetadata` canonical in `registry/types.ts`. `module/types.ts` is a thin re-export. The `InjectionTokenLike` duck-type and the duplicated `ProviderOptions` are gone.
|
|
74
|
+
- **Layering fixed**: `MiddlewareConsumer`/`MiddlewareBuilder`/`NestModule`/`RouteInfo` moved from `http/` to `module/`. `module/module-loader.ts` no longer imports from `http/`.
|
|
75
|
+
- **`module-loader` `new moduleClass()` footgun fixed.** `NestModule.configure()` modules are now resolved through the container, so they can have constructor-injected deps.
|
|
76
|
+
- **One path util** (`registry/paths.ts`: `normalizePath`, `joinPaths`, `toOpenApiPath`). Replaces 2× duplicated implementations in `http/decorators.ts`, `openapi/document.ts`, and `route.manager.ts`.
|
|
77
|
+
- **One `ExecutionContext` factory** (`http/execution-context.ts`: `buildExecutionContext`). Replaces 2× duplicated literal construction.
|
|
78
|
+
- **One `bindAppProviders` helper** (`pipeline/app-providers.ts`). Implements the NestJS APP_* provider convention in one place; replaces 5× duplicated APP_* wiring blocks across `factory.ts` and `testing.builder.ts`.
|
|
79
|
+
- **One module-graph walk** (`module/graph.ts`: `collectControllers`). Replaces the duplicate implementation in `openapi/document.ts`.
|
|
80
|
+
- **schedule/event-emitter/openapi decorators** now use `MetadataRegistry.appendCustomClassMeta`/`appendCustomHandlerMeta` instead of direct `Reflect.defineMetadata` calls.
|
|
81
|
+
- **Stub `pnpm-workspace.yaml` and `bunfig.toml` deleted** — they only set `onlyBuiltDependencies`, which lives in `package.json#pnpm`. `bun.lock` deleted; pnpm is the source of truth.
|
|
82
|
+
|
|
3
83
|
## 0.10.0 (2026-04-28)
|
|
4
84
|
|
|
5
85
|
Edge-runtime audit and AI-drift cleanup.
|
package/README.md
CHANGED
|
@@ -73,13 +73,47 @@ Vela runs on any runtime that supports the Web Standards API:
|
|
|
73
73
|
|
|
74
74
|
No Node.js-specific APIs (`node:fs`, `Buffer`, `process`) are used.
|
|
75
75
|
|
|
76
|
-
##
|
|
76
|
+
## Dynamic modules
|
|
77
|
+
|
|
78
|
+
Configurable modules use `forRoot` (sync) and `forRootAsync` (DI-resolved):
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
@Module({
|
|
82
|
+
imports: [
|
|
83
|
+
CacheModule.forRoot({ ttl: 60 }),
|
|
84
|
+
HttpModule.forRoot({ baseURL: 'https://api.example.com' }),
|
|
85
|
+
ConfigModule.forRootAsync({
|
|
86
|
+
useFactory: async (loader: ConfigLoader) => loader.load(),
|
|
87
|
+
inject: [ConfigLoader],
|
|
88
|
+
}),
|
|
89
|
+
],
|
|
90
|
+
})
|
|
91
|
+
class AppModule {}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Companion packages
|
|
95
|
+
|
|
96
|
+
| Package | Purpose |
|
|
97
|
+
|---|---|
|
|
98
|
+
| [`@velajs/cloudflare`](https://github.com/velajs/cloudflare) | Cloudflare Workers adapter — typed services for KV, D1, R2, Queues, DO, AI, Vectorize, Hyperdrive |
|
|
99
|
+
| [`@velajs/crud`](https://github.com/velajs/crud) | NestJS-style CRUD controllers on top of `hono-crud` |
|
|
100
|
+
| [`@velajs/testing`](https://github.com/velajs/testing) | `Test.createTestingModule()` with `overrideProvider/Guard/Pipe/Interceptor/Filter` |
|
|
77
101
|
|
|
78
102
|
```bash
|
|
103
|
+
pnpm add @velajs/testing -D
|
|
104
|
+
pnpm add @velajs/cloudflare @cloudflare/workers-types
|
|
79
105
|
pnpm add @velajs/crud hono-crud @hono/zod-openapi zod
|
|
80
106
|
```
|
|
81
107
|
|
|
82
|
-
|
|
108
|
+
## `/internal` subpath (for plugin authors)
|
|
109
|
+
|
|
110
|
+
Framework primitives — `MetadataRegistry`, `Container`, `RouteManager`, `ModuleLoader`, `ComponentManager`, `VelaApplication`, `bindAppProviders`, `APP_*` tokens — are exposed at `@velajs/vela/internal`. This is the stable target for plugin packages that need to reach below the public API.
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { MetadataRegistry, Container } from '@velajs/vela/internal';
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The public root barrel still exports `MetadataRegistry` (used by tests for `clear()` between cases). Everything else lives at `/internal` only.
|
|
83
117
|
|
|
84
118
|
## License
|
|
85
119
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CacheKey: (key: string) => (target:
|
|
2
|
-
export declare const CacheTTL: (seconds: number) => (target:
|
|
1
|
+
export declare const CacheKey: (key: string) => (target: object, propertyKey?: string | symbol) => void;
|
|
2
|
+
export declare const CacheTTL: (seconds: number) => (target: object, propertyKey?: string | symbol) => void;
|
|
@@ -2,7 +2,7 @@ import type { AsyncModuleOptions, DynamicModule } from '../module/types';
|
|
|
2
2
|
import type { CacheModuleOptions } from './cache.types';
|
|
3
3
|
export declare class CacheModule {
|
|
4
4
|
static forRoot(options?: CacheModuleOptions): DynamicModule;
|
|
5
|
-
static
|
|
5
|
+
static forRootAsync(options: AsyncModuleOptions<CacheModuleOptions> & {
|
|
6
6
|
isGlobal?: boolean;
|
|
7
7
|
}): DynamicModule;
|
|
8
8
|
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -14,14 +14,14 @@ export declare const METADATA_KEYS: {
|
|
|
14
14
|
readonly CRUD: "vela:crud";
|
|
15
15
|
};
|
|
16
16
|
export declare const HttpMethod: {
|
|
17
|
-
readonly GET: "
|
|
18
|
-
readonly POST: "
|
|
19
|
-
readonly PUT: "
|
|
20
|
-
readonly PATCH: "
|
|
21
|
-
readonly DELETE: "
|
|
22
|
-
readonly OPTIONS: "
|
|
23
|
-
readonly HEAD: "
|
|
24
|
-
readonly ALL: "
|
|
17
|
+
readonly GET: "GET";
|
|
18
|
+
readonly POST: "POST";
|
|
19
|
+
readonly PUT: "PUT";
|
|
20
|
+
readonly PATCH: "PATCH";
|
|
21
|
+
readonly DELETE: "DELETE";
|
|
22
|
+
readonly OPTIONS: "OPTIONS";
|
|
23
|
+
readonly HEAD: "HEAD";
|
|
24
|
+
readonly ALL: "ALL";
|
|
25
25
|
};
|
|
26
26
|
export type HttpMethod = (typeof HttpMethod)[keyof typeof HttpMethod];
|
|
27
27
|
export declare const ParamType: {
|
package/dist/constants.js
CHANGED
|
@@ -19,14 +19,14 @@ export const METADATA_KEYS = {
|
|
|
19
19
|
CRUD: 'vela:crud'
|
|
20
20
|
};
|
|
21
21
|
export const HttpMethod = {
|
|
22
|
-
GET: '
|
|
23
|
-
POST: '
|
|
24
|
-
PUT: '
|
|
25
|
-
PATCH: '
|
|
26
|
-
DELETE: '
|
|
27
|
-
OPTIONS: '
|
|
28
|
-
HEAD: '
|
|
29
|
-
ALL: '
|
|
22
|
+
GET: 'GET',
|
|
23
|
+
POST: 'POST',
|
|
24
|
+
PUT: 'PUT',
|
|
25
|
+
PATCH: 'PATCH',
|
|
26
|
+
DELETE: 'DELETE',
|
|
27
|
+
OPTIONS: 'OPTIONS',
|
|
28
|
+
HEAD: 'HEAD',
|
|
29
|
+
ALL: 'ALL'
|
|
30
30
|
};
|
|
31
31
|
export const ParamType = {
|
|
32
32
|
BODY: 'body',
|
|
@@ -211,10 +211,10 @@ export class Container {
|
|
|
211
211
|
}
|
|
212
212
|
return this.resolve(token);
|
|
213
213
|
}
|
|
214
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
215
214
|
createLazyProxy(token) {
|
|
216
215
|
const container = this;
|
|
217
|
-
|
|
216
|
+
const target = Object.create(null);
|
|
217
|
+
return new Proxy(target, {
|
|
218
218
|
get (_target, prop) {
|
|
219
219
|
const instance = container.resolve(token);
|
|
220
220
|
const value = instance[prop];
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { defineMetadata, getMetadata } from "../metadata.js";
|
|
1
|
+
import { Scope } from "../constants.js";
|
|
3
2
|
import { MetadataRegistry } from "../registry/metadata.registry.js";
|
|
4
3
|
export function Injectable(options = {}) {
|
|
5
4
|
return (target)=>{
|
|
6
5
|
const { scope = Scope.SINGLETON } = options;
|
|
7
6
|
MetadataRegistry.markInjectable(target);
|
|
8
7
|
MetadataRegistry.setScope(target, scope);
|
|
9
|
-
// Keep WeakMap write for external package compat
|
|
10
|
-
defineMetadata(METADATA_KEYS.INJECTABLE, true, target);
|
|
11
|
-
defineMetadata(METADATA_KEYS.SCOPE, scope, target);
|
|
12
8
|
};
|
|
13
9
|
}
|
|
14
10
|
export function Optional() {
|
|
@@ -24,7 +20,6 @@ export function Optional() {
|
|
|
24
20
|
});
|
|
25
21
|
}
|
|
26
22
|
MetadataRegistry.setInjectTokens(target, existing);
|
|
27
|
-
defineMetadata(METADATA_KEYS.INJECT, existing, target);
|
|
28
23
|
};
|
|
29
24
|
}
|
|
30
25
|
export function Inject(token) {
|
|
@@ -40,18 +35,20 @@ export function Inject(token) {
|
|
|
40
35
|
});
|
|
41
36
|
}
|
|
42
37
|
MetadataRegistry.setInjectTokens(target, existing);
|
|
43
|
-
defineMetadata(METADATA_KEYS.INJECT, existing, target);
|
|
44
38
|
};
|
|
45
39
|
}
|
|
46
40
|
export function isInjectable(target) {
|
|
47
|
-
return MetadataRegistry.hasInjectable(target)
|
|
41
|
+
return MetadataRegistry.hasInjectable(target);
|
|
48
42
|
}
|
|
49
43
|
export function getScope(target) {
|
|
50
|
-
return MetadataRegistry.getScope(target) ??
|
|
44
|
+
return MetadataRegistry.getScope(target) ?? Scope.SINGLETON;
|
|
51
45
|
}
|
|
52
46
|
export function getConstructorDependencies(target) {
|
|
53
|
-
|
|
47
|
+
// Read through Reflect so dist/src coexistence in tests routes through the
|
|
48
|
+
// single polyfill-installed registry — SWC writes `design:paramtypes` via
|
|
49
|
+
// Reflect, so reads must too.
|
|
50
|
+
return Reflect.getMetadata('design:paramtypes', target) ?? [];
|
|
54
51
|
}
|
|
55
52
|
export function getInjectMetadata(target) {
|
|
56
|
-
return MetadataRegistry.getInjectTokens(target) ??
|
|
53
|
+
return MetadataRegistry.getInjectTokens(target) ?? [];
|
|
57
54
|
}
|
|
@@ -1,61 +1,62 @@
|
|
|
1
|
+
export type ExceptionResponse = string | Record<string, unknown>;
|
|
1
2
|
export declare class HttpException extends Error {
|
|
2
3
|
readonly statusCode: number;
|
|
3
4
|
private readonly _response;
|
|
4
|
-
constructor(response:
|
|
5
|
+
constructor(response: ExceptionResponse, statusCode: number);
|
|
5
6
|
getStatus(): number;
|
|
6
|
-
getResponse(): unknown
|
|
7
|
+
getResponse(): Record<string, unknown>;
|
|
7
8
|
}
|
|
8
9
|
export declare class BadRequestException extends HttpException {
|
|
9
|
-
constructor(message?:
|
|
10
|
+
constructor(message?: ExceptionResponse);
|
|
10
11
|
}
|
|
11
12
|
export declare class UnauthorizedException extends HttpException {
|
|
12
|
-
constructor(message?:
|
|
13
|
+
constructor(message?: ExceptionResponse);
|
|
13
14
|
}
|
|
14
15
|
export declare class ForbiddenException extends HttpException {
|
|
15
|
-
constructor(message?:
|
|
16
|
+
constructor(message?: ExceptionResponse);
|
|
16
17
|
}
|
|
17
18
|
export declare class NotFoundException extends HttpException {
|
|
18
|
-
constructor(message?:
|
|
19
|
+
constructor(message?: ExceptionResponse);
|
|
19
20
|
}
|
|
20
21
|
export declare class MethodNotAllowedException extends HttpException {
|
|
21
|
-
constructor(message?:
|
|
22
|
+
constructor(message?: ExceptionResponse);
|
|
22
23
|
}
|
|
23
24
|
export declare class NotAcceptableException extends HttpException {
|
|
24
|
-
constructor(message?:
|
|
25
|
+
constructor(message?: ExceptionResponse);
|
|
25
26
|
}
|
|
26
27
|
export declare class RequestTimeoutException extends HttpException {
|
|
27
|
-
constructor(message?:
|
|
28
|
+
constructor(message?: ExceptionResponse);
|
|
28
29
|
}
|
|
29
30
|
export declare class ConflictException extends HttpException {
|
|
30
|
-
constructor(message?:
|
|
31
|
+
constructor(message?: ExceptionResponse);
|
|
31
32
|
}
|
|
32
33
|
export declare class GoneException extends HttpException {
|
|
33
|
-
constructor(message?:
|
|
34
|
+
constructor(message?: ExceptionResponse);
|
|
34
35
|
}
|
|
35
36
|
export declare class PayloadTooLargeException extends HttpException {
|
|
36
|
-
constructor(message?:
|
|
37
|
+
constructor(message?: ExceptionResponse);
|
|
37
38
|
}
|
|
38
39
|
export declare class UnsupportedMediaTypeException extends HttpException {
|
|
39
|
-
constructor(message?:
|
|
40
|
+
constructor(message?: ExceptionResponse);
|
|
40
41
|
}
|
|
41
42
|
export declare class UnprocessableEntityException extends HttpException {
|
|
42
|
-
constructor(message?:
|
|
43
|
+
constructor(message?: ExceptionResponse);
|
|
43
44
|
}
|
|
44
45
|
export declare class TooManyRequestsException extends HttpException {
|
|
45
|
-
constructor(message?:
|
|
46
|
+
constructor(message?: ExceptionResponse);
|
|
46
47
|
}
|
|
47
48
|
export declare class InternalServerErrorException extends HttpException {
|
|
48
|
-
constructor(message?:
|
|
49
|
+
constructor(message?: ExceptionResponse);
|
|
49
50
|
}
|
|
50
51
|
export declare class NotImplementedException extends HttpException {
|
|
51
|
-
constructor(message?:
|
|
52
|
+
constructor(message?: ExceptionResponse);
|
|
52
53
|
}
|
|
53
54
|
export declare class BadGatewayException extends HttpException {
|
|
54
|
-
constructor(message?:
|
|
55
|
+
constructor(message?: ExceptionResponse);
|
|
55
56
|
}
|
|
56
57
|
export declare class ServiceUnavailableException extends HttpException {
|
|
57
|
-
constructor(message?:
|
|
58
|
+
constructor(message?: ExceptionResponse);
|
|
58
59
|
}
|
|
59
60
|
export declare class GatewayTimeoutException extends HttpException {
|
|
60
|
-
constructor(message?:
|
|
61
|
+
constructor(message?: ExceptionResponse);
|
|
61
62
|
}
|
|
@@ -13,13 +13,13 @@ export class HttpException extends Error {
|
|
|
13
13
|
return this.statusCode;
|
|
14
14
|
}
|
|
15
15
|
getResponse() {
|
|
16
|
-
if (typeof this._response === '
|
|
17
|
-
return
|
|
16
|
+
if (typeof this._response === 'string') {
|
|
17
|
+
return {
|
|
18
|
+
statusCode: this.statusCode,
|
|
19
|
+
message: this._response
|
|
20
|
+
};
|
|
18
21
|
}
|
|
19
|
-
return
|
|
20
|
-
statusCode: this.statusCode,
|
|
21
|
-
message: this._response
|
|
22
|
-
};
|
|
22
|
+
return this._response;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
// 4xx
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
+
import { MetadataRegistry } from "../registry/metadata.registry.js";
|
|
1
2
|
import { ON_EVENT_METADATA } from "./event-emitter.tokens.js";
|
|
2
3
|
export function OnEvent(event) {
|
|
3
4
|
return (target, propertyKey)=>{
|
|
4
|
-
|
|
5
|
-
existing.push({
|
|
5
|
+
MetadataRegistry.appendCustomClassMeta(target.constructor, ON_EVENT_METADATA, {
|
|
6
6
|
event,
|
|
7
7
|
methodName: String(propertyKey)
|
|
8
8
|
});
|
|
9
|
-
Reflect.defineMetadata(ON_EVENT_METADATA, existing, target.constructor);
|
|
10
9
|
};
|
|
11
10
|
}
|
|
@@ -14,6 +14,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
14
14
|
}
|
|
15
15
|
import { Injectable, Inject } from "../container/index.js";
|
|
16
16
|
import { Container } from "../container/container.js";
|
|
17
|
+
import { MetadataRegistry } from "../registry/metadata.registry.js";
|
|
17
18
|
import { EventEmitter } from "./event-emitter.service.js";
|
|
18
19
|
import { ON_EVENT_METADATA } from "./event-emitter.tokens.js";
|
|
19
20
|
export class EventEmitterSubscriber {
|
|
@@ -28,7 +29,7 @@ export class EventEmitterSubscriber {
|
|
|
28
29
|
for (const token of tokens){
|
|
29
30
|
// Skip non-class tokens
|
|
30
31
|
if (typeof token !== 'function') continue;
|
|
31
|
-
const metadata =
|
|
32
|
+
const metadata = MetadataRegistry.getCustomClassMeta(token, ON_EVENT_METADATA);
|
|
32
33
|
if (!metadata || metadata.length === 0) continue;
|
|
33
34
|
let instance;
|
|
34
35
|
try {
|
package/dist/factory.d.ts
CHANGED
package/dist/factory.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { VelaApplication } from "./application.js";
|
|
2
2
|
import { Container } from "./container/container.js";
|
|
3
3
|
import { ModuleRef } from "./container/module-ref.js";
|
|
4
|
+
import { bindAppProviders } from "./pipeline/app-providers.js";
|
|
4
5
|
import { RouteManager } from "./http/route.manager.js";
|
|
5
6
|
import { ModuleLoader } from "./module/module-loader.js";
|
|
6
7
|
import { ComponentManager } from "./pipeline/component.manager.js";
|
|
7
|
-
import { APP_GUARD, APP_PIPE, APP_INTERCEPTOR, APP_FILTER, APP_MIDDLEWARE } from "./pipeline/tokens.js";
|
|
8
8
|
export const VelaFactory = {
|
|
9
9
|
async create (rootModule, options = {}) {
|
|
10
10
|
const container = new Container();
|
|
@@ -23,36 +23,7 @@ export const VelaFactory = {
|
|
|
23
23
|
ComponentManager.init(container);
|
|
24
24
|
const loader = new ModuleLoader(container, routeManager);
|
|
25
25
|
loader.load(rootModule);
|
|
26
|
-
|
|
27
|
-
if (appGuards.length > 0) {
|
|
28
|
-
routeManager.useGlobalGuardTokens(...appGuards);
|
|
29
|
-
} else if (container.has(APP_GUARD)) {
|
|
30
|
-
routeManager.useGlobalGuardTokens(APP_GUARD);
|
|
31
|
-
}
|
|
32
|
-
const appPipes = loader.getAppProviderTokens(APP_PIPE);
|
|
33
|
-
if (appPipes.length > 0) {
|
|
34
|
-
routeManager.useGlobalPipeTokens(...appPipes);
|
|
35
|
-
} else if (container.has(APP_PIPE)) {
|
|
36
|
-
routeManager.useGlobalPipeTokens(APP_PIPE);
|
|
37
|
-
}
|
|
38
|
-
const appInterceptors = loader.getAppProviderTokens(APP_INTERCEPTOR);
|
|
39
|
-
if (appInterceptors.length > 0) {
|
|
40
|
-
routeManager.useGlobalInterceptorTokens(...appInterceptors);
|
|
41
|
-
} else if (container.has(APP_INTERCEPTOR)) {
|
|
42
|
-
routeManager.useGlobalInterceptorTokens(APP_INTERCEPTOR);
|
|
43
|
-
}
|
|
44
|
-
const appFilters = loader.getAppProviderTokens(APP_FILTER);
|
|
45
|
-
if (appFilters.length > 0) {
|
|
46
|
-
routeManager.useGlobalFilterTokens(...appFilters);
|
|
47
|
-
} else if (container.has(APP_FILTER)) {
|
|
48
|
-
routeManager.useGlobalFilterTokens(APP_FILTER);
|
|
49
|
-
}
|
|
50
|
-
const appMiddleware = loader.getAppProviderTokens(APP_MIDDLEWARE);
|
|
51
|
-
if (appMiddleware.length > 0) {
|
|
52
|
-
routeManager.useGlobalMiddlewareTokens(...appMiddleware);
|
|
53
|
-
} else if (container.has(APP_MIDDLEWARE)) {
|
|
54
|
-
routeManager.useGlobalMiddlewareTokens(APP_MIDDLEWARE);
|
|
55
|
-
}
|
|
26
|
+
bindAppProviders(routeManager, container, loader);
|
|
56
27
|
routeManager.registerConsumerMiddleware(loader.getConsumerMiddlewareDefinitions());
|
|
57
28
|
if (options.globalPrefix) {
|
|
58
29
|
routeManager.setGlobalPrefix(options.globalPrefix);
|
|
@@ -73,4 +44,3 @@ export const VelaFactory = {
|
|
|
73
44
|
return app;
|
|
74
45
|
}
|
|
75
46
|
};
|
|
76
|
-
export const createApplication = VelaFactory.create.bind(VelaFactory);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AsyncModuleOptions, DynamicModule } from '../module/types';
|
|
2
2
|
import type { HttpModuleOptions } from './fetch.types';
|
|
3
3
|
export declare class HttpModule {
|
|
4
|
-
static
|
|
5
|
-
static
|
|
4
|
+
static forRoot(options?: HttpModuleOptions): DynamicModule;
|
|
5
|
+
static forRootAsync(options: AsyncModuleOptions<HttpModuleOptions>): DynamicModule;
|
|
6
6
|
}
|
|
@@ -8,7 +8,7 @@ import { createModuleRef } from "../module/decorators.js";
|
|
|
8
8
|
import { Module } from "../module/decorators.js";
|
|
9
9
|
import { HttpService, HTTP_MODULE_OPTIONS } from "./fetch.service.js";
|
|
10
10
|
export class HttpModule {
|
|
11
|
-
static
|
|
11
|
+
static forRoot(options = {}) {
|
|
12
12
|
return {
|
|
13
13
|
module: createModuleRef('HttpModule'),
|
|
14
14
|
providers: [
|
|
@@ -24,7 +24,7 @@ export class HttpModule {
|
|
|
24
24
|
]
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
-
static
|
|
27
|
+
static forRootAsync(options) {
|
|
28
28
|
return {
|
|
29
29
|
module: createModuleRef('HttpModule'),
|
|
30
30
|
imports: options.imports ?? [],
|
|
@@ -19,7 +19,9 @@ export class HealthCheckService {
|
|
|
19
19
|
error: {},
|
|
20
20
|
details: {}
|
|
21
21
|
};
|
|
22
|
-
throw new ServiceUnavailableException(
|
|
22
|
+
throw new ServiceUnavailableException({
|
|
23
|
+
...result
|
|
24
|
+
});
|
|
23
25
|
}
|
|
24
26
|
const results = await Promise.allSettled(indicators.map((fn)=>fn()));
|
|
25
27
|
const info = {};
|
|
@@ -55,7 +57,9 @@ export class HealthCheckService {
|
|
|
55
57
|
details
|
|
56
58
|
};
|
|
57
59
|
if (status === 'error') {
|
|
58
|
-
throw new ServiceUnavailableException(
|
|
60
|
+
throw new ServiceUnavailableException({
|
|
61
|
+
...checkResult
|
|
62
|
+
});
|
|
59
63
|
}
|
|
60
64
|
return checkResult;
|
|
61
65
|
}
|
|
@@ -3,16 +3,16 @@ import type { ControllerOptions } from './types';
|
|
|
3
3
|
import type { ExecutionContext } from '../pipeline/types';
|
|
4
4
|
/**
|
|
5
5
|
* Marks a class as a controller.
|
|
6
|
-
* Accepts a
|
|
6
|
+
* Accepts a path string or an options object with `path` and `version`.
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* ```ts
|
|
10
10
|
* @Controller('/users')
|
|
11
|
-
* @Controller({
|
|
12
|
-
* @Controller({
|
|
11
|
+
* @Controller({ path: '/users', version: 1 })
|
|
12
|
+
* @Controller({ path: '/users', version: [1, 2] })
|
|
13
13
|
* ```
|
|
14
14
|
*/
|
|
15
|
-
export declare function Controller(
|
|
15
|
+
export declare function Controller(pathOrOptions?: string | ControllerOptions): ClassDecorator;
|
|
16
16
|
/**
|
|
17
17
|
* Override the version for a specific route method.
|
|
18
18
|
*
|
|
@@ -184,5 +184,6 @@ export declare function getRedirect(target: Constructor, method: string | symbol
|
|
|
184
184
|
* handle() { ... }
|
|
185
185
|
* ```
|
|
186
186
|
*/
|
|
187
|
-
export
|
|
187
|
+
export type ComposedDecorator = <T>(target: T, propertyKey?: string | symbol, descriptor?: PropertyDescriptor | number) => void;
|
|
188
|
+
export declare function applyDecorators(...decorators: Array<ClassDecorator | MethodDecorator | PropertyDecorator | ParameterDecorator>): ComposedDecorator;
|
|
188
189
|
export declare function isController(target: Constructor): boolean;
|