@whatwg-node/server 0.4.5 → 0.4.6-alpha-20220921172951-5c43d9d
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/index.d.ts +14 -9
- package/index.js +73 -33
- package/index.mjs +73 -33
- package/package.json +1 -1
- package/utils.d.ts +1 -0
package/index.d.ts
CHANGED
|
@@ -17,15 +17,20 @@ export interface ServerAdapterObject<TServerContext, TBaseObject extends ServerA
|
|
|
17
17
|
/**
|
|
18
18
|
* WHATWG Fetch spec compliant `fetch` function that can be used for testing purposes.
|
|
19
19
|
*/
|
|
20
|
-
fetch(request: Request,
|
|
21
|
-
fetch(
|
|
22
|
-
fetch(urlStr: string,
|
|
23
|
-
fetch(
|
|
24
|
-
fetch(
|
|
20
|
+
fetch(request: Request, ctx: TServerContext): Promise<Response> | Response;
|
|
21
|
+
fetch(request: Request, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
|
|
22
|
+
fetch(urlStr: string, ctx: TServerContext): Promise<Response> | Response;
|
|
23
|
+
fetch(urlStr: string, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
|
|
24
|
+
fetch(urlStr: string, init: RequestInit, ctx: TServerContext): Promise<Response> | Response;
|
|
25
|
+
fetch(urlStr: string, init: RequestInit, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
|
|
26
|
+
fetch(url: URL, ctx: TServerContext): Promise<Response> | Response;
|
|
27
|
+
fetch(url: URL, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
|
|
28
|
+
fetch(url: URL, init: RequestInit, ctx: TServerContext): Promise<Response> | Response;
|
|
29
|
+
fetch(url: URL, init: RequestInit, ...ctx: Partial<TServerContext>[]): Promise<Response> | Response;
|
|
25
30
|
/**
|
|
26
31
|
* This function takes Node's request object and returns a WHATWG Fetch spec compliant `Response` object.
|
|
27
32
|
**/
|
|
28
|
-
handleNodeRequest(nodeRequest: NodeRequest,
|
|
33
|
+
handleNodeRequest(nodeRequest: NodeRequest, ctx: TServerContext): Promise<Response> | Response;
|
|
29
34
|
/**
|
|
30
35
|
* A request listener function that can be used with any Node server variation.
|
|
31
36
|
*/
|
|
@@ -33,10 +38,10 @@ export interface ServerAdapterObject<TServerContext, TBaseObject extends ServerA
|
|
|
33
38
|
/**
|
|
34
39
|
* Proxy to requestListener to mimic Node middlewares
|
|
35
40
|
*/
|
|
36
|
-
handle:
|
|
41
|
+
handle: ServerAdapterObject<TServerContext, TBaseObject>['requestListener'] & ServerAdapterObject<TServerContext, TBaseObject>['fetch'];
|
|
37
42
|
}
|
|
38
|
-
export declare type ServerAdapter<TServerContext, TBaseObject extends ServerAdapterBaseObject<TServerContext>> = TBaseObject &
|
|
39
|
-
export declare type ServerAdapterRequestHandler<TServerContext> = (request: Request,
|
|
43
|
+
export declare type ServerAdapter<TServerContext, TBaseObject extends ServerAdapterBaseObject<TServerContext>> = TBaseObject & ServerAdapterObject<TServerContext, TBaseObject>['requestListener'] & ServerAdapterObject<TServerContext, TBaseObject>['fetch'] & ServerAdapterObject<TServerContext, TBaseObject>;
|
|
44
|
+
export declare type ServerAdapterRequestHandler<TServerContext> = (request: Request, ctx: TServerContext) => Promise<Response> | Response;
|
|
40
45
|
export declare type DefaultServerAdapterContext = {
|
|
41
46
|
req: NodeRequest;
|
|
42
47
|
res: ServerResponse;
|
package/index.js
CHANGED
|
@@ -154,6 +154,23 @@ async function sendNodeResponse({ headers, status, statusText, body }, serverRes
|
|
|
154
154
|
}
|
|
155
155
|
});
|
|
156
156
|
}
|
|
157
|
+
function isRequestInit(val) {
|
|
158
|
+
return (val != null &&
|
|
159
|
+
typeof val === 'object' &&
|
|
160
|
+
('body' in val ||
|
|
161
|
+
'cache' in val ||
|
|
162
|
+
'credentials' in val ||
|
|
163
|
+
'headers' in val ||
|
|
164
|
+
'integrity' in val ||
|
|
165
|
+
'keepalive' in val ||
|
|
166
|
+
'method' in val ||
|
|
167
|
+
'mode' in val ||
|
|
168
|
+
'redirect' in val ||
|
|
169
|
+
'referrer' in val ||
|
|
170
|
+
'referrerPolicy' in val ||
|
|
171
|
+
'signal' in val ||
|
|
172
|
+
'window' in val));
|
|
173
|
+
}
|
|
157
174
|
|
|
158
175
|
/// <reference lib="webworker" />
|
|
159
176
|
async function handleWaitUntils(waitUntilPromises) {
|
|
@@ -170,9 +187,9 @@ function createServerAdapter(serverAdapterBaseObject,
|
|
|
170
187
|
*/
|
|
171
188
|
RequestCtor = fetch.Request) {
|
|
172
189
|
const handleRequest = typeof serverAdapterBaseObject === 'function' ? serverAdapterBaseObject : serverAdapterBaseObject.handle;
|
|
173
|
-
function handleNodeRequest(nodeRequest,
|
|
190
|
+
function handleNodeRequest(nodeRequest, ctx) {
|
|
174
191
|
const request = normalizeNodeRequest(nodeRequest, RequestCtor);
|
|
175
|
-
return handleRequest(request,
|
|
192
|
+
return handleRequest(request, ctx);
|
|
176
193
|
}
|
|
177
194
|
async function requestListener(nodeRequest, serverResponse) {
|
|
178
195
|
const waitUntilPromises = [];
|
|
@@ -195,30 +212,34 @@ RequestCtor = fetch.Request) {
|
|
|
195
212
|
if (waitUntilPromises.length > 0) {
|
|
196
213
|
await handleWaitUntils(waitUntilPromises);
|
|
197
214
|
}
|
|
215
|
+
return response;
|
|
198
216
|
}
|
|
199
|
-
function handleEvent(event) {
|
|
217
|
+
function handleEvent(event, ...ctx) {
|
|
200
218
|
if (!event.respondWith || !event.request) {
|
|
201
219
|
throw new TypeError(`Expected FetchEvent, got ${event}`);
|
|
202
220
|
}
|
|
203
|
-
|
|
221
|
+
let serverContext = {};
|
|
222
|
+
if ((ctx === null || ctx === void 0 ? void 0 : ctx.length) > 0) {
|
|
223
|
+
serverContext = Object.assign({}, serverContext, ...ctx);
|
|
224
|
+
}
|
|
225
|
+
const response$ = handleRequest(event.request, serverContext);
|
|
204
226
|
event.respondWith(response$);
|
|
227
|
+
return response$;
|
|
205
228
|
}
|
|
206
|
-
function handleRequestWithWaitUntil(request, ctx
|
|
229
|
+
function handleRequestWithWaitUntil(request, ctx) {
|
|
207
230
|
var _a;
|
|
231
|
+
const extendedCtx = ctx;
|
|
208
232
|
if ('process' in globalThis && ((_a = process.versions) === null || _a === void 0 ? void 0 : _a['bun']) != null) {
|
|
209
233
|
// This is required for bun
|
|
210
234
|
request.text();
|
|
211
235
|
}
|
|
212
|
-
if (
|
|
213
|
-
ctx = Object.assign({}, ctx, ...rest);
|
|
214
|
-
}
|
|
215
|
-
if (!ctx.waitUntil) {
|
|
236
|
+
if (!extendedCtx.waitUntil) {
|
|
216
237
|
const waitUntilPromises = [];
|
|
217
|
-
|
|
238
|
+
extendedCtx.waitUntil = (p) => {
|
|
218
239
|
waitUntilPromises.push(p);
|
|
219
240
|
};
|
|
220
241
|
const response$ = handleRequest(request, {
|
|
221
|
-
...
|
|
242
|
+
...extendedCtx,
|
|
222
243
|
waitUntil(p) {
|
|
223
244
|
waitUntilPromises.push(p);
|
|
224
245
|
},
|
|
@@ -228,32 +249,51 @@ RequestCtor = fetch.Request) {
|
|
|
228
249
|
}
|
|
229
250
|
return response$;
|
|
230
251
|
}
|
|
231
|
-
return handleRequest(request,
|
|
252
|
+
return handleRequest(request, extendedCtx);
|
|
232
253
|
}
|
|
233
|
-
|
|
254
|
+
const fetchFn = (input, initOrCtx, ...ctx) => {
|
|
255
|
+
let init;
|
|
256
|
+
let serverContext = {};
|
|
257
|
+
if (isRequestInit(initOrCtx)) {
|
|
258
|
+
init = initOrCtx;
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
init = {};
|
|
262
|
+
serverContext = Object.assign({}, serverContext, initOrCtx);
|
|
263
|
+
}
|
|
264
|
+
if ((ctx === null || ctx === void 0 ? void 0 : ctx.length) > 0) {
|
|
265
|
+
serverContext = Object.assign({}, serverContext, ...ctx);
|
|
266
|
+
}
|
|
267
|
+
if (typeof input === 'string' || input instanceof URL) {
|
|
268
|
+
return handleRequestWithWaitUntil(new RequestCtor(input, init), serverContext);
|
|
269
|
+
}
|
|
270
|
+
return handleRequestWithWaitUntil(input, serverContext);
|
|
271
|
+
};
|
|
272
|
+
const genericRequestHandler = (input, initOrCtxOrRes, ...ctx) => {
|
|
234
273
|
// If it is a Node request
|
|
235
|
-
if (isReadable(input) &&
|
|
236
|
-
return requestListener(input,
|
|
274
|
+
if (isReadable(input) && isServerResponse(initOrCtxOrRes)) {
|
|
275
|
+
return requestListener(input, initOrCtxOrRes);
|
|
276
|
+
}
|
|
277
|
+
if (isServerResponse(initOrCtxOrRes)) {
|
|
278
|
+
throw new Error('Got Node response without Node request');
|
|
237
279
|
}
|
|
238
280
|
// Is input a container object over Request?
|
|
239
|
-
if (input
|
|
281
|
+
if (typeof input === 'object' && 'request' in input) {
|
|
240
282
|
// Is it FetchEvent?
|
|
241
|
-
if (input
|
|
242
|
-
return handleEvent(input);
|
|
283
|
+
if ('respondWith' in input) {
|
|
284
|
+
return handleEvent(input, isRequestInit(initOrCtxOrRes) ? {} : initOrCtxOrRes, ...ctx);
|
|
243
285
|
}
|
|
244
286
|
// In this input is also the context
|
|
245
|
-
return
|
|
287
|
+
return fetchFn(
|
|
288
|
+
// @ts-expect-error input can indeed be a Request
|
|
289
|
+
input.request, initOrCtxOrRes, ...ctx);
|
|
246
290
|
}
|
|
247
291
|
// Or is it Request itself?
|
|
248
292
|
// Then ctx is present and it is the context
|
|
249
|
-
return
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
return handleRequestWithWaitUntil(new RequestCtor(input, init), ...ctx);
|
|
254
|
-
}
|
|
255
|
-
return handleRequestWithWaitUntil(input, init, ...ctx);
|
|
256
|
-
}
|
|
293
|
+
return fetchFn(
|
|
294
|
+
// @ts-expect-error input can indeed string | Request | URL
|
|
295
|
+
input, initOrCtxOrRes, ...ctx);
|
|
296
|
+
};
|
|
257
297
|
const adapterObj = {
|
|
258
298
|
handleRequest,
|
|
259
299
|
fetch: fetchFn,
|
|
@@ -277,12 +317,12 @@ RequestCtor = fetch.Request) {
|
|
|
277
317
|
}
|
|
278
318
|
return adapterProp;
|
|
279
319
|
}
|
|
280
|
-
const
|
|
281
|
-
if (
|
|
282
|
-
if (
|
|
283
|
-
return
|
|
320
|
+
const handleProp = genericRequestHandler[prop];
|
|
321
|
+
if (handleProp) {
|
|
322
|
+
if (handleProp.bind) {
|
|
323
|
+
return handleProp.bind(genericRequestHandler);
|
|
284
324
|
}
|
|
285
|
-
return
|
|
325
|
+
return handleProp;
|
|
286
326
|
}
|
|
287
327
|
if (serverAdapterBaseObject) {
|
|
288
328
|
const serverAdapterBaseObjectProp = serverAdapterBaseObject[prop];
|
|
@@ -297,7 +337,7 @@ RequestCtor = fetch.Request) {
|
|
|
297
337
|
apply(_, __, [input, ctx]) {
|
|
298
338
|
return genericRequestHandler(input, ctx);
|
|
299
339
|
},
|
|
300
|
-
});
|
|
340
|
+
}); // 😡
|
|
301
341
|
}
|
|
302
342
|
|
|
303
343
|
exports.createServerAdapter = createServerAdapter;
|
package/index.mjs
CHANGED
|
@@ -150,6 +150,23 @@ async function sendNodeResponse({ headers, status, statusText, body }, serverRes
|
|
|
150
150
|
}
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
|
+
function isRequestInit(val) {
|
|
154
|
+
return (val != null &&
|
|
155
|
+
typeof val === 'object' &&
|
|
156
|
+
('body' in val ||
|
|
157
|
+
'cache' in val ||
|
|
158
|
+
'credentials' in val ||
|
|
159
|
+
'headers' in val ||
|
|
160
|
+
'integrity' in val ||
|
|
161
|
+
'keepalive' in val ||
|
|
162
|
+
'method' in val ||
|
|
163
|
+
'mode' in val ||
|
|
164
|
+
'redirect' in val ||
|
|
165
|
+
'referrer' in val ||
|
|
166
|
+
'referrerPolicy' in val ||
|
|
167
|
+
'signal' in val ||
|
|
168
|
+
'window' in val));
|
|
169
|
+
}
|
|
153
170
|
|
|
154
171
|
/// <reference lib="webworker" />
|
|
155
172
|
async function handleWaitUntils(waitUntilPromises) {
|
|
@@ -166,9 +183,9 @@ function createServerAdapter(serverAdapterBaseObject,
|
|
|
166
183
|
*/
|
|
167
184
|
RequestCtor = Request) {
|
|
168
185
|
const handleRequest = typeof serverAdapterBaseObject === 'function' ? serverAdapterBaseObject : serverAdapterBaseObject.handle;
|
|
169
|
-
function handleNodeRequest(nodeRequest,
|
|
186
|
+
function handleNodeRequest(nodeRequest, ctx) {
|
|
170
187
|
const request = normalizeNodeRequest(nodeRequest, RequestCtor);
|
|
171
|
-
return handleRequest(request,
|
|
188
|
+
return handleRequest(request, ctx);
|
|
172
189
|
}
|
|
173
190
|
async function requestListener(nodeRequest, serverResponse) {
|
|
174
191
|
const waitUntilPromises = [];
|
|
@@ -191,30 +208,34 @@ RequestCtor = Request) {
|
|
|
191
208
|
if (waitUntilPromises.length > 0) {
|
|
192
209
|
await handleWaitUntils(waitUntilPromises);
|
|
193
210
|
}
|
|
211
|
+
return response;
|
|
194
212
|
}
|
|
195
|
-
function handleEvent(event) {
|
|
213
|
+
function handleEvent(event, ...ctx) {
|
|
196
214
|
if (!event.respondWith || !event.request) {
|
|
197
215
|
throw new TypeError(`Expected FetchEvent, got ${event}`);
|
|
198
216
|
}
|
|
199
|
-
|
|
217
|
+
let serverContext = {};
|
|
218
|
+
if ((ctx === null || ctx === void 0 ? void 0 : ctx.length) > 0) {
|
|
219
|
+
serverContext = Object.assign({}, serverContext, ...ctx);
|
|
220
|
+
}
|
|
221
|
+
const response$ = handleRequest(event.request, serverContext);
|
|
200
222
|
event.respondWith(response$);
|
|
223
|
+
return response$;
|
|
201
224
|
}
|
|
202
|
-
function handleRequestWithWaitUntil(request, ctx
|
|
225
|
+
function handleRequestWithWaitUntil(request, ctx) {
|
|
203
226
|
var _a;
|
|
227
|
+
const extendedCtx = ctx;
|
|
204
228
|
if ('process' in globalThis && ((_a = process.versions) === null || _a === void 0 ? void 0 : _a['bun']) != null) {
|
|
205
229
|
// This is required for bun
|
|
206
230
|
request.text();
|
|
207
231
|
}
|
|
208
|
-
if (
|
|
209
|
-
ctx = Object.assign({}, ctx, ...rest);
|
|
210
|
-
}
|
|
211
|
-
if (!ctx.waitUntil) {
|
|
232
|
+
if (!extendedCtx.waitUntil) {
|
|
212
233
|
const waitUntilPromises = [];
|
|
213
|
-
|
|
234
|
+
extendedCtx.waitUntil = (p) => {
|
|
214
235
|
waitUntilPromises.push(p);
|
|
215
236
|
};
|
|
216
237
|
const response$ = handleRequest(request, {
|
|
217
|
-
...
|
|
238
|
+
...extendedCtx,
|
|
218
239
|
waitUntil(p) {
|
|
219
240
|
waitUntilPromises.push(p);
|
|
220
241
|
},
|
|
@@ -224,32 +245,51 @@ RequestCtor = Request) {
|
|
|
224
245
|
}
|
|
225
246
|
return response$;
|
|
226
247
|
}
|
|
227
|
-
return handleRequest(request,
|
|
248
|
+
return handleRequest(request, extendedCtx);
|
|
228
249
|
}
|
|
229
|
-
|
|
250
|
+
const fetchFn = (input, initOrCtx, ...ctx) => {
|
|
251
|
+
let init;
|
|
252
|
+
let serverContext = {};
|
|
253
|
+
if (isRequestInit(initOrCtx)) {
|
|
254
|
+
init = initOrCtx;
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
init = {};
|
|
258
|
+
serverContext = Object.assign({}, serverContext, initOrCtx);
|
|
259
|
+
}
|
|
260
|
+
if ((ctx === null || ctx === void 0 ? void 0 : ctx.length) > 0) {
|
|
261
|
+
serverContext = Object.assign({}, serverContext, ...ctx);
|
|
262
|
+
}
|
|
263
|
+
if (typeof input === 'string' || input instanceof URL) {
|
|
264
|
+
return handleRequestWithWaitUntil(new RequestCtor(input, init), serverContext);
|
|
265
|
+
}
|
|
266
|
+
return handleRequestWithWaitUntil(input, serverContext);
|
|
267
|
+
};
|
|
268
|
+
const genericRequestHandler = (input, initOrCtxOrRes, ...ctx) => {
|
|
230
269
|
// If it is a Node request
|
|
231
|
-
if (isReadable(input) &&
|
|
232
|
-
return requestListener(input,
|
|
270
|
+
if (isReadable(input) && isServerResponse(initOrCtxOrRes)) {
|
|
271
|
+
return requestListener(input, initOrCtxOrRes);
|
|
272
|
+
}
|
|
273
|
+
if (isServerResponse(initOrCtxOrRes)) {
|
|
274
|
+
throw new Error('Got Node response without Node request');
|
|
233
275
|
}
|
|
234
276
|
// Is input a container object over Request?
|
|
235
|
-
if (input
|
|
277
|
+
if (typeof input === 'object' && 'request' in input) {
|
|
236
278
|
// Is it FetchEvent?
|
|
237
|
-
if (input
|
|
238
|
-
return handleEvent(input);
|
|
279
|
+
if ('respondWith' in input) {
|
|
280
|
+
return handleEvent(input, isRequestInit(initOrCtxOrRes) ? {} : initOrCtxOrRes, ...ctx);
|
|
239
281
|
}
|
|
240
282
|
// In this input is also the context
|
|
241
|
-
return
|
|
283
|
+
return fetchFn(
|
|
284
|
+
// @ts-expect-error input can indeed be a Request
|
|
285
|
+
input.request, initOrCtxOrRes, ...ctx);
|
|
242
286
|
}
|
|
243
287
|
// Or is it Request itself?
|
|
244
288
|
// Then ctx is present and it is the context
|
|
245
|
-
return
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
return handleRequestWithWaitUntil(new RequestCtor(input, init), ...ctx);
|
|
250
|
-
}
|
|
251
|
-
return handleRequestWithWaitUntil(input, init, ...ctx);
|
|
252
|
-
}
|
|
289
|
+
return fetchFn(
|
|
290
|
+
// @ts-expect-error input can indeed string | Request | URL
|
|
291
|
+
input, initOrCtxOrRes, ...ctx);
|
|
292
|
+
};
|
|
253
293
|
const adapterObj = {
|
|
254
294
|
handleRequest,
|
|
255
295
|
fetch: fetchFn,
|
|
@@ -273,12 +313,12 @@ RequestCtor = Request) {
|
|
|
273
313
|
}
|
|
274
314
|
return adapterProp;
|
|
275
315
|
}
|
|
276
|
-
const
|
|
277
|
-
if (
|
|
278
|
-
if (
|
|
279
|
-
return
|
|
316
|
+
const handleProp = genericRequestHandler[prop];
|
|
317
|
+
if (handleProp) {
|
|
318
|
+
if (handleProp.bind) {
|
|
319
|
+
return handleProp.bind(genericRequestHandler);
|
|
280
320
|
}
|
|
281
|
-
return
|
|
321
|
+
return handleProp;
|
|
282
322
|
}
|
|
283
323
|
if (serverAdapterBaseObject) {
|
|
284
324
|
const serverAdapterBaseObjectProp = serverAdapterBaseObject[prop];
|
|
@@ -293,7 +333,7 @@ RequestCtor = Request) {
|
|
|
293
333
|
apply(_, __, [input, ctx]) {
|
|
294
334
|
return genericRequestHandler(input, ctx);
|
|
295
335
|
},
|
|
296
|
-
});
|
|
336
|
+
}); // 😡
|
|
297
337
|
}
|
|
298
338
|
|
|
299
339
|
export { createServerAdapter };
|
package/package.json
CHANGED
package/utils.d.ts
CHANGED
|
@@ -21,3 +21,4 @@ export declare function normalizeNodeRequest(nodeRequest: NodeRequest, RequestCt
|
|
|
21
21
|
export declare function isReadable(stream: any): stream is Readable;
|
|
22
22
|
export declare function isServerResponse(stream: any): stream is ServerResponse;
|
|
23
23
|
export declare function sendNodeResponse({ headers, status, statusText, body }: Response, serverResponse: ServerResponse): Promise<void>;
|
|
24
|
+
export declare function isRequestInit(val: unknown): val is RequestInit;
|