@whatwg-node/server 0.9.1 → 0.9.2-alpha-20230702143635-7d0af11

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,227 @@
1
+ import { URL } from '@whatwg-node/fetch';
2
+ import { completeAssign, isAsyncIterable } from '../utils';
3
+ export function useNodeAdapter() {
4
+ const nodeResponseMap = new WeakMap();
5
+ return {
6
+ onRequestAdapt({ args: [req, res, ...restOfCtx], setRequest, setServerContext, fetchAPI }) {
7
+ if (isNodeRequest(req)) {
8
+ const defaultServerContext = {
9
+ req,
10
+ };
11
+ const request = normalizeNodeRequest(req, fetchAPI.Request);
12
+ setRequest(request);
13
+ let ctxParams = restOfCtx;
14
+ if (isServerResponse(res)) {
15
+ defaultServerContext.res = res;
16
+ nodeResponseMap.set(request, res);
17
+ }
18
+ else {
19
+ ctxParams = [res, ...restOfCtx];
20
+ }
21
+ const serverContext = ctxParams.length > 0 ? completeAssign(...ctxParams) : defaultServerContext;
22
+ setServerContext(serverContext);
23
+ }
24
+ },
25
+ onResponse({ request, response }) {
26
+ const nodeResponse = nodeResponseMap.get(request);
27
+ if (nodeResponse) {
28
+ return sendNodeResponse(response, nodeResponse);
29
+ }
30
+ },
31
+ };
32
+ }
33
+ export function isReadable(stream) {
34
+ return stream.read != null;
35
+ }
36
+ export function isNodeRequest(request) {
37
+ return isReadable(request);
38
+ }
39
+ export function isServerResponse(stream) {
40
+ // Check all used functions are defined
41
+ return (stream != null &&
42
+ stream.setHeader != null &&
43
+ stream.end != null &&
44
+ stream.once != null &&
45
+ stream.write != null);
46
+ }
47
+ function getPort(nodeRequest) {
48
+ if (nodeRequest.socket?.localPort) {
49
+ return nodeRequest.socket?.localPort;
50
+ }
51
+ const hostInHeader = nodeRequest.headers?.[':authority'] || nodeRequest.headers?.host;
52
+ const portInHeader = hostInHeader?.split(':')?.[1];
53
+ if (portInHeader) {
54
+ return portInHeader;
55
+ }
56
+ return 80;
57
+ }
58
+ function getHostnameWithPort(nodeRequest) {
59
+ if (nodeRequest.headers?.[':authority']) {
60
+ return nodeRequest.headers?.[':authority'];
61
+ }
62
+ if (nodeRequest.headers?.host) {
63
+ return nodeRequest.headers?.host;
64
+ }
65
+ const port = getPort(nodeRequest);
66
+ if (nodeRequest.hostname) {
67
+ return nodeRequest.hostname + ':' + port;
68
+ }
69
+ const localIp = nodeRequest.socket?.localAddress;
70
+ if (localIp && !localIp?.includes('::') && !localIp?.includes('ffff')) {
71
+ return `${localIp}:${port}`;
72
+ }
73
+ return 'localhost';
74
+ }
75
+ function buildFullUrl(nodeRequest) {
76
+ const hostnameWithPort = getHostnameWithPort(nodeRequest);
77
+ const protocol = nodeRequest.protocol || 'http';
78
+ const endpoint = nodeRequest.originalUrl || nodeRequest.url || '/graphql';
79
+ return `${protocol}://${hostnameWithPort}${endpoint}`;
80
+ }
81
+ function isRequestBody(body) {
82
+ const stringTag = body[Symbol.toStringTag];
83
+ if (typeof body === 'string' ||
84
+ stringTag === 'Uint8Array' ||
85
+ stringTag === 'Blob' ||
86
+ stringTag === 'FormData' ||
87
+ stringTag === 'URLSearchParams' ||
88
+ isAsyncIterable(body)) {
89
+ return true;
90
+ }
91
+ return false;
92
+ }
93
+ export function normalizeNodeRequest(nodeRequest, RequestCtor) {
94
+ const rawRequest = nodeRequest.raw || nodeRequest.req || nodeRequest;
95
+ let fullUrl = buildFullUrl(rawRequest);
96
+ if (nodeRequest.query) {
97
+ const url = new URL(fullUrl);
98
+ for (const key in nodeRequest.query) {
99
+ url.searchParams.set(key, nodeRequest.query[key]);
100
+ }
101
+ fullUrl = url.toString();
102
+ }
103
+ if (nodeRequest.method === 'GET' || nodeRequest.method === 'HEAD') {
104
+ return new RequestCtor(fullUrl, {
105
+ method: nodeRequest.method,
106
+ headers: nodeRequest.headers,
107
+ });
108
+ }
109
+ /**
110
+ * Some Node server frameworks like Serverless Express sends a dummy object with body but as a Buffer not string
111
+ * so we do those checks to see is there something we can use directly as BodyInit
112
+ * because the presence of body means the request stream is already consumed and,
113
+ * rawRequest cannot be used as BodyInit/ReadableStream by Fetch API in this case.
114
+ */
115
+ const maybeParsedBody = nodeRequest.body;
116
+ if (maybeParsedBody != null && Object.keys(maybeParsedBody).length > 0) {
117
+ if (isRequestBody(maybeParsedBody)) {
118
+ return new RequestCtor(fullUrl, {
119
+ method: nodeRequest.method,
120
+ headers: nodeRequest.headers,
121
+ body: maybeParsedBody,
122
+ });
123
+ }
124
+ const request = new RequestCtor(fullUrl, {
125
+ method: nodeRequest.method,
126
+ headers: nodeRequest.headers,
127
+ });
128
+ if (!request.headers.get('content-type')?.includes('json')) {
129
+ request.headers.set('content-type', 'application/json; charset=utf-8');
130
+ }
131
+ return new Proxy(request, {
132
+ get: (target, prop, receiver) => {
133
+ switch (prop) {
134
+ case 'json':
135
+ return async () => maybeParsedBody;
136
+ case 'text':
137
+ return async () => JSON.stringify(maybeParsedBody);
138
+ default:
139
+ return Reflect.get(target, prop, receiver);
140
+ }
141
+ },
142
+ });
143
+ }
144
+ // perf: instead of spreading the object, we can just pass it as is and it performs better
145
+ return new RequestCtor(fullUrl, {
146
+ method: nodeRequest.method,
147
+ headers: nodeRequest.headers,
148
+ body: rawRequest,
149
+ });
150
+ }
151
+ function configureSocket(rawRequest) {
152
+ rawRequest?.socket?.setTimeout?.(0);
153
+ rawRequest?.socket?.setNoDelay?.(true);
154
+ rawRequest?.socket?.setKeepAlive?.(true);
155
+ }
156
+ function endResponse(serverResponse) {
157
+ // @ts-expect-error Avoid arguments adaptor trampoline https://v8.dev/blog/adaptor-frame
158
+ serverResponse.end(null, null, null);
159
+ }
160
+ function getHeaderPairs(headers) {
161
+ const headerPairs = new Map();
162
+ headers.forEach((value, key) => {
163
+ let headerValues = headerPairs.get(key);
164
+ if (headerValues === undefined) {
165
+ headerValues = [];
166
+ headerPairs.set(key, headerValues);
167
+ }
168
+ if (key === 'set-cookie') {
169
+ const setCookies = headers.getSetCookie?.();
170
+ if (setCookies) {
171
+ setCookies.forEach(setCookie => {
172
+ headerValues.push(setCookie);
173
+ });
174
+ return;
175
+ }
176
+ }
177
+ headerValues.push(value);
178
+ });
179
+ return headerPairs;
180
+ }
181
+ async function sendAsyncIterable(serverResponse, asyncIterable) {
182
+ for await (const chunk of asyncIterable) {
183
+ if (!serverResponse
184
+ // @ts-expect-error http and http2 writes are actually compatible
185
+ .write(chunk)) {
186
+ break;
187
+ }
188
+ }
189
+ endResponse(serverResponse);
190
+ }
191
+ export function sendNodeResponse(fetchResponse, serverResponse) {
192
+ const headerPairs = getHeaderPairs(fetchResponse.headers);
193
+ serverResponse.writeHead(fetchResponse.status, fetchResponse.statusText, Object.fromEntries(headerPairs.entries()));
194
+ // Optimizations for node-fetch
195
+ if (fetchResponse.bodyType === 'Buffer' ||
196
+ fetchResponse.bodyType === 'String' ||
197
+ fetchResponse.bodyType === 'Uint8Array') {
198
+ // @ts-expect-error http and http2 writes are actually compatible
199
+ serverResponse.write(fetchResponse.bodyInit);
200
+ endResponse(serverResponse);
201
+ return;
202
+ }
203
+ // Other fetch implementations
204
+ const fetchBody = fetchResponse.body;
205
+ if (fetchBody == null) {
206
+ endResponse(serverResponse);
207
+ return;
208
+ }
209
+ if (fetchBody[Symbol.toStringTag] === 'Uint8Array') {
210
+ serverResponse
211
+ // @ts-expect-error http and http2 writes are actually compatible
212
+ .write(fetchBody);
213
+ endResponse(serverResponse);
214
+ return;
215
+ }
216
+ configureSocket(serverResponse.req);
217
+ if (isReadable(fetchBody)) {
218
+ serverResponse.once('close', () => {
219
+ fetchBody.destroy();
220
+ });
221
+ fetchBody.pipe(serverResponse);
222
+ return;
223
+ }
224
+ if (isAsyncIterable(fetchBody)) {
225
+ return sendAsyncIterable(serverResponse, fetchBody);
226
+ }
227
+ }
@@ -1,3 +1,35 @@
1
+ import { completeAssign } from '../utils.js';
2
+ export function useUWSAdapter() {
3
+ const uwsResponseMap = new WeakMap();
4
+ return {
5
+ onRequestAdapt({ args: [res, req, ...restOfCtx], setRequest, setServerContext, fetchAPI }) {
6
+ if (isUWSResponse(res)) {
7
+ const request = getRequestFromUWSRequest({
8
+ req: req,
9
+ res,
10
+ fetchAPI,
11
+ });
12
+ uwsResponseMap.set(request, res);
13
+ setRequest(request);
14
+ const defaultServerContext = {
15
+ req,
16
+ res,
17
+ };
18
+ const serverContext = restOfCtx.length > 0 ? completeAssign(...restOfCtx) : defaultServerContext;
19
+ setServerContext(serverContext);
20
+ }
21
+ },
22
+ onResponse({ request, response }) {
23
+ const res = uwsResponseMap.get(request);
24
+ if (res) {
25
+ sendResponseToUwsOpts({
26
+ res,
27
+ response,
28
+ });
29
+ }
30
+ },
31
+ };
32
+ }
1
33
  export function isUWSResponse(res) {
2
34
  return !!res.onData;
3
35
  }
