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.
@@ -0,0 +1,2 @@
1
+ import { a as createFetcher, c as FilesInterceptor, i as Fetcher, l as MultipartLimits, n as CreateHandlerOptions, o as AnyFilesInterceptor, r as FetchAdapter, s as FileInterceptor, t as CorsOptions, u as MultipartOptions } from "./index-DCLeOkkF.mjs";
2
+ export { AnyFilesInterceptor, CorsOptions, CreateHandlerOptions, FetchAdapter, Fetcher, FileInterceptor, FilesInterceptor, type MultipartLimits, type MultipartOptions, createFetcher };
package/dist/fetch.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import { a as FilesInterceptor, i as FileInterceptor, n as createFetcher, r as AnyFilesInterceptor, t as FetchAdapter } from "./fetch-Bmr9TEe3.mjs";
2
+ export { AnyFilesInterceptor, FetchAdapter, FileInterceptor, FilesInterceptor, createFetcher };
@@ -0,0 +1,45 @@
1
+ //#region src/lib/gateway.d.ts
2
+ interface GatewayClient {
3
+ send(data: string): void;
4
+ data: {
5
+ path: string;
6
+ };
7
+ }
8
+ interface Gateway {
9
+ path: string;
10
+ connect?: (client: GatewayClient) => void;
11
+ }
12
+ interface MessageHandler {
13
+ message: string;
14
+ callback: (data: unknown) => unknown;
15
+ }
16
+ interface Subscription {
17
+ unsubscribe(): void;
18
+ }
19
+ interface ResultStream {
20
+ subscribe(observer: {
21
+ next: (value: unknown) => void;
22
+ error?: (error: unknown) => void;
23
+ }): Subscription;
24
+ }
25
+ /**
26
+ * Records Nest gateways during `init`. The runtime server performs the upgrade.
27
+ */
28
+ declare class WsGateway<T extends GatewayClient = GatewayClient> {
29
+ private readonly gateways;
30
+ private readonly clients;
31
+ create(_port: number, options?: {
32
+ path?: string;
33
+ }): Gateway;
34
+ bindClientConnect(server: Gateway, callback: (client: T) => void): void;
35
+ bindMessageHandlers(client: T, handlers: MessageHandler[], transform: (result: unknown) => ResultStream): void;
36
+ bindClientDisconnect(client: T, callback: () => void): void;
37
+ close(): void;
38
+ matches(pathname: string): boolean;
39
+ hasGateways(): boolean;
40
+ open(client: T): void;
41
+ receive(client: T, raw: string | Uint8Array): void;
42
+ closed(client: T): void;
43
+ }
44
+ //#endregion
45
+ export { WsGateway as n, GatewayClient as t };
@@ -0,0 +1,89 @@
1
+ //#region src/lib/gateway.ts
2
+ function gatewayPath(path) {
3
+ if (!path.startsWith("/")) path = `/${path}`;
4
+ if (path.length > 1 && path.endsWith("/")) path = path.slice(0, -1);
5
+ return path;
6
+ }
7
+ /**
8
+ * Records Nest gateways during `init`. The runtime server performs the upgrade.
9
+ */
10
+ var WsGateway = class {
11
+ gateways = [];
12
+ clients = /* @__PURE__ */ new WeakMap();
13
+ create(_port, options) {
14
+ const gateway = { path: gatewayPath(options?.path ?? "/") };
15
+ this.gateways.push(gateway);
16
+ return gateway;
17
+ }
18
+ bindClientConnect(server, callback) {
19
+ server.connect = callback;
20
+ }
21
+ bindMessageHandlers(client, handlers, transform) {
22
+ const prev = this.clients.get(client);
23
+ this.clients.set(client, {
24
+ handlers,
25
+ transform,
26
+ subscriptions: prev?.subscriptions ?? [],
27
+ onClose: prev?.onClose
28
+ });
29
+ }
30
+ bindClientDisconnect(client, callback) {
31
+ const state = this.clients.get(client);
32
+ if (!state) return;
33
+ state.onClose = callback;
34
+ }
35
+ close() {}
36
+ matches(pathname) {
37
+ const path = gatewayPath(pathname);
38
+ return this.gateways.some((gateway) => gateway.path === path);
39
+ }
40
+ hasGateways() {
41
+ return this.gateways.length > 0;
42
+ }
43
+ open(client) {
44
+ this.gateways.find((item) => item.path === client.data.path)?.connect?.(client);
45
+ }
46
+ receive(client, raw) {
47
+ const state = this.clients.get(client);
48
+ if (!state) return;
49
+ let event;
50
+ let data;
51
+ try {
52
+ const text = typeof raw === "string" ? raw : new TextDecoder().decode(raw);
53
+ const parsed = JSON.parse(text);
54
+ if (typeof parsed.event !== "string") return;
55
+ event = parsed.event;
56
+ data = parsed.data;
57
+ } catch {
58
+ return;
59
+ }
60
+ const handler = state.handlers.find((item) => item.message === event);
61
+ if (!handler) return;
62
+ let stream;
63
+ try {
64
+ stream = state.transform(handler.callback(data));
65
+ } catch {
66
+ return;
67
+ }
68
+ const subscription = stream.subscribe({
69
+ next: (value) => {
70
+ if (value === void 0) return;
71
+ client.send(JSON.stringify({
72
+ event,
73
+ data: value
74
+ }));
75
+ },
76
+ error: () => {}
77
+ });
78
+ state.subscriptions.push(subscription);
79
+ }
80
+ closed(client) {
81
+ const state = this.clients.get(client);
82
+ if (!state) return;
83
+ for (const subscription of state.subscriptions) subscription.unsubscribe();
84
+ state.onClose?.();
85
+ this.clients.delete(client);
86
+ }
87
+ };
88
+ //#endregion
89
+ export { gatewayPath as n, WsGateway as t };
@@ -0,0 +1,217 @@
1
+ import { INestApplication, NestApplicationOptions, NestInterceptor, RequestMethod, Type, VersioningOptions } from "@nestjs/common";
2
+ import { AbstractHttpAdapter } from "@nestjs/core";
3
+ import { VersionValue } from "@nestjs/common/interfaces/version-options.interface";
4
+ //#region src/lib/events.d.ts
5
+ type Listener = (...args: unknown[]) => void;
6
+ declare class Emitter {
7
+ private listeners;
8
+ on(event: string, fn: Listener): this;
9
+ once(event: string, fn: Listener): this;
10
+ removeListener(event: string, fn: Listener): this;
11
+ emit(event: string, ...args: unknown[]): void;
12
+ }
13
+ //#endregion
14
+ //#region src/lib/request.d.ts
15
+ declare class FetchSocket extends Emitter {
16
+ destroyed: boolean;
17
+ readable: boolean;
18
+ writable: boolean;
19
+ setKeepAlive(): void;
20
+ setNoDelay(): void;
21
+ setTimeout(): void;
22
+ close(): void;
23
+ }
24
+ interface UploadedFile {
25
+ fieldname: string;
26
+ originalname: string;
27
+ encoding: string;
28
+ mimetype: string;
29
+ buffer: Uint8Array;
30
+ size: number;
31
+ }
32
+ interface FetchRequest {
33
+ raw: Request;
34
+ method: string;
35
+ url: string;
36
+ originalUrl: string;
37
+ path: string;
38
+ headers: Record<string, string | string[]>;
39
+ query: Record<string, string | string[]>;
40
+ params: Record<string, string>;
41
+ body: unknown;
42
+ /**
43
+ * Set when a parser has consumed the body, or when a middleware wants later
44
+ * parsers to leave the stream unread.
45
+ */
46
+ _body?: boolean;
47
+ rawBody?: Uint8Array;
48
+ ip: string;
49
+ hostname: string;
50
+ socket: FetchSocket;
51
+ file?: UploadedFile;
52
+ files?: UploadedFile[];
53
+ }
54
+ //#endregion
55
+ //#region src/lib/response.d.ts
56
+ declare class FetchResponse extends Emitter {
57
+ statusCode: number;
58
+ headersSent: boolean;
59
+ writableEnded: boolean;
60
+ destroyed: boolean;
61
+ writable: boolean;
62
+ readonly socket: FetchSocket;
63
+ private readonly headers;
64
+ private controller;
65
+ private wrote;
66
+ private streamClosed;
67
+ private readonly drainWaiters;
68
+ private resolveReady;
69
+ private readonly readyPromise;
70
+ readonly stream: ReadableStream<Uint8Array<ArrayBufferLike>>;
71
+ constructor(socket: FetchSocket);
72
+ ready(): Promise<Response>;
73
+ setHeader(name: string, value: string): void;
74
+ appendHeader(name: string, value: string): void;
75
+ getHeader(name: string): string | null;
76
+ removeHeader(name: string): void;
77
+ getHeaders(): Record<string, string>;
78
+ status(code: number): this;
79
+ writeHead(status: number, headers?: Record<string, string | number | readonly string[]>): void;
80
+ flushHeaders(): void;
81
+ write(chunk: unknown, encoding?: BufferEncoding | ((error?: Error | null) => void), cb?: (error?: Error | null) => void): boolean;
82
+ end(chunk?: unknown, encoding?: BufferEncoding | (() => void), cb?: () => void): void;
83
+ private closeStream;
84
+ send(body?: string): void;
85
+ json(body: unknown): void;
86
+ destroy(): void;
87
+ private commit;
88
+ }
89
+ //#endregion
90
+ //#region src/lib/router.d.ts
91
+ type Next = (err?: unknown) => void;
92
+ type Handler = (req: FetchRequest, res: FetchResponse, next: Next) => unknown;
93
+ type ErrorHandler = (err: unknown, req: FetchRequest, res: FetchResponse, next: Next) => unknown;
94
+ type Callback = Handler | ErrorHandler;
95
+ declare class Router {
96
+ private layers;
97
+ use(handler: Handler): void;
98
+ use(path: string | string[], handler: Handler): void;
99
+ use(handler: ErrorHandler): void;
100
+ use(path: string | string[], handler: ErrorHandler): void;
101
+ get(path: string | Handler, handler?: Handler): void;
102
+ post(path: string | Handler, handler?: Handler): void;
103
+ head(path: string | Handler, handler?: Handler): void;
104
+ delete(path: string | Handler, handler?: Handler): void;
105
+ put(path: string | Handler, handler?: Handler): void;
106
+ patch(path: string | Handler, handler?: Handler): void;
107
+ options(path: string | Handler, handler?: Handler): void;
108
+ all(path: string | Handler, handler?: Handler): void;
109
+ propfind(path: string | Handler, handler?: Handler): void;
110
+ proppatch(path: string | Handler, handler?: Handler): void;
111
+ mkcol(path: string | Handler, handler?: Handler): void;
112
+ copy(path: string | Handler, handler?: Handler): void;
113
+ move(path: string | Handler, handler?: Handler): void;
114
+ lock(path: string | Handler, handler?: Handler): void;
115
+ unlock(path: string | Handler, handler?: Handler): void;
116
+ search(path: string | Handler, handler?: Handler): void;
117
+ query(path: string | Handler, handler?: Handler): void;
118
+ add(method: string | null, path: string | Callback, handler: Callback | undefined, kind: "exact" | "prefix"): void;
119
+ handle(req: FetchRequest, res: FetchResponse): void;
120
+ }
121
+ //#endregion
122
+ //#region src/lib/multipart/index.d.ts
123
+ interface MultipartLimits {
124
+ fileSize?: number;
125
+ files?: number;
126
+ fields?: number;
127
+ }
128
+ interface MultipartOptions {
129
+ limits?: MultipartLimits;
130
+ }
131
+ declare function FileInterceptor(field: string, options?: MultipartOptions): Type<NestInterceptor>;
132
+ declare function FilesInterceptor(field: string, maxCount?: number, options?: MultipartOptions): Type<NestInterceptor>;
133
+ declare function AnyFilesInterceptor(options?: MultipartOptions): Type<NestInterceptor>;
134
+ //#endregion
135
+ //#region src/fetch/index.d.ts
136
+ interface CorsOptions {
137
+ origin?: boolean | string | RegExp | Array<string | RegExp> | ((origin: string) => boolean);
138
+ methods?: string | string[];
139
+ allowedHeaders?: string | string[];
140
+ exposedHeaders?: string | string[];
141
+ credentials?: boolean;
142
+ maxAge?: number;
143
+ }
144
+ /**
145
+ * Options for {@link createFetcher}.
146
+ */
147
+ interface CreateHandlerOptions {
148
+ /**
149
+ * Root Nest module.
150
+ */
151
+ module: Type<unknown>;
152
+ /**
153
+ * Runs after the app is created and before init.
154
+ */
155
+ configure?: (app: INestApplication) => void | Promise<void>;
156
+ /**
157
+ * Forwarded to `NestFactory.create`.
158
+ */
159
+ opts?: NestApplicationOptions;
160
+ /**
161
+ * Max JSON or urlencoded body size in bytes. Defaults to 1 MiB.
162
+ */
163
+ bodyLimit?: number;
164
+ }
165
+ interface Fetcher {
166
+ (request: Request): Promise<Response>;
167
+ /**
168
+ * Resolves the underlying Nest app instance.
169
+ */
170
+ app(): Promise<INestApplication>;
171
+ /**
172
+ * Closes the underlying Nest app.
173
+ */
174
+ close(): Promise<void>;
175
+ }
176
+ declare class FetchAdapter extends AbstractHttpAdapter<undefined, FetchRequest, FetchResponse> {
177
+ private bodyLimit;
178
+ private rawBody;
179
+ private shuttingDown;
180
+ private parsersReady;
181
+ constructor();
182
+ protected get router(): Router;
183
+ handle(input: Request): Promise<Response>;
184
+ listen(): never;
185
+ initHttpServer(options: NestApplicationOptions): void;
186
+ beforeClose(): void;
187
+ close(): void;
188
+ useStaticAssets(_root?: string, _options?: {
189
+ prefix?: string;
190
+ index?: string | false;
191
+ }): this;
192
+ setViewEngine(): this;
193
+ getRequestHostname(request: FetchRequest): string;
194
+ getRequestMethod(request: FetchRequest): string;
195
+ getRequestUrl(request: FetchRequest): string;
196
+ status(response: FetchResponse, statusCode: number): FetchResponse;
197
+ reply(response: FetchResponse, body: unknown, statusCode?: number): void;
198
+ end(response: FetchResponse, message?: string): void;
199
+ render(): never;
200
+ redirect(response: FetchResponse, statusCode: number, url: string): void;
201
+ isHeadersSent(response: FetchResponse): boolean;
202
+ getHeader(response: FetchResponse, name: string): string | null;
203
+ setHeader(response: FetchResponse, name: string, value: string): void;
204
+ appendHeader(response: FetchResponse, name: string, value: string): void;
205
+ setErrorHandler(handler: Function): void;
206
+ setNotFoundHandler(handler: Function): void;
207
+ getType(): string;
208
+ isRouteOrderSensitive(): boolean;
209
+ applyVersionFilter(handler: Function, version: VersionValue, versioningOptions: VersioningOptions): (req: FetchRequest, res: FetchResponse, next: () => void) => Function;
210
+ createMiddlewareFactory(method: RequestMethod): (path: string, callback: Function) => void;
211
+ registerParserMiddleware(): void;
212
+ enableCors(options?: CorsOptions): void;
213
+ setBodyLimit(limit: number): void;
214
+ }
215
+ declare function createFetcher({ module, configure, opts, bodyLimit }: CreateHandlerOptions, adapter?: FetchAdapter): Fetcher;
216
+ //#endregion
217
+ export { createFetcher as a, FilesInterceptor as c, Fetcher as i, MultipartLimits as l, CreateHandlerOptions as n, AnyFilesInterceptor as o, FetchAdapter as r, FileInterceptor as s, CorsOptions as t, MultipartOptions as u };
@@ -0,0 +1,53 @@
1
+ import { i as Fetcher, r as FetchAdapter } from "./index-DCLeOkkF.mjs";
2
+ import { n as WsGateway, t as GatewayClient } from "./gateway-CrNeg78D.mjs";
3
+ import { INestApplication, NestApplicationOptions, Type } from "@nestjs/common";
4
+ //#region src/adapters/node/index.d.ts
5
+ interface NodeSocket extends GatewayClient {
6
+ data: {
7
+ path: string;
8
+ };
9
+ }
10
+ /**
11
+ * Records Nest gateways during `init`. `node:http` performs the upgrade.
12
+ */
13
+ export declare class NodeWsAdapter extends WsGateway<NodeSocket> {
14
+ constructor();
15
+ dispose(): Promise<void>;
16
+ }
17
+ /**
18
+ * Fetch adapter plus static files via `node:fs`.
19
+ */
20
+ export declare class NodeAdapter extends FetchAdapter {
21
+ useStaticAssets(root?: string, options?: {
22
+ prefix?: string;
23
+ index?: string | false;
24
+ }): this;
25
+ }
26
+ export interface CreateNodeServerOptions {
27
+ /**
28
+ * Root Nest module.
29
+ */
30
+ module: Type<unknown>;
31
+ /**
32
+ * Port passed to `node:http`. `0` asks the OS for a free port.
33
+ */
34
+ port?: number;
35
+ /**
36
+ * Runs after the app is created and before init.
37
+ */
38
+ configure?: (app: INestApplication) => void | Promise<void>;
39
+ /**
40
+ * Forwarded to `NestFactory.create`.
41
+ */
42
+ opts?: NestApplicationOptions;
43
+ }
44
+ export interface NodeServer {
45
+ port: number;
46
+ fetch: Fetcher;
47
+ close(): Promise<void>;
48
+ }
49
+ /**
50
+ * Boots a Nest app and serves it with `node:http`, including WebSocket upgrades.
51
+ */
52
+ export declare function createNodeServer({ module, port, configure, opts }: CreateNodeServerOptions): Promise<NodeServer>;
53
+ //#endregion
package/dist/node.mjs ADDED
@@ -0,0 +1,190 @@
1
+ import { n as createFetcher, t as FetchAdapter } from "./fetch-Bmr9TEe3.mjs";
2
+ import { n as gatewayPath, t as WsGateway } from "./gateway-D7PGV2DW.mjs";
3
+ import { Readable } from "node:stream";
4
+ import { extname, resolve, sep } from "node:path";
5
+ import { openAsBlob } from "node:fs";
6
+ import { stat } from "node:fs/promises";
7
+ import { createServer } from "node:http";
8
+ import { WebSocketServer } from "ws";
9
+ //#region src/adapters/node/index.ts
10
+ const adapters = [];
11
+ /**
12
+ * Records Nest gateways during `init`. `node:http` performs the upgrade.
13
+ */
14
+ var NodeWsAdapter = class extends WsGateway {
15
+ constructor() {
16
+ super();
17
+ adapters.push(this);
18
+ }
19
+ async dispose() {
20
+ const index = adapters.indexOf(this);
21
+ if (index !== -1) adapters.splice(index, 1);
22
+ }
23
+ };
24
+ /**
25
+ * Fetch adapter plus static files via `node:fs`.
26
+ */
27
+ var NodeAdapter = class extends FetchAdapter {
28
+ useStaticAssets(root, options) {
29
+ if (!root) return this;
30
+ const prefix = options?.prefix ?? "/";
31
+ const index = options?.index === void 0 ? "index.html" : options.index;
32
+ const rootResolved = resolve(root);
33
+ this.router.use(prefix, async (req, res, next) => {
34
+ if (req.method !== "GET" && req.method !== "HEAD") return next();
35
+ let relative;
36
+ try {
37
+ relative = decodeURIComponent(req.path);
38
+ } catch {
39
+ return next();
40
+ }
41
+ if (relative === "/") {
42
+ if (index === false) return next();
43
+ relative = index;
44
+ } else relative = relative.replace(/^\//, "");
45
+ const target = resolve(rootResolved, relative);
46
+ if (target !== rootResolved && !target.startsWith(rootResolved + sep)) return next();
47
+ let size;
48
+ try {
49
+ const info = await stat(target);
50
+ if (!info.isFile()) return next();
51
+ size = info.size;
52
+ } catch {
53
+ return next();
54
+ }
55
+ const type = contentType(target);
56
+ const blob = await openAsBlob(target);
57
+ res.setHeader("content-type", type);
58
+ res.setHeader("content-length", String(size));
59
+ if (req.method === "HEAD") {
60
+ res.end();
61
+ return;
62
+ }
63
+ const reader = blob.stream().getReader();
64
+ for (;;) {
65
+ const { done, value } = await reader.read();
66
+ if (done) break;
67
+ res.write(value);
68
+ }
69
+ res.end();
70
+ });
71
+ return this;
72
+ }
73
+ };
74
+ function contentType(file) {
75
+ switch (extname(file).toLowerCase()) {
76
+ case ".html": return "text/html; charset=utf-8";
77
+ case ".txt": return "text/plain; charset=utf-8";
78
+ case ".json": return "application/json";
79
+ case ".css": return "text/css; charset=utf-8";
80
+ case ".js": return "text/javascript; charset=utf-8";
81
+ case ".svg": return "image/svg+xml";
82
+ case ".png": return "image/png";
83
+ case ".jpg":
84
+ case ".jpeg": return "image/jpeg";
85
+ case ".webp": return "image/webp";
86
+ case ".pdf": return "application/pdf";
87
+ case ".wasm": return "application/wasm";
88
+ default: return "application/octet-stream";
89
+ }
90
+ }
91
+ /**
92
+ * Boots a Nest app and serves it with `node:http`, including WebSocket upgrades.
93
+ */
94
+ async function createNodeServer({ module, port, configure, opts }) {
95
+ const fallback = new NodeWsAdapter();
96
+ const seen = new Set(adapters);
97
+ const fetcher = createFetcher({
98
+ module,
99
+ opts,
100
+ configure: async (app) => {
101
+ app.useWebSocketAdapter(fallback);
102
+ await configure?.(app);
103
+ }
104
+ }, new NodeAdapter());
105
+ await fetcher.app();
106
+ const active = [...adapters].reverse().find((adapter) => !seen.has(adapter) && adapter.hasGateways()) ?? fallback;
107
+ const sockets = new WebSocketServer({ noServer: true });
108
+ const server = createServer((req, res) => {
109
+ writeFetch(fetcher, req, res);
110
+ });
111
+ server.on("upgrade", (req, socket, head) => {
112
+ const pathname = gatewayPath(new URL(req.url ?? "/", "http://localhost").pathname);
113
+ if (!active.matches(pathname)) {
114
+ socket.destroy();
115
+ return;
116
+ }
117
+ sockets.handleUpgrade(req, socket, head, (ws) => {
118
+ const client = {
119
+ data: { path: pathname },
120
+ send(data) {
121
+ ws.send(data);
122
+ }
123
+ };
124
+ active.open(client);
125
+ ws.on("message", (data) => {
126
+ const raw = typeof data === "string" ? data : Array.isArray(data) ? Buffer.concat(data) : data instanceof ArrayBuffer ? new Uint8Array(data) : data;
127
+ active.receive(client, raw);
128
+ });
129
+ ws.on("close", () => {
130
+ active.closed(client);
131
+ });
132
+ });
133
+ });
134
+ await new Promise((resolve) => {
135
+ server.listen(port ?? 3e3, "127.0.0.1", () => resolve());
136
+ });
137
+ const address = server.address();
138
+ return {
139
+ port: typeof address === "object" && address ? address.port : port ?? 3e3,
140
+ fetch: fetcher,
141
+ close: async () => {
142
+ for (const client of sockets.clients) client.terminate();
143
+ await new Promise((resolve, reject) => {
144
+ sockets.close((error) => error ? reject(error) : resolve());
145
+ });
146
+ server.closeAllConnections();
147
+ await new Promise((resolve, reject) => {
148
+ server.close((error) => error ? reject(error) : resolve());
149
+ });
150
+ await fetcher.close();
151
+ }
152
+ };
153
+ }
154
+ async function writeFetch(fetcher, req, res) {
155
+ try {
156
+ const response = await fetcher(toRequest(req));
157
+ const headers = Object.fromEntries(response.headers.entries());
158
+ res.writeHead(response.status, headers);
159
+ if (!response.body) {
160
+ res.end();
161
+ return;
162
+ }
163
+ await new Promise((resolve, reject) => {
164
+ Readable.fromWeb(response.body).pipe(res).on("finish", () => resolve()).on("error", reject);
165
+ });
166
+ } catch {
167
+ if (!res.headersSent) res.writeHead(500);
168
+ res.end();
169
+ }
170
+ }
171
+ function toRequest(req) {
172
+ const host = req.headers.host ?? "127.0.0.1";
173
+ const url = new URL(req.url ?? "/", `http://${host}`);
174
+ const headers = new Headers();
175
+ for (const [name, value] of Object.entries(req.headers)) {
176
+ if (value == null) continue;
177
+ if (Array.isArray(value)) for (const item of value) headers.append(name, item);
178
+ else headers.set(name, value);
179
+ }
180
+ const method = req.method ?? "GET";
181
+ const bodyless = method === "GET" || method === "HEAD";
182
+ return new Request(url.href, {
183
+ method,
184
+ headers,
185
+ body: bodyless ? void 0 : Readable.toWeb(req),
186
+ duplex: "half"
187
+ });
188
+ }
189
+ //#endregion
190
+ export { NodeAdapter, NodeWsAdapter, createNodeServer };
@@ -0,0 +1,38 @@
1
+ import { i as Fetcher, n as CreateHandlerOptions } from "./index-DCLeOkkF.mjs";
2
+ //#region src/adapters/workers/index.d.ts
3
+ /**
4
+ * The `ctx` argument from a Worker `fetch` handler.
5
+ */
6
+ export interface WorkerExecutionContext {
7
+ waitUntil(promise: Promise<unknown>): void;
8
+ passThroughOnException(): void;
9
+ readonly props?: unknown;
10
+ }
11
+ /**
12
+ * Bindings and the raw execution context for the request in flight.
13
+ */
14
+ export interface WorkerContext<Env> {
15
+ env: Env;
16
+ ctx: WorkerExecutionContext;
17
+ }
18
+ /**
19
+ * Bindings and execution context for the current Worker request.
20
+ */
21
+ export declare function workerContext<Env>(): WorkerContext<Env>;
22
+ export interface WorkerFetcher<Env> {
23
+ (request: Request, env: Env, ctx: WorkerExecutionContext): Promise<Response>;
24
+ /**
25
+ * Resolves the underlying Nest app instance.
26
+ */
27
+ app: Fetcher["app"];
28
+ /**
29
+ * Closes the underlying Nest app.
30
+ */
31
+ close: Fetcher["close"];
32
+ }
33
+ /**
34
+ * `createFetcher` whose handler also receives Worker bindings and `ctx`.
35
+ * `workerContext()` reads them for the duration of the request.
36
+ */
37
+ export declare function createWorkerFetcher<Env>(options: CreateHandlerOptions): WorkerFetcher<Env>;
38
+ //#endregion
@@ -0,0 +1,28 @@
1
+ import { n as createFetcher } from "./fetch-Bmr9TEe3.mjs";
2
+ import { AsyncLocalStorage } from "node:async_hooks";
3
+ //#region src/adapters/workers/index.ts
4
+ const storage = new AsyncLocalStorage();
5
+ /**
6
+ * Bindings and execution context for the current Worker request.
7
+ */
8
+ function workerContext() {
9
+ const context = storage.getStore();
10
+ if (!context) throw new Error("Called outside a worker request.");
11
+ return context;
12
+ }
13
+ /**
14
+ * `createFetcher` whose handler also receives Worker bindings and `ctx`.
15
+ * `workerContext()` reads them for the duration of the request.
16
+ */
17
+ function createWorkerFetcher(options) {
18
+ const fetcher = createFetcher(options);
19
+ const handler = (async (request, env, ctx) => storage.run({
20
+ env,
21
+ ctx
22
+ }, () => fetcher(request)));
23
+ handler.app = () => fetcher.app();
24
+ handler.close = () => fetcher.close();
25
+ return handler;
26
+ }
27
+ //#endregion
28
+ export { createWorkerFetcher, workerContext };