open-nest 0.0.1 → 0.0.2
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/dist/bun.d.mts +48 -0
- package/dist/bun.mjs +100 -0
- package/dist/fetch-Bmr9TEe3.mjs +958 -0
- package/dist/fetch.d.mts +2 -0
- package/dist/fetch.mjs +2 -0
- package/dist/gateway-CrNeg78D.d.mts +45 -0
- package/dist/gateway-D7PGV2DW.mjs +89 -0
- package/dist/index-DCLeOkkF.d.mts +217 -0
- package/dist/node.d.mts +53 -0
- package/dist/node.mjs +190 -0
- package/dist/workers.d.mts +38 -0
- package/dist/workers.mjs +28 -0
- package/package.json +50 -20
- package/readme.md +138 -40
- package/dist/express.d.mts +0 -61
- package/dist/express.mjs +0 -46
- package/dist/fastify.d.mts +0 -61
- package/dist/fastify.mjs +0 -46
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "open-nest",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Run any Nest application as a Web-Standard Request/Response handler. First class support for Bun, Node, and Cloudflare Workers.",
|
|
5
5
|
"files": [
|
|
6
6
|
"package.json",
|
|
7
7
|
"readme.md",
|
|
@@ -10,13 +10,21 @@
|
|
|
10
10
|
"type": "module",
|
|
11
11
|
"sideEffects": false,
|
|
12
12
|
"exports": {
|
|
13
|
-
"
|
|
14
|
-
"types": "./dist/
|
|
15
|
-
"import": "./dist/
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/fetch.d.mts",
|
|
15
|
+
"import": "./dist/fetch.mjs"
|
|
16
16
|
},
|
|
17
|
-
"./
|
|
18
|
-
"types": "./dist/
|
|
19
|
-
"import": "./dist/
|
|
17
|
+
"./bun": {
|
|
18
|
+
"types": "./dist/bun.d.mts",
|
|
19
|
+
"import": "./dist/bun.mjs"
|
|
20
|
+
},
|
|
21
|
+
"./node": {
|
|
22
|
+
"types": "./dist/node.d.mts",
|
|
23
|
+
"import": "./dist/node.mjs"
|
|
24
|
+
},
|
|
25
|
+
"./workers": {
|
|
26
|
+
"types": "./dist/workers.d.mts",
|
|
27
|
+
"import": "./dist/workers.mjs"
|
|
20
28
|
},
|
|
21
29
|
"./package.json": "./package.json"
|
|
22
30
|
},
|
|
@@ -26,36 +34,58 @@
|
|
|
26
34
|
"typecheck": "bun check",
|
|
27
35
|
"test": "bun test",
|
|
28
36
|
"lint": "oxlint --type-aware && oxfmt --check",
|
|
29
|
-
"format": "oxlint --fix --fix-suggestions && oxfmt"
|
|
37
|
+
"format": "oxlint --fix --fix-suggestions && oxfmt",
|
|
38
|
+
"example:bun": "bun examples/bun/index.ts",
|
|
39
|
+
"example:bun-websockets": "bun examples/bun-websockets/index.ts",
|
|
40
|
+
"example:node": "node --no-strip-types --import tsx examples/node/index.ts",
|
|
41
|
+
"example:node-websockets": "node --no-strip-types --import tsx examples/node-websockets/index.ts",
|
|
42
|
+
"example:workers": "bunx wrangler dev --config examples/workers/wrangler.jsonc --tsconfig ../../tsconfig.json"
|
|
30
43
|
},
|
|
31
44
|
"dependencies": {
|
|
32
|
-
"
|
|
45
|
+
"ws": "8.22.0"
|
|
33
46
|
},
|
|
34
47
|
"devDependencies": {
|
|
35
48
|
"@arethetypeswrong/core": "0.18.5",
|
|
49
|
+
"@nats-io/transport-node": "3.4.0",
|
|
50
|
+
"@nestjs/common": "12.1.3",
|
|
51
|
+
"@nestjs/core": "12.1.3",
|
|
52
|
+
"@nestjs/microservices": "12.1.3",
|
|
53
|
+
"@nestjs/platform-express": "12.1.3",
|
|
54
|
+
"@nestjs/platform-socket.io": "12.1.3",
|
|
55
|
+
"@nestjs/websockets": "12.1.3",
|
|
36
56
|
"@types/bun": "latest",
|
|
57
|
+
"@types/express": "5.0.6",
|
|
37
58
|
"@types/node": "26.6.5",
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"
|
|
59
|
+
"@types/ws": "8.18.2",
|
|
60
|
+
"amqp-connection-manager": "5.0.0",
|
|
61
|
+
"amqplib": "2.2.0",
|
|
62
|
+
"class-transformer": "0.5.1",
|
|
63
|
+
"class-validator": "0.15.1",
|
|
64
|
+
"express": "5.3.0",
|
|
65
|
+
"helmet": "8.3.0",
|
|
66
|
+
"ioredis": "6.0.0",
|
|
67
|
+
"kafkajs": "2.2.4",
|
|
68
|
+
"mqtt": "5.16.0",
|
|
69
|
+
"oxfmt": "0.72.0",
|
|
70
|
+
"oxlint": "1.87.0",
|
|
71
|
+
"oxlint-tsgolint": "7.0.2003",
|
|
72
|
+
"publint": "0.3.25",
|
|
73
|
+
"reflect-metadata": "0.2.2",
|
|
74
|
+
"rxjs": "7.8.2",
|
|
42
75
|
"tsdown": "0.23.0",
|
|
43
76
|
"tsup": "8.5.1",
|
|
77
|
+
"tsx": "4.23.15",
|
|
44
78
|
"typescript": "7.0.2"
|
|
45
79
|
},
|
|
46
80
|
"peerDependencies": {
|
|
47
81
|
"@nestjs/common": "^12.0.0",
|
|
48
82
|
"@nestjs/core": "^12.0.0",
|
|
49
|
-
"@nestjs/
|
|
50
|
-
"@nestjs/platform-fastify": "^12.0.0",
|
|
83
|
+
"@nestjs/websockets": "^12.0.0",
|
|
51
84
|
"reflect-metadata": "^0.1.12 || ^0.2.0",
|
|
52
85
|
"rxjs": "^7.1.0"
|
|
53
86
|
},
|
|
54
87
|
"peerDependenciesMeta": {
|
|
55
|
-
"@nestjs/
|
|
56
|
-
"optional": true
|
|
57
|
-
},
|
|
58
|
-
"@nestjs/platform-fastify": {
|
|
88
|
+
"@nestjs/websockets": {
|
|
59
89
|
"optional": true
|
|
60
90
|
}
|
|
61
91
|
}
|
package/readme.md
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
# `open-nest`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://workers.cloudflare.com)
|
|
4
|
+
[](https://bun.sh)
|
|
5
|
+
[](https://nodejs.org)<br>
|
|
6
|
+
[](https://github.com/juriadams/open-nest/actions/workflows/validate.yml)
|
|
7
|
+
[](https://www.npmjs.com/package/open-nest)
|
|
8
|
+
[](https://bundlejs.com/?q=open-nest)
|
|
9
|
+
|
|
10
|
+
Run any Nest application as a Web-Standard `Request`/`Response` handler. First class support for **Bun**, **Node**, and **Cloudflare Workers**.
|
|
4
11
|
|
|
5
12
|
## Installation
|
|
6
13
|
|
|
@@ -8,87 +15,178 @@ Turn a Nest application into a Web fetch handler. Pass a `Request`, get a `Respo
|
|
|
8
15
|
bun add open-nest
|
|
9
16
|
```
|
|
10
17
|
|
|
11
|
-
|
|
18
|
+
Peer dependencies are `@nestjs/common`, `@nestjs/core`, `reflect-metadata`, and `rxjs`. WebSocket gateways also need `@nestjs/websockets`. These should already ship with your Nest installation.
|
|
19
|
+
|
|
20
|
+
## Examples
|
|
21
|
+
|
|
22
|
+
- [`examples/workers`](/examples/workers)<br />
|
|
23
|
+
<sup>[readme](/examples/workers/readme.md) ⋅ [code](/examples/workers/)</sup><br />
|
|
24
|
+
Run a Nest application on Cloudflare Workers.
|
|
25
|
+
|
|
26
|
+
- [`examples/bun`](/examples/bun)<br />
|
|
27
|
+
<sup>[readme](/examples/bun/readme.md) ⋅ [code](/examples/bun/)</sup><br />
|
|
28
|
+
Run a Nest application via `Bun.serve`.
|
|
29
|
+
|
|
30
|
+
- [`examples/bun-websockets`](/examples/bun-websockets)<br />
|
|
31
|
+
<sup>[readme](/examples/bun-websockets/readme.md) ⋅ [code](/examples/bun-websockets/)</sup><br />
|
|
32
|
+
Run a Nest application via `Bun.serve` with WebSockets.
|
|
33
|
+
|
|
34
|
+
- [`examples/node`](/examples/node)<br />
|
|
35
|
+
<sup>[readme](/examples/node/readme.md) ⋅ [code](/examples/node/)</sup><br />
|
|
36
|
+
Run a Nest application via `http.Server`.
|
|
37
|
+
|
|
38
|
+
- [`examples/node-websockets`](/examples/node-websockets)<br />
|
|
39
|
+
<sup>[readme](/examples/node-websockets/readme.md) ⋅ [code](/examples/node-websockets/)</sup><br />
|
|
40
|
+
Run a Nest application via `http.Server` with WebSockets.
|
|
12
41
|
|
|
13
42
|
## Usage
|
|
14
43
|
|
|
15
44
|
```ts
|
|
16
45
|
import "reflect-metadata";
|
|
17
|
-
import { Controller, Get, Module } from "@nestjs/common";
|
|
18
|
-
import { createFetcher } from "open-nest/fastify";
|
|
19
|
-
import { AppModule } from "@/app.module";
|
|
20
46
|
|
|
21
|
-
|
|
47
|
+
import { createFetcher } from "open-nest";
|
|
48
|
+
|
|
49
|
+
import { AppModule } from "@/app/module";
|
|
50
|
+
|
|
51
|
+
const fetcher = createFetcher({ module: AppModule });
|
|
22
52
|
|
|
23
53
|
await Bun.serve({
|
|
24
|
-
fetch,
|
|
54
|
+
fetch: fetcher,
|
|
25
55
|
port: 3000,
|
|
26
56
|
});
|
|
27
57
|
```
|
|
28
58
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
The Nest app boots on the first request and its instance is cached for all further requests.
|
|
59
|
+
`createFetcher` from `open-nest` is the HTTP entry. It returns a function from `Request` to `Response`. WebSocket gateways and static files are available for the respective runtime under `open-nest/bun` and `open-nest/node`.
|
|
32
60
|
|
|
33
|
-
|
|
61
|
+
### Bun
|
|
34
62
|
|
|
35
63
|
```ts
|
|
36
|
-
|
|
37
|
-
```
|
|
64
|
+
import "reflect-metadata";
|
|
38
65
|
|
|
39
|
-
|
|
66
|
+
import { BunWsAdapter, createBunServer } from "open-nest/bun";
|
|
40
67
|
|
|
41
|
-
|
|
68
|
+
import { AppModule } from "@/app/module";
|
|
42
69
|
|
|
43
|
-
|
|
44
|
-
const fetch = createFetcher({
|
|
70
|
+
await createBunServer({
|
|
45
71
|
module: AppModule,
|
|
72
|
+
port: 3000,
|
|
46
73
|
configure: (app) => {
|
|
47
|
-
app.
|
|
74
|
+
app.useWebSocketAdapter(new BunWsAdapter());
|
|
75
|
+
app.useStaticAssets("public", { prefix: "/static" });
|
|
48
76
|
},
|
|
49
77
|
});
|
|
50
78
|
```
|
|
51
79
|
|
|
52
|
-
|
|
80
|
+
`createBunServer` from `open-nest/bun` serves that handler with `Bun.serve`. It upgrades gateway paths and serves files with `Bun.file()`.
|
|
53
81
|
|
|
54
|
-
`
|
|
82
|
+
- `createBunServer` initializes the Nest application once and starts and returns a `Bun.serve` instance.
|
|
83
|
+
- `BunWsAdapter` is the Nest WebSocket adapter. `Bun.serve` performs the upgrade.
|
|
84
|
+
- `BunAdapter` extends `FetchAdapter` and implements `useStaticAssets` with `Bun.file()`.
|
|
85
|
+
|
|
86
|
+
### Node
|
|
55
87
|
|
|
56
88
|
```ts
|
|
57
|
-
|
|
89
|
+
import "reflect-metadata";
|
|
90
|
+
|
|
91
|
+
import { createNodeServer, NodeWsAdapter } from "open-nest/node";
|
|
92
|
+
|
|
93
|
+
import { AppModule } from "@/app/module";
|
|
94
|
+
|
|
95
|
+
await createNodeServer({
|
|
58
96
|
module: AppModule,
|
|
59
|
-
|
|
97
|
+
port: 3000,
|
|
98
|
+
configure: (app) => {
|
|
99
|
+
app.useWebSocketAdapter(new NodeWsAdapter());
|
|
100
|
+
app.useStaticAssets("public", { prefix: "/static" });
|
|
101
|
+
},
|
|
60
102
|
});
|
|
61
103
|
```
|
|
62
104
|
|
|
63
|
-
|
|
105
|
+
`createNodeServer` from `open-nest/node` initializes the Nest application and starts and returns a `http.Server` instance. HTTP uses `node:http`, `node:stream`, and `node:fs` (`openAsBlob`).
|
|
64
106
|
|
|
65
|
-
|
|
107
|
+
Gateway upgrades go through [`ws`](https://github.com/websockets/ws). The WebSocket client is the global `WebSocket` from Node 22 onward.
|
|
66
108
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
109
|
+
- `createNodeServer` initializes the Nest application once and starts and returns a `http.Server` instance.
|
|
110
|
+
- `NodeWsAdapter` is the Nest WebSocket adapter. Upgrades go through `ws`.
|
|
111
|
+
- `NodeAdapter` extends `FetchAdapter` and implements `useStaticAssets` with `node:fs`.
|
|
70
112
|
|
|
71
|
-
|
|
113
|
+
### Workers
|
|
72
114
|
|
|
73
|
-
```
|
|
74
|
-
|
|
115
|
+
```ts
|
|
116
|
+
import "reflect-metadata";
|
|
117
|
+
|
|
118
|
+
import {
|
|
119
|
+
createWorkerFetcher,
|
|
120
|
+
workerContext,
|
|
121
|
+
type WorkerExecutionContext,
|
|
122
|
+
} from "open-nest/workers";
|
|
123
|
+
|
|
124
|
+
interface Env {
|
|
125
|
+
APP_NAME: string;
|
|
126
|
+
CACHE: KVNamespace;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@Controller()
|
|
130
|
+
class AppController {
|
|
131
|
+
@Get()
|
|
132
|
+
async index() {
|
|
133
|
+
const { env, ctx } = workerContext<Env>();
|
|
134
|
+
const lastOpenedAt = await env.CACHE.get("last-opened-at");
|
|
135
|
+
|
|
136
|
+
ctx.waitUntil(env.CACHE.put("last-opened-at", new Date().toISOString()));
|
|
137
|
+
|
|
138
|
+
return { data: { app: env.APP_NAME, lastOpenedAt }, error: null };
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
@Module({ controllers: [AppController] })
|
|
143
|
+
class AppModule {}
|
|
144
|
+
|
|
145
|
+
const fetcher = createWorkerFetcher<Env>({ module: AppModule });
|
|
146
|
+
|
|
147
|
+
export default {
|
|
148
|
+
fetch: (request: Request, env: Env, ctx: WorkerExecutionContext) =>
|
|
149
|
+
fetcher(request, env, ctx),
|
|
150
|
+
};
|
|
75
151
|
```
|
|
76
152
|
|
|
77
|
-
|
|
153
|
+
`createWorkerFetcher` from `open-nest/workers` initializes the Nest application and returns a handler of `(request, env, ctx)`.
|
|
78
154
|
|
|
79
|
-
|
|
80
|
-
|
|
155
|
+
Pass bindings and the execution context through, then read them with `workerContext()` from a controller or provider. The Worker needs the `nodejs_compat` compatibility flag.
|
|
156
|
+
|
|
157
|
+
- `createWorkerFetcher` initializes the Nest application once and returns a handler of `(request, env, ctx)`.
|
|
158
|
+
- `workerContext()` reads the bindings and the raw execution context for the request in flight.
|
|
159
|
+
- `WorkerExecutionContext` is the `ctx` argument: `waitUntil`, `passThroughOnException`, and `props`.
|
|
160
|
+
|
|
161
|
+
### App Configuration
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
const fetcher = createFetcher({
|
|
165
|
+
module: AppModule,
|
|
166
|
+
configure: (app) => {
|
|
167
|
+
app.enableCors();
|
|
168
|
+
app.setGlobalPrefix("api");
|
|
169
|
+
},
|
|
170
|
+
});
|
|
81
171
|
```
|
|
82
172
|
|
|
83
|
-
|
|
173
|
+
`configure` runs after the app is created and before `init`. Use it for pipes, a global prefix, CORS, and the other app methods.
|
|
174
|
+
|
|
175
|
+
### App Instance
|
|
84
176
|
|
|
85
|
-
```
|
|
86
|
-
|
|
177
|
+
```ts
|
|
178
|
+
const app = await fetcher.app();
|
|
87
179
|
```
|
|
88
180
|
|
|
89
|
-
|
|
181
|
+
`app()` resolves the underlying Nest application.
|
|
90
182
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
183
|
+
#### Nest Options
|
|
184
|
+
|
|
185
|
+
```ts
|
|
186
|
+
const fetcher = createFetcher({
|
|
187
|
+
module: AppModule,
|
|
188
|
+
opts: { logger: ["error", "warn"] },
|
|
189
|
+
});
|
|
94
190
|
```
|
|
191
|
+
|
|
192
|
+
`opts` is forwarded to `NestFactory.create` as `NestApplicationOptions`. When omitted, Nest keeps its own defaults.
|
package/dist/express.d.mts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { NestExpressApplication } from "@nestjs/platform-express";
|
|
2
|
-
import { NestApplicationOptions, Type } from "@nestjs/common";
|
|
3
|
-
//#region src/adapters/express/index.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Options for {@link createFetcher}.
|
|
6
|
-
*/
|
|
7
|
-
export interface CreateHandlerOptions {
|
|
8
|
-
/**
|
|
9
|
-
* Root Nest module.
|
|
10
|
-
*/
|
|
11
|
-
module: Type<any>;
|
|
12
|
-
/**
|
|
13
|
-
* Optional hook to configure the app before init (pipes, prefix, cors, ...).
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```ts
|
|
17
|
-
* const fetch = createFetcher({
|
|
18
|
-
* module: AppModule,
|
|
19
|
-
* configure: (app) => {
|
|
20
|
-
* app.use(cors());
|
|
21
|
-
* app.use(bodyParser.json());
|
|
22
|
-
* },
|
|
23
|
-
* });
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
configure?: (app: NestExpressApplication) => void | Promise<void>;
|
|
27
|
-
/**
|
|
28
|
-
* Optional Nest factory options.
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* ```ts
|
|
32
|
-
* const fetch = createFetcher({
|
|
33
|
-
* module: AppModule,
|
|
34
|
-
* opts: { logger: ["error", "warn"] },
|
|
35
|
-
* });
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
opts?: NestApplicationOptions;
|
|
39
|
-
}
|
|
40
|
-
export interface Fetcher {
|
|
41
|
-
(request: Request): Promise<Response>;
|
|
42
|
-
/**
|
|
43
|
-
* Resolves the underlying Nest app instance.
|
|
44
|
-
* @example
|
|
45
|
-
* ```ts
|
|
46
|
-
* const app = await fetch.app();
|
|
47
|
-
* ```
|
|
48
|
-
*/
|
|
49
|
-
app(): Promise<NestExpressApplication>;
|
|
50
|
-
/**
|
|
51
|
-
* Closes the underlying Nest app.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```ts
|
|
55
|
-
* await fetch.close();
|
|
56
|
-
* ```
|
|
57
|
-
*/
|
|
58
|
-
close(): Promise<void>;
|
|
59
|
-
}
|
|
60
|
-
export declare function createFetcher({ module, configure, opts }: CreateHandlerOptions): Fetcher;
|
|
61
|
-
//#endregion
|
package/dist/express.mjs
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { NestFactory } from "@nestjs/core";
|
|
2
|
-
import { ExpressAdapter } from "@nestjs/platform-express";
|
|
3
|
-
import inject from "light-my-request";
|
|
4
|
-
//#region src/adapters/express/index.ts
|
|
5
|
-
function createFetcher({ module, configure, opts }) {
|
|
6
|
-
let pending;
|
|
7
|
-
const instance = () => {
|
|
8
|
-
if (pending) return pending;
|
|
9
|
-
pending = (async () => {
|
|
10
|
-
const app = await NestFactory.create(module, new ExpressAdapter(), opts);
|
|
11
|
-
await configure?.(app);
|
|
12
|
-
await app.init();
|
|
13
|
-
return app;
|
|
14
|
-
})();
|
|
15
|
-
return pending;
|
|
16
|
-
};
|
|
17
|
-
const handler = (async (request) => {
|
|
18
|
-
const app = await instance();
|
|
19
|
-
const url = new URL(request.url);
|
|
20
|
-
const hasBody = !["GET", "HEAD"].includes(request.method);
|
|
21
|
-
const res = await inject(app.getHttpAdapter().getInstance(), {
|
|
22
|
-
method: request.method,
|
|
23
|
-
url: url.pathname + url.search,
|
|
24
|
-
headers: Object.fromEntries(request.headers),
|
|
25
|
-
payload: hasBody ? Buffer.from(await request.arrayBuffer()) : void 0
|
|
26
|
-
});
|
|
27
|
-
const headers = new Headers();
|
|
28
|
-
for (const [k, v] of Object.entries(res.headers)) {
|
|
29
|
-
if (k === "content-length" || k === "transfer-encoding") continue;
|
|
30
|
-
if (Array.isArray(v)) v.forEach((x) => headers.append(k, x));
|
|
31
|
-
else if (v != null) headers.set(k, String(v));
|
|
32
|
-
}
|
|
33
|
-
return new Response(res.rawPayload, {
|
|
34
|
-
status: res.statusCode,
|
|
35
|
-
headers
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
handler.app = instance;
|
|
39
|
-
handler.close = async () => {
|
|
40
|
-
if (pending) await (await pending).close();
|
|
41
|
-
pending = void 0;
|
|
42
|
-
};
|
|
43
|
-
return handler;
|
|
44
|
-
}
|
|
45
|
-
//#endregion
|
|
46
|
-
export { createFetcher };
|
package/dist/fastify.d.mts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { NestFastifyApplication } from "@nestjs/platform-fastify";
|
|
2
|
-
import { NestApplicationOptions, Type } from "@nestjs/common";
|
|
3
|
-
//#region src/adapters/fastify/index.d.ts
|
|
4
|
-
/**
|
|
5
|
-
* Options for {@link createFetcher}.
|
|
6
|
-
*/
|
|
7
|
-
export interface CreateHandlerOptions {
|
|
8
|
-
/**
|
|
9
|
-
* Root Nest module.
|
|
10
|
-
*/
|
|
11
|
-
module: Type<any>;
|
|
12
|
-
/**
|
|
13
|
-
* Optional hook to configure the app before init (pipes, prefix, cors, ...).
|
|
14
|
-
*
|
|
15
|
-
* @example
|
|
16
|
-
* ```ts
|
|
17
|
-
* const fetch = createFetcher({
|
|
18
|
-
* module: AppModule,
|
|
19
|
-
* configure: (app) => {
|
|
20
|
-
* app.use(cors());
|
|
21
|
-
* app.use(bodyParser.json());
|
|
22
|
-
* },
|
|
23
|
-
* });
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
|
-
configure?: (app: NestFastifyApplication) => void | Promise<void>;
|
|
27
|
-
/**
|
|
28
|
-
* Optional Nest factory options.
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* ```ts
|
|
32
|
-
* const fetch = createFetcher({
|
|
33
|
-
* module: AppModule,
|
|
34
|
-
* opts: { logger: ["error", "warn"] },
|
|
35
|
-
* });
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
opts?: NestApplicationOptions;
|
|
39
|
-
}
|
|
40
|
-
export interface Fetcher {
|
|
41
|
-
(request: Request): Promise<Response>;
|
|
42
|
-
/**
|
|
43
|
-
* Resolves the underlying Nest app instance.
|
|
44
|
-
* @example
|
|
45
|
-
* ```ts
|
|
46
|
-
* const app = await fetch.app();
|
|
47
|
-
* ```
|
|
48
|
-
*/
|
|
49
|
-
app(): Promise<NestFastifyApplication>;
|
|
50
|
-
/**
|
|
51
|
-
* Closes the underlying Nest app.
|
|
52
|
-
*
|
|
53
|
-
* @example
|
|
54
|
-
* ```ts
|
|
55
|
-
* await fetch.close();
|
|
56
|
-
* ```
|
|
57
|
-
*/
|
|
58
|
-
close(): Promise<void>;
|
|
59
|
-
}
|
|
60
|
-
export declare function createFetcher({ module, configure, opts }: CreateHandlerOptions): Fetcher;
|
|
61
|
-
//#endregion
|
package/dist/fastify.mjs
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { NestFactory } from "@nestjs/core";
|
|
2
|
-
import { FastifyAdapter } from "@nestjs/platform-fastify";
|
|
3
|
-
//#region src/adapters/fastify/index.ts
|
|
4
|
-
function createFetcher({ module, configure, opts }) {
|
|
5
|
-
let pending;
|
|
6
|
-
const instance = () => {
|
|
7
|
-
if (pending) return pending;
|
|
8
|
-
pending = (async () => {
|
|
9
|
-
const app = await NestFactory.create(module, new FastifyAdapter(), opts);
|
|
10
|
-
await configure?.(app);
|
|
11
|
-
await app.init();
|
|
12
|
-
await app.getHttpAdapter().getInstance().ready();
|
|
13
|
-
return app;
|
|
14
|
-
})();
|
|
15
|
-
return pending;
|
|
16
|
-
};
|
|
17
|
-
const handler = (async (request) => {
|
|
18
|
-
const app = await instance();
|
|
19
|
-
const url = new URL(request.url);
|
|
20
|
-
const hasBody = !["GET", "HEAD"].includes(request.method);
|
|
21
|
-
const res = await app.getHttpAdapter().getInstance().inject({
|
|
22
|
-
method: request.method,
|
|
23
|
-
url: url.pathname + url.search,
|
|
24
|
-
headers: Object.fromEntries(request.headers),
|
|
25
|
-
payload: hasBody ? Buffer.from(await request.arrayBuffer()) : void 0
|
|
26
|
-
});
|
|
27
|
-
const headers = new Headers();
|
|
28
|
-
for (const [k, v] of Object.entries(res.headers)) {
|
|
29
|
-
if (k === "content-length" || k === "transfer-encoding") continue;
|
|
30
|
-
if (Array.isArray(v)) v.forEach((x) => headers.append(k, x));
|
|
31
|
-
else if (v != null) headers.set(k, String(v));
|
|
32
|
-
}
|
|
33
|
-
return new Response(res.rawPayload, {
|
|
34
|
-
status: res.statusCode,
|
|
35
|
-
headers
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
handler.app = instance;
|
|
39
|
-
handler.close = async () => {
|
|
40
|
-
if (pending) await (await pending).close();
|
|
41
|
-
pending = void 0;
|
|
42
|
-
};
|
|
43
|
-
return handler;
|
|
44
|
-
}
|
|
45
|
-
//#endregion
|
|
46
|
-
export { createFetcher };
|