@marcosvnmelo/nestjs-platform-h3 11.1.14-1
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/LICENSE +21 -0
- package/README.md +228 -0
- package/dist/adapters/h3-adapter.d.ts +253 -0
- package/dist/adapters/index.d.ts +1 -0
- package/dist/decorators/h3-decorators.d.ts +168 -0
- package/dist/decorators/index.d.ts +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1609 -0
- package/dist/interfaces/index.d.ts +2 -0
- package/dist/interfaces/nest-h3-application.interface.d.ts +161 -0
- package/dist/interfaces/serve-static-options.interface.d.ts +68 -0
- package/dist/multer/decorators/form-fields.decorator.d.ts +62 -0
- package/dist/multer/decorators/index.d.ts +1 -0
- package/dist/multer/files.constants.d.ts +4 -0
- package/dist/multer/index.d.ts +7 -0
- package/dist/multer/interceptors/any-files-stream.interceptor.d.ts +26 -0
- package/dist/multer/interceptors/any-files.interceptor.d.ts +13 -0
- package/dist/multer/interceptors/file-fields.interceptor.d.ts +13 -0
- package/dist/multer/interceptors/file-stream.interceptor.d.ts +26 -0
- package/dist/multer/interceptors/file.interceptor.d.ts +13 -0
- package/dist/multer/interceptors/files-stream.interceptor.d.ts +28 -0
- package/dist/multer/interceptors/files.interceptor.d.ts +15 -0
- package/dist/multer/interceptors/index.d.ts +8 -0
- package/dist/multer/interceptors/no-files.interceptor.d.ts +13 -0
- package/dist/multer/interfaces/files-upload-module.interface.d.ts +18 -0
- package/dist/multer/interfaces/index.d.ts +2 -0
- package/dist/multer/interfaces/multer-options.interface.d.ts +133 -0
- package/dist/multer/multer/multer.utils.d.ts +28 -0
- package/dist/multer/multer/multipart.utils.d.ts +61 -0
- package/dist/multer/multer/stream.utils.d.ts +58 -0
- package/dist/multer/multer.module.d.ts +25 -0
- package/dist/multer/storage/disk.storage.d.ts +62 -0
- package/dist/multer/storage/index.d.ts +3 -0
- package/dist/multer/storage/memory.storage.d.ts +47 -0
- package/dist/multer/storage/storage.interface.d.ts +59 -0
- package/dist/rslib-runtime.js +18 -0
- package/package.json +75 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) marcosvnmelo <marcosvnmelo.dev@gmail.com> (https://github.com/marcosvnmelo)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
|
13
|
+
all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
21
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# @marcosvnmelo/nestjs-platform-h3
|
|
2
|
+
|
|
3
|
+
H3 platform adapter for NestJS.
|
|
4
|
+
|
|
5
|
+
This package lets you run regular NestJS apps on top of [h3](https://h3.unjs.io), including support for:
|
|
6
|
+
|
|
7
|
+
- Nest core HTTP features (routing, pipes, guards, interceptors, filters, middleware)
|
|
8
|
+
- CORS and static assets
|
|
9
|
+
- HTTP/1.1, HTTPS, HTTP/2 (h2), and HTTP/2 cleartext (h2c)
|
|
10
|
+
- Multipart uploads (multer-style interceptors + stream interceptors)
|
|
11
|
+
- H3-specific parameter decorators
|
|
12
|
+
|
|
13
|
+
## Requirements
|
|
14
|
+
|
|
15
|
+
- Node.js 20+
|
|
16
|
+
- NestJS 11 (`@nestjs/common` and `@nestjs/core`)
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pnpm add @marcosvnmelo/nestjs-platform-h3 h3
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick start
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { NestFactory } from '@nestjs/core';
|
|
28
|
+
|
|
29
|
+
import type { NestH3Application } from '@marcosvnmelo/nestjs-platform-h3';
|
|
30
|
+
import { H3Adapter } from '@marcosvnmelo/nestjs-platform-h3';
|
|
31
|
+
|
|
32
|
+
import { AppModule } from './app.module';
|
|
33
|
+
|
|
34
|
+
async function bootstrap() {
|
|
35
|
+
const app = await NestFactory.create<NestH3Application>(
|
|
36
|
+
AppModule,
|
|
37
|
+
new H3Adapter(),
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
app.enableCors();
|
|
41
|
+
app.useStaticAssets('public', { prefix: '/static' });
|
|
42
|
+
|
|
43
|
+
await app.listen(3000);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
void bootstrap();
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## HTTP/2 support
|
|
50
|
+
|
|
51
|
+
### HTTP/2 over TLS (h2)
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { readFileSync } from 'node:fs';
|
|
55
|
+
|
|
56
|
+
import { NestFactory } from '@nestjs/core';
|
|
57
|
+
|
|
58
|
+
import type { NestH3Application } from '@marcosvnmelo/nestjs-platform-h3';
|
|
59
|
+
import { H3Adapter } from '@marcosvnmelo/nestjs-platform-h3';
|
|
60
|
+
|
|
61
|
+
const key = readFileSync('./certs/key.pem');
|
|
62
|
+
const cert = readFileSync('./certs/cert.pem');
|
|
63
|
+
|
|
64
|
+
const app = await NestFactory.create<NestH3Application>(
|
|
65
|
+
AppModule,
|
|
66
|
+
new H3Adapter(),
|
|
67
|
+
{
|
|
68
|
+
httpsOptions: { key, cert },
|
|
69
|
+
http2Options: { http2: true, allowHTTP1: true },
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### HTTP/2 cleartext (h2c)
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
const app = await NestFactory.create<NestH3Application>(
|
|
78
|
+
AppModule,
|
|
79
|
+
new H3Adapter(),
|
|
80
|
+
{
|
|
81
|
+
http2Options: { http2: true },
|
|
82
|
+
},
|
|
83
|
+
);
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> h2c is useful for server-to-server traffic. Browsers do not support h2c.
|
|
87
|
+
|
|
88
|
+
## H3 decorators
|
|
89
|
+
|
|
90
|
+
Use H3-specific decorators when you want direct access to H3 request primitives:
|
|
91
|
+
|
|
92
|
+
- `@H3Event()`
|
|
93
|
+
- `@H3Request()`
|
|
94
|
+
- `@H3Response()`
|
|
95
|
+
- `@H3Query()`
|
|
96
|
+
- `@H3Params()`
|
|
97
|
+
- `@H3Body()`
|
|
98
|
+
|
|
99
|
+
Example:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
import { Controller, Get } from '@nestjs/common';
|
|
103
|
+
|
|
104
|
+
import { H3Event, H3Query } from '@marcosvnmelo/nestjs-platform-h3';
|
|
105
|
+
|
|
106
|
+
@Controller('users')
|
|
107
|
+
export class UsersController {
|
|
108
|
+
@Get()
|
|
109
|
+
list(@H3Event() event: any, @H3Query('page') page?: string) {
|
|
110
|
+
return {
|
|
111
|
+
hasEvent: !!event,
|
|
112
|
+
page,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Multipart uploads
|
|
119
|
+
|
|
120
|
+
The library exposes multer-style interceptors and storage engines:
|
|
121
|
+
|
|
122
|
+
- Interceptors:
|
|
123
|
+
- `FileInterceptor`
|
|
124
|
+
- `FilesInterceptor`
|
|
125
|
+
- `FileFieldsInterceptor`
|
|
126
|
+
- `AnyFilesInterceptor`
|
|
127
|
+
- `NoFilesInterceptor`
|
|
128
|
+
- `FileStreamInterceptor`
|
|
129
|
+
- `FilesStreamInterceptor`
|
|
130
|
+
- `AnyFilesStreamInterceptor`
|
|
131
|
+
- Decorators:
|
|
132
|
+
- `@UploadedFields()`
|
|
133
|
+
- `@FormBody()`
|
|
134
|
+
- `@FormField('name')`
|
|
135
|
+
- Storage:
|
|
136
|
+
- `memoryStorage()`
|
|
137
|
+
- `diskStorage()`
|
|
138
|
+
|
|
139
|
+
Single file example:
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
import {
|
|
143
|
+
Controller,
|
|
144
|
+
Post,
|
|
145
|
+
UploadedFile,
|
|
146
|
+
UseInterceptors,
|
|
147
|
+
} from '@nestjs/common';
|
|
148
|
+
|
|
149
|
+
import type { H3UploadedFile } from '@marcosvnmelo/nestjs-platform-h3';
|
|
150
|
+
import { FileInterceptor } from '@marcosvnmelo/nestjs-platform-h3';
|
|
151
|
+
|
|
152
|
+
@Controller('upload')
|
|
153
|
+
export class UploadController {
|
|
154
|
+
@Post('single')
|
|
155
|
+
@UseInterceptors(FileInterceptor('file'))
|
|
156
|
+
uploadSingle(@UploadedFile() file: H3UploadedFile) {
|
|
157
|
+
return {
|
|
158
|
+
name: file.originalname,
|
|
159
|
+
size: file.size,
|
|
160
|
+
mime: file.mimetype,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
You can also configure upload defaults globally with `H3MulterModule.register(...)` or `H3MulterModule.registerAsync(...)`.
|
|
167
|
+
|
|
168
|
+
## Adapter hooks
|
|
169
|
+
|
|
170
|
+
`H3Adapter` includes lightweight lifecycle hooks:
|
|
171
|
+
|
|
172
|
+
- `setOnRequestHook((req, res, done) => ...)`
|
|
173
|
+
- `setOnResponseHook((req, res) => ...)`
|
|
174
|
+
|
|
175
|
+
These are useful for custom request/response instrumentation.
|
|
176
|
+
|
|
177
|
+
## Public exports
|
|
178
|
+
|
|
179
|
+
The package exports:
|
|
180
|
+
|
|
181
|
+
- `H3Adapter`
|
|
182
|
+
- `NestH3Application` interface
|
|
183
|
+
- H3 decorators
|
|
184
|
+
- Multipart module/interceptors/decorators/storage/utilities
|
|
185
|
+
|
|
186
|
+
## Development
|
|
187
|
+
|
|
188
|
+
Install dependencies:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
pnpm install
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Build:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
pnpm run build
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Watch mode:
|
|
201
|
+
|
|
202
|
+
```bash
|
|
203
|
+
pnpm run dev
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Run tests:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
pnpm run test
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Lint:
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
pnpm run lint
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Format:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
pnpm run format
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Benchmark (builds library + benchmark package):
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
pnpm run benchmark
|
|
228
|
+
```
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import * as http from 'http';
|
|
2
|
+
import * as http2 from 'http2';
|
|
3
|
+
import * as https from 'https';
|
|
4
|
+
import type { CorsOptions, H3Config, H3Event } from 'h3';
|
|
5
|
+
import { H3 } from 'h3';
|
|
6
|
+
import type { NestApplicationOptions, RequestMethod, VersioningOptions } from '@nestjs/common';
|
|
7
|
+
import type { VersionValue } from '@nestjs/common/interfaces';
|
|
8
|
+
import { AbstractHttpAdapter } from '@nestjs/core/adapters/http-adapter.js';
|
|
9
|
+
import type { ServeStaticOptions } from '../interfaces/serve-static-options.interface';
|
|
10
|
+
/**
|
|
11
|
+
* HTTP/2 options for the H3 adapter.
|
|
12
|
+
*
|
|
13
|
+
* @publicApi
|
|
14
|
+
*/
|
|
15
|
+
export interface H3Http2Options {
|
|
16
|
+
/**
|
|
17
|
+
* Enable HTTP/2 support.
|
|
18
|
+
*/
|
|
19
|
+
http2: true;
|
|
20
|
+
/**
|
|
21
|
+
* TLS/SSL options for secure HTTP/2 connections (h2).
|
|
22
|
+
* Required for HTTP/2 in browsers.
|
|
23
|
+
*/
|
|
24
|
+
http2Options?: http2.SecureServerOptions;
|
|
25
|
+
/**
|
|
26
|
+
* Allow HTTP/1 connections as a fallback via ALPN negotiation.
|
|
27
|
+
* Defaults to true.
|
|
28
|
+
*/
|
|
29
|
+
allowHTTP1?: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* HTTP/2 cleartext options (h2c) - HTTP/2 without TLS.
|
|
33
|
+
* Note: Browsers do not support h2c, only server-to-server communication.
|
|
34
|
+
*
|
|
35
|
+
* @publicApi
|
|
36
|
+
*/
|
|
37
|
+
export interface H3Http2CleartextOptions {
|
|
38
|
+
/**
|
|
39
|
+
* Enable HTTP/2 cleartext support (h2c).
|
|
40
|
+
*/
|
|
41
|
+
http2: true;
|
|
42
|
+
/**
|
|
43
|
+
* HTTP/2 server options (without TLS).
|
|
44
|
+
*/
|
|
45
|
+
http2Options?: http2.ServerOptions;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Extended application options for H3 with HTTP/2 support.
|
|
49
|
+
*
|
|
50
|
+
* @publicApi
|
|
51
|
+
*/
|
|
52
|
+
export interface H3ApplicationOptions extends NestApplicationOptions {
|
|
53
|
+
/**
|
|
54
|
+
* HTTP/2 configuration options.
|
|
55
|
+
*/
|
|
56
|
+
http2Options?: H3Http2Options | H3Http2CleartextOptions;
|
|
57
|
+
}
|
|
58
|
+
type VersionedRoute = <TRequest extends Record<string, any> = any, TResponse = any>(req: TRequest, res: TResponse, next: () => void) => any;
|
|
59
|
+
/**
|
|
60
|
+
* HTTP/2 compatible server type
|
|
61
|
+
*/
|
|
62
|
+
type H3Server = http.Server | https.Server | http2.Http2Server | http2.Http2SecureServer;
|
|
63
|
+
export declare class H3Adapter extends AbstractHttpAdapter<H3Server, http.IncomingMessage | http2.Http2ServerRequest, http.ServerResponse | http2.Http2ServerResponse> {
|
|
64
|
+
protected readonly instance: H3;
|
|
65
|
+
private readonly logger;
|
|
66
|
+
private isHttp2;
|
|
67
|
+
private onRequestHook?;
|
|
68
|
+
private onResponseHook?;
|
|
69
|
+
/**
|
|
70
|
+
* Route registry mapping 'METHOD:path' to array of handlers.
|
|
71
|
+
* Enables multiple versioned handlers for the same path.
|
|
72
|
+
*/
|
|
73
|
+
private readonly routeMap;
|
|
74
|
+
/**
|
|
75
|
+
* Tracks which method:path combinations have been registered with H3.
|
|
76
|
+
* Prevents duplicate route registrations.
|
|
77
|
+
*/
|
|
78
|
+
private readonly registeredPaths;
|
|
79
|
+
constructor(instanceOrOptions?: H3 | H3Config);
|
|
80
|
+
getInstance<T = H3>(): T;
|
|
81
|
+
/**
|
|
82
|
+
* Sets a hook that is called before each request is processed.
|
|
83
|
+
* The hook can perform async operations and must call `done()` when finished.
|
|
84
|
+
*
|
|
85
|
+
* @param onRequestHook - The hook function to call before each request
|
|
86
|
+
*/
|
|
87
|
+
setOnRequestHook(onRequestHook: (req: any, res: any, done: () => void) => Promise<void> | void): void;
|
|
88
|
+
/**
|
|
89
|
+
* Sets a hook that is called after each response is finished.
|
|
90
|
+
*
|
|
91
|
+
* @param onResponseHook - The hook function to call after each response
|
|
92
|
+
*/
|
|
93
|
+
setOnResponseHook(onResponseHook: (req: any, res: any) => Promise<void> | void): void;
|
|
94
|
+
reply(response: http.ServerResponse | H3Event, body: any, statusCode?: number): http.ServerResponse<http.IncomingMessage> | undefined;
|
|
95
|
+
status(response: http.ServerResponse | H3Event, statusCode: number): http.ServerResponse<http.IncomingMessage> | H3Event<import("h3").EventHandlerRequest>;
|
|
96
|
+
end(response: http.ServerResponse | H3Event, message?: string): http.ServerResponse<http.IncomingMessage> | http2.Http2ServerResponse<http2.Http2ServerRequest> | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Render method is part of the AbstractHttpAdapter interface contract.
|
|
99
|
+
* Template rendering is not yet supported in H3Adapter.
|
|
100
|
+
*/
|
|
101
|
+
render(response: http.ServerResponse | H3Event, _view: string, _options: any): http.ServerResponse<http.IncomingMessage> | http2.Http2ServerResponse<http2.Http2ServerRequest> | undefined;
|
|
102
|
+
redirect(response: http.ServerResponse | H3Event, statusCode: number, url: string): void;
|
|
103
|
+
/**
|
|
104
|
+
* The prefix parameter is part of the AbstractHttpAdapter interface contract.
|
|
105
|
+
* It represents the global prefix but is not used in H3's error handler implementation.
|
|
106
|
+
*/
|
|
107
|
+
setErrorHandler(handler: Function, _prefix?: string): this;
|
|
108
|
+
/**
|
|
109
|
+
* The prefix parameter is part of the AbstractHttpAdapter interface contract.
|
|
110
|
+
* It represents the global prefix but is not used in H3's not-found handler implementation.
|
|
111
|
+
*/
|
|
112
|
+
setNotFoundHandler(handler: Function, _prefix?: string): this;
|
|
113
|
+
isHeadersSent(response: http.ServerResponse | H3Event): boolean;
|
|
114
|
+
getHeader(response: http.ServerResponse | H3Event, name: string): string | number | string[] | undefined;
|
|
115
|
+
setHeader(response: http.ServerResponse | H3Event, name: string, value: string): void;
|
|
116
|
+
appendHeader(response: http.ServerResponse | H3Event, name: string, value: string): void;
|
|
117
|
+
listen(port: string | number, callback?: () => void): any;
|
|
118
|
+
listen(port: string | number, hostname: string, callback?: () => void): any;
|
|
119
|
+
close(): Promise<unknown> | undefined;
|
|
120
|
+
set(..._args: any[]): this;
|
|
121
|
+
enable(..._args: any[]): this;
|
|
122
|
+
disable(..._args: any[]): this;
|
|
123
|
+
engine(..._args: any[]): this;
|
|
124
|
+
/**
|
|
125
|
+
* Serves static files from the specified directory.
|
|
126
|
+
*
|
|
127
|
+
* @param staticPath - The path to the directory containing static files
|
|
128
|
+
* @param options - Options for serving static files (prefix, maxAge, etc.)
|
|
129
|
+
*/
|
|
130
|
+
useStaticAssets(staticPath: string, options?: ServeStaticOptions): this;
|
|
131
|
+
/**
|
|
132
|
+
* Parse a max-age string like '1d', '2h', '30m' to milliseconds
|
|
133
|
+
*/
|
|
134
|
+
private parseMaxAge;
|
|
135
|
+
setBaseViewsDir(..._args: any[]): this;
|
|
136
|
+
setViewEngine(..._args: any[]): this;
|
|
137
|
+
getRequestHostname(request: http.IncomingMessage | H3Event): string;
|
|
138
|
+
getRequestMethod(request: http.IncomingMessage | H3Event): string;
|
|
139
|
+
getRequestUrl(request: http.IncomingMessage | H3Event): string;
|
|
140
|
+
enableCors(options?: CorsOptions): void;
|
|
141
|
+
/**
|
|
142
|
+
* The requestMethod parameter is part of the AbstractHttpAdapter interface contract.
|
|
143
|
+
* H3 middleware uses instance.use() which doesn't filter by HTTP method (similar to Fastify).
|
|
144
|
+
*/
|
|
145
|
+
createMiddlewareFactory(_requestMethod: RequestMethod): (path: string, callback: Function) => any;
|
|
146
|
+
/**
|
|
147
|
+
* Initialize the HTTP server with support for HTTP/1.1, HTTPS, and HTTP/2.
|
|
148
|
+
*
|
|
149
|
+
* HTTP/2 can be enabled by passing `http2Options` in the application options:
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```typescript
|
|
153
|
+
* // HTTP/2 with TLS (h2)
|
|
154
|
+
* const app = await NestFactory.create(AppModule, new H3Adapter(), {
|
|
155
|
+
* httpsOptions: { key, cert },
|
|
156
|
+
* http2Options: { http2: true, allowHTTP1: true }
|
|
157
|
+
* });
|
|
158
|
+
*
|
|
159
|
+
* // HTTP/2 cleartext (h2c) - for server-to-server only
|
|
160
|
+
* const app = await NestFactory.create(AppModule, new H3Adapter(), {
|
|
161
|
+
* http2Options: { http2: true }
|
|
162
|
+
* });
|
|
163
|
+
* ```
|
|
164
|
+
*
|
|
165
|
+
* @param options - Application options including HTTP/2 configuration
|
|
166
|
+
*/
|
|
167
|
+
initHttpServer(options: NestApplicationOptions & {
|
|
168
|
+
http2Options?: H3Http2Options | H3Http2CleartextOptions;
|
|
169
|
+
}): void;
|
|
170
|
+
/**
|
|
171
|
+
* Returns whether the server is running in HTTP/2 mode.
|
|
172
|
+
*
|
|
173
|
+
* @returns {boolean} True if HTTP/2 is enabled
|
|
174
|
+
*/
|
|
175
|
+
isHttp2Enabled(): boolean;
|
|
176
|
+
/**
|
|
177
|
+
* Parameters are part of the AbstractHttpAdapter interface contract.
|
|
178
|
+
* The prefix parameter could be used to conditionally apply parsing based on path prefix.
|
|
179
|
+
* The rawBody parameter could be used to configure raw body parsing.
|
|
180
|
+
* Currently, H3 adapter applies body parsing globally for POST, PUT, and PATCH requests.
|
|
181
|
+
* Multipart form data is skipped to allow interceptors to handle file uploads.
|
|
182
|
+
*/
|
|
183
|
+
registerParserMiddleware(_prefix?: string, _rawBody?: boolean): void;
|
|
184
|
+
getType(): string;
|
|
185
|
+
get(handler: Function): void;
|
|
186
|
+
get(path: string, handler: Function): void;
|
|
187
|
+
post(handler: Function): void;
|
|
188
|
+
post(path: string, handler: Function): void;
|
|
189
|
+
put(handler: Function): void;
|
|
190
|
+
put(path: string, handler: Function): void;
|
|
191
|
+
delete(handler: Function): void;
|
|
192
|
+
delete(path: string, handler: Function): void;
|
|
193
|
+
patch(handler: Function): void;
|
|
194
|
+
patch(path: string, handler: Function): void;
|
|
195
|
+
options(handler: Function): void;
|
|
196
|
+
options(path: string, handler: Function): void;
|
|
197
|
+
head(handler: Function): void;
|
|
198
|
+
head(path: string, handler: Function): void;
|
|
199
|
+
/**
|
|
200
|
+
* Registers a route handler using H3's native routing with handler chaining.
|
|
201
|
+
* Uses H3's radix tree router for fast O(1) path matching.
|
|
202
|
+
*
|
|
203
|
+
* Implementation notes:
|
|
204
|
+
* - Uses H3's native routing (instance.on()) for optimal performance
|
|
205
|
+
* - Maintains route map to support multiple versioned handlers per path
|
|
206
|
+
* - On first registration: creates chain handler and registers with H3
|
|
207
|
+
* - On subsequent registrations: adds to route map, existing chain handler finds it
|
|
208
|
+
* - Lazy lookup pattern: chain handler queries route map at request time
|
|
209
|
+
* - Supports version filtering via next() callback mechanism
|
|
210
|
+
*
|
|
211
|
+
* @param method - HTTP method (GET, POST, etc.)
|
|
212
|
+
* @param routePath - The route path pattern
|
|
213
|
+
* @param handler - The route handler (possibly wrapped with version filter)
|
|
214
|
+
*/
|
|
215
|
+
private registerRoute;
|
|
216
|
+
/**
|
|
217
|
+
* Executes a NestJS handler within an H3 event context.
|
|
218
|
+
* Used by native routing chain handler to invoke individual route handlers.
|
|
219
|
+
*
|
|
220
|
+
* @param handler - The NestJS route handler (possibly version-wrapped)
|
|
221
|
+
* @param event - The H3 event
|
|
222
|
+
* @param params - Route parameters (extracted by H3's router)
|
|
223
|
+
* @returns Promise that resolves to kHandled (if handled) or undefined (if next() called)
|
|
224
|
+
*/
|
|
225
|
+
private executeHandler;
|
|
226
|
+
/**
|
|
227
|
+
* Invokes the actual NestJS handler and manages response lifecycle.
|
|
228
|
+
* Optimized to avoid unnecessary listener registration.
|
|
229
|
+
*
|
|
230
|
+
* Response handling:
|
|
231
|
+
* - For async handlers (return promise): resolve when promise completes, no res listener needed
|
|
232
|
+
* - For sync handlers: wait for res 'finish' event to know when response is sent
|
|
233
|
+
* - next() callback allows versioned handlers to skip to next handler if version doesn't match
|
|
234
|
+
* - Returns kHandled to signal H3 that response is handled, or undefined to continue middleware chain
|
|
235
|
+
*
|
|
236
|
+
* @param handler - The NestJS route handler function
|
|
237
|
+
* @param req - Node.js request (HTTP/1 or HTTP/2)
|
|
238
|
+
* @param res - Node.js response (HTTP/1 or HTTP/2)
|
|
239
|
+
* @returns Promise resolving to kHandled or undefined
|
|
240
|
+
*/
|
|
241
|
+
private invokeHandler;
|
|
242
|
+
/**
|
|
243
|
+
* Applies version filtering to a route handler.
|
|
244
|
+
* Supports URI, Header, Media Type, and Custom versioning strategies.
|
|
245
|
+
*
|
|
246
|
+
* @param handler - The route handler function
|
|
247
|
+
* @param version - The version(s) this handler supports
|
|
248
|
+
* @param versioningOptions - The versioning configuration options
|
|
249
|
+
* @returns A wrapped handler that filters by version
|
|
250
|
+
*/
|
|
251
|
+
applyVersionFilter(handler: Function, version: VersionValue, versioningOptions: VersioningOptions): VersionedRoute;
|
|
252
|
+
}
|
|
253
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './h3-adapter';
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parameter decorator that extracts the underlying H3 event from the request.
|
|
3
|
+
* The H3 event provides access to H3-specific APIs and utilities.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```typescript
|
|
7
|
+
* import { H3Event } from '@marcosvnmelo/nestjs-platform-h3';
|
|
8
|
+
*
|
|
9
|
+
* @Controller('users')
|
|
10
|
+
* export class UsersController {
|
|
11
|
+
* @Get()
|
|
12
|
+
* findAll(@H3Event() event: H3EventType) {
|
|
13
|
+
* // Access H3-specific APIs
|
|
14
|
+
* const query = getQuery(event);
|
|
15
|
+
* const cookies = parseCookies(event);
|
|
16
|
+
* return { query, cookies };
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @returns The H3Event object attached to the request
|
|
22
|
+
*
|
|
23
|
+
* @publicApi
|
|
24
|
+
*/
|
|
25
|
+
export declare const H3Event: (...dataOrPipes: unknown[]) => ParameterDecorator;
|
|
26
|
+
/**
|
|
27
|
+
* Parameter decorator that extracts the raw H3 request object.
|
|
28
|
+
* This is the Node.js IncomingMessage with H3-specific properties attached.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* import { H3Request } from '@marcosvnmelo/nestjs-platform-h3';
|
|
33
|
+
*
|
|
34
|
+
* @Controller('users')
|
|
35
|
+
* export class UsersController {
|
|
36
|
+
* @Get()
|
|
37
|
+
* findAll(@H3Request() req: any) {
|
|
38
|
+
* // Access request with H3 properties
|
|
39
|
+
* console.log(req.query); // Query parameters
|
|
40
|
+
* console.log(req.params); // Route parameters
|
|
41
|
+
* console.log(req.body); // Parsed body
|
|
42
|
+
* return { url: req.url };
|
|
43
|
+
* }
|
|
44
|
+
* }
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @returns The request object with H3 properties
|
|
48
|
+
*
|
|
49
|
+
* @publicApi
|
|
50
|
+
*/
|
|
51
|
+
export declare const H3Request: (...dataOrPipes: unknown[]) => ParameterDecorator;
|
|
52
|
+
/**
|
|
53
|
+
* Parameter decorator that extracts the raw H3 response object.
|
|
54
|
+
* This is the Node.js ServerResponse used by the H3 adapter.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* import { H3Response } from '@marcosvnmelo/nestjs-platform-h3';
|
|
59
|
+
*
|
|
60
|
+
* @Controller('users')
|
|
61
|
+
* export class UsersController {
|
|
62
|
+
* @Get()
|
|
63
|
+
* findAll(@H3Response() res: ServerResponse) {
|
|
64
|
+
* // Access response to set headers, status, etc.
|
|
65
|
+
* res.setHeader('X-Custom-Header', 'value');
|
|
66
|
+
* return { message: 'success' };
|
|
67
|
+
* }
|
|
68
|
+
* }
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @returns The Node.js ServerResponse object
|
|
72
|
+
*
|
|
73
|
+
* @publicApi
|
|
74
|
+
*/
|
|
75
|
+
export declare const H3Response: (...dataOrPipes: unknown[]) => ParameterDecorator;
|
|
76
|
+
/**
|
|
77
|
+
* Parameter decorator that extracts query parameters from the H3 request.
|
|
78
|
+
* If a key is provided, returns the specific query parameter value.
|
|
79
|
+
* If no key is provided, returns all query parameters.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```typescript
|
|
83
|
+
* import { H3Query } from '@marcosvnmelo/nestjs-platform-h3';
|
|
84
|
+
*
|
|
85
|
+
* @Controller('users')
|
|
86
|
+
* export class UsersController {
|
|
87
|
+
* // Get all query parameters
|
|
88
|
+
* @Get()
|
|
89
|
+
* findAll(@H3Query() query: Record<string, string>) {
|
|
90
|
+
* return { query };
|
|
91
|
+
* }
|
|
92
|
+
*
|
|
93
|
+
* // Get specific query parameter
|
|
94
|
+
* @Get('search')
|
|
95
|
+
* search(@H3Query('term') searchTerm: string) {
|
|
96
|
+
* return { searchTerm };
|
|
97
|
+
* }
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* @param key - Optional key to extract a specific query parameter
|
|
102
|
+
* @returns The query parameters object or a specific value
|
|
103
|
+
*
|
|
104
|
+
* @publicApi
|
|
105
|
+
*/
|
|
106
|
+
export declare const H3Query: (...dataOrPipes: (string | import("@nestjs/common").PipeTransform<any, any> | import("@nestjs/common").Type<import("@nestjs/common").PipeTransform<any, any>> | undefined)[]) => ParameterDecorator;
|
|
107
|
+
/**
|
|
108
|
+
* Parameter decorator that extracts route parameters from the H3 request.
|
|
109
|
+
* If a key is provided, returns the specific route parameter value.
|
|
110
|
+
* If no key is provided, returns all route parameters.
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* ```typescript
|
|
114
|
+
* import { H3Params } from '@marcosvnmelo/nestjs-platform-h3';
|
|
115
|
+
*
|
|
116
|
+
* @Controller('users')
|
|
117
|
+
* export class UsersController {
|
|
118
|
+
* // Get all route parameters
|
|
119
|
+
* @Get(':id/posts/:postId')
|
|
120
|
+
* getPost(@H3Params() params: { id: string; postId: string }) {
|
|
121
|
+
* return { params };
|
|
122
|
+
* }
|
|
123
|
+
*
|
|
124
|
+
* // Get specific route parameter
|
|
125
|
+
* @Get(':id')
|
|
126
|
+
* findOne(@H3Params('id') id: string) {
|
|
127
|
+
* return { userId: id };
|
|
128
|
+
* }
|
|
129
|
+
* }
|
|
130
|
+
* ```
|
|
131
|
+
*
|
|
132
|
+
* @param key - Optional key to extract a specific route parameter
|
|
133
|
+
* @returns The route parameters object or a specific value
|
|
134
|
+
*
|
|
135
|
+
* @publicApi
|
|
136
|
+
*/
|
|
137
|
+
export declare const H3Params: (...dataOrPipes: (string | import("@nestjs/common").PipeTransform<any, any> | import("@nestjs/common").Type<import("@nestjs/common").PipeTransform<any, any>> | undefined)[]) => ParameterDecorator;
|
|
138
|
+
/**
|
|
139
|
+
* Parameter decorator that extracts the request body from the H3 request.
|
|
140
|
+
* If a key is provided, returns the specific body property value.
|
|
141
|
+
* If no key is provided, returns the entire body.
|
|
142
|
+
*
|
|
143
|
+
* @example
|
|
144
|
+
* ```typescript
|
|
145
|
+
* import { H3Body } from '@marcosvnmelo/nestjs-platform-h3';
|
|
146
|
+
*
|
|
147
|
+
* @Controller('users')
|
|
148
|
+
* export class UsersController {
|
|
149
|
+
* // Get entire body
|
|
150
|
+
* @Post()
|
|
151
|
+
* create(@H3Body() body: CreateUserDto) {
|
|
152
|
+
* return { user: body };
|
|
153
|
+
* }
|
|
154
|
+
*
|
|
155
|
+
* // Get specific body property
|
|
156
|
+
* @Post('register')
|
|
157
|
+
* register(@H3Body('email') email: string) {
|
|
158
|
+
* return { email };
|
|
159
|
+
* }
|
|
160
|
+
* }
|
|
161
|
+
* ```
|
|
162
|
+
*
|
|
163
|
+
* @param key - Optional key to extract a specific body property
|
|
164
|
+
* @returns The body object or a specific value
|
|
165
|
+
*
|
|
166
|
+
* @publicApi
|
|
167
|
+
*/
|
|
168
|
+
export declare const H3Body: (...dataOrPipes: (string | import("@nestjs/common").PipeTransform<any, any> | import("@nestjs/common").Type<import("@nestjs/common").PipeTransform<any, any>> | undefined)[]) => ParameterDecorator;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './h3-decorators';
|
package/dist/index.d.ts
ADDED