@webiny/handler 0.0.0-unstable.de38392959 → 0.0.0-unstable.df7a8bb475
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/Context.d.ts +4 -3
- package/Context.js +6 -14
- package/Context.js.map +1 -1
- package/PreHandler/IPreHandler.d.ts +9 -0
- package/PreHandler/IPreHandler.js +7 -0
- package/PreHandler/IPreHandler.js.map +1 -0
- package/PreHandler/IfNotOptionsRequest.d.ts +9 -0
- package/PreHandler/IfNotOptionsRequest.js +21 -0
- package/PreHandler/IfNotOptionsRequest.js.map +1 -0
- package/PreHandler/IfOptionsRequest.d.ts +9 -0
- package/PreHandler/IfOptionsRequest.js +21 -0
- package/PreHandler/IfOptionsRequest.js.map +1 -0
- package/PreHandler/PreHandler.d.ts +9 -0
- package/PreHandler/PreHandler.js +17 -0
- package/PreHandler/PreHandler.js.map +1 -0
- package/PreHandler/ProcessBeforeHandlerPlugins.d.ts +10 -0
- package/PreHandler/ProcessBeforeHandlerPlugins.js +24 -0
- package/PreHandler/ProcessBeforeHandlerPlugins.js.map +1 -0
- package/PreHandler/ProcessContextPlugins.d.ts +10 -0
- package/PreHandler/ProcessContextPlugins.js +24 -0
- package/PreHandler/ProcessContextPlugins.js.map +1 -0
- package/PreHandler/ProcessHandlerOnRequestPlugins.d.ts +10 -0
- package/PreHandler/ProcessHandlerOnRequestPlugins.js +26 -0
- package/PreHandler/ProcessHandlerOnRequestPlugins.js.map +1 -0
- package/PreHandler/SendEarlyOptionsResponse.d.ts +9 -0
- package/PreHandler/SendEarlyOptionsResponse.js +31 -0
- package/PreHandler/SendEarlyOptionsResponse.js.map +1 -0
- package/PreHandler/SetDefaultHeaders.d.ts +9 -0
- package/PreHandler/SetDefaultHeaders.js +57 -0
- package/PreHandler/SetDefaultHeaders.js.map +1 -0
- package/README.md +10 -14
- package/ResponseHeaders.d.ts +6 -7
- package/ResponseHeaders.js +1 -8
- package/ResponseHeaders.js.map +1 -1
- package/abstractions/Reply.d.ts +5 -0
- package/abstractions/Reply.js +4 -0
- package/abstractions/Reply.js.map +1 -0
- package/abstractions/Request.d.ts +5 -0
- package/abstractions/Request.js +4 -0
- package/abstractions/Request.js.map +1 -0
- package/fastify.d.ts +6 -4
- package/fastify.js +177 -193
- package/fastify.js.map +1 -1
- package/index.d.ts +17 -12
- package/index.js +18 -126
- package/index.js.map +1 -1
- package/package.json +16 -24
- package/plugins/BeforeHandlerPlugin.d.ts +1 -1
- package/plugins/BeforeHandlerPlugin.js +3 -11
- package/plugins/BeforeHandlerPlugin.js.map +1 -1
- package/plugins/EventPlugin.d.ts +3 -3
- package/plugins/EventPlugin.js +3 -12
- package/plugins/EventPlugin.js.map +1 -1
- package/plugins/HandlerErrorPlugin.d.ts +1 -1
- package/plugins/HandlerErrorPlugin.js +3 -11
- package/plugins/HandlerErrorPlugin.js.map +1 -1
- package/plugins/HandlerOnRequestPlugin.d.ts +9 -8
- package/plugins/HandlerOnRequestPlugin.js +5 -12
- package/plugins/HandlerOnRequestPlugin.js.map +1 -1
- package/plugins/HandlerResultPlugin.d.ts +1 -1
- package/plugins/HandlerResultPlugin.js +3 -11
- package/plugins/HandlerResultPlugin.js.map +1 -1
- package/plugins/ModifyFastifyPlugin.d.ts +2 -2
- package/plugins/ModifyFastifyPlugin.js +3 -11
- package/plugins/ModifyFastifyPlugin.js.map +1 -1
- package/plugins/ModifyResponseHeadersPlugin.d.ts +3 -3
- package/plugins/ModifyResponseHeadersPlugin.js +3 -11
- package/plugins/ModifyResponseHeadersPlugin.js.map +1 -1
- package/plugins/OnRequestResponseSendPlugin.d.ts +26 -0
- package/plugins/OnRequestResponseSendPlugin.js +31 -0
- package/plugins/OnRequestResponseSendPlugin.js.map +1 -0
- package/plugins/OnRequestTimeoutPlugin.d.ts +12 -0
- package/plugins/OnRequestTimeoutPlugin.js +16 -0
- package/plugins/OnRequestTimeoutPlugin.js.map +1 -0
- package/plugins/RoutePlugin.d.ts +2 -2
- package/plugins/RoutePlugin.js +3 -11
- package/plugins/RoutePlugin.js.map +1 -1
- package/stringifyError.d.ts +5 -0
- package/stringifyError.js +20 -0
- package/stringifyError.js.map +1 -0
- package/suppressPunycodeWarnings.d.ts +1 -0
- package/suppressPunycodeWarnings.js +10 -0
- package/suppressPunycodeWarnings.js.map +1 -0
- package/types.d.ts +9 -7
- package/types.js +1 -19
- package/types.js.map +1 -1
- package/middleware.d.ts +0 -7
- package/middleware.js +0 -47
- package/middleware.js.map +0 -1
package/fastify.d.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { FastifyServerOptions as ServerOptions } from "fastify";
|
|
1
|
+
import type { PluginCollection } from "@webiny/plugins/types.js";
|
|
2
|
+
import { PluginsContainer } from "@webiny/plugins/types.js";
|
|
3
|
+
import type { FastifyInstance, FastifyServerOptions as ServerOptions } from "fastify";
|
|
4
4
|
export interface CreateHandlerParams {
|
|
5
5
|
plugins: PluginCollection | PluginsContainer;
|
|
6
6
|
options?: ServerOptions;
|
|
7
7
|
debug?: boolean;
|
|
8
8
|
}
|
|
9
|
-
export declare const createHandler: (params: CreateHandlerParams) =>
|
|
9
|
+
export declare const createHandler: (params: CreateHandlerParams) => FastifyInstance<import("fastify").RawServerDefault, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault> & PromiseLike<FastifyInstance<import("fastify").RawServerDefault, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault>> & {
|
|
10
|
+
__linterBrands: "SafePromiseLike";
|
|
11
|
+
};
|
package/fastify.js
CHANGED
|
@@ -1,84 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return _ResponseHeaders.ResponseHeaders.create({
|
|
38
|
-
"access-control-max-age": "86400",
|
|
39
|
-
"cache-control": "public, max-age=86400"
|
|
1
|
+
import { PluginsContainer } from "@webiny/plugins/types.js";
|
|
2
|
+
import fastify from "fastify";
|
|
3
|
+
import { middleware } from "@webiny/utils";
|
|
4
|
+
import { Context } from "./Context.js";
|
|
5
|
+
import WebinyError from "@webiny/error";
|
|
6
|
+
import { RoutePlugin } from "./plugins/RoutePlugin.js";
|
|
7
|
+
import { createHandlerClient } from "@webiny/handler-client";
|
|
8
|
+
import fastifyCookie from "@fastify/cookie";
|
|
9
|
+
import fastifyCompress from "@fastify/compress";
|
|
10
|
+
import { ContextPlugin } from "@webiny/api";
|
|
11
|
+
import { BeforeHandlerPlugin } from "./plugins/BeforeHandlerPlugin.js";
|
|
12
|
+
import { HandlerResultPlugin } from "./plugins/HandlerResultPlugin.js";
|
|
13
|
+
import { HandlerErrorPlugin } from "./plugins/HandlerErrorPlugin.js";
|
|
14
|
+
import { ModifyFastifyPlugin } from "./plugins/ModifyFastifyPlugin.js";
|
|
15
|
+
import { HandlerOnRequestPlugin } from "./plugins/HandlerOnRequestPlugin.js";
|
|
16
|
+
import { ResponseHeaders } from "./ResponseHeaders.js";
|
|
17
|
+
import { ModifyResponseHeadersPlugin } from "./plugins/ModifyResponseHeadersPlugin.js";
|
|
18
|
+
import { SetDefaultHeaders } from "./PreHandler/SetDefaultHeaders.js";
|
|
19
|
+
import { PreHandler } from "./PreHandler/PreHandler.js";
|
|
20
|
+
import { stringifyError } from "./stringifyError.js";
|
|
21
|
+
import { ProcessHandlerOnRequestPlugins } from "./PreHandler/ProcessHandlerOnRequestPlugins.js";
|
|
22
|
+
import { ProcessContextPlugins } from "./PreHandler/ProcessContextPlugins.js";
|
|
23
|
+
import { IfNotOptionsRequest } from "./PreHandler/IfNotOptionsRequest.js";
|
|
24
|
+
import { ProcessBeforeHandlerPlugins } from "./PreHandler/ProcessBeforeHandlerPlugins.js";
|
|
25
|
+
import { IfOptionsRequest } from "./PreHandler/IfOptionsRequest.js";
|
|
26
|
+
import { SendEarlyOptionsResponse } from "./PreHandler/SendEarlyOptionsResponse.js";
|
|
27
|
+
import { OnRequestTimeoutPlugin } from "./plugins/OnRequestTimeoutPlugin.js";
|
|
28
|
+
import { OnRequestResponseSendPlugin } from "./plugins/OnRequestResponseSendPlugin.js";
|
|
29
|
+
import { Request } from "./abstractions/Request.js";
|
|
30
|
+
import { Reply } from "./abstractions/Reply.js";
|
|
31
|
+
const modifyResponseHeaders = (app, request, reply) => {
|
|
32
|
+
const modifyHeaders = app.webiny.plugins.byType(ModifyResponseHeadersPlugin.type);
|
|
33
|
+
const replyHeaders = reply.getHeaders();
|
|
34
|
+
const headers = ResponseHeaders.create(replyHeaders);
|
|
35
|
+
modifyHeaders.forEach(plugin => {
|
|
36
|
+
plugin.modify(request, headers);
|
|
40
37
|
});
|
|
41
|
-
};
|
|
42
|
-
const getDefaultHeaders = routes => {
|
|
43
|
-
const headers = createDefaultHeaders();
|
|
44
38
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (all) {
|
|
51
|
-
headers.set("access-control-allow-methods", "*");
|
|
52
|
-
} else {
|
|
53
|
-
const allowedMethods = keys.filter(type => {
|
|
54
|
-
if (!routes[type] || !Array.isArray(routes[type])) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
return routes[type].length > 0;
|
|
58
|
-
}).sort().join(",");
|
|
59
|
-
headers.set("access-control-allow-methods", allowedMethods);
|
|
60
|
-
}
|
|
61
|
-
return headers;
|
|
62
|
-
};
|
|
63
|
-
const stringifyError = error => {
|
|
64
|
-
const {
|
|
65
|
-
name,
|
|
66
|
-
message,
|
|
67
|
-
code,
|
|
68
|
-
stack,
|
|
69
|
-
data
|
|
70
|
-
} = error;
|
|
71
|
-
return JSON.stringify({
|
|
72
|
-
...error,
|
|
73
|
-
constructorName: error.constructor?.name || "UnknownError",
|
|
74
|
-
name: name || "No error name",
|
|
75
|
-
message: message || "No error message",
|
|
76
|
-
code: code || "NO_CODE",
|
|
77
|
-
data,
|
|
78
|
-
stack: process.env.DEBUG === "true" ? stack : "Turn on the debug flag to see the stack."
|
|
79
|
-
});
|
|
39
|
+
// Exclude 'set-cookie' header to avoid duplication.
|
|
40
|
+
// Cookies are managed by @fastify/cookie and calling reply.headers() with 'set-cookie' duplicates them.
|
|
41
|
+
const headersToSet = headers.getHeaders();
|
|
42
|
+
delete headersToSet["set-cookie"];
|
|
43
|
+
reply.headers(headersToSet);
|
|
80
44
|
};
|
|
81
|
-
const createHandler = params => {
|
|
45
|
+
export const createHandler = params => {
|
|
82
46
|
const definedRoutes = {
|
|
83
47
|
POST: [],
|
|
84
48
|
GET: [],
|
|
@@ -95,11 +59,14 @@ const createHandler = params => {
|
|
|
95
59
|
PROPPATCH: [],
|
|
96
60
|
SEARCH: [],
|
|
97
61
|
TRACE: [],
|
|
98
|
-
UNLOCK: []
|
|
62
|
+
UNLOCK: [],
|
|
63
|
+
REPORT: [],
|
|
64
|
+
MKCALENDAR: []
|
|
99
65
|
};
|
|
100
66
|
const throwOnDefinedRoute = (type, path, options) => {
|
|
101
67
|
if (type === "ALL") {
|
|
102
|
-
const all = Object.keys(definedRoutes).find(
|
|
68
|
+
const all = Object.keys(definedRoutes).find(k => {
|
|
69
|
+
const key = k.toUpperCase();
|
|
103
70
|
const routes = definedRoutes[key];
|
|
104
71
|
return routes.includes(path);
|
|
105
72
|
});
|
|
@@ -108,7 +75,7 @@ const createHandler = params => {
|
|
|
108
75
|
}
|
|
109
76
|
console.error(`Error while registering onAll route. One of the routes is already defined.`);
|
|
110
77
|
console.error(JSON.stringify(all));
|
|
111
|
-
throw new
|
|
78
|
+
throw new WebinyError(`You cannot override a route with onAll() method, please remove unnecessary route from the system.`, "OVERRIDE_ROUTE_ERROR", {
|
|
112
79
|
type,
|
|
113
80
|
path
|
|
114
81
|
});
|
|
@@ -118,12 +85,13 @@ const createHandler = params => {
|
|
|
118
85
|
return;
|
|
119
86
|
}
|
|
120
87
|
console.error(`Error while trying to override route: [${type}] ${path}`);
|
|
121
|
-
throw new
|
|
88
|
+
throw new WebinyError(`When you are trying to override existing route, you must send "override" parameter when adding that route.`, "OVERRIDE_ROUTE_ERROR", {
|
|
122
89
|
type,
|
|
123
90
|
path
|
|
124
91
|
});
|
|
125
92
|
};
|
|
126
|
-
const addDefinedRoute = (
|
|
93
|
+
const addDefinedRoute = (input, path) => {
|
|
94
|
+
const type = input.toUpperCase();
|
|
127
95
|
if (!definedRoutes[type]) {
|
|
128
96
|
return;
|
|
129
97
|
} else if (definedRoutes[type].includes(path)) {
|
|
@@ -131,16 +99,20 @@ const createHandler = params => {
|
|
|
131
99
|
}
|
|
132
100
|
definedRoutes[type].push(path);
|
|
133
101
|
};
|
|
102
|
+
|
|
134
103
|
/**
|
|
135
104
|
* We must attach the server to our internal context if we want to have it accessible.
|
|
136
105
|
*/
|
|
137
|
-
const app = (
|
|
138
|
-
bodyLimit:
|
|
139
|
-
//
|
|
106
|
+
const app = fastify({
|
|
107
|
+
bodyLimit: 536870912,
|
|
108
|
+
// 512MB
|
|
109
|
+
disableRequestLogging: true,
|
|
110
|
+
allowErrorHandlerOverride: true,
|
|
140
111
|
...(params.options || {})
|
|
141
112
|
});
|
|
113
|
+
|
|
142
114
|
/**
|
|
143
|
-
* We need to register routes in our system
|
|
115
|
+
* We need to register routes in our system to output headers later on, and disallow route overriding.
|
|
144
116
|
*/
|
|
145
117
|
app.addHook("onRoute", route => {
|
|
146
118
|
const method = route.method;
|
|
@@ -161,7 +133,7 @@ const createHandler = params => {
|
|
|
161
133
|
*
|
|
162
134
|
* https://github.com/fastify/fastify-cookie
|
|
163
135
|
*/
|
|
164
|
-
app.register(
|
|
136
|
+
app.register(fastifyCookie, {
|
|
165
137
|
parseOptions: {} // options for parsing cookies
|
|
166
138
|
});
|
|
167
139
|
/**
|
|
@@ -169,7 +141,7 @@ const createHandler = params => {
|
|
|
169
141
|
*
|
|
170
142
|
* https://github.com/fastify/fastify-compress
|
|
171
143
|
*/
|
|
172
|
-
app.register(
|
|
144
|
+
app.register(fastifyCompress, {
|
|
173
145
|
global: true,
|
|
174
146
|
threshold: 1024,
|
|
175
147
|
onUnsupportedEncoding: (encoding, _, reply) => {
|
|
@@ -217,15 +189,15 @@ const createHandler = params => {
|
|
|
217
189
|
}
|
|
218
190
|
};
|
|
219
191
|
let context;
|
|
220
|
-
const plugins = new
|
|
192
|
+
const plugins = new PluginsContainer([
|
|
221
193
|
/**
|
|
222
194
|
* We must have handlerClient by default.
|
|
223
195
|
* And it must be one of the first context plugins applied.
|
|
224
196
|
*/
|
|
225
|
-
|
|
197
|
+
createHandlerClient()]);
|
|
226
198
|
plugins.merge(params.plugins || []);
|
|
227
199
|
try {
|
|
228
|
-
context = new
|
|
200
|
+
context = new Context({
|
|
229
201
|
plugins,
|
|
230
202
|
/**
|
|
231
203
|
* Inserted via webpack at build time.
|
|
@@ -245,94 +217,68 @@ const createHandler = params => {
|
|
|
245
217
|
app.decorate("webiny", context);
|
|
246
218
|
|
|
247
219
|
/**
|
|
248
|
-
*
|
|
249
|
-
*
|
|
220
|
+
* To prevent Unsupported Media Type errors on OPTIONS requests with a body,
|
|
221
|
+
* we need to have a custom parser
|
|
250
222
|
*/
|
|
251
|
-
app.
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const initialHeaders = isOptionsRequest ? defaultHeaders.merge(getDefaultOptionsHeaders()) : defaultHeaders;
|
|
258
|
-
reply.headers(initialHeaders.getHeaders());
|
|
259
|
-
/**
|
|
260
|
-
* Users can define their own custom handlers for the onRequest event - so let's run them first.
|
|
261
|
-
*/
|
|
262
|
-
const plugins = app.webiny.plugins.byType(_HandlerOnRequestPlugin.HandlerOnRequestPlugin.type);
|
|
263
|
-
let name;
|
|
264
|
-
try {
|
|
265
|
-
for (const plugin of plugins) {
|
|
266
|
-
name = plugin.name;
|
|
267
|
-
const result = await plugin.exec(request, reply);
|
|
268
|
-
if (result === false) {
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
} catch (ex) {
|
|
273
|
-
console.error(`Error while running the "HandlerOnRequestPlugin" ${name ? `(${name})` : ""} plugin in the onRequest hook.`);
|
|
274
|
-
console.error(stringifyError(ex));
|
|
275
|
-
throw ex;
|
|
276
|
-
}
|
|
277
|
-
/**
|
|
278
|
-
* When we receive the OPTIONS request, we end it before it goes any further as there is no need for anything to run after this - at least for our use cases.
|
|
279
|
-
*
|
|
280
|
-
* Users can prevent this by creating their own HandlerOnRequestPlugin and returning false as the result of the callable.
|
|
281
|
-
*/
|
|
282
|
-
if (!isOptionsRequest) {
|
|
223
|
+
app.addContentTypeParser("application/json", {
|
|
224
|
+
parseAs: "string",
|
|
225
|
+
bodyLimit: 1024 * 1024
|
|
226
|
+
}, (req, body, done) => {
|
|
227
|
+
if (req.method === "OPTIONS") {
|
|
228
|
+
done(null, undefined);
|
|
283
229
|
return;
|
|
284
230
|
}
|
|
285
|
-
if (reply.sent) {
|
|
286
|
-
/**
|
|
287
|
-
* At this point throwing an exception will not do anything with the response. So just log it.
|
|
288
|
-
*/
|
|
289
|
-
console.error(JSON.stringify({
|
|
290
|
-
message: `Output was already sent. Please check custom plugins of type "HandlerOnRequestPlugin".`,
|
|
291
|
-
explanation: "This error can happen if the user plugin ended the reply, but did not return false as response."
|
|
292
|
-
}));
|
|
293
|
-
return;
|
|
294
|
-
}
|
|
295
|
-
reply.code(204).send("").hijack();
|
|
296
|
-
});
|
|
297
|
-
app.addHook("preParsing", async (request, reply) => {
|
|
298
|
-
app.webiny.request = request;
|
|
299
|
-
app.webiny.reply = reply;
|
|
300
|
-
const plugins = app.webiny.plugins.byType(_api.ContextPlugin.type);
|
|
301
|
-
let name;
|
|
302
231
|
try {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
} catch (ex) {
|
|
308
|
-
console.error(`Error while running the "ContextPlugin" ${name ? `(${name})` : ""} plugin in the preParsing hook.`);
|
|
309
|
-
console.error(stringifyError(ex));
|
|
310
|
-
throw ex;
|
|
232
|
+
const json = typeof body === "string" ? body : body.toString("utf8");
|
|
233
|
+
done(null, JSON.parse(json));
|
|
234
|
+
} catch (err) {
|
|
235
|
+
done(err);
|
|
311
236
|
}
|
|
312
237
|
});
|
|
238
|
+
|
|
313
239
|
/**
|
|
240
|
+
* With this we ensure that an undefined request body is not parsed on OPTIONS requests,
|
|
241
|
+
* in case there's a `content-type` header set for whatever reason.
|
|
314
242
|
*
|
|
243
|
+
* @see https://fastify.dev/docs/latest/Reference/ContentTypeParser/#content-type-parser
|
|
315
244
|
*/
|
|
316
|
-
app.addHook("
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
try {
|
|
320
|
-
for (const plugin of plugins) {
|
|
321
|
-
name = plugin.name;
|
|
322
|
-
await plugin.apply(app.webiny);
|
|
323
|
-
}
|
|
324
|
-
} catch (ex) {
|
|
325
|
-
console.error(`Error while running the "BeforeHandlerPlugin" ${name ? `(${name})` : ""} plugin in the preHandler hook.`);
|
|
326
|
-
console.error(stringifyError(ex));
|
|
327
|
-
throw ex;
|
|
245
|
+
app.addHook("onRequest", async request => {
|
|
246
|
+
if (request.method === "OPTIONS" && request.body === undefined) {
|
|
247
|
+
request.headers["content-type"] = undefined;
|
|
328
248
|
}
|
|
329
249
|
});
|
|
330
250
|
|
|
331
251
|
/**
|
|
332
|
-
*
|
|
252
|
+
* At this point, request body is properly parsed, and we can execute Webiny business logic.
|
|
253
|
+
* - set default headers
|
|
254
|
+
* - process `HandlerOnRequestPlugin`
|
|
255
|
+
* - if OPTIONS request, exit early
|
|
256
|
+
* - process `ContextPlugin`
|
|
257
|
+
* - process `BeforeHandlerPlugin`
|
|
333
258
|
*/
|
|
334
|
-
|
|
335
|
-
|
|
259
|
+
app.addHook("preHandler", async (request, reply) => {
|
|
260
|
+
app.webiny.request = request;
|
|
261
|
+
app.webiny.reply = reply;
|
|
262
|
+
|
|
263
|
+
// Bind request and reply to DI container for runtime access
|
|
264
|
+
if (app.webiny.container) {
|
|
265
|
+
app.webiny.container.registerInstance(Request, request);
|
|
266
|
+
app.webiny.container.registerInstance(Reply, reply);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Default code to 200 - so we do not need to set it again.
|
|
270
|
+
* Usually we set errors manually when we use reply.send.
|
|
271
|
+
*/
|
|
272
|
+
reply.code(200);
|
|
273
|
+
const handlerOnRequestPlugins = app.webiny.plugins.byType(HandlerOnRequestPlugin.type);
|
|
274
|
+
const contextPlugins = app.webiny.plugins.byType(ContextPlugin.type);
|
|
275
|
+
const beforeHandlerPlugins = app.webiny.plugins.byType(BeforeHandlerPlugin.type);
|
|
276
|
+
const modifyHeadersPlugins = app.webiny.plugins.byType(ModifyResponseHeadersPlugin.type);
|
|
277
|
+
const preHandler = new PreHandler([new SetDefaultHeaders(definedRoutes), new ProcessHandlerOnRequestPlugins(handlerOnRequestPlugins), new IfNotOptionsRequest([new ProcessContextPlugins(app.webiny, contextPlugins), new ProcessBeforeHandlerPlugins(app.webiny, beforeHandlerPlugins)]), new IfOptionsRequest([new SendEarlyOptionsResponse(modifyHeadersPlugins)])]);
|
|
278
|
+
await preHandler.execute(request, reply, app.webiny);
|
|
279
|
+
});
|
|
280
|
+
app.addHook("preSerialization", async (_, __, payload) => {
|
|
281
|
+
const plugins = app.webiny.plugins.byType(HandlerResultPlugin.type);
|
|
336
282
|
let name;
|
|
337
283
|
try {
|
|
338
284
|
for (const plugin of plugins) {
|
|
@@ -345,9 +291,31 @@ const createHandler = params => {
|
|
|
345
291
|
throw ex;
|
|
346
292
|
}
|
|
347
293
|
return payload;
|
|
348
|
-
};
|
|
349
|
-
app.
|
|
350
|
-
|
|
294
|
+
});
|
|
295
|
+
app.setErrorHandler(async (error, _, reply) => {
|
|
296
|
+
/**
|
|
297
|
+
* IMPORTANT! Do not send anything if reply was already sent.
|
|
298
|
+
*/
|
|
299
|
+
if (reply.sent) {
|
|
300
|
+
console.warn("Reply already sent, cannot send the result (handler:setErrorHandler).");
|
|
301
|
+
return reply;
|
|
302
|
+
}
|
|
303
|
+
if (error.code?.startsWith("Authentication/")) {
|
|
304
|
+
return reply.status(401).headers({
|
|
305
|
+
"Cache-Control": "no-store"
|
|
306
|
+
}).send(JSON.stringify({
|
|
307
|
+
message: error.message,
|
|
308
|
+
code: error.code
|
|
309
|
+
}));
|
|
310
|
+
}
|
|
311
|
+
if (error.code === "Tenancy/TenantDisabled") {
|
|
312
|
+
return reply.status(503).headers({
|
|
313
|
+
"Cache-Control": "no-store"
|
|
314
|
+
}).send(JSON.stringify({
|
|
315
|
+
message: error.message,
|
|
316
|
+
code: error.code
|
|
317
|
+
}));
|
|
318
|
+
}
|
|
351
319
|
return reply.status(500).headers({
|
|
352
320
|
"Cache-Control": "no-store"
|
|
353
321
|
}).send(
|
|
@@ -361,24 +329,37 @@ const createHandler = params => {
|
|
|
361
329
|
}));
|
|
362
330
|
});
|
|
363
331
|
app.addHook("onError", async (_, reply, error) => {
|
|
364
|
-
const plugins = app.webiny.plugins.byType(
|
|
332
|
+
const plugins = app.webiny.plugins.byType(HandlerErrorPlugin.type);
|
|
365
333
|
/**
|
|
366
334
|
* Log error to cloud, as these can be extremely annoying to debug!
|
|
367
335
|
*/
|
|
368
|
-
console.error("@webiny/handler");
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
336
|
+
console.error("Logging error in @webiny/handler");
|
|
337
|
+
try {
|
|
338
|
+
console.error(stringifyError(error));
|
|
339
|
+
} catch (ex) {
|
|
340
|
+
console.warn("Could not stringify error:");
|
|
341
|
+
console.log(error);
|
|
342
|
+
console.error("Stringify error:", ex);
|
|
343
|
+
}
|
|
373
344
|
/**
|
|
374
|
-
*
|
|
345
|
+
* IMPORTANT! Do not send anything if reply was already sent.
|
|
375
346
|
*/
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
347
|
+
if (!reply.sent) {
|
|
348
|
+
reply.status(500).headers({
|
|
349
|
+
"Cache-Control": "no-store"
|
|
350
|
+
}).send(
|
|
351
|
+
/**
|
|
352
|
+
* When we are sending the error in the response, we cannot send the whole error object, as it might contain some sensitive data.
|
|
353
|
+
*/
|
|
354
|
+
JSON.stringify({
|
|
355
|
+
message: error.message,
|
|
356
|
+
code: error.code,
|
|
357
|
+
data: error.data
|
|
358
|
+
}));
|
|
359
|
+
} else {
|
|
360
|
+
console.warn("Reply already sent, cannot send the result (handler:addHook:onError).");
|
|
361
|
+
}
|
|
362
|
+
const handler = middleware(plugins.map(pl => {
|
|
382
363
|
return (context, error, next) => {
|
|
383
364
|
return pl.handle(context, error, next);
|
|
384
365
|
};
|
|
@@ -390,13 +371,13 @@ const createHandler = params => {
|
|
|
390
371
|
/**
|
|
391
372
|
* Apply response headers modifier plugins.
|
|
392
373
|
*/
|
|
393
|
-
app.addHook("onSend", async (request, reply,
|
|
394
|
-
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
374
|
+
app.addHook("onSend", async (request, reply, input) => {
|
|
375
|
+
modifyResponseHeaders(app, request, reply);
|
|
376
|
+
const plugins = app.webiny.plugins.byType(OnRequestResponseSendPlugin.type);
|
|
377
|
+
let payload = input;
|
|
378
|
+
for (const plugin of plugins) {
|
|
379
|
+
payload = await plugin.exec(request, reply, payload);
|
|
380
|
+
}
|
|
400
381
|
return payload;
|
|
401
382
|
});
|
|
402
383
|
|
|
@@ -406,14 +387,18 @@ const createHandler = params => {
|
|
|
406
387
|
app.addHook("onResponse", async () => {
|
|
407
388
|
await context.benchmark.output();
|
|
408
389
|
});
|
|
409
|
-
app.addHook("onTimeout", async () => {
|
|
390
|
+
app.addHook("onTimeout", async (request, reply) => {
|
|
391
|
+
const plugins = app.webiny.plugins.byType(OnRequestTimeoutPlugin.type);
|
|
392
|
+
for (const plugin of plugins) {
|
|
393
|
+
await plugin.exec(request, reply);
|
|
394
|
+
}
|
|
410
395
|
await context.benchmark.output();
|
|
411
396
|
});
|
|
412
397
|
|
|
413
398
|
/**
|
|
414
399
|
* With these plugins we give users possibility to do anything they want on our fastify instance.
|
|
415
400
|
*/
|
|
416
|
-
const modifyPlugins = app.webiny.plugins.byType(
|
|
401
|
+
const modifyPlugins = app.webiny.plugins.byType(ModifyFastifyPlugin.type);
|
|
417
402
|
let modifyFastifyPluginName;
|
|
418
403
|
try {
|
|
419
404
|
for (const plugin of modifyPlugins) {
|
|
@@ -433,7 +418,7 @@ const createHandler = params => {
|
|
|
433
418
|
*
|
|
434
419
|
* Routes are registered in fastify but events must be handled in package which implements cloud specific methods.
|
|
435
420
|
*/
|
|
436
|
-
const routePlugins = app.webiny.plugins.byType(
|
|
421
|
+
const routePlugins = app.webiny.plugins.byType(RoutePlugin.type);
|
|
437
422
|
|
|
438
423
|
/**
|
|
439
424
|
* Add routes to the system.
|
|
@@ -454,6 +439,5 @@ const createHandler = params => {
|
|
|
454
439
|
}
|
|
455
440
|
return app;
|
|
456
441
|
};
|
|
457
|
-
exports.createHandler = createHandler;
|
|
458
442
|
|
|
459
443
|
//# sourceMappingURL=fastify.js.map
|