package/esm/utils.js CHANGED
@@ -1,208 +1,9 @@
1
- import { URL } from '@whatwg-node/fetch';
2
1
  export function isAsyncIterable(body) {
3
2
  return (body != null && typeof body === 'object' && typeof body[Symbol.asyncIterator] === 'function');
4
3
  }
5
- function getPort(nodeRequest) {
6
- if (nodeRequest.socket?.localPort) {
7
- return nodeRequest.socket?.localPort;
8
- }
9
- const hostInHeader = nodeRequest.headers?.[':authority'] || nodeRequest.headers?.host;
10
- const portInHeader = hostInHeader?.split(':')?.[1];
11
- if (portInHeader) {
12
- return portInHeader;
13
- }
14
- return 80;
15
- }
16
- function getHostnameWithPort(nodeRequest) {
17
- if (nodeRequest.headers?.[':authority']) {
18
- return nodeRequest.headers?.[':authority'];
19
- }
20
- if (nodeRequest.headers?.host) {
21
- return nodeRequest.headers?.host;
22
- }
23
- const port = getPort(nodeRequest);
24
- if (nodeRequest.hostname) {
25
- return nodeRequest.hostname + ':' + port;
26
- }
27
- const localIp = nodeRequest.socket?.localAddress;
28
- if (localIp && !localIp?.includes('::') && !localIp?.includes('ffff')) {
29
- return `${localIp}:${port}`;
30
- }
31
- return 'localhost';
32
- }
33
- function buildFullUrl(nodeRequest) {
34
- const hostnameWithPort = getHostnameWithPort(nodeRequest);
35
- const protocol = nodeRequest.protocol || 'http';
36
- const endpoint = nodeRequest.originalUrl || nodeRequest.url || '/graphql';
37
- return `${protocol}://${hostnameWithPort}${endpoint}`;
38
- }
39
- function isRequestBody(body) {
40
- const stringTag = body[Symbol.toStringTag];
41
- if (typeof body === 'string' ||
42
- stringTag === 'Uint8Array' ||
43
- stringTag === 'Blob' ||
44
- stringTag === 'FormData' ||
45
- stringTag === 'URLSearchParams' ||
46
- isAsyncIterable(body)) {
47
- return true;
48
- }
49
- return false;
50
- }
51
- export function normalizeNodeRequest(nodeRequest, RequestCtor) {
52
- const rawRequest = nodeRequest.raw || nodeRequest.req || nodeRequest;
53
- let fullUrl = buildFullUrl(rawRequest);
54
- if (nodeRequest.query) {
55
- const url = new URL(fullUrl);
56
- for (const key in nodeRequest.query) {
57
- url.searchParams.set(key, nodeRequest.query[key]);
58
- }
59
- fullUrl = url.toString();
60
- }
61
- if (nodeRequest.method === 'GET' || nodeRequest.method === 'HEAD') {
62
- return new RequestCtor(fullUrl, {
63
- method: nodeRequest.method,
64
- headers: nodeRequest.headers,
65
- });
66
- }
67
- /**
68
- * Some Node server frameworks like Serverless Express sends a dummy object with body but as a Buffer not string
69
- * so we do those checks to see is there something we can use directly as BodyInit
70
- * because the presence of body means the request stream is already consumed and,
71
- * rawRequest cannot be used as BodyInit/ReadableStream by Fetch API in this case.
72
- */
73
- const maybeParsedBody = nodeRequest.body;
74
- if (maybeParsedBody != null && Object.keys(maybeParsedBody).length > 0) {
75
- if (isRequestBody(maybeParsedBody)) {
76
- return new RequestCtor(fullUrl, {
77
- method: nodeRequest.method,
78
- headers: nodeRequest.headers,
79
- body: maybeParsedBody,
80
- });
81
- }
82
- const request = new RequestCtor(fullUrl, {
83
- method: nodeRequest.method,
84
- headers: nodeRequest.headers,
85
- });
86
- if (!request.headers.get('content-type')?.includes('json')) {
87
- request.headers.set('content-type', 'application/json; charset=utf-8');
88
- }
89
- return new Proxy(request, {
90
- get: (target, prop, receiver) => {
91
- switch (prop) {
92
- case 'json':
93
- return async () => maybeParsedBody;
94
- case 'text':
95
- return async () => JSON.stringify(maybeParsedBody);
96
- default:
97
- return Reflect.get(target, prop, receiver);
98
- }
99
- },
100
- });
101
- }
102
- // perf: instead of spreading the object, we can just pass it as is and it performs better
103
- return new RequestCtor(fullUrl, {
104
- method: nodeRequest.method,
105
- headers: nodeRequest.headers,
106
- body: rawRequest,
107
- });
108
- }
109
- export function isReadable(stream) {
110
- return stream.read != null;
111
- }
112
- export function isNodeRequest(request) {
113
- return isReadable(request);
114
- }
115
- export function isServerResponse(stream) {
116
- // Check all used functions are defined
117
- return (stream != null &&
118
- stream.setHeader != null &&
119
- stream.end != null &&
120
- stream.once != null &&
121
- stream.write != null);
122
- }
123
4
  export function isReadableStream(stream) {
124
5
  return stream != null && stream.getReader != null;
125
6
  }
