@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 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, ...ctx: any[]): Promise<Response> | Response;
21
- fetch(urlStr: string, ...ctx: any[]): Promise<Response> | Response;
22
- fetch(urlStr: string, init: RequestInit, ...ctx: any[]): Promise<Response> | Response;
23
- fetch(url: URL, ...ctx: any[]): Promise<Response> | Response;
24
- fetch(url: URL, init: RequestInit, ...ctx: any[]): Promise<Response> | Response;
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, serverContext: TServerContext): Promise<Response> | Response;
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: RequestListener & ServerAdapterObject<TServerContext, TBaseObject>['fetch'];
41
+ handle: ServerAdapterObject<TServerContext, TBaseObject>['requestListener'] & ServerAdapterObject<TServerContext, TBaseObject>['fetch'];
37
42
  }
38
- export declare type ServerAdapter<TServerContext, TBaseObject extends ServerAdapterBaseObject<TServerContext>> = TBaseObject & RequestListener & ServerAdapterObject<TServerContext, TBaseObject>['fetch'] & ServerAdapterObject<TServerContext, TBaseObject>;
39
- export declare type ServerAdapterRequestHandler<TServerContext> = (request: Request, serverContext: TServerContext) => Promise<Response> | Response;
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, serverContext) {
190
+ function handleNodeRequest(nodeRequest, ctx) {
174
191
  const request = normalizeNodeRequest(nodeRequest, RequestCtor);
175
- return handleRequest(request, serverContext);
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
- const response$ = handleRequest(event.request, event);
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 = {}, ...rest) {
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 ((rest === null || rest === void 0 ? void 0 : rest.length) > 0) {
213
- ctx = Object.assign({}, ctx, ...rest);
214
- }
215
- if (!ctx.waitUntil) {
236
+ if (!extendedCtx.waitUntil) {
216
237
  const waitUntilPromises = [];
217
- ctx.waitUntil = (p) => {
238
+ extendedCtx.waitUntil = (p) => {
218
239
  waitUntilPromises.push(p);
219
240
  };
220
241
  const response$ = handleRequest(request, {
221
- ...ctx,
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, ctx);
252
+ return handleRequest(request, extendedCtx);
232
253
  }
233
- function genericRequestHandler(input, ctx, ...rest) {
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) && ctx != null && isServerResponse(ctx)) {
236
- return requestListener(input, ctx);
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.request) {
281
+ if (typeof input === 'object' && 'request' in input) {
240
282
  // Is it FetchEvent?
241
- if (input.respondWith) {
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 handleRequestWithWaitUntil(input.request, input, ...rest);
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 handleRequestWithWaitUntil(input, ctx, ...rest);
250
- }
251
- function fetchFn(input, init, ...ctx) {
252
- if (typeof input === 'string' || input instanceof URL) {
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 genericRequestHandlerProp = genericRequestHandler[prop];
281
- if (genericRequestHandlerProp) {
282
- if (genericRequestHandlerProp.bind) {
283
- return genericRequestHandlerProp.bind(genericRequestHandler);
320
+ const handleProp = genericRequestHandler[prop];
321
+ if (handleProp) {
322
+ if (handleProp.bind) {
323
+ return handleProp.bind(genericRequestHandler);
284
324
  }
285
- return genericRequestHandlerProp;
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, serverContext) {
186
+ function handleNodeRequest(nodeRequest, ctx) {
170
187
  const request = normalizeNodeRequest(nodeRequest, RequestCtor);
171
- return handleRequest(request, serverContext);
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
- const response$ = handleRequest(event.request, event);
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 = {}, ...rest) {
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 ((rest === null || rest === void 0 ? void 0 : rest.length) > 0) {
209
- ctx = Object.assign({}, ctx, ...rest);
210
- }
211
- if (!ctx.waitUntil) {
232
+ if (!extendedCtx.waitUntil) {
212
233
  const waitUntilPromises = [];
213
- ctx.waitUntil = (p) => {
234
+ extendedCtx.waitUntil = (p) => {
214
235
  waitUntilPromises.push(p);
215
236
  };
216
237
  const response$ = handleRequest(request, {
217
- ...ctx,
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, ctx);
248
+ return handleRequest(request, extendedCtx);
228
249
  }
229
- function genericRequestHandler(input, ctx, ...rest) {
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) && ctx != null && isServerResponse(ctx)) {
232
- return requestListener(input, ctx);
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.request) {
277
+ if (typeof input === 'object' && 'request' in input) {
236
278
  // Is it FetchEvent?
237
- if (input.respondWith) {
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 handleRequestWithWaitUntil(input.request, input, ...rest);
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 handleRequestWithWaitUntil(input, ctx, ...rest);
246
- }
247
- function fetchFn(input, init, ...ctx) {
248
- if (typeof input === 'string' || input instanceof URL) {
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 genericRequestHandlerProp = genericRequestHandler[prop];
277
- if (genericRequestHandlerProp) {
278
- if (genericRequestHandlerProp.bind) {
279
- return genericRequestHandlerProp.bind(genericRequestHandler);
316
+ const handleProp = genericRequestHandler[prop];
317
+ if (handleProp) {
318
+ if (handleProp.bind) {
319
+ return handleProp.bind(genericRequestHandler);
280
320
  }
281
- return genericRequestHandlerProp;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@whatwg-node/server",
3
- "version": "0.4.5",
3
+ "version": "0.4.6-alpha-20220921172951-5c43d9d",
4
4
  "description": "Fetch API compliant HTTP Server adapter",
5
5
  "sideEffects": false,
6
6
  "peerDependencies": {
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;