@whatwg-node/server 0.7.7 → 0.8.0

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.mjs DELETED
@@ -1,643 +0,0 @@
1
- import * as DefaultFetchAPI from '@whatwg-node/fetch';
2
- import { URL, Response } from '@whatwg-node/fetch';
3
- export { Response } from '@whatwg-node/fetch';
4
-
5
- function isAsyncIterable(body) {
6
- return (body != null && typeof body === 'object' && typeof body[Symbol.asyncIterator] === 'function');
7
- }
8
- function getPort(nodeRequest) {
9
- var _a, _b, _c, _d, _e;
10
- if ((_a = nodeRequest.socket) === null || _a === void 0 ? void 0 : _a.localPort) {
11
- return (_b = nodeRequest.socket) === null || _b === void 0 ? void 0 : _b.localPort;
12
- }
13
- const hostInHeader = ((_c = nodeRequest.headers) === null || _c === void 0 ? void 0 : _c[':authority']) || ((_d = nodeRequest.headers) === null || _d === void 0 ? void 0 : _d.host);
14
- const portInHeader = (_e = hostInHeader === null || hostInHeader === void 0 ? void 0 : hostInHeader.split(':')) === null || _e === void 0 ? void 0 : _e[1];
15
- if (portInHeader) {
16
- return portInHeader;
17
- }
18
- return 80;
19
- }
20
- function getHostnameWithPort(nodeRequest) {
21
- var _a, _b, _c, _d, _e;
22
- if ((_a = nodeRequest.headers) === null || _a === void 0 ? void 0 : _a[':authority']) {
23
- return (_b = nodeRequest.headers) === null || _b === void 0 ? void 0 : _b[':authority'];
24
- }
25
- if ((_c = nodeRequest.headers) === null || _c === void 0 ? void 0 : _c.host) {
26
- return (_d = nodeRequest.headers) === null || _d === void 0 ? void 0 : _d.host;
27
- }
28
- const port = getPort(nodeRequest);
29
- if (nodeRequest.hostname) {
30
- return nodeRequest.hostname + ':' + port;
31
- }
32
- const localIp = (_e = nodeRequest.socket) === null || _e === void 0 ? void 0 : _e.localAddress;
33
- if (localIp && !(localIp === null || localIp === void 0 ? void 0 : localIp.includes('::')) && !(localIp === null || localIp === void 0 ? void 0 : localIp.includes('ffff'))) {
34
- return `${localIp}:${port}`;
35
- }
36
- return 'localhost';
37
- }
38
- function buildFullUrl(nodeRequest) {
39
- const hostnameWithPort = getHostnameWithPort(nodeRequest);
40
- const protocol = nodeRequest.protocol || 'http';
41
- const endpoint = nodeRequest.originalUrl || nodeRequest.url || '/graphql';
42
- return `${protocol}://${hostnameWithPort}${endpoint}`;
43
- }
44
- function isRequestBody(body) {
45
- const stringTag = body[Symbol.toStringTag];
46
- if (typeof body === 'string' ||
47
- stringTag === 'Uint8Array' ||
48
- stringTag === 'Blob' ||
49
- stringTag === 'FormData' ||
50
- stringTag === 'URLSearchParams' ||
51
- isAsyncIterable(body)) {
52
- return true;
53
- }
54
- return false;
55
- }
56
- function normalizeNodeRequest(nodeRequest, RequestCtor) {
57
- var _a;
58
- const rawRequest = nodeRequest.raw || nodeRequest.req || nodeRequest;
59
- let fullUrl = buildFullUrl(rawRequest);
60
- if (nodeRequest.query) {
61
- const url = new URL(fullUrl);
62
- for (const key in nodeRequest.query) {
63
- url.searchParams.set(key, nodeRequest.query[key]);
64
- }
65
- fullUrl = url.toString();
66
- }
67
- if (nodeRequest.method === 'GET' || nodeRequest.method === 'HEAD') {
68
- return new RequestCtor(fullUrl, {
69
- method: nodeRequest.method,
70
- headers: nodeRequest.headers,
71
- });
72
- }
73
- /**
74
- * Some Node server frameworks like Serverless Express sends a dummy object with body but as a Buffer not string
75
- * so we do those checks to see is there something we can use directly as BodyInit
76
- * because the presence of body means the request stream is already consumed and,
77
- * rawRequest cannot be used as BodyInit/ReadableStream by Fetch API in this case.
78
- */
79
- const maybeParsedBody = nodeRequest.body;
80
- if (maybeParsedBody != null && Object.keys(maybeParsedBody).length > 0) {
81
- if (isRequestBody(maybeParsedBody)) {
82
- return new RequestCtor(fullUrl, {
83
- method: nodeRequest.method,
84
- headers: nodeRequest.headers,
85
- body: maybeParsedBody,
86
- });
87
- }
88
- const request = new RequestCtor(fullUrl, {
89
- method: nodeRequest.method,
90
- headers: nodeRequest.headers,
91
- });
92
- if (!((_a = request.headers.get('content-type')) === null || _a === void 0 ? void 0 : _a.includes('json'))) {
93
- request.headers.set('content-type', 'application/json');
94
- }
95
- return new Proxy(request, {
96
- get: (target, prop, receiver) => {
97
- switch (prop) {
98
- case 'json':
99
- return async () => maybeParsedBody;
100
- case 'text':
101
- return async () => JSON.stringify(maybeParsedBody);
102
- default:
103
- return Reflect.get(target, prop, receiver);
104
- }
105
- },
106
- });
107
- }
108
- // perf: instead of spreading the object, we can just pass it as is and it performs better
109
- return new RequestCtor(fullUrl, {
110
- method: nodeRequest.method,
111
- headers: nodeRequest.headers,
112
- body: rawRequest,
113
- });
114
- }
115
- function isReadable(stream) {
116
- return stream.read != null;
117
- }
118
- function isNodeRequest(request) {
119
- return isReadable(request);
120
- }
121
- function isServerResponse(stream) {
122
- // Check all used functions are defined
123
- return (stream != null &&
124
- stream.setHeader != null &&
125
- stream.end != null &&
126
- stream.once != null &&
127
- stream.write != null);
128
- }
129
- function isReadableStream(stream) {
130
- return stream != null && stream.getReader != null;
131
- }
132
- function isFetchEvent(event) {
133
- return event != null && event.request != null && event.respondWith != null;
134
- }
135
- function configureSocket(rawRequest) {
136
- var _a, _b, _c, _d, _e, _f;
137
- (_b = (_a = rawRequest === null || rawRequest === void 0 ? void 0 : rawRequest.socket) === null || _a === void 0 ? void 0 : _a.setTimeout) === null || _b === void 0 ? void 0 : _b.call(_a, 0);
138
- (_d = (_c = rawRequest === null || rawRequest === void 0 ? void 0 : rawRequest.socket) === null || _c === void 0 ? void 0 : _c.setNoDelay) === null || _d === void 0 ? void 0 : _d.call(_c, true);
139
- (_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
- }
141
- function endResponse(serverResponse) {
142
- // @ts-expect-error Avoid arguments adaptor trampoline https://v8.dev/blog/adaptor-frame
143
- serverResponse.end(null, null, null);
144
- }
145
- function getHeadersObj(headers) {
146
- return new Proxy({}, {
147
- get(_target, prop) {
148
- return headers.get(prop) || undefined;
149
- },
150
- set(_target, prop, value) {
151
- headers.set(prop, value);
152
- return true;
153
- },
154
- has(_target, prop) {
155
- return headers.has(prop);
156
- },
157
- deleteProperty(_target, prop) {
158
- headers.delete(prop);
159
- return true;
160
- },
161
- ownKeys() {
162
- const keys = [];
163
- headers.forEach((_, key) => keys.push(key));
164
- return keys;
165
- },
166
- getOwnPropertyDescriptor() {
167
- return {
168
- enumerable: true,
169
- configurable: true,
170
- };
171
- },
172
- });
173
- }
174
- async function sendNodeResponse(fetchResponse, serverResponse, nodeRequest) {
175
- const headersObj = getHeadersObj(fetchResponse.headers);
176
- serverResponse.writeHead(fetchResponse.status, fetchResponse.statusText, headersObj);
177
- // eslint-disable-next-line no-async-promise-executor
178
- return new Promise(async (resolve) => {
179
- serverResponse.once('close', resolve);
180
- // Our Node-fetch enhancements
181
- if ('bodyType' in fetchResponse &&
182
- fetchResponse.bodyType != null &&
183
- (fetchResponse.bodyType === 'String' || fetchResponse.bodyType === 'Uint8Array')) {
184
- // @ts-expect-error http and http2 writes are actually compatible
185
- serverResponse.write(fetchResponse.bodyInit);
186
- endResponse(serverResponse);
187
- return;
188
- }
189
- // Other fetch implementations
190
- const fetchBody = fetchResponse.body;
191
- if (fetchBody == null) {
192
- endResponse(serverResponse);
193
- return;
194
- }
195
- if (fetchBody[Symbol.toStringTag] === 'Uint8Array') {
196
- serverResponse
197
- // @ts-expect-error http and http2 writes are actually compatible
198
- .write(fetchBody);
199
- endResponse(serverResponse);
200
- return;
201
- }
202
- configureSocket(nodeRequest);
203
- if (isReadable(fetchBody)) {
204
- serverResponse.once('close', () => {
205
- fetchBody.destroy();
206
- });
207
- fetchBody.pipe(serverResponse);
208
- return;
209
- }
210
- if (isAsyncIterable(fetchBody)) {
211
- for await (const chunk of fetchBody) {
212
- if (!serverResponse
213
- // @ts-expect-error http and http2 writes are actually compatible
214
- .write(chunk)) {
215
- break;
216
- }
217
- }
218
- endResponse(serverResponse);
219
- }
220
- });
221
- }
222
- function isRequestInit(val) {
223
- return (val != null &&
224
- typeof val === 'object' &&
225
- ('body' in val ||
226
- 'cache' in val ||
227
- 'credentials' in val ||
228
- 'headers' in val ||
229
- 'integrity' in val ||
230
- 'keepalive' in val ||
231
- 'method' in val ||
232
- 'mode' in val ||
233
- 'redirect' in val ||
234
- 'referrer' in val ||
235
- 'referrerPolicy' in val ||
236
- 'signal' in val ||
237
- 'window' in val));
238
- }
239
-
240
- /* eslint-disable @typescript-eslint/ban-types */
241
- async function handleWaitUntils(waitUntilPromises) {
242
- const waitUntils = await Promise.allSettled(waitUntilPromises);
243
- waitUntils.forEach(waitUntil => {
244
- if (waitUntil.status === 'rejected') {
245
- console.error(waitUntil.reason);
246
- }
247
- });
248
- }
249
- // Required for envs like nextjs edge runtime
250
- function isRequestAccessible(serverContext) {
251
- try {
252
- return !!(serverContext === null || serverContext === void 0 ? void 0 : serverContext.request);
253
- }
254
- catch (_a) {
255
- return false;
256
- }
257
- }
258
- function createServerAdapter(serverAdapterBaseObject, options) {
259
- const fetchAPI = {
260
- ...DefaultFetchAPI,
261
- ...options === null || options === void 0 ? void 0 : options.fetchAPI,
262
- };
263
- const givenHandleRequest = typeof serverAdapterBaseObject === 'function'
264
- ? serverAdapterBaseObject
265
- : serverAdapterBaseObject.handle;
266
- const onRequestHooks = [];
267
- const onResponseHooks = [];
268
- if ((options === null || options === void 0 ? void 0 : options.plugins) != null) {
269
- for (const plugin of options.plugins) {
270
- if (plugin.onRequest) {
271
- onRequestHooks.push(plugin.onRequest);
272
- }
273
- if (plugin.onResponse) {
274
- onResponseHooks.push(plugin.onResponse);
275
- }
276
- }
277
- }
278
- async function handleRequest(request, serverContext) {
279
- let url = new Proxy({}, {
280
- get: (_target, prop, _receiver) => {
281
- url = new fetchAPI.URL(request.url, 'http://localhost');
282
- return Reflect.get(url, prop, url);
283
- },
284
- });
285
- let requestHandler = givenHandleRequest;
286
- let response;
287
- for (const onRequestHook of onRequestHooks) {
288
- await onRequestHook({
289
- request,
290
- serverContext,
291
- fetchAPI,
292
- url,
293
- requestHandler,
294
- setRequestHandler(newRequestHandler) {
295
- requestHandler = newRequestHandler;
296
- },
297
- endResponse(newResponse) {
298
- response = newResponse;
299
- },
300
- });
301
- if (response) {
302
- break;
303
- }
304
- }
305
- if (!response) {
306
- response = await requestHandler(request, serverContext);
307
- }
308
- for (const onResponseHook of onResponseHooks) {
309
- await onResponseHook({
310
- request,
311
- response,
312
- serverContext,
313
- });
314
- }
315
- return response;
316
- }
317
- function handleNodeRequest(nodeRequest, ...ctx) {
318
- const serverContext = ctx.length > 1 ? completeAssign({}, ...ctx) : ctx[0];
319
- const request = normalizeNodeRequest(nodeRequest, fetchAPI.Request);
320
- return handleRequest(request, serverContext);
321
- }
322
- async function requestListener(nodeRequest, serverResponse, ...ctx) {
323
- const waitUntilPromises = [];
324
- const defaultServerContext = {
325
- req: nodeRequest,
326
- res: serverResponse,
327
- waitUntil(promise) {
328
- if (promise != null) {
329
- waitUntilPromises.push(promise);
330
- }
331
- },
332
- };
333
- const response = await handleNodeRequest(nodeRequest, defaultServerContext, ...ctx);
334
- if (response) {
335
- await sendNodeResponse(response, serverResponse, nodeRequest);
336
- }
337
- else {
338
- await new Promise(resolve => {
339
- serverResponse.statusCode = 404;
340
- serverResponse.once('end', resolve);
341
- serverResponse.end();
342
- });
343
- }
344
- if (waitUntilPromises.length > 0) {
345
- await handleWaitUntils(waitUntilPromises);
346
- }
347
- }
348
- function handleEvent(event, ...ctx) {
349
- if (!event.respondWith || !event.request) {
350
- throw new TypeError(`Expected FetchEvent, got ${event}`);
351
- }
352
- const serverContext = ctx.length > 0 ? Object.assign({}, event, ...ctx) : event;
353
- const response$ = handleRequest(event.request, serverContext);
354
- event.respondWith(response$);
355
- }
356
- function handleRequestWithWaitUntil(request, ...ctx) {
357
- const serverContext = ctx.length > 1 ? completeAssign({}, ...ctx) : ctx[0] || {};
358
- if (!('waitUntil' in serverContext)) {
359
- const waitUntilPromises = [];
360
- const response$ = handleRequest(request, {
361
- ...serverContext,
362
- waitUntil(promise) {
363
- if (promise != null) {
364
- waitUntilPromises.push(promise);
365
- }
366
- },
367
- });
368
- if (waitUntilPromises.length > 0) {
369
- return handleWaitUntils(waitUntilPromises).then(() => response$);
370
- }
371
- return response$;
372
- }
373
- return handleRequest(request, serverContext);
374
- }
375
- const fetchFn = (input, ...maybeCtx) => {
376
- if (typeof input === 'string' || 'href' in input) {
377
- const [initOrCtx, ...restOfCtx] = maybeCtx;
378
- if (isRequestInit(initOrCtx)) {
379
- return handleRequestWithWaitUntil(new fetchAPI.Request(input, initOrCtx), ...restOfCtx);
380
- }
381
- return handleRequestWithWaitUntil(new fetchAPI.Request(input), ...maybeCtx);
382
- }
383
- return handleRequestWithWaitUntil(input, ...maybeCtx);
384
- };
385
- const genericRequestHandler = (input, ...maybeCtx) => {
386
- // If it is a Node request
387
- const [initOrCtxOrRes, ...restOfCtx] = maybeCtx;
388
- if (isNodeRequest(input)) {
389
- if (!isServerResponse(initOrCtxOrRes)) {
390
- throw new TypeError(`Expected ServerResponse, got ${initOrCtxOrRes}`);
391
- }
392
- return requestListener(input, initOrCtxOrRes, ...restOfCtx);
393
- }
394
- if (isServerResponse(initOrCtxOrRes)) {
395
- throw new TypeError('Got Node response without Node request');
396
- }
397
- // Is input a container object over Request?
398
- if (isRequestAccessible(input)) {
399
- // Is it FetchEvent?
400
- if (isFetchEvent(input)) {
401
- return handleEvent(input, ...maybeCtx);
402
- }
403
- // In this input is also the context
404
- return handleRequestWithWaitUntil(input.request, input, ...maybeCtx);
405
- }
406
- // Or is it Request itself?
407
- // Then ctx is present and it is the context
408
- return fetchFn(input, ...maybeCtx);
409
- };
410
- const adapterObj = {
411
- handleRequest,
412
- fetch: fetchFn,
413
- handleNodeRequest,
414
- requestListener,
415
- handleEvent,
416
- handle: genericRequestHandler,
417
- };
418
- const serverAdapter = new Proxy(genericRequestHandler, {
419
- // It should have all the attributes of the handler function and the server instance
420
- has: (_, prop) => {
421
- return (prop in adapterObj ||
422
- prop in genericRequestHandler ||
423
- (serverAdapterBaseObject && prop in serverAdapterBaseObject));
424
- },
425
- get: (_, prop) => {
426
- const adapterProp = adapterObj[prop];
427
- if (adapterProp) {
428
- if (adapterProp.bind) {
429
- return adapterProp.bind(adapterObj);
430
- }
431
- return adapterProp;
432
- }
433
- const handleProp = genericRequestHandler[prop];
434
- if (handleProp) {
435
- if (handleProp.bind) {
436
- return handleProp.bind(genericRequestHandler);
437
- }
438
- return handleProp;
439
- }
440
- if (serverAdapterBaseObject) {
441
- const serverAdapterBaseObjectProp = serverAdapterBaseObject[prop];
442
- if (serverAdapterBaseObjectProp) {
443
- if (serverAdapterBaseObjectProp.bind) {
444
- return function (...args) {
445
- const returnedVal = serverAdapterBaseObject[prop](...args);
446
- if (returnedVal === serverAdapterBaseObject) {
447
- return serverAdapter;
448
- }
449
- return returnedVal;
450
- };
451
- }
452
- return serverAdapterBaseObjectProp;
453
- }
454
- }
455
- },
456
- apply(_, __, args) {
457
- return genericRequestHandler(...args);
458
- },
459
- });
460
- return serverAdapter;
461
- }
462
- // from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#copying_accessors
463
- function completeAssign(target, ...sources) {
464
- sources.forEach(source => {
465
- if (source != null && typeof source === 'object') {
466
- // modified Object.keys to Object.getOwnPropertyNames
467
- // because Object.keys only returns enumerable properties
468
- const descriptors = Object.getOwnPropertyNames(source).reduce((descriptors, key) => {
469
- descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
470
- return descriptors;
471
- }, {});
472
- // By default, Object.assign copies enumerable Symbols, too
473
- Object.getOwnPropertySymbols(source).forEach(sym => {
474
- const descriptor = Object.getOwnPropertyDescriptor(source, sym);
475
- if (descriptor.enumerable) {
476
- descriptors[sym] = descriptor;
477
- }
478
- });
479
- Object.defineProperties(target, descriptors);
480
- }
481
- });
482
- return target;
483
- }
484
-
485
- function getCORSHeadersByRequestAndOptions(request, corsOptions) {
486
- var _a, _b;
487
- const currentOrigin = request.headers.get('origin');
488
- if (corsOptions === false || currentOrigin == null) {
489
- return null;
490
- }
491
- const headers = {};
492
- // If defined origins have '*' or undefined by any means, we should allow all origins
493
- if (corsOptions.origin == null ||
494
- corsOptions.origin.length === 0 ||
495
- corsOptions.origin.includes('*')) {
496
- headers['Access-Control-Allow-Origin'] = currentOrigin;
497
- // Vary by origin because there are multiple origins
498
- headers['Vary'] = 'Origin';
499
- }
500
- else if (typeof corsOptions.origin === 'string') {
501
- // If there is one specific origin is specified, use it directly
502
- headers['Access-Control-Allow-Origin'] = corsOptions.origin;
503
- }
504
- else if (Array.isArray(corsOptions.origin)) {
505
- // If there is only one origin defined in the array, consider it as a single one
506
- if (corsOptions.origin.length === 1) {
507
- headers['Access-Control-Allow-Origin'] = corsOptions.origin[0];
508
- }
509
- else if (corsOptions.origin.includes(currentOrigin)) {
510
- // If origin is available in the headers, use it
511
- headers['Access-Control-Allow-Origin'] = currentOrigin;
512
- // Vary by origin because there are multiple origins
513
- headers['Vary'] = 'Origin';
514
- }
515
- else {
516
- // There is no origin found in the headers, so we should return null
517
- headers['Access-Control-Allow-Origin'] = 'null';
518
- }
519
- }
520
- if ((_a = corsOptions.methods) === null || _a === void 0 ? void 0 : _a.length) {
521
- headers['Access-Control-Allow-Methods'] = corsOptions.methods.join(', ');
522
- }
523
- else {
524
- const requestMethod = request.headers.get('access-control-request-method');
525
- if (requestMethod) {
526
- headers['Access-Control-Allow-Methods'] = requestMethod;
527
- }
528
- }
529
- if ((_b = corsOptions.allowedHeaders) === null || _b === void 0 ? void 0 : _b.length) {
530
- headers['Access-Control-Allow-Headers'] = corsOptions.allowedHeaders.join(', ');
531
- }
532
- else {
533
- const requestHeaders = request.headers.get('access-control-request-headers');
534
- if (requestHeaders) {
535
- headers['Access-Control-Allow-Headers'] = requestHeaders;
536
- if (headers['Vary']) {
537
- headers['Vary'] += ', Access-Control-Request-Headers';
538
- }
539
- headers['Vary'] = 'Access-Control-Request-Headers';
540
- }
541
- }
542
- if (corsOptions.credentials != null) {
543
- if (corsOptions.credentials === true) {
544
- headers['Access-Control-Allow-Credentials'] = 'true';
545
- }
546
- }
547
- else if (headers['Access-Control-Allow-Origin'] !== '*') {
548
- headers['Access-Control-Allow-Credentials'] = 'true';
549
- }
550
- if (corsOptions.exposedHeaders) {
551
- headers['Access-Control-Expose-Headers'] = corsOptions.exposedHeaders.join(', ');
552
- }
553
- if (corsOptions.maxAge) {
554
- headers['Access-Control-Max-Age'] = corsOptions.maxAge.toString();
555
- }
556
- return headers;
557
- }
558
- async function getCORSResponseHeaders(request, corsOptionsFactory, serverContext) {
559
- const corsOptions = await corsOptionsFactory(request, serverContext);
560
- return getCORSHeadersByRequestAndOptions(request, corsOptions);
561
- }
562
- function useCORS(options) {
563
- let corsOptionsFactory = () => ({});
564
- if (options != null) {
565
- if (typeof options === 'function') {
566
- corsOptionsFactory = options;
567
- }
568
- else if (typeof options === 'object') {
569
- const corsOptions = {
570
- ...options,
571
- };
572
- corsOptionsFactory = () => corsOptions;
573
- }
574
- else if (options === false) {
575
- corsOptionsFactory = () => false;
576
- }
577
- }
578
- return {
579
- onRequest({ request, fetchAPI, endResponse }) {
580
- if (request.method.toUpperCase() === 'OPTIONS') {
581
- const response = new fetchAPI.Response(null, {
582
- status: 204,
583
- // Safari (and potentially other browsers) need content-length 0,
584
- // for 204 or they just hang waiting for a body
585
- // see: https://github.com/expressjs/cors/blob/master/lib/index.js#L176
586
- headers: {
587
- 'Content-Length': '0',
588
- },
589
- });
590
- endResponse(response);
591
- }
592
- },
593
- async onResponse({ request, serverContext, response }) {
594
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
595
- const headers = await getCORSResponseHeaders(request, corsOptionsFactory, serverContext);
596
- if (headers != null) {
597
- for (const headerName in headers) {
598
- response.headers.set(headerName, headers[headerName]);
599
- }
600
- }
601
- },
602
- };
603
- }
604
-
605
- function createDefaultErrorHandler(ResponseCtor = Response) {
606
- return function defaultErrorHandler(e) {
607
- return new ResponseCtor(typeof e.details === 'object'
608
- ? JSON.stringify(e.details)
609
- : e.stack || e.message || e.toString(), {
610
- status: e.statusCode || e.status || 500,
611
- headers: e.headers || {},
612
- });
613
- };
614
- }
615
- class HTTPError extends Error {
616
- constructor(status, message, headers = {}, details) {
617
- super(message);
618
- this.status = status;
619
- this.message = message;
620
- this.headers = headers;
621
- this.details = details;
622
- Error.captureStackTrace(this, HTTPError);
623
- }
624
- }
625
- function useErrorHandling(onError) {
626
- return {
627
- onRequest({ requestHandler, setRequestHandler, fetchAPI }) {
628
- const errorHandler = onError || createDefaultErrorHandler(fetchAPI.Response);
629
- setRequestHandler(async function handlerWithErrorHandling(request, serverContext) {
630
- try {
631
- const response = await requestHandler(request, serverContext);
632
- return response;
633
- }
634
- catch (e) {
635
- const response = await errorHandler(e, request, serverContext);
636
- return response;
637
- }
638
- });
639
- },
640
- };
641
- }
642
-
643
- export { HTTPError, createDefaultErrorHandler, createServerAdapter, getCORSHeadersByRequestAndOptions, getHeadersObj, isAsyncIterable, isFetchEvent, isNodeRequest, isReadable, isReadableStream, isRequestInit, isServerResponse, normalizeNodeRequest, sendNodeResponse, useCORS, useErrorHandling };
@@ -1,21 +0,0 @@
1
- import { FetchAPI, ServerAdapterRequestHandler } from '../types';
2
- export interface ServerAdapterPlugin<TServerContext = {}> {
3
- onRequest?: OnRequestHook<TServerContext>;
4
- onResponse?: OnResponseHook<TServerContext>;
5
- }
6
- export type OnRequestHook<TServerContext> = (payload: OnRequestEventPayload<TServerContext>) => Promise<void> | void;
7
- export interface OnRequestEventPayload<TServerContext> {
8
- request: Request;
9
- serverContext: TServerContext | undefined;
10
- fetchAPI: FetchAPI;
11
- requestHandler: ServerAdapterRequestHandler<TServerContext>;
12
- setRequestHandler(newRequestHandler: ServerAdapterRequestHandler<TServerContext>): void;
13
- endResponse(response: Response): void;
14
- url: URL;
15
- }
16
- export type OnResponseHook<TServerContext> = (payload: OnResponseEventPayload<TServerContext>) => Promise<void> | void;
17
- export interface OnResponseEventPayload<TServerContext> {
18
- request: Request;
19
- serverContext: TServerContext | undefined;
20
- response: Response;
21
- }
@@ -1,13 +0,0 @@
1
- import { ServerAdapterPlugin } from './types.js';
2
- export type CORSOptions = {
3
- origin?: string[] | string;
4
- methods?: string[];
5
- allowedHeaders?: string[];
6
- exposedHeaders?: string[];
7
- credentials?: boolean;
8
- maxAge?: number;
9
- } | false;
10
- export type CORSPluginOptions<TServerContext> = CORSOptionsFactory<TServerContext> | CORSOptions | boolean;
11
- export type CORSOptionsFactory<TServerContext> = (request: Request, ...args: {} extends TServerContext ? [serverContext?: TServerContext | undefined] : [serverContext: TServerContext]) => CORSOptions | Promise<CORSOptions>;
12
- export declare function getCORSHeadersByRequestAndOptions(request: Request, corsOptions: CORSOptions): Record<string, string> | null;
13
- export declare function useCORS<TServerContext>(options?: CORSPluginOptions<TServerContext>): ServerAdapterPlugin<TServerContext>;
@@ -1,11 +0,0 @@
1
- import { ServerAdapterPlugin } from './types';
2
- export declare function createDefaultErrorHandler<TServerContext = {}>(ResponseCtor?: typeof Response): ErrorHandler<TServerContext>;
3
- export declare class HTTPError extends Error {
4
- status: number;
5
- message: string;
6
- headers: HeadersInit;
7
- details?: any;
8
- constructor(status: number, message: string, headers?: HeadersInit, details?: any);
9
- }
10
- export type ErrorHandler<TServerContext> = (e: any, request: Request, ctx: TServerContext) => Response | Promise<Response>;
11
- export declare function useErrorHandling<TServerContext>(onError?: ErrorHandler<TServerContext>): ServerAdapterPlugin<TServerContext>;