126
- export function isFetchEvent(event) {
127
- return event != null && event.request != null && event.respondWith != null;
128
- }
129
- function configureSocket(rawRequest) {
130
- rawRequest?.socket?.setTimeout?.(0);
131
- rawRequest?.socket?.setNoDelay?.(true);
132
- rawRequest?.socket?.setKeepAlive?.(true);
133
- }
134
- function endResponse(serverResponse) {
135
- // @ts-expect-error Avoid arguments adaptor trampoline https://v8.dev/blog/adaptor-frame
136
- serverResponse.end(null, null, null);
137
- }
138
- function getHeaderPairs(headers) {
139
- const headerPairs = new Map();
140
- headers.forEach((value, key) => {
141
- let headerValues = headerPairs.get(key);
142
- if (headerValues === undefined) {
143
- headerValues = [];
144
- headerPairs.set(key, headerValues);
145
- }
146
- if (key === 'set-cookie') {
147
- const setCookies = headers.getSetCookie?.();
148
- if (setCookies) {
149
- setCookies.forEach(setCookie => {
150
- headerValues.push(setCookie);
151
- });
152
- return;
153
- }
154
- }
155
- headerValues.push(value);
156
- });
157
- return headerPairs;
158
- }
159
- async function sendAsyncIterable(serverResponse, asyncIterable) {
160
- for await (const chunk of asyncIterable) {
161
- if (!serverResponse
162
- // @ts-expect-error http and http2 writes are actually compatible
163
- .write(chunk)) {
164
- break;
165
- }
166
- }
167
- endResponse(serverResponse);
168
- }
169
- export function sendNodeResponse(fetchResponse, serverResponse, nodeRequest) {
170
- const headerPairs = getHeaderPairs(fetchResponse.headers);
171
- serverResponse.writeHead(fetchResponse.status, fetchResponse.statusText, Object.fromEntries(headerPairs.entries()));
172
- // Optimizations for node-fetch
173
- if (fetchResponse.bodyType === 'Buffer' ||
174
- fetchResponse.bodyType === 'String' ||
175
- fetchResponse.bodyType === 'Uint8Array') {
176
- // @ts-expect-error http and http2 writes are actually compatible
177
- serverResponse.write(fetchResponse.bodyInit);
178
- endResponse(serverResponse);
179
- return;
180
- }
181
- // Other fetch implementations
182
- const fetchBody = fetchResponse.body;
183
- if (fetchBody == null) {
184
- endResponse(serverResponse);
185
- return;
186
- }
187
- if (fetchBody[Symbol.toStringTag] === 'Uint8Array') {
188
- serverResponse
189
- // @ts-expect-error http and http2 writes are actually compatible
190
- .write(fetchBody);
191
- endResponse(serverResponse);
192
- return;
193
- }
194
- configureSocket(nodeRequest);
195
- if (isReadable(fetchBody)) {
196
- serverResponse.once('close', () => {
197
- fetchBody.destroy();
198
- });
199
- fetchBody.pipe(serverResponse);
200
- return;
201
- }
202
- if (isAsyncIterable(fetchBody)) {
203
- return sendAsyncIterable(serverResponse, fetchBody);
204
- }
205
- }
206
7
  export function isRequestInit(val) {
207
8
  return (val != null &&
208
9
  typeof val === 'object' &&
@@ -241,3 +42,10 @@ export function completeAssign(...args) {
241
42
  });
242
43
  return target;
243
44
  }
