@whatwg-node/server 0.8.0 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/createServerAdapter.js +88 -5
- package/cjs/plugins/useCors.js +2 -3
- package/cjs/utils.js +14 -18
- package/cjs/uwebsockets.js +7 -0
- package/esm/createServerAdapter.js +88 -5
- package/esm/plugins/useCors.js +2 -3
- package/esm/utils.js +14 -18
- package/esm/uwebsockets.js +3 -0
- package/package.json +1 -1
- package/typings/types.d.cts +3 -0
- package/typings/types.d.ts +3 -0
- package/typings/uwebsockets.d.cts +16 -0
- package/typings/uwebsockets.d.ts +16 -0
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createServerAdapter = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
6
5
|
const DefaultFetchAPI = tslib_1.__importStar(require("@whatwg-node/fetch"));
|
|
7
6
|
const utils_js_1 = require("./utils.js");
|
|
7
|
+
const uwebsockets_js_1 = require("./uwebsockets.js");
|
|
8
8
|
async function handleWaitUntils(waitUntilPromises) {
|
|
9
9
|
const waitUntils = await Promise.allSettled(waitUntilPromises);
|
|
10
10
|
waitUntils.forEach(waitUntil => {
|
|
@@ -16,23 +16,23 @@ async function handleWaitUntils(waitUntilPromises) {
|
|
|
16
16
|
// Required for envs like nextjs edge runtime
|
|
17
17
|
function isRequestAccessible(serverContext) {
|
|
18
18
|
try {
|
|
19
|
-
return !!
|
|
19
|
+
return !!serverContext?.request;
|
|
20
20
|
}
|
|
21
|
-
catch
|
|
21
|
+
catch {
|
|
22
22
|
return false;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
function createServerAdapter(serverAdapterBaseObject, options) {
|
|
26
26
|
const fetchAPI = {
|
|
27
27
|
...DefaultFetchAPI,
|
|
28
|
-
...options
|
|
28
|
+
...options?.fetchAPI,
|
|
29
29
|
};
|
|
30
30
|
const givenHandleRequest = typeof serverAdapterBaseObject === 'function'
|
|
31
31
|
? serverAdapterBaseObject
|
|
32
32
|
: serverAdapterBaseObject.handle;
|
|
33
33
|
const onRequestHooks = [];
|
|
34
34
|
const onResponseHooks = [];
|
|
35
|
-
if (
|
|
35
|
+
if (options?.plugins != null) {
|
|
36
36
|
for (const plugin of options.plugins) {
|
|
37
37
|
if (plugin.onRequest) {
|
|
38
38
|
onRequestHooks.push(plugin.onRequest);
|
|
@@ -112,6 +112,85 @@ function createServerAdapter(serverAdapterBaseObject, options) {
|
|
|
112
112
|
await handleWaitUntils(waitUntilPromises);
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
+
async function handleUWS(res, req, ...ctx) {
|
|
116
|
+
const waitUntilPromises = [];
|
|
117
|
+
const serverContext = completeAssign({
|
|
118
|
+
res,
|
|
119
|
+
req,
|
|
120
|
+
waitUntil(promise) {
|
|
121
|
+
if (promise != null) {
|
|
122
|
+
waitUntilPromises.push(promise);
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
}, ...ctx);
|
|
126
|
+
let body;
|
|
127
|
+
const method = req.getMethod();
|
|
128
|
+
let resAborted = false;
|
|
129
|
+
res.onAborted(function () {
|
|
130
|
+
resAborted = true;
|
|
131
|
+
body?.readable.push(null);
|
|
132
|
+
});
|
|
133
|
+
if (method !== 'get' && method !== 'head') {
|
|
134
|
+
body = new fetchAPI.ReadableStream({});
|
|
135
|
+
res.onData(function (chunk, isLast) {
|
|
136
|
+
body?.readable.push(Buffer.from(chunk, 0, chunk.byteLength));
|
|
137
|
+
if (isLast) {
|
|
138
|
+
body?.readable.push(null);
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
const headers = {};
|
|
143
|
+
req.forEach((key, value) => {
|
|
144
|
+
headers[key] = value;
|
|
145
|
+
});
|
|
146
|
+
const url = `http://localhost${req.getUrl()}`;
|
|
147
|
+
const request = new fetchAPI.Request(url, {
|
|
148
|
+
method,
|
|
149
|
+
headers,
|
|
150
|
+
body,
|
|
151
|
+
});
|
|
152
|
+
const response = await handleRequest(request, serverContext);
|
|
153
|
+
if (resAborted) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (!response) {
|
|
157
|
+
res.writeStatus('404 Not Found');
|
|
158
|
+
res.end();
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
res.cork(() => {
|
|
162
|
+
res.writeStatus(`${response.status} ${response.statusText}`);
|
|
163
|
+
});
|
|
164
|
+
response.headers.forEach((value, key) => {
|
|
165
|
+
// content-length causes an error with Node.js's fetch
|
|
166
|
+
if (key.toLowerCase() !== 'content-length') {
|
|
167
|
+
res.cork(() => {
|
|
168
|
+
res.writeHeader(key, value);
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
if (!response.body) {
|
|
173
|
+
res.end();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (response.bodyType === 'String' || response.bodyType === 'Uint8Array') {
|
|
177
|
+
res.cork(() => {
|
|
178
|
+
res.end(response.bodyInit);
|
|
179
|
+
});
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
for await (const chunk of response.body.readable) {
|
|
183
|
+
if (resAborted) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
res.cork(() => {
|
|
187
|
+
res.write(chunk);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
res.cork(() => {
|
|
191
|
+
res.end();
|
|
192
|
+
});
|
|
193
|
+
}
|
|
115
194
|
function handleEvent(event, ...ctx) {
|
|
116
195
|
if (!event.respondWith || !event.request) {
|
|
117
196
|
throw new TypeError(`Expected FetchEvent, got ${event}`);
|
|
@@ -152,6 +231,9 @@ function createServerAdapter(serverAdapterBaseObject, options) {
|
|
|
152
231
|
const genericRequestHandler = (input, ...maybeCtx) => {
|
|
153
232
|
// If it is a Node request
|
|
154
233
|
const [initOrCtxOrRes, ...restOfCtx] = maybeCtx;
|
|
234
|
+
if ((0, uwebsockets_js_1.isUWSResponse)(input)) {
|
|
235
|
+
return handleUWS(input, initOrCtxOrRes, ...restOfCtx);
|
|
236
|
+
}
|
|
155
237
|
if ((0, utils_js_1.isNodeRequest)(input)) {
|
|
156
238
|
if (!(0, utils_js_1.isServerResponse)(initOrCtxOrRes)) {
|
|
157
239
|
throw new TypeError(`Expected ServerResponse, got ${initOrCtxOrRes}`);
|
|
@@ -180,6 +262,7 @@ function createServerAdapter(serverAdapterBaseObject, options) {
|
|
|
180
262
|
handleNodeRequest,
|
|
181
263
|
requestListener,
|
|
182
264
|
handleEvent,
|
|
265
|
+
handleUWS,
|
|
183
266
|
handle: genericRequestHandler,
|
|
184
267
|
};
|
|
185
268
|
const serverAdapter = new Proxy(genericRequestHandler, {
|
package/cjs/plugins/useCors.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.useCORS = exports.getCORSHeadersByRequestAndOptions = void 0;
|
|
4
4
|
function getCORSHeadersByRequestAndOptions(request, corsOptions) {
|
|
5
|
-
var _a, _b;
|
|
6
5
|
const currentOrigin = request.headers.get('origin');
|
|
7
6
|
if (corsOptions === false || currentOrigin == null) {
|
|
8
7
|
return null;
|
|
@@ -36,7 +35,7 @@ function getCORSHeadersByRequestAndOptions(request, corsOptions) {
|
|
|
36
35
|
headers['Access-Control-Allow-Origin'] = 'null';
|
|
37
36
|
}
|
|
38
37
|
}
|
|
39
|
-
if (
|
|
38
|
+
if (corsOptions.methods?.length) {
|
|
40
39
|
headers['Access-Control-Allow-Methods'] = corsOptions.methods.join(', ');
|
|
41
40
|
}
|
|
42
41
|
else {
|
|
@@ -45,7 +44,7 @@ function getCORSHeadersByRequestAndOptions(request, corsOptions) {
|
|
|
45
44
|
headers['Access-Control-Allow-Methods'] = requestMethod;
|
|
46
45
|
}
|
|
47
46
|
}
|
|
48
|
-
if (
|
|
47
|
+
if (corsOptions.allowedHeaders?.length) {
|
|
49
48
|
headers['Access-Control-Allow-Headers'] = corsOptions.allowedHeaders.join(', ');
|
|
50
49
|
}
|
|
51
50
|
else {
|
package/cjs/utils.js
CHANGED
|
@@ -7,31 +7,29 @@ function isAsyncIterable(body) {
|
|
|
7
7
|
}
|
|
8
8
|
exports.isAsyncIterable = isAsyncIterable;
|
|
9
9
|
function getPort(nodeRequest) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
return (_b = nodeRequest.socket) === null || _b === void 0 ? void 0 : _b.localPort;
|
|
10
|
+
if (nodeRequest.socket?.localPort) {
|
|
11
|
+
return nodeRequest.socket?.localPort;
|
|
13
12
|
}
|
|
14
|
-
const hostInHeader =
|
|
15
|
-
const portInHeader =
|
|
13
|
+
const hostInHeader = nodeRequest.headers?.[':authority'] || nodeRequest.headers?.host;
|
|
14
|
+
const portInHeader = hostInHeader?.split(':')?.[1];
|
|
16
15
|
if (portInHeader) {
|
|
17
16
|
return portInHeader;
|
|
18
17
|
}
|
|
19
18
|
return 80;
|
|
20
19
|
}
|
|
21
20
|
function getHostnameWithPort(nodeRequest) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
return (_b = nodeRequest.headers) === null || _b === void 0 ? void 0 : _b[':authority'];
|
|
21
|
+
if (nodeRequest.headers?.[':authority']) {
|
|
22
|
+
return nodeRequest.headers?.[':authority'];
|
|
25
23
|
}
|
|
26
|
-
if (
|
|
27
|
-
return
|
|
24
|
+
if (nodeRequest.headers?.host) {
|
|
25
|
+
return nodeRequest.headers?.host;
|
|
28
26
|
}
|
|
29
27
|
const port = getPort(nodeRequest);
|
|
30
28
|
if (nodeRequest.hostname) {
|
|
31
29
|
return nodeRequest.hostname + ':' + port;
|
|
32
30
|
}
|
|
33
|
-
const localIp =
|
|
34
|
-
if (localIp && !
|
|
31
|
+
const localIp = nodeRequest.socket?.localAddress;
|
|
32
|
+
if (localIp && !localIp?.includes('::') && !localIp?.includes('ffff')) {
|
|
35
33
|
return `${localIp}:${port}`;
|
|
36
34
|
}
|
|
37
35
|
return 'localhost';
|
|
@@ -55,7 +53,6 @@ function isRequestBody(body) {
|
|
|
55
53
|
return false;
|
|
56
54
|
}
|
|
57
55
|
function normalizeNodeRequest(nodeRequest, RequestCtor) {
|
|
58
|
-
var _a;
|
|
59
56
|
const rawRequest = nodeRequest.raw || nodeRequest.req || nodeRequest;
|
|
60
57
|
let fullUrl = buildFullUrl(rawRequest);
|
|
61
58
|
if (nodeRequest.query) {
|
|
@@ -90,7 +87,7 @@ function normalizeNodeRequest(nodeRequest, RequestCtor) {
|
|
|
90
87
|
method: nodeRequest.method,
|
|
91
88
|
headers: nodeRequest.headers,
|
|
92
89
|
});
|
|
93
|
-
if (!
|
|
90
|
+
if (!request.headers.get('content-type')?.includes('json')) {
|
|
94
91
|
request.headers.set('content-type', 'application/json');
|
|
95
92
|
}
|
|
96
93
|
return new Proxy(request, {
|
|
@@ -140,10 +137,9 @@ function isFetchEvent(event) {
|
|
|
140
137
|
}
|
|
141
138
|
exports.isFetchEvent = isFetchEvent;
|
|
142
139
|
function configureSocket(rawRequest) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
(_f = (_e = rawRequest === null || rawRequest === void 0 ? void 0 : rawRequest.socket) === null || _e === void 0 ? void 0 : _e.setKeepAlive) === null || _f === void 0 ? void 0 : _f.call(_e, true);
|
|
140
|
+
rawRequest?.socket?.setTimeout?.(0);
|
|
141
|
+
rawRequest?.socket?.setNoDelay?.(true);
|
|
142
|
+
rawRequest?.socket?.setKeepAlive?.(true);
|
|
147
143
|
}
|
|
148
144
|
function endResponse(serverResponse) {
|
|
149
145
|
// @ts-expect-error Avoid arguments adaptor trampoline https://v8.dev/blog/adaptor-frame
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/ban-types */
|
|
2
1
|
import * as DefaultFetchAPI from '@whatwg-node/fetch';
|
|
3
2
|
import { isFetchEvent, isNodeRequest, isRequestInit, isServerResponse, normalizeNodeRequest, sendNodeResponse, } from './utils.js';
|
|
3
|
+
import { isUWSResponse } from './uwebsockets.js';
|
|
4
4
|
async function handleWaitUntils(waitUntilPromises) {
|
|
5
5
|
const waitUntils = await Promise.allSettled(waitUntilPromises);
|
|
6
6
|
waitUntils.forEach(waitUntil => {
|
|
@@ -12,23 +12,23 @@ async function handleWaitUntils(waitUntilPromises) {
|
|
|
12
12
|
// Required for envs like nextjs edge runtime
|
|
13
13
|
function isRequestAccessible(serverContext) {
|
|
14
14
|
try {
|
|
15
|
-
return !!
|
|
15
|
+
return !!serverContext?.request;
|
|
16
16
|
}
|
|
17
|
-
catch
|
|
17
|
+
catch {
|
|
18
18
|
return false;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
21
|
function createServerAdapter(serverAdapterBaseObject, options) {
|
|
22
22
|
const fetchAPI = {
|
|
23
23
|
...DefaultFetchAPI,
|
|
24
|
-
...options
|
|
24
|
+
...options?.fetchAPI,
|
|
25
25
|
};
|
|
26
26
|
const givenHandleRequest = typeof serverAdapterBaseObject === 'function'
|
|
27
27
|
? serverAdapterBaseObject
|
|
28
28
|
: serverAdapterBaseObject.handle;
|
|
29
29
|
const onRequestHooks = [];
|
|
30
30
|
const onResponseHooks = [];
|
|
31
|
-
if (
|
|
31
|
+
if (options?.plugins != null) {
|
|
32
32
|
for (const plugin of options.plugins) {
|
|
33
33
|
if (plugin.onRequest) {
|
|
34
34
|
onRequestHooks.push(plugin.onRequest);
|
|
@@ -108,6 +108,85 @@ function createServerAdapter(serverAdapterBaseObject, options) {
|
|
|
108
108
|
await handleWaitUntils(waitUntilPromises);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
+
async function handleUWS(res, req, ...ctx) {
|
|
112
|
+
const waitUntilPromises = [];
|
|
113
|
+
const serverContext = completeAssign({
|
|
114
|
+
res,
|
|
115
|
+
req,
|
|
116
|
+
waitUntil(promise) {
|
|
117
|
+
if (promise != null) {
|
|
118
|
+
waitUntilPromises.push(promise);
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
}, ...ctx);
|
|
122
|
+
let body;
|
|
123
|
+
const method = req.getMethod();
|
|
124
|
+
let resAborted = false;
|
|
125
|
+
res.onAborted(function () {
|
|
126
|
+
resAborted = true;
|
|
127
|
+
body?.readable.push(null);
|
|
128
|
+
});
|
|
129
|
+
if (method !== 'get' && method !== 'head') {
|
|
130
|
+
body = new fetchAPI.ReadableStream({});
|
|
131
|
+
res.onData(function (chunk, isLast) {
|
|
132
|
+
body?.readable.push(Buffer.from(chunk, 0, chunk.byteLength));
|
|
133
|
+
if (isLast) {
|
|
134
|
+
body?.readable.push(null);
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
const headers = {};
|
|
139
|
+
req.forEach((key, value) => {
|
|
140
|
+
headers[key] = value;
|
|
141
|
+
});
|
|
142
|
+
const url = `http://localhost${req.getUrl()}`;
|
|
143
|
+
const request = new fetchAPI.Request(url, {
|
|
144
|
+
method,
|
|
145
|
+
headers,
|
|
146
|
+
body,
|
|
147
|
+
});
|
|
148
|
+
const response = await handleRequest(request, serverContext);
|
|
149
|
+
if (resAborted) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (!response) {
|
|
153
|
+
res.writeStatus('404 Not Found');
|
|
154
|
+
res.end();
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
res.cork(() => {
|
|
158
|
+
res.writeStatus(`${response.status} ${response.statusText}`);
|
|
159
|
+
});
|
|
160
|
+
response.headers.forEach((value, key) => {
|
|
161
|
+
// content-length causes an error with Node.js's fetch
|
|
162
|
+
if (key.toLowerCase() !== 'content-length') {
|
|
163
|
+
res.cork(() => {
|
|
164
|
+
res.writeHeader(key, value);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
if (!response.body) {
|
|
169
|
+
res.end();
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (response.bodyType === 'String' || response.bodyType === 'Uint8Array') {
|
|
173
|
+
res.cork(() => {
|
|
174
|
+
res.end(response.bodyInit);
|
|
175
|
+
});
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
for await (const chunk of response.body.readable) {
|
|
179
|
+
if (resAborted) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
res.cork(() => {
|
|
183
|
+
res.write(chunk);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
res.cork(() => {
|
|
187
|
+
res.end();
|
|
188
|
+
});
|
|
189
|
+
}
|
|
111
190
|
function handleEvent(event, ...ctx) {
|
|
112
191
|
if (!event.respondWith || !event.request) {
|
|
113
192
|
throw new TypeError(`Expected FetchEvent, got ${event}`);
|
|
@@ -148,6 +227,9 @@ function createServerAdapter(serverAdapterBaseObject, options) {
|
|
|
148
227
|
const genericRequestHandler = (input, ...maybeCtx) => {
|
|
149
228
|
// If it is a Node request
|
|
150
229
|
const [initOrCtxOrRes, ...restOfCtx] = maybeCtx;
|
|
230
|
+
if (isUWSResponse(input)) {
|
|
231
|
+
return handleUWS(input, initOrCtxOrRes, ...restOfCtx);
|
|
232
|
+
}
|
|
151
233
|
if (isNodeRequest(input)) {
|
|
152
234
|
if (!isServerResponse(initOrCtxOrRes)) {
|
|
153
235
|
throw new TypeError(`Expected ServerResponse, got ${initOrCtxOrRes}`);
|
|
@@ -176,6 +258,7 @@ function createServerAdapter(serverAdapterBaseObject, options) {
|
|
|
176
258
|
handleNodeRequest,
|
|
177
259
|
requestListener,
|
|
178
260
|
handleEvent,
|
|
261
|
+
handleUWS,
|
|
179
262
|
handle: genericRequestHandler,
|
|
180
263
|
};
|
|
181
264
|
const serverAdapter = new Proxy(genericRequestHandler, {
|
package/esm/plugins/useCors.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export function getCORSHeadersByRequestAndOptions(request, corsOptions) {
|
|
2
|
-
var _a, _b;
|
|
3
2
|
const currentOrigin = request.headers.get('origin');
|
|
4
3
|
if (corsOptions === false || currentOrigin == null) {
|
|
5
4
|
return null;
|
|
@@ -33,7 +32,7 @@ export function getCORSHeadersByRequestAndOptions(request, corsOptions) {
|
|
|
33
32
|
headers['Access-Control-Allow-Origin'] = 'null';
|
|
34
33
|
}
|
|
35
34
|
}
|
|
36
|
-
if (
|
|
35
|
+
if (corsOptions.methods?.length) {
|
|
37
36
|
headers['Access-Control-Allow-Methods'] = corsOptions.methods.join(', ');
|
|
38
37
|
}
|
|
39
38
|
else {
|
|
@@ -42,7 +41,7 @@ export function getCORSHeadersByRequestAndOptions(request, corsOptions) {
|
|
|
42
41
|
headers['Access-Control-Allow-Methods'] = requestMethod;
|
|
43
42
|
}
|
|
44
43
|
}
|
|
45
|
-
if (
|
|
44
|
+
if (corsOptions.allowedHeaders?.length) {
|
|
46
45
|
headers['Access-Control-Allow-Headers'] = corsOptions.allowedHeaders.join(', ');
|
|
47
46
|
}
|
|
48
47
|
else {
|
package/esm/utils.js
CHANGED
|
@@ -3,31 +3,29 @@ export function isAsyncIterable(body) {
|
|
|
3
3
|
return (body != null && typeof body === 'object' && typeof body[Symbol.asyncIterator] === 'function');
|
|
4
4
|
}
|
|
5
5
|
function getPort(nodeRequest) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return (_b = nodeRequest.socket) === null || _b === void 0 ? void 0 : _b.localPort;
|
|
6
|
+
if (nodeRequest.socket?.localPort) {
|
|
7
|
+
return nodeRequest.socket?.localPort;
|
|
9
8
|
}
|
|
10
|
-
const hostInHeader =
|
|
11
|
-
const portInHeader =
|
|
9
|
+
const hostInHeader = nodeRequest.headers?.[':authority'] || nodeRequest.headers?.host;
|
|
10
|
+
const portInHeader = hostInHeader?.split(':')?.[1];
|
|
12
11
|
if (portInHeader) {
|
|
13
12
|
return portInHeader;
|
|
14
13
|
}
|
|
15
14
|
return 80;
|
|
16
15
|
}
|
|
17
16
|
function getHostnameWithPort(nodeRequest) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return (_b = nodeRequest.headers) === null || _b === void 0 ? void 0 : _b[':authority'];
|
|
17
|
+
if (nodeRequest.headers?.[':authority']) {
|
|
18
|
+
return nodeRequest.headers?.[':authority'];
|
|
21
19
|
}
|
|
22
|
-
if (
|
|
23
|
-
return
|
|
20
|
+
if (nodeRequest.headers?.host) {
|
|
21
|
+
return nodeRequest.headers?.host;
|
|
24
22
|
}
|
|
25
23
|
const port = getPort(nodeRequest);
|
|
26
24
|
if (nodeRequest.hostname) {
|
|
27
25
|
return nodeRequest.hostname + ':' + port;
|
|
28
26
|
}
|
|
29
|
-
const localIp =
|
|
30
|
-
if (localIp && !
|
|
27
|
+
const localIp = nodeRequest.socket?.localAddress;
|
|
28
|
+
if (localIp && !localIp?.includes('::') && !localIp?.includes('ffff')) {
|
|
31
29
|
return `${localIp}:${port}`;
|
|
32
30
|
}
|
|
33
31
|
return 'localhost';
|
|
@@ -51,7 +49,6 @@ function isRequestBody(body) {
|
|
|
51
49
|
return false;
|
|
52
50
|
}
|
|
53
51
|
export function normalizeNodeRequest(nodeRequest, RequestCtor) {
|
|
54
|
-
var _a;
|
|
55
52
|
const rawRequest = nodeRequest.raw || nodeRequest.req || nodeRequest;
|
|
56
53
|
let fullUrl = buildFullUrl(rawRequest);
|
|
57
54
|
if (nodeRequest.query) {
|
|
@@ -86,7 +83,7 @@ export function normalizeNodeRequest(nodeRequest, RequestCtor) {
|
|
|
86
83
|
method: nodeRequest.method,
|
|
87
84
|
headers: nodeRequest.headers,
|
|
88
85
|
});
|
|
89
|
-
if (!
|
|
86
|
+
if (!request.headers.get('content-type')?.includes('json')) {
|
|
90
87
|
request.headers.set('content-type', 'application/json');
|
|
91
88
|
}
|
|
92
89
|
return new Proxy(request, {
|
|
@@ -130,10 +127,9 @@ export function isFetchEvent(event) {
|
|
|
130
127
|
return event != null && event.request != null && event.respondWith != null;
|
|
131
128
|
}
|
|
132
129
|
function configureSocket(rawRequest) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
(_f = (_e = rawRequest === null || rawRequest === void 0 ? void 0 : rawRequest.socket) === null || _e === void 0 ? void 0 : _e.setKeepAlive) === null || _f === void 0 ? void 0 : _f.call(_e, true);
|
|
130
|
+
rawRequest?.socket?.setTimeout?.(0);
|
|
131
|
+
rawRequest?.socket?.setNoDelay?.(true);
|
|
132
|
+
rawRequest?.socket?.setKeepAlive?.(true);
|
|
137
133
|
}
|
|
138
134
|
function endResponse(serverResponse) {
|
|
139
135
|
// @ts-expect-error Avoid arguments adaptor trampoline https://v8.dev/blog/adaptor-frame
|
package/package.json
CHANGED
package/typings/types.d.cts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { RequestListener } from 'node:http';
|
|
3
3
|
import type { NodeRequest, NodeResponse } from './utils.cjs';
|
|
4
|
+
import { UWSHandler, UWSRequest, UWSResponse } from './uwebsockets.cjs';
|
|
4
5
|
export interface FetchEvent extends Event {
|
|
5
6
|
waitUntil(f: Promise<void> | void): void;
|
|
6
7
|
request: Request;
|
|
@@ -39,9 +40,11 @@ export interface ServerAdapterObject<TServerContext> extends EventListenerObject
|
|
|
39
40
|
* A request listener function that can be used with any Node server variation.
|
|
40
41
|
*/
|
|
41
42
|
requestListener: RequestListener;
|
|
43
|
+
handleUWS: UWSHandler;
|
|
42
44
|
handle(req: NodeRequest, res: NodeResponse, ...ctx: Partial<TServerContext>[]): Promise<void>;
|
|
43
45
|
handle(request: Request, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
|
|
44
46
|
handle(fetchEvent: FetchEvent & Partial<TServerContext>, ...ctx: Partial<TServerContext>[]): void;
|
|
47
|
+
handle(res: UWSResponse, req: UWSRequest, ...ctx: Partial<TServerContext>[]): Promise<void>;
|
|
45
48
|
handle(container: {
|
|
46
49
|
request: Request;
|
|
47
50
|
} & Partial<TServerContext>, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
|
package/typings/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { RequestListener } from 'node:http';
|
|
3
3
|
import type { NodeRequest, NodeResponse } from './utils.js';
|
|
4
|
+
import { UWSHandler, UWSRequest, UWSResponse } from './uwebsockets.js';
|
|
4
5
|
export interface FetchEvent extends Event {
|
|
5
6
|
waitUntil(f: Promise<void> | void): void;
|
|
6
7
|
request: Request;
|
|
@@ -39,9 +40,11 @@ export interface ServerAdapterObject<TServerContext> extends EventListenerObject
|
|
|
39
40
|
* A request listener function that can be used with any Node server variation.
|
|
40
41
|
*/
|
|
41
42
|
requestListener: RequestListener;
|
|
43
|
+
handleUWS: UWSHandler;
|
|
42
44
|
handle(req: NodeRequest, res: NodeResponse, ...ctx: Partial<TServerContext>[]): Promise<void>;
|
|
43
45
|
handle(request: Request, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
|
|
44
46
|
handle(fetchEvent: FetchEvent & Partial<TServerContext>, ...ctx: Partial<TServerContext>[]): void;
|
|
47
|
+
handle(res: UWSResponse, req: UWSRequest, ...ctx: Partial<TServerContext>[]): Promise<void>;
|
|
45
48
|
handle(container: {
|
|
46
49
|
request: Request;
|
|
47
50
|
} & Partial<TServerContext>, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface UWSRequest {
|
|
2
|
+
getMethod(): string;
|
|
3
|
+
forEach(callback: (key: string, value: string) => void): void;
|
|
4
|
+
getUrl(): string;
|
|
5
|
+
}
|
|
6
|
+
export interface UWSResponse {
|
|
7
|
+
onData(callback: (chunk: ArrayBuffer, isLast: boolean) => void): void;
|
|
8
|
+
onAborted(callback: () => void): void;
|
|
9
|
+
writeStatus(status: string): void;
|
|
10
|
+
writeHeader(key: string, value: string): void;
|
|
11
|
+
end(body?: any): void;
|
|
12
|
+
write(body: any): boolean;
|
|
13
|
+
cork(callback: () => void): void;
|
|
14
|
+
}
|
|
15
|
+
export type UWSHandler = (res: UWSResponse, req: UWSRequest) => void | Promise<void>;
|
|
16
|
+
export declare function isUWSResponse(res: any): res is UWSResponse;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface UWSRequest {
|
|
2
|
+
getMethod(): string;
|
|
3
|
+
forEach(callback: (key: string, value: string) => void): void;
|
|
4
|
+
getUrl(): string;
|
|
5
|
+
}
|
|
6
|
+
export interface UWSResponse {
|
|
7
|
+
onData(callback: (chunk: ArrayBuffer, isLast: boolean) => void): void;
|
|
8
|
+
onAborted(callback: () => void): void;
|
|
9
|
+
writeStatus(status: string): void;
|
|
10
|
+
writeHeader(key: string, value: string): void;
|
|
11
|
+
end(body?: any): void;
|
|
12
|
+
write(body: any): boolean;
|
|
13
|
+
cork(callback: () => void): void;
|
|
14
|
+
}
|
|
15
|
+
export type UWSHandler = (res: UWSResponse, req: UWSRequest) => void | Promise<void>;
|
|
16
|
+
export declare function isUWSResponse(res: any): res is UWSResponse;
|