@whatwg-node/server 0.9.2-alpha-20230702150553-e1b62ad → 0.9.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/cjs/createServerAdapter.js +135 -66
- package/cjs/index.js +1 -3
- package/cjs/utils.js +195 -9
- package/cjs/{internal-plugins/useUWSAdapter.js → uwebsockets.js} +1 -34
- package/esm/createServerAdapter.js +136 -67
- package/esm/index.js +1 -3
- package/esm/utils.js +188 -7
- package/esm/{internal-plugins/useUWSAdapter.js → uwebsockets.js} +0 -32
- package/package.json +1 -1
- package/typings/index.d.cts +1 -3
- package/typings/index.d.ts +1 -3
- package/typings/plugins/types.d.cts +0 -13
- package/typings/plugins/types.d.ts +0 -13
- package/typings/types.d.cts +8 -3
- package/typings/types.d.ts +8 -3
- package/typings/utils.d.cts +29 -1
- package/typings/utils.d.ts +29 -1
- package/typings/{internal-plugins/useUWSAdapter.d.ts → uwebsockets.d.cts} +1 -7
- package/typings/{internal-plugins/useUWSAdapter.d.cts → uwebsockets.d.ts} +1 -7
- package/cjs/internal-plugins/useFetchEvent.js +0 -36
- package/cjs/internal-plugins/useNodeAdapter.js +0 -225
- package/esm/internal-plugins/useFetchEvent.js +0 -31
- package/esm/internal-plugins/useNodeAdapter.js +0 -216
- package/typings/internal-plugins/useFetchEvent.d.cts +0 -4
- package/typings/internal-plugins/useFetchEvent.d.ts +0 -4
- package/typings/internal-plugins/useNodeAdapter.d.cts +0 -34
- package/typings/internal-plugins/useNodeAdapter.d.ts +0 -34
|
@@ -4,10 +4,32 @@ exports.createServerAdapter = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
/* eslint-disable @typescript-eslint/ban-types */
|
|
6
6
|
const DefaultFetchAPI = tslib_1.__importStar(require("@whatwg-node/fetch"));
|
|
7
|
-
const useFetchEvent_js_1 = require("./internal-plugins/useFetchEvent.js");
|
|
8
|
-
const useNodeAdapter_js_1 = require("./internal-plugins/useNodeAdapter.js");
|
|
9
|
-
const useUWSAdapter_js_1 = require("./internal-plugins/useUWSAdapter.js");
|
|
10
7
|
const utils_js_1 = require("./utils.js");
|
|
8
|
+
const uwebsockets_js_1 = require("./uwebsockets.js");
|
|
9
|
+
async function handleWaitUntils(waitUntilPromises) {
|
|
10
|
+
const waitUntils = await Promise.allSettled(waitUntilPromises);
|
|
11
|
+
waitUntils.forEach(waitUntil => {
|
|
12
|
+
if (waitUntil.status === 'rejected') {
|
|
13
|
+
console.error(waitUntil.reason);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
// Required for envs like nextjs edge runtime
|
|
18
|
+
function isRequestAccessible(serverContext) {
|
|
19
|
+
try {
|
|
20
|
+
return !!serverContext?.request;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function addWaitUntil(serverContext, waitUntilPromises) {
|
|
27
|
+
serverContext['waitUntil'] = function (promise) {
|
|
28
|
+
if (promise != null) {
|
|
29
|
+
waitUntilPromises.push(promise);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
11
33
|
const EMPTY_OBJECT = {};
|
|
12
34
|
function createServerAdapter(serverAdapterBaseObject, options) {
|
|
13
35
|
const fetchAPI = {
|
|
@@ -17,20 +39,16 @@ function createServerAdapter(serverAdapterBaseObject, options) {
|
|
|
17
39
|
const givenHandleRequest = typeof serverAdapterBaseObject === 'function'
|
|
18
40
|
? serverAdapterBaseObject
|
|
19
41
|
: serverAdapterBaseObject.handle;
|
|
20
|
-
const onRequestAdaptHooks = [];
|
|
21
42
|
const onRequestHooks = [];
|
|
22
43
|
const onResponseHooks = [];
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
if (plugin.onResponse) {
|
|
33
|
-
onResponseHooks.push(plugin.onResponse);
|
|
44
|
+
if (options?.plugins != null) {
|
|
45
|
+
for (const plugin of options.plugins) {
|
|
46
|
+
if (plugin.onRequest) {
|
|
47
|
+
onRequestHooks.push(plugin.onRequest);
|
|
48
|
+
}
|
|
49
|
+
if (plugin.onResponse) {
|
|
50
|
+
onResponseHooks.push(plugin.onResponse);
|
|
51
|
+
}
|
|
34
52
|
}
|
|
35
53
|
}
|
|
36
54
|
async function handleRequest(request, serverContext) {
|
|
@@ -42,16 +60,6 @@ function createServerAdapter(serverAdapterBaseObject, options) {
|
|
|
42
60
|
});
|
|
43
61
|
let requestHandler = givenHandleRequest;
|
|
44
62
|
let response;
|
|
45
|
-
let waitUntilPromises;
|
|
46
|
-
if (serverContext['waitUntil'] == null) {
|
|
47
|
-
waitUntilPromises = new Set();
|
|
48
|
-
serverContext['waitUntil'] = (promise) => {
|
|
49
|
-
waitUntilPromises.add(promise);
|
|
50
|
-
promise.then(() => {
|
|
51
|
-
waitUntilPromises.delete(promise);
|
|
52
|
-
});
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
63
|
for (const onRequestHook of onRequestHooks) {
|
|
56
64
|
await onRequestHook({
|
|
57
65
|
request,
|
|
@@ -73,12 +81,6 @@ function createServerAdapter(serverAdapterBaseObject, options) {
|
|
|
73
81
|
if (!response) {
|
|
74
82
|
response = await requestHandler(request, serverContext);
|
|
75
83
|
}
|
|
76
|
-
if (!response) {
|
|
77
|
-
response = new fetchAPI.Response(undefined, {
|
|
78
|
-
status: 404,
|
|
79
|
-
statusText: 'Not Found',
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
84
|
for (const onResponseHook of onResponseHooks) {
|
|
83
85
|
await onResponseHook({
|
|
84
86
|
request,
|
|
@@ -86,58 +88,125 @@ function createServerAdapter(serverAdapterBaseObject, options) {
|
|
|
86
88
|
serverContext,
|
|
87
89
|
});
|
|
88
90
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
91
|
+
return response;
|
|
92
|
+
}
|
|
93
|
+
function handleNodeRequest(nodeRequest, ...ctx) {
|
|
94
|
+
const serverContext = ctx.length > 1 ? (0, utils_js_1.completeAssign)(...ctx) : ctx[0] || {};
|
|
95
|
+
const request = (0, utils_js_1.normalizeNodeRequest)(nodeRequest, fetchAPI.Request);
|
|
96
|
+
return handleRequest(request, serverContext);
|
|
97
|
+
}
|
|
98
|
+
async function requestListener(nodeRequest, serverResponse, ...ctx) {
|
|
99
|
+
const waitUntilPromises = [];
|
|
100
|
+
const defaultServerContext = {
|
|
101
|
+
req: nodeRequest,
|
|
102
|
+
res: serverResponse,
|
|
103
|
+
};
|
|
104
|
+
addWaitUntil(defaultServerContext, waitUntilPromises);
|
|
105
|
+
const response = await handleNodeRequest(nodeRequest, defaultServerContext, ...ctx);
|
|
106
|
+
if (response) {
|
|
107
|
+
await (0, utils_js_1.sendNodeResponse)(response, serverResponse, nodeRequest);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
await new Promise(resolve => {
|
|
111
|
+
serverResponse.statusCode = 404;
|
|
112
|
+
serverResponse.once('end', resolve);
|
|
113
|
+
serverResponse.end();
|
|
95
114
|
});
|
|
96
115
|
}
|
|
97
|
-
|
|
116
|
+
if (waitUntilPromises.length > 0) {
|
|
117
|
+
await handleWaitUntils(waitUntilPromises);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async function handleUWS(res, req, ...ctx) {
|
|
121
|
+
const waitUntilPromises = [];
|
|
122
|
+
const defaultServerContext = {
|
|
123
|
+
res,
|
|
124
|
+
req,
|
|
125
|
+
};
|
|
126
|
+
addWaitUntil(defaultServerContext, waitUntilPromises);
|
|
127
|
+
const serverContext = ctx.length > 0 ? (0, utils_js_1.completeAssign)(defaultServerContext, ...ctx) : defaultServerContext;
|
|
128
|
+
const request = (0, uwebsockets_js_1.getRequestFromUWSRequest)({
|
|
129
|
+
req,
|
|
130
|
+
res,
|
|
131
|
+
fetchAPI,
|
|
132
|
+
});
|
|
133
|
+
const response = await handleRequest(request, serverContext);
|
|
134
|
+
if (!response) {
|
|
135
|
+
res.writeStatus('404 Not Found');
|
|
136
|
+
res.end();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
return (0, uwebsockets_js_1.sendResponseToUwsOpts)({
|
|
140
|
+
response,
|
|
141
|
+
res,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
function handleEvent(event, ...ctx) {
|
|
145
|
+
if (!event.respondWith || !event.request) {
|
|
146
|
+
throw new TypeError(`Expected FetchEvent, got ${event}`);
|
|
147
|
+
}
|
|
148
|
+
const serverContext = ctx.length > 0 ? Object.assign({}, event, ...ctx) : event;
|
|
149
|
+
const response$ = handleRequest(event.request, serverContext);
|
|
150
|
+
event.respondWith(response$);
|
|
151
|
+
}
|
|
152
|
+
function handleRequestWithWaitUntil(request, ...ctx) {
|
|
153
|
+
const serverContext = (ctx.length > 1 ? (0, utils_js_1.completeAssign)(...ctx) : ctx[0]) || {};
|
|
154
|
+
if (serverContext.waitUntil == null) {
|
|
155
|
+
const waitUntilPromises = [];
|
|
156
|
+
addWaitUntil(serverContext, waitUntilPromises);
|
|
157
|
+
const response$ = handleRequest(request, serverContext);
|
|
158
|
+
if (waitUntilPromises.length > 0) {
|
|
159
|
+
return handleWaitUntils(waitUntilPromises).then(() => response$);
|
|
160
|
+
}
|
|
161
|
+
return response$;
|
|
162
|
+
}
|
|
163
|
+
return handleRequest(request, serverContext);
|
|
98
164
|
}
|
|
99
165
|
const fetchFn = (input, ...maybeCtx) => {
|
|
100
166
|
if (typeof input === 'string' || 'href' in input) {
|
|
101
167
|
const [initOrCtx, ...restOfCtx] = maybeCtx;
|
|
102
168
|
if ((0, utils_js_1.isRequestInit)(initOrCtx)) {
|
|
103
|
-
|
|
104
|
-
return handleRequest(new fetchAPI.Request(input, initOrCtx), serverContext);
|
|
169
|
+
return handleRequestWithWaitUntil(new fetchAPI.Request(input, initOrCtx), ...restOfCtx);
|
|
105
170
|
}
|
|
106
|
-
|
|
107
|
-
return handleRequest(new fetchAPI.Request(input), serverContext);
|
|
171
|
+
return handleRequestWithWaitUntil(new fetchAPI.Request(input), ...maybeCtx);
|
|
108
172
|
}
|
|
109
|
-
|
|
110
|
-
return handleRequest(input, serverContext);
|
|
173
|
+
return handleRequestWithWaitUntil(input, ...maybeCtx);
|
|
111
174
|
};
|
|
112
|
-
const genericRequestHandler = (...
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
175
|
+
const genericRequestHandler = (input, ...maybeCtx) => {
|
|
176
|
+
// If it is a Node request
|
|
177
|
+
const [initOrCtxOrRes, ...restOfCtx] = maybeCtx;
|
|
178
|
+
if ((0, utils_js_1.isNodeRequest)(input)) {
|
|
179
|
+
if (!(0, utils_js_1.isServerResponse)(initOrCtxOrRes)) {
|
|
180
|
+
throw new TypeError(`Expected ServerResponse, got ${initOrCtxOrRes}`);
|
|
181
|
+
}
|
|
182
|
+
return requestListener(input, initOrCtxOrRes, ...restOfCtx);
|
|
183
|
+
}
|
|
184
|
+
if ((0, uwebsockets_js_1.isUWSResponse)(input)) {
|
|
185
|
+
return handleUWS(input, initOrCtxOrRes, ...restOfCtx);
|
|
186
|
+
}
|
|
187
|
+
if ((0, utils_js_1.isServerResponse)(initOrCtxOrRes)) {
|
|
188
|
+
throw new TypeError('Got Node response without Node request');
|
|
126
189
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
190
|
+
// Is input a container object over Request?
|
|
191
|
+
if (isRequestAccessible(input)) {
|
|
192
|
+
// Is it FetchEvent?
|
|
193
|
+
if ((0, utils_js_1.isFetchEvent)(input)) {
|
|
194
|
+
return handleEvent(input, ...maybeCtx);
|
|
130
195
|
}
|
|
131
|
-
|
|
196
|
+
// In this input is also the context
|
|
197
|
+
return handleRequestWithWaitUntil(input.request, input, ...maybeCtx);
|
|
132
198
|
}
|
|
133
|
-
|
|
199
|
+
// Or is it Request itself?
|
|
200
|
+
// Then ctx is present and it is the context
|
|
201
|
+
return fetchFn(input, ...maybeCtx);
|
|
134
202
|
};
|
|
135
203
|
const adapterObj = {
|
|
136
204
|
handleRequest,
|
|
137
205
|
fetch: fetchFn,
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
handleEvent
|
|
206
|
+
handleNodeRequest,
|
|
207
|
+
requestListener,
|
|
208
|
+
handleEvent,
|
|
209
|
+
handleUWS,
|
|
141
210
|
handle: genericRequestHandler,
|
|
142
211
|
};
|
|
143
212
|
const serverAdapter = new Proxy(genericRequestHandler, {
|
package/cjs/index.js
CHANGED
|
@@ -8,8 +8,6 @@ tslib_1.__exportStar(require("./utils.js"), exports);
|
|
|
8
8
|
tslib_1.__exportStar(require("./plugins/types.js"), exports);
|
|
9
9
|
tslib_1.__exportStar(require("./plugins/useCors.js"), exports);
|
|
10
10
|
tslib_1.__exportStar(require("./plugins/useErrorHandling.js"), exports);
|
|
11
|
-
tslib_1.__exportStar(require("./
|
|
12
|
-
tslib_1.__exportStar(require("./internal-plugins/useNodeAdapter.js"), exports);
|
|
13
|
-
tslib_1.__exportStar(require("./internal-plugins/useUWSAdapter.js"), exports);
|
|
11
|
+
tslib_1.__exportStar(require("./uwebsockets.js"), exports);
|
|
14
12
|
var fetch_1 = require("@whatwg-node/fetch");
|
|
15
13
|
Object.defineProperty(exports, "Response", { enumerable: true, get: function () { return fetch_1.Response; } });
|
package/cjs/utils.js
CHANGED
|
@@ -1,14 +1,208 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.completeAssign = exports.isRequestInit = exports.sendNodeResponse = exports.isFetchEvent = exports.isReadableStream = exports.isServerResponse = exports.isNodeRequest = exports.isReadable = exports.normalizeNodeRequest = exports.isAsyncIterable = void 0;
|
|
4
|
+
const fetch_1 = require("@whatwg-node/fetch");
|
|
4
5
|
function isAsyncIterable(body) {
|
|
5
6
|
return (body != null && typeof body === 'object' && typeof body[Symbol.asyncIterator] === 'function');
|
|
6
7
|
}
|
|
7
8
|
exports.isAsyncIterable = isAsyncIterable;
|
|
9
|
+
function getPort(nodeRequest) {
|
|
10
|
+
if (nodeRequest.socket?.localPort) {
|
|
11
|
+
return nodeRequest.socket?.localPort;
|
|
12
|
+
}
|
|
13
|
+
const hostInHeader = nodeRequest.headers?.[':authority'] || nodeRequest.headers?.host;
|
|
14
|
+
const portInHeader = hostInHeader?.split(':')?.[1];
|
|
15
|
+
if (portInHeader) {
|
|
16
|
+
return portInHeader;
|
|
17
|
+
}
|
|
18
|
+
return 80;
|
|
19
|
+
}
|
|
20
|
+
function getHostnameWithPort(nodeRequest) {
|
|
21
|
+
if (nodeRequest.headers?.[':authority']) {
|
|
22
|
+
return nodeRequest.headers?.[':authority'];
|
|
23
|
+
}
|
|
24
|
+
if (nodeRequest.headers?.host) {
|
|
25
|
+
return nodeRequest.headers?.host;
|
|
26
|
+
}
|
|
27
|
+
const port = getPort(nodeRequest);
|
|
28
|
+
if (nodeRequest.hostname) {
|
|
29
|
+
return nodeRequest.hostname + ':' + port;
|
|
30
|
+
}
|
|
31
|
+
const localIp = nodeRequest.socket?.localAddress;
|
|
32
|
+
if (localIp && !localIp?.includes('::') && !localIp?.includes('ffff')) {
|
|
33
|
+
return `${localIp}:${port}`;
|
|
34
|
+
}
|
|
35
|
+
return 'localhost';
|
|
36
|
+
}
|
|
37
|
+
function buildFullUrl(nodeRequest) {
|
|
38
|
+
const hostnameWithPort = getHostnameWithPort(nodeRequest);
|
|
39
|
+
const protocol = nodeRequest.protocol || 'http';
|
|
40
|
+
const endpoint = nodeRequest.originalUrl || nodeRequest.url || '/graphql';
|
|
41
|
+
return `${protocol}://${hostnameWithPort}${endpoint}`;
|
|
42
|
+
}
|
|
43
|
+
function isRequestBody(body) {
|
|
44
|
+
const stringTag = body[Symbol.toStringTag];
|
|
45
|
+
if (typeof body === 'string' ||
|
|
46
|
+
stringTag === 'Uint8Array' ||
|
|
47
|
+
stringTag === 'Blob' ||
|
|
48
|
+
stringTag === 'FormData' ||
|
|
49
|
+
stringTag === 'URLSearchParams' ||
|
|
50
|
+
isAsyncIterable(body)) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
function normalizeNodeRequest(nodeRequest, RequestCtor) {
|
|
56
|
+
const rawRequest = nodeRequest.raw || nodeRequest.req || nodeRequest;
|
|
57
|
+
let fullUrl = buildFullUrl(rawRequest);
|
|
58
|
+
if (nodeRequest.query) {
|
|
59
|
+
const url = new fetch_1.URL(fullUrl);
|
|
60
|
+
for (const key in nodeRequest.query) {
|
|
61
|
+
url.searchParams.set(key, nodeRequest.query[key]);
|
|
62
|
+
}
|
|
63
|
+
fullUrl = url.toString();
|
|
64
|
+
}
|
|
65
|
+
if (nodeRequest.method === 'GET' || nodeRequest.method === 'HEAD') {
|
|
66
|
+
return new RequestCtor(fullUrl, {
|
|
67
|
+
method: nodeRequest.method,
|
|
68
|
+
headers: nodeRequest.headers,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Some Node server frameworks like Serverless Express sends a dummy object with body but as a Buffer not string
|
|
73
|
+
* so we do those checks to see is there something we can use directly as BodyInit
|
|
74
|
+
* because the presence of body means the request stream is already consumed and,
|
|
75
|
+
* rawRequest cannot be used as BodyInit/ReadableStream by Fetch API in this case.
|
|
76
|
+
*/
|
|
77
|
+
const maybeParsedBody = nodeRequest.body;
|
|
78
|
+
if (maybeParsedBody != null && Object.keys(maybeParsedBody).length > 0) {
|
|
79
|
+
if (isRequestBody(maybeParsedBody)) {
|
|
80
|
+
return new RequestCtor(fullUrl, {
|
|
81
|
+
method: nodeRequest.method,
|
|
82
|
+
headers: nodeRequest.headers,
|
|
83
|
+
body: maybeParsedBody,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
const request = new RequestCtor(fullUrl, {
|
|
87
|
+
method: nodeRequest.method,
|
|
88
|
+
headers: nodeRequest.headers,
|
|
89
|
+
});
|
|
90
|
+
if (!request.headers.get('content-type')?.includes('json')) {
|
|
91
|
+
request.headers.set('content-type', 'application/json; charset=utf-8');
|
|
92
|
+
}
|
|
93
|
+
return new Proxy(request, {
|
|
94
|
+
get: (target, prop, receiver) => {
|
|
95
|
+
switch (prop) {
|
|
96
|
+
case 'json':
|
|
97
|
+
return async () => maybeParsedBody;
|
|
98
|
+
case 'text':
|
|
99
|
+
return async () => JSON.stringify(maybeParsedBody);
|
|
100
|
+
default:
|
|
101
|
+
return Reflect.get(target, prop, receiver);
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// perf: instead of spreading the object, we can just pass it as is and it performs better
|
|
107
|
+
return new RequestCtor(fullUrl, {
|
|
108
|
+
method: nodeRequest.method,
|
|
109
|
+
headers: nodeRequest.headers,
|
|
110
|
+
body: rawRequest,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
exports.normalizeNodeRequest = normalizeNodeRequest;
|
|
114
|
+
function isReadable(stream) {
|
|
115
|
+
return stream.read != null;
|
|
116
|
+
}
|
|
117
|
+
exports.isReadable = isReadable;
|
|
118
|
+
function isNodeRequest(request) {
|
|
119
|
+
return isReadable(request);
|
|
120
|
+
}
|
|
121
|
+
exports.isNodeRequest = isNodeRequest;
|
|
122
|
+
function isServerResponse(stream) {
|
|
123
|
+
// Check all used functions are defined
|
|
124
|
+
return (stream != null &&
|
|
125
|
+
stream.setHeader != null &&
|
|
126
|
+
stream.end != null &&
|
|
127
|
+
stream.once != null &&
|
|
128
|
+
stream.write != null);
|
|
129
|
+
}
|
|
130
|
+
exports.isServerResponse = isServerResponse;
|
|
8
131
|
function isReadableStream(stream) {
|
|
9
132
|
return stream != null && stream.getReader != null;
|
|
10
133
|
}
|
|
11
134
|
exports.isReadableStream = isReadableStream;
|
|
135
|
+
function isFetchEvent(event) {
|
|
136
|
+
return event != null && event.request != null && event.respondWith != null;
|
|
137
|
+
}
|
|
138
|
+
exports.isFetchEvent = isFetchEvent;
|
|
139
|
+
function configureSocket(rawRequest) {
|
|
140
|
+
rawRequest?.socket?.setTimeout?.(0);
|
|
141
|
+
rawRequest?.socket?.setNoDelay?.(true);
|
|
142
|
+
rawRequest?.socket?.setKeepAlive?.(true);
|
|
143
|
+
}
|
|
144
|
+
function endResponse(serverResponse) {
|
|
145
|
+
// @ts-expect-error Avoid arguments adaptor trampoline https://v8.dev/blog/adaptor-frame
|
|
146
|
+
serverResponse.end(null, null, null);
|
|
147
|
+
}
|
|
148
|
+
async function sendAsyncIterable(serverResponse, asyncIterable) {
|
|
149
|
+
for await (const chunk of asyncIterable) {
|
|
150
|
+
if (!serverResponse
|
|
151
|
+
// @ts-expect-error http and http2 writes are actually compatible
|
|
152
|
+
.write(chunk)) {
|
|
153
|
+
break;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
endResponse(serverResponse);
|
|
157
|
+
}
|
|
158
|
+
function sendNodeResponse(fetchResponse, serverResponse, nodeRequest) {
|
|
159
|
+
serverResponse.statusCode = fetchResponse.status;
|
|
160
|
+
serverResponse.statusMessage = fetchResponse.statusText;
|
|
161
|
+
fetchResponse.headers.forEach((value, key) => {
|
|
162
|
+
if (key === 'set-cookie') {
|
|
163
|
+
const setCookies = fetchResponse.headers.getSetCookie?.();
|
|
164
|
+
if (setCookies) {
|
|
165
|
+
serverResponse.setHeader('set-cookie', setCookies);
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
serverResponse.setHeader(key, value);
|
|
170
|
+
});
|
|
171
|
+
// Optimizations for node-fetch
|
|
172
|
+
if (fetchResponse.bodyType === 'Buffer' ||
|
|
173
|
+
fetchResponse.bodyType === 'String' ||
|
|
174
|
+
fetchResponse.bodyType === 'Uint8Array') {
|
|
175
|
+
// @ts-expect-error http and http2 writes are actually compatible
|
|
176
|
+
serverResponse.write(fetchResponse.bodyInit);
|
|
177
|
+
endResponse(serverResponse);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
// Other fetch implementations
|
|
181
|
+
const fetchBody = fetchResponse.body;
|
|
182
|
+
if (fetchBody == null) {
|
|
183
|
+
endResponse(serverResponse);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (fetchBody[Symbol.toStringTag] === 'Uint8Array') {
|
|
187
|
+
serverResponse
|
|
188
|
+
// @ts-expect-error http and http2 writes are actually compatible
|
|
189
|
+
.write(fetchBody);
|
|
190
|
+
endResponse(serverResponse);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
configureSocket(nodeRequest);
|
|
194
|
+
if (isReadable(fetchBody)) {
|
|
195
|
+
serverResponse.once('close', () => {
|
|
196
|
+
fetchBody.destroy();
|
|
197
|
+
});
|
|
198
|
+
fetchBody.pipe(serverResponse);
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
if (isAsyncIterable(fetchBody)) {
|
|
202
|
+
return sendAsyncIterable(serverResponse, fetchBody);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
exports.sendNodeResponse = sendNodeResponse;
|
|
12
206
|
function isRequestInit(val) {
|
|
13
207
|
return (val != null &&
|
|
14
208
|
typeof val === 'object' &&
|
|
@@ -49,11 +243,3 @@ function completeAssign(...args) {
|
|
|
49
243
|
return target;
|
|
50
244
|
}
|
|
51
245
|
exports.completeAssign = completeAssign;
|
|
52
|
-
function addWaitUntil(serverContext, waitUntilPromises) {
|
|
53
|
-
serverContext['waitUntil'] = function (promise) {
|
|
54
|
-
if (promise != null) {
|
|
55
|
-
waitUntilPromises.push(promise);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
exports.addWaitUntil = addWaitUntil;
|
|
@@ -1,39 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sendResponseToUwsOpts = exports.getRequestFromUWSRequest = exports.isUWSResponse =
|
|
4
|
-
const utils_js_1 = require("../utils.js");
|
|
5
|
-
function useUWSAdapter() {
|
|
6
|
-
const uwsResponseMap = new WeakMap();
|
|
7
|
-
return {
|
|
8
|
-
onRequestAdapt({ args: [res, req, ...restOfCtx], setRequest, setServerContext, fetchAPI }) {
|
|
9
|
-
if (isUWSResponse(res)) {
|
|
10
|
-
const request = getRequestFromUWSRequest({
|
|
11
|
-
req: req,
|
|
12
|
-
res,
|
|
13
|
-
fetchAPI,
|
|
14
|
-
});
|
|
15
|
-
uwsResponseMap.set(request, res);
|
|
16
|
-
setRequest(request);
|
|
17
|
-
const defaultServerContext = {
|
|
18
|
-
req,
|
|
19
|
-
res,
|
|
20
|
-
};
|
|
21
|
-
const serverContext = restOfCtx.length > 0 ? (0, utils_js_1.completeAssign)(...restOfCtx) : defaultServerContext;
|
|
22
|
-
setServerContext(serverContext);
|
|
23
|
-
}
|
|
24
|
-
},
|
|
25
|
-
onResponse({ request, response }) {
|
|
26
|
-
const res = uwsResponseMap.get(request);
|
|
27
|
-
if (res) {
|
|
28
|
-
return sendResponseToUwsOpts({
|
|
29
|
-
res,
|
|
30
|
-
response,
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
exports.useUWSAdapter = useUWSAdapter;
|
|
3
|
+
exports.sendResponseToUwsOpts = exports.getRequestFromUWSRequest = exports.isUWSResponse = void 0;
|
|
37
4
|
function isUWSResponse(res) {
|
|
38
5
|
return !!res.onData;
|
|
39
6
|
}
|