45
+ export function addWaitUntil(serverContext, waitUntilPromises) {
46
+ serverContext['waitUntil'] = function (promise) {
47
+ if (promise != null) {
48
+ waitUntilPromises.push(promise);
49
+ }
50
+ };
51
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whatwg-node/server",
3
- "version": "0.9.1",
3
+ "version": "0.9.2-alpha-20230702143635-7d0af11",
4
4
  "description": "Fetch API compliant HTTP Server adapter",
5
5
  "sideEffects": false,
6
6
  "dependencies": {
@@ -4,5 +4,7 @@ export * from './utils.cjs';
4
4
  export * from './plugins/types.cjs';
5
5
  export * from './plugins/useCors.cjs';
6
6
  export * from './plugins/useErrorHandling.cjs';
7
- export * from './uwebsockets.cjs';
7
+ export * from './internal-plugins/useFetchEvent.cjs';
8
+ export * from './internal-plugins/useNodeAdapter.cjs';
9
+ export * from './internal-plugins/useUWSAdapter.cjs';
8
10
  export { Response } from '@whatwg-node/fetch';
@@ -4,5 +4,7 @@ export * from './utils.js';
4
4
  export * from './plugins/types.js';
5
5
  export * from './plugins/useCors.js';
6
6
  export * from './plugins/useErrorHandling.js';
7
- export * from './uwebsockets.js';
7
+ export * from './internal-plugins/useFetchEvent.js';
8
+ export * from './internal-plugins/useNodeAdapter.js';
9
+ export * from './internal-plugins/useUWSAdapter.js';
8
10
  export { Response } from '@whatwg-node/fetch';
@@ -0,0 +1,4 @@
1
+ import { ServerAdapterPlugin } from '../plugins/types';
2
+ import { FetchEvent } from '../types';
3
+ export declare function isFetchEvent(event: any): event is FetchEvent;
4
+ export declare function useFetchEvent(): ServerAdapterPlugin<FetchEvent>;
@@ -0,0 +1,4 @@
1
+ import { ServerAdapterPlugin } from '../plugins/types';
2
+ import { FetchEvent } from '../types';
3
+ export declare function isFetchEvent(event: any): event is FetchEvent;
4
+ export declare function useFetchEvent(): ServerAdapterPlugin<FetchEvent>;
@@ -0,0 +1,34 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ /// <reference types="node" />
5
+ import { IncomingMessage, ServerResponse } from 'node:http';
6
+ import { Http2ServerRequest, Http2ServerResponse } from 'node:http2';
7
+ import { Socket } from 'node:net';
8
+ import type { Readable } from 'node:stream';
9
+ import { ServerAdapterPlugin } from '../plugins/types';
10
+ interface NodeServerContext {
11
+ req: NodeRequest;
12
+ res?: NodeResponse;
13
+ }
14
+ export declare function useNodeAdapter(): ServerAdapterPlugin<NodeServerContext>;
15
+ export interface NodeRequest {
16
+ protocol?: string;
17
+ hostname?: string;
18
+ body?: any;
19
+ url?: string;
20
+ originalUrl?: string;
21
+ method?: string;
22
+ headers?: any;
23
+ req?: IncomingMessage | Http2ServerRequest;
24
+ raw?: IncomingMessage | Http2ServerRequest;
25
+ socket?: Socket;
26
+ query?: any;
27
+ }
28
+ export type NodeResponse = ServerResponse | Http2ServerResponse;
29
+ export declare function isReadable(stream: any): stream is Readable;
30
+ export declare function isNodeRequest(request: any): request is NodeRequest;
31
+ export declare function isServerResponse(stream: any): stream is NodeResponse;
32
+ export declare function normalizeNodeRequest(nodeRequest: NodeRequest, RequestCtor: typeof Request): Request;
33
+ export declare function sendNodeResponse(fetchResponse: Response, serverResponse: NodeResponse): Promise<void> | undefined;
34
+ export {};
@@ -0,0 +1,34 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ /// <reference types="node" />
5
+ import { IncomingMessage, ServerResponse } from 'node:http';
6
+ import { Http2ServerRequest, Http2ServerResponse } from 'node:http2';
7
+ import { Socket } from 'node:net';
8
+ import type { Readable } from 'node:stream';
9
+ import { ServerAdapterPlugin } from '../plugins/types';
10
+ interface NodeServerContext {
11
+ req: NodeRequest;
12
+ res?: NodeResponse;
13
+ }
14
+ export declare function useNodeAdapter(): ServerAdapterPlugin<NodeServerContext>;
15
+ export interface NodeRequest {
16
+ protocol?: string;
17
+ hostname?: string;
18
+ body?: any;
19
+ url?: string;
20
+ originalUrl?: string;
21
+ method?: string;
22
+ headers?: any;
23
+ req?: IncomingMessage | Http2ServerRequest;
24
+ raw?: IncomingMessage | Http2ServerRequest;
25
+ socket?: Socket;
26
+ query?: any;
27
+ }
28
+ export type NodeResponse = ServerResponse | Http2ServerResponse;
29
+ export declare function isReadable(stream: any): stream is Readable;
30
+ export declare function isNodeRequest(request: any): request is NodeRequest;
31
+ export declare function isServerResponse(stream: any): stream is NodeResponse;
32
+ export declare function normalizeNodeRequest(nodeRequest: NodeRequest, RequestCtor: typeof Request): Request;
33
+ export declare function sendNodeResponse(fetchResponse: Response, serverResponse: NodeResponse): Promise<void> | undefined;
34
+ export {};
@@ -1,4 +1,10 @@
1
- import type { FetchAPI } from './types.js';
1
+ import { ServerAdapterPlugin } from '../plugins/types.cjs';
2
+ import type { FetchAPI } from '../types.cjs';
3
+ interface UWSServerContext {
4
+ req: UWSRequest;
5
+ res: UWSResponse;
6
+ }
7
+ export declare function useUWSAdapter(): ServerAdapterPlugin<UWSServerContext>;
2
8
  export interface UWSRequest {
3
9
  getMethod(): string;
4
10
  forEach(callback: (key: string, value: string) => void): void;
@@ -1,4 +1,10 @@
1
- import type { FetchAPI } from './types.cjs';
1
+ import { ServerAdapterPlugin } from '../plugins/types.js';
2
+ import type { FetchAPI } from '../types.js';
3
+ interface UWSServerContext {
4
+ req: UWSRequest;
5
+ res: UWSResponse;
6
+ }
7
+ export declare function useUWSAdapter(): ServerAdapterPlugin<UWSServerContext>;
2
8
  export interface UWSRequest {
3
9
  getMethod(): string;
4
10
  forEach(callback: (key: string, value: string) => void): void;
@@ -1,8 +1,21 @@
1
1
  import { FetchAPI, ServerAdapterRequestHandler } from '../types.cjs';
2
2
  export interface ServerAdapterPlugin<TServerContext = {}> {
3
+ onRequestAdapt?: OnRequestAdapt<TServerContext>;
3
4
  onRequest?: OnRequestHook<TServerContext>;
4
5
  onResponse?: OnResponseHook<TServerContext>;
5
6
  }
7
+ export type OnRequestAdapt<TServerContext> = (payload: OnRequestAdaptEventPayload<TServerContext>) => Promise<void> | void;
8
+ export interface RequestAdapterResult<TServerContext> {
9
+ serverContext: TServerContext;
10
+ request: Request;
11
+ }
12
+ export type RequestAdapter<TServerContext> = () => RequestAdapterResult<TServerContext>;
13
+ export interface OnRequestAdaptEventPayload<TServerContext> {
14
+ args: unknown[];
15
+ setRequest(request: Request): void;
16
+ setServerContext(serverContext: TServerContext): void;
17
+ fetchAPI: FetchAPI;
18
+ }
6
19
  export type OnRequestHook<TServerContext> = (payload: OnRequestEventPayload<TServerContext>) => Promise<void> | void;
7
20
  export interface OnRequestEventPayload<TServerContext> {
8
21
  request: Request;
@@ -1,8 +1,21 @@
1
1
  import { FetchAPI, ServerAdapterRequestHandler } from '../types.js';
2
2
  export interface ServerAdapterPlugin<TServerContext = {}> {
3
+ onRequestAdapt?: OnRequestAdapt<TServerContext>;
3
4
  onRequest?: OnRequestHook<TServerContext>;
4
5
  onResponse?: OnResponseHook<TServerContext>;
5
6
  }
7
+ export type OnRequestAdapt<TServerContext> = (payload: OnRequestAdaptEventPayload<TServerContext>) => Promise<void> | void;
8
+ export interface RequestAdapterResult<TServerContext> {
9
+ serverContext: TServerContext;
10
+ request: Request;
11
+ }
12
+ export type RequestAdapter<TServerContext> = () => RequestAdapterResult<TServerContext>;
13
+ export interface OnRequestAdaptEventPayload<TServerContext> {
14
+ args: unknown[];
15
+ setRequest(request: Request): void;
16
+ setServerContext(serverContext: TServerContext): void;
17
+ fetchAPI: FetchAPI;
18
+ }
6
19
  export type OnRequestHook<TServerContext> = (payload: OnRequestEventPayload<TServerContext>) => Promise<void> | void;
7
20
  export interface OnRequestEventPayload<TServerContext> {
8
21
  request: Request;