@whatwg-node/server 0.7.4 → 0.7.5-alpha-20230320124321-e6b82e7
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/README.md +1 -1
- package/cjs/createServerAdapter.js +251 -0
- package/cjs/index.js +12 -0
- package/cjs/package.json +1 -0
- package/cjs/plugins/types.js +0 -0
- package/cjs/plugins/useCors.js +124 -0
- package/cjs/plugins/useErrorHandling.js +44 -0
- package/cjs/types.js +0 -0
- package/cjs/utils.js +248 -0
- package/esm/createServerAdapter.js +247 -0
- package/esm/index.js +7 -0
- package/esm/plugins/types.js +0 -0
- package/esm/plugins/useCors.js +119 -0
- package/esm/plugins/useErrorHandling.js +38 -0
- package/esm/types.js +0 -0
- package/esm/utils.js +235 -0
- package/package.json +20 -13
- package/typings/createServerAdapter.d.cts +9 -0
- package/{createServerAdapter.d.ts → typings/createServerAdapter.d.ts} +2 -2
- package/typings/index.d.cts +7 -0
- package/typings/index.d.ts +7 -0
- package/typings/plugins/types.d.cts +21 -0
- package/{plugins → typings/plugins}/types.d.ts +1 -1
- package/typings/plugins/useCors.d.cts +13 -0
- package/typings/plugins/useErrorHandling.d.cts +11 -0
- package/{plugins → typings/plugins}/useErrorHandling.d.ts +1 -1
- package/typings/types.d.cts +56 -0
- package/{types.d.ts → typings/types.d.ts} +1 -1
- package/typings/utils.d.cts +33 -0
- package/{utils.d.ts → typings/utils.d.ts} +1 -1
- package/index.d.ts +0 -7
- package/index.js +0 -666
- package/index.mjs +0 -643
- /package/{plugins → typings/plugins}/useCors.d.ts +0 -0
package/README.md
CHANGED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createServerAdapter = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
/* eslint-disable @typescript-eslint/ban-types */
|
|
6
|
+
const DefaultFetchAPI = tslib_1.__importStar(require("@whatwg-node/fetch"));
|
|
7
|
+
const utils_js_1 = require("./utils.js");
|
|
8
|
+
async function handleWaitUntils(waitUntilPromises) {
|
|
9
|
+
const waitUntils = await Promise.allSettled(waitUntilPromises);
|
|
10
|
+
waitUntils.forEach(waitUntil => {
|
|
11
|
+
if (waitUntil.status === 'rejected') {
|
|
12
|
+
console.error(waitUntil.reason);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
// Required for envs like nextjs edge runtime
|
|
17
|
+
function isRequestAccessible(serverContext) {
|
|
18
|
+
try {
|
|
19
|
+
return !!(serverContext === null || serverContext === void 0 ? void 0 : serverContext.request);
|
|
20
|
+
}
|
|
21
|
+
catch (_a) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function createServerAdapter(serverAdapterBaseObject, options) {
|
|
26
|
+
const fetchAPI = {
|
|
27
|
+
...DefaultFetchAPI,
|
|
28
|
+
...options === null || options === void 0 ? void 0 : options.fetchAPI,
|
|
29
|
+
};
|
|
30
|
+
const givenHandleRequest = typeof serverAdapterBaseObject === 'function'
|
|
31
|
+
? serverAdapterBaseObject
|
|
32
|
+
: serverAdapterBaseObject.handle;
|
|
33
|
+
const onRequestHooks = [];
|
|
34
|
+
const onResponseHooks = [];
|
|
35
|
+
if ((options === null || options === void 0 ? void 0 : options.plugins) != null) {
|
|
36
|
+
for (const plugin of options.plugins) {
|
|
37
|
+
if (plugin.onRequest) {
|
|
38
|
+
onRequestHooks.push(plugin.onRequest);
|
|
39
|
+
}
|
|
40
|
+
if (plugin.onResponse) {
|
|
41
|
+
onResponseHooks.push(plugin.onResponse);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async function handleRequest(request, serverContext) {
|
|
46
|
+
let url = new Proxy({}, {
|
|
47
|
+
get: (_target, prop, _receiver) => {
|
|
48
|
+
url = new fetchAPI.URL(request.url, 'http://localhost');
|
|
49
|
+
return Reflect.get(url, prop, url);
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
let requestHandler = givenHandleRequest;
|
|
53
|
+
let response;
|
|
54
|
+
for (const onRequestHook of onRequestHooks) {
|
|
55
|
+
await onRequestHook({
|
|
56
|
+
request,
|
|
57
|
+
serverContext,
|
|
58
|
+
fetchAPI,
|
|
59
|
+
url,
|
|
60
|
+
requestHandler,
|
|
61
|
+
setRequestHandler(newRequestHandler) {
|
|
62
|
+
requestHandler = newRequestHandler;
|
|
63
|
+
},
|
|
64
|
+
endResponse(newResponse) {
|
|
65
|
+
response = newResponse;
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
if (response) {
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (!response) {
|
|
73
|
+
response = await requestHandler(request, serverContext);
|
|
74
|
+
}
|
|
75
|
+
for (const onResponseHook of onResponseHooks) {
|
|
76
|
+
await onResponseHook({
|
|
77
|
+
request,
|
|
78
|
+
response,
|
|
79
|
+
serverContext,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return response;
|
|
83
|
+
}
|
|
84
|
+
function handleNodeRequest(nodeRequest, ...ctx) {
|
|
85
|
+
const serverContext = ctx.length > 1 ? completeAssign({}, ...ctx) : ctx[0];
|
|
86
|
+
const request = (0, utils_js_1.normalizeNodeRequest)(nodeRequest, fetchAPI.Request);
|
|
87
|
+
return handleRequest(request, serverContext);
|
|
88
|
+
}
|
|
89
|
+
async function requestListener(nodeRequest, serverResponse, ...ctx) {
|
|
90
|
+
const waitUntilPromises = [];
|
|
91
|
+
const defaultServerContext = {
|
|
92
|
+
req: nodeRequest,
|
|
93
|
+
res: serverResponse,
|
|
94
|
+
waitUntil(promise) {
|
|
95
|
+
if (promise != null) {
|
|
96
|
+
waitUntilPromises.push(promise);
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
const response = await handleNodeRequest(nodeRequest, defaultServerContext, ...ctx);
|
|
101
|
+
if (response) {
|
|
102
|
+
await (0, utils_js_1.sendNodeResponse)(response, serverResponse, nodeRequest);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
await new Promise(resolve => {
|
|
106
|
+
serverResponse.statusCode = 404;
|
|
107
|
+
serverResponse.once('end', resolve);
|
|
108
|
+
serverResponse.end();
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
if (waitUntilPromises.length > 0) {
|
|
112
|
+
await handleWaitUntils(waitUntilPromises);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function handleEvent(event, ...ctx) {
|
|
116
|
+
if (!event.respondWith || !event.request) {
|
|
117
|
+
throw new TypeError(`Expected FetchEvent, got ${event}`);
|
|
118
|
+
}
|
|
119
|
+
const serverContext = ctx.length > 0 ? Object.assign({}, event, ...ctx) : event;
|
|
120
|
+
const response$ = handleRequest(event.request, serverContext);
|
|
121
|
+
event.respondWith(response$);
|
|
122
|
+
}
|
|
123
|
+
function handleRequestWithWaitUntil(request, ...ctx) {
|
|
124
|
+
const serverContext = ctx.length > 1 ? completeAssign({}, ...ctx) : ctx[0] || {};
|
|
125
|
+
if (!('waitUntil' in serverContext)) {
|
|
126
|
+
const waitUntilPromises = [];
|
|
127
|
+
const response$ = handleRequest(request, {
|
|
128
|
+
...serverContext,
|
|
129
|
+
waitUntil(promise) {
|
|
130
|
+
if (promise != null) {
|
|
131
|
+
waitUntilPromises.push(promise);
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
if (waitUntilPromises.length > 0) {
|
|
136
|
+
return handleWaitUntils(waitUntilPromises).then(() => response$);
|
|
137
|
+
}
|
|
138
|
+
return response$;
|
|
139
|
+
}
|
|
140
|
+
return handleRequest(request, serverContext);
|
|
141
|
+
}
|
|
142
|
+
const fetchFn = (input, ...maybeCtx) => {
|
|
143
|
+
if (typeof input === 'string' || 'href' in input) {
|
|
144
|
+
const [initOrCtx, ...restOfCtx] = maybeCtx;
|
|
145
|
+
if ((0, utils_js_1.isRequestInit)(initOrCtx)) {
|
|
146
|
+
return handleRequestWithWaitUntil(new fetchAPI.Request(input, initOrCtx), ...restOfCtx);
|
|
147
|
+
}
|
|
148
|
+
return handleRequestWithWaitUntil(new fetchAPI.Request(input), ...maybeCtx);
|
|
149
|
+
}
|
|
150
|
+
return handleRequestWithWaitUntil(input, ...maybeCtx);
|
|
151
|
+
};
|
|
152
|
+
const genericRequestHandler = (input, ...maybeCtx) => {
|
|
153
|
+
// If it is a Node request
|
|
154
|
+
const [initOrCtxOrRes, ...restOfCtx] = maybeCtx;
|
|
155
|
+
if ((0, utils_js_1.isNodeRequest)(input)) {
|
|
156
|
+
if (!(0, utils_js_1.isServerResponse)(initOrCtxOrRes)) {
|
|
157
|
+
throw new TypeError(`Expected ServerResponse, got ${initOrCtxOrRes}`);
|
|
158
|
+
}
|
|
159
|
+
return requestListener(input, initOrCtxOrRes, ...restOfCtx);
|
|
160
|
+
}
|
|
161
|
+
if ((0, utils_js_1.isServerResponse)(initOrCtxOrRes)) {
|
|
162
|
+
throw new TypeError('Got Node response without Node request');
|
|
163
|
+
}
|
|
164
|
+
// Is input a container object over Request?
|
|
165
|
+
if (isRequestAccessible(input)) {
|
|
166
|
+
// Is it FetchEvent?
|
|
167
|
+
if ((0, utils_js_1.isFetchEvent)(input)) {
|
|
168
|
+
return handleEvent(input, ...maybeCtx);
|
|
169
|
+
}
|
|
170
|
+
// In this input is also the context
|
|
171
|
+
return handleRequestWithWaitUntil(input.request, input, ...maybeCtx);
|
|
172
|
+
}
|
|
173
|
+
// Or is it Request itself?
|
|
174
|
+
// Then ctx is present and it is the context
|
|
175
|
+
return fetchFn(input, ...maybeCtx);
|
|
176
|
+
};
|
|
177
|
+
const adapterObj = {
|
|
178
|
+
handleRequest,
|
|
179
|
+
fetch: fetchFn,
|
|
180
|
+
handleNodeRequest,
|
|
181
|
+
requestListener,
|
|
182
|
+
handleEvent,
|
|
183
|
+
handle: genericRequestHandler,
|
|
184
|
+
};
|
|
185
|
+
const serverAdapter = new Proxy(genericRequestHandler, {
|
|
186
|
+
// It should have all the attributes of the handler function and the server instance
|
|
187
|
+
has: (_, prop) => {
|
|
188
|
+
return (prop in adapterObj ||
|
|
189
|
+
prop in genericRequestHandler ||
|
|
190
|
+
(serverAdapterBaseObject && prop in serverAdapterBaseObject));
|
|
191
|
+
},
|
|
192
|
+
get: (_, prop) => {
|
|
193
|
+
const adapterProp = adapterObj[prop];
|
|
194
|
+
if (adapterProp) {
|
|
195
|
+
if (adapterProp.bind) {
|
|
196
|
+
return adapterProp.bind(adapterObj);
|
|
197
|
+
}
|
|
198
|
+
return adapterProp;
|
|
199
|
+
}
|
|
200
|
+
const handleProp = genericRequestHandler[prop];
|
|
201
|
+
if (handleProp) {
|
|
202
|
+
if (handleProp.bind) {
|
|
203
|
+
return handleProp.bind(genericRequestHandler);
|
|
204
|
+
}
|
|
205
|
+
return handleProp;
|
|
206
|
+
}
|
|
207
|
+
if (serverAdapterBaseObject) {
|
|
208
|
+
const serverAdapterBaseObjectProp = serverAdapterBaseObject[prop];
|
|
209
|
+
if (serverAdapterBaseObjectProp) {
|
|
210
|
+
if (serverAdapterBaseObjectProp.bind) {
|
|
211
|
+
return function (...args) {
|
|
212
|
+
const returnedVal = serverAdapterBaseObject[prop](...args);
|
|
213
|
+
if (returnedVal === serverAdapterBaseObject) {
|
|
214
|
+
return serverAdapter;
|
|
215
|
+
}
|
|
216
|
+
return returnedVal;
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
return serverAdapterBaseObjectProp;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
apply(_, __, args) {
|
|
224
|
+
return genericRequestHandler(...args);
|
|
225
|
+
},
|
|
226
|
+
});
|
|
227
|
+
return serverAdapter;
|
|
228
|
+
}
|
|
229
|
+
exports.createServerAdapter = createServerAdapter;
|
|
230
|
+
// from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#copying_accessors
|
|
231
|
+
function completeAssign(target, ...sources) {
|
|
232
|
+
sources.forEach(source => {
|
|
233
|
+
if (source != null && typeof source === 'object') {
|
|
234
|
+
// modified Object.keys to Object.getOwnPropertyNames
|
|
235
|
+
// because Object.keys only returns enumerable properties
|
|
236
|
+
const descriptors = Object.getOwnPropertyNames(source).reduce((descriptors, key) => {
|
|
237
|
+
descriptors[key] = Object.getOwnPropertyDescriptor(source, key);
|
|
238
|
+
return descriptors;
|
|
239
|
+
}, {});
|
|
240
|
+
// By default, Object.assign copies enumerable Symbols, too
|
|
241
|
+
Object.getOwnPropertySymbols(source).forEach(sym => {
|
|
242
|
+
const descriptor = Object.getOwnPropertyDescriptor(source, sym);
|
|
243
|
+
if (descriptor.enumerable) {
|
|
244
|
+
descriptors[sym] = descriptor;
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
Object.defineProperties(target, descriptors);
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
return target;
|
|
251
|
+
}
|
package/cjs/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Response = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
tslib_1.__exportStar(require("./createServerAdapter.js"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./types.js"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./utils.js"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./plugins/types.js"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./plugins/useCors.js"), exports);
|
|
10
|
+
tslib_1.__exportStar(require("./plugins/useErrorHandling.js"), exports);
|
|
11
|
+
var fetch_1 = require("@whatwg-node/fetch");
|
|
12
|
+
Object.defineProperty(exports, "Response", { enumerable: true, get: function () { return fetch_1.Response; } });
|
package/cjs/package.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
File without changes
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useCORS = exports.getCORSHeadersByRequestAndOptions = void 0;
|
|
4
|
+
function getCORSHeadersByRequestAndOptions(request, corsOptions) {
|
|
5
|
+
var _a, _b;
|
|
6
|
+
const currentOrigin = request.headers.get('origin');
|
|
7
|
+
if (corsOptions === false || currentOrigin == null) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const headers = {};
|
|
11
|
+
// If defined origins have '*' or undefined by any means, we should allow all origins
|
|
12
|
+
if (corsOptions.origin == null ||
|
|
13
|
+
corsOptions.origin.length === 0 ||
|
|
14
|
+
corsOptions.origin.includes('*')) {
|
|
15
|
+
headers['Access-Control-Allow-Origin'] = currentOrigin;
|
|
16
|
+
// Vary by origin because there are multiple origins
|
|
17
|
+
headers['Vary'] = 'Origin';
|
|
18
|
+
}
|
|
19
|
+
else if (typeof corsOptions.origin === 'string') {
|
|
20
|
+
// If there is one specific origin is specified, use it directly
|
|
21
|
+
headers['Access-Control-Allow-Origin'] = corsOptions.origin;
|
|
22
|
+
}
|
|
23
|
+
else if (Array.isArray(corsOptions.origin)) {
|
|
24
|
+
// If there is only one origin defined in the array, consider it as a single one
|
|
25
|
+
if (corsOptions.origin.length === 1) {
|
|
26
|
+
headers['Access-Control-Allow-Origin'] = corsOptions.origin[0];
|
|
27
|
+
}
|
|
28
|
+
else if (corsOptions.origin.includes(currentOrigin)) {
|
|
29
|
+
// If origin is available in the headers, use it
|
|
30
|
+
headers['Access-Control-Allow-Origin'] = currentOrigin;
|
|
31
|
+
// Vary by origin because there are multiple origins
|
|
32
|
+
headers['Vary'] = 'Origin';
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// There is no origin found in the headers, so we should return null
|
|
36
|
+
headers['Access-Control-Allow-Origin'] = 'null';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if ((_a = corsOptions.methods) === null || _a === void 0 ? void 0 : _a.length) {
|
|
40
|
+
headers['Access-Control-Allow-Methods'] = corsOptions.methods.join(', ');
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const requestMethod = request.headers.get('access-control-request-method');
|
|
44
|
+
if (requestMethod) {
|
|
45
|
+
headers['Access-Control-Allow-Methods'] = requestMethod;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if ((_b = corsOptions.allowedHeaders) === null || _b === void 0 ? void 0 : _b.length) {
|
|
49
|
+
headers['Access-Control-Allow-Headers'] = corsOptions.allowedHeaders.join(', ');
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const requestHeaders = request.headers.get('access-control-request-headers');
|
|
53
|
+
if (requestHeaders) {
|
|
54
|
+
headers['Access-Control-Allow-Headers'] = requestHeaders;
|
|
55
|
+
if (headers['Vary']) {
|
|
56
|
+
headers['Vary'] += ', Access-Control-Request-Headers';
|
|
57
|
+
}
|
|
58
|
+
headers['Vary'] = 'Access-Control-Request-Headers';
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (corsOptions.credentials != null) {
|
|
62
|
+
if (corsOptions.credentials === true) {
|
|
63
|
+
headers['Access-Control-Allow-Credentials'] = 'true';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
else if (headers['Access-Control-Allow-Origin'] !== '*') {
|
|
67
|
+
headers['Access-Control-Allow-Credentials'] = 'true';
|
|
68
|
+
}
|
|
69
|
+
if (corsOptions.exposedHeaders) {
|
|
70
|
+
headers['Access-Control-Expose-Headers'] = corsOptions.exposedHeaders.join(', ');
|
|
71
|
+
}
|
|
72
|
+
if (corsOptions.maxAge) {
|
|
73
|
+
headers['Access-Control-Max-Age'] = corsOptions.maxAge.toString();
|
|
74
|
+
}
|
|
75
|
+
return headers;
|
|
76
|
+
}
|
|
77
|
+
exports.getCORSHeadersByRequestAndOptions = getCORSHeadersByRequestAndOptions;
|
|
78
|
+
async function getCORSResponseHeaders(request, corsOptionsFactory, serverContext) {
|
|
79
|
+
const corsOptions = await corsOptionsFactory(request, serverContext);
|
|
80
|
+
return getCORSHeadersByRequestAndOptions(request, corsOptions);
|
|
81
|
+
}
|
|
82
|
+
function useCORS(options) {
|
|
83
|
+
let corsOptionsFactory = () => ({});
|
|
84
|
+
if (options != null) {
|
|
85
|
+
if (typeof options === 'function') {
|
|
86
|
+
corsOptionsFactory = options;
|
|
87
|
+
}
|
|
88
|
+
else if (typeof options === 'object') {
|
|
89
|
+
const corsOptions = {
|
|
90
|
+
...options,
|
|
91
|
+
};
|
|
92
|
+
corsOptionsFactory = () => corsOptions;
|
|
93
|
+
}
|
|
94
|
+
else if (options === false) {
|
|
95
|
+
corsOptionsFactory = () => false;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
onRequest({ request, fetchAPI, endResponse }) {
|
|
100
|
+
if (request.method.toUpperCase() === 'OPTIONS') {
|
|
101
|
+
const response = new fetchAPI.Response(null, {
|
|
102
|
+
status: 204,
|
|
103
|
+
// Safari (and potentially other browsers) need content-length 0,
|
|
104
|
+
// for 204 or they just hang waiting for a body
|
|
105
|
+
// see: https://github.com/expressjs/cors/blob/master/lib/index.js#L176
|
|
106
|
+
headers: {
|
|
107
|
+
'Content-Length': '0',
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
endResponse(response);
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
async onResponse({ request, serverContext, response }) {
|
|
114
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
115
|
+
const headers = await getCORSResponseHeaders(request, corsOptionsFactory, serverContext);
|
|
116
|
+
if (headers != null) {
|
|
117
|
+
for (const headerName in headers) {
|
|
118
|
+
response.headers.set(headerName, headers[headerName]);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
exports.useCORS = useCORS;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useErrorHandling = exports.HTTPError = exports.createDefaultErrorHandler = void 0;
|
|
4
|
+
const fetch_1 = require("@whatwg-node/fetch");
|
|
5
|
+
function createDefaultErrorHandler(ResponseCtor = fetch_1.Response) {
|
|
6
|
+
return function defaultErrorHandler(e) {
|
|
7
|
+
return new ResponseCtor(typeof e.details === 'object'
|
|
8
|
+
? JSON.stringify(e.details)
|
|
9
|
+
: e.stack || e.message || e.toString(), {
|
|
10
|
+
status: e.statusCode || e.status || 500,
|
|
11
|
+
headers: e.headers || {},
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
exports.createDefaultErrorHandler = createDefaultErrorHandler;
|
|
16
|
+
class HTTPError extends Error {
|
|
17
|
+
constructor(status, message, headers = {}, details) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.status = status;
|
|
20
|
+
this.message = message;
|
|
21
|
+
this.headers = headers;
|
|
22
|
+
this.details = details;
|
|
23
|
+
Error.captureStackTrace(this, HTTPError);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.HTTPError = HTTPError;
|
|
27
|
+
function useErrorHandling(onError) {
|
|
28
|
+
return {
|
|
29
|
+
onRequest({ requestHandler, setRequestHandler, fetchAPI }) {
|
|
30
|
+
const errorHandler = onError || createDefaultErrorHandler(fetchAPI.Response);
|
|
31
|
+
setRequestHandler(async function handlerWithErrorHandling(request, serverContext) {
|
|
32
|
+
try {
|
|
33
|
+
const response = await requestHandler(request, serverContext);
|
|
34
|
+
return response;
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
const response = await errorHandler(e, request, serverContext);
|
|
38
|
+
return response;
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
exports.useErrorHandling = useErrorHandling;
|
package/cjs/types.js
ADDED
|
File without changes
|