UNPKG

4.99 kBJavaScriptView Raw
1"use strict";
2
3const middy = (handler = () => {}, plugin) => {
4 var _plugin$beforePrefetc;
5
6 plugin === null || plugin === void 0 ? void 0 : (_plugin$beforePrefetc = plugin.beforePrefetch) === null || _plugin$beforePrefetc === void 0 ? void 0 : _plugin$beforePrefetc.call(plugin);
7 const beforeMiddlewares = [];
8 const afterMiddlewares = [];
9 const onErrorMiddlewares = [];
10
11 const instance = (event = {}, context = {}) => {
12 var _plugin$requestStart;
13
14 plugin === null || plugin === void 0 ? void 0 : (_plugin$requestStart = plugin.requestStart) === null || _plugin$requestStart === void 0 ? void 0 : _plugin$requestStart.call(plugin);
15 const request = {
16 event,
17 context,
18 response: undefined,
19 error: undefined,
20 internal: {}
21 };
22
23 const middyPromise = async () => {
24 try {
25 await runMiddlewares(beforeMiddlewares, request, plugin); // Check if before stack doesn't need to exit early
26
27 if (request.response === undefined) {
28 var _plugin$beforeHandler, _plugin$afterHandler;
29
30 plugin === null || plugin === void 0 ? void 0 : (_plugin$beforeHandler = plugin.beforeHandler) === null || _plugin$beforeHandler === void 0 ? void 0 : _plugin$beforeHandler.call(plugin);
31 request.response = await handler(request.event, request.context);
32 plugin === null || plugin === void 0 ? void 0 : (_plugin$afterHandler = plugin.afterHandler) === null || _plugin$afterHandler === void 0 ? void 0 : _plugin$afterHandler.call(plugin);
33 await runMiddlewares(afterMiddlewares, request, plugin);
34 }
35 } catch (e) {
36 // Reset response changes made by after stack before error thrown
37 request.response = undefined;
38 request.error = e;
39
40 try {
41 await runMiddlewares(onErrorMiddlewares, request, plugin); // Catch if onError stack hasn't handled the error
42
43 if (request.response === undefined) {
44 throw request.error;
45 }
46 } catch (e) {
47 // Save error that wasn't handled
48 e.originalError = request.error;
49 request.error = e;
50 throw request.error;
51 }
52 } finally {
53 var _plugin$requestEnd;
54
55 await (plugin === null || plugin === void 0 ? void 0 : (_plugin$requestEnd = plugin.requestEnd) === null || _plugin$requestEnd === void 0 ? void 0 : _plugin$requestEnd.call(plugin));
56 }
57
58 return request.response;
59 };
60
61 return middyPromise();
62 };
63
64 instance.use = middlewares => {
65 if (Array.isArray(middlewares)) {
66 middlewares.forEach(middleware => instance.applyMiddleware(middleware));
67 return instance;
68 } else if (typeof middlewares === 'object') {
69 return instance.applyMiddleware(middlewares);
70 }
71
72 throw new Error('Middy.use() accepts an object or an array of objects');
73 };
74
75 instance.applyMiddleware = middleware => {
76 if (typeof middleware !== 'object') {
77 throw new Error('Middleware must be an object');
78 }
79
80 const {
81 before,
82 after,
83 onError
84 } = middleware;
85
86 if (!before && !after && !onError) {
87 throw new Error('Middleware must contain at least one key among "before", "after", "onError"');
88 }
89
90 if (before) instance.before(before);
91 if (after) instance.after(after);
92 if (onError) instance.onError(onError);
93 return instance;
94 }; // Inline Middlewares
95
96
97 instance.before = beforeMiddleware => {
98 beforeMiddlewares.push(beforeMiddleware);
99 return instance;
100 };
101
102 instance.after = afterMiddleware => {
103 afterMiddlewares.unshift(afterMiddleware);
104 return instance;
105 };
106
107 instance.onError = onErrorMiddleware => {
108 onErrorMiddlewares.push(onErrorMiddleware);
109 return instance;
110 };
111
112 instance.__middlewares = {
113 before: beforeMiddlewares,
114 after: afterMiddlewares,
115 onError: onErrorMiddlewares
116 };
117 return instance;
118};
119
120const runMiddlewares = async (middlewares, request, plugin) => {
121 var _plugin$beforeMiddlew, _plugin$afterMiddlewa;
122
123 const stack = Array.from(middlewares);
124 if (!stack.length) return;
125 const nextMiddleware = stack.shift();
126 plugin === null || plugin === void 0 ? void 0 : (_plugin$beforeMiddlew = plugin.beforeMiddleware) === null || _plugin$beforeMiddlew === void 0 ? void 0 : _plugin$beforeMiddlew.call(plugin, nextMiddleware === null || nextMiddleware === void 0 ? void 0 : nextMiddleware.name);
127 const res = await (nextMiddleware === null || nextMiddleware === void 0 ? void 0 : nextMiddleware(request));
128 plugin === null || plugin === void 0 ? void 0 : (_plugin$afterMiddlewa = plugin.afterMiddleware) === null || _plugin$afterMiddlewa === void 0 ? void 0 : _plugin$afterMiddlewa.call(plugin, nextMiddleware === null || nextMiddleware === void 0 ? void 0 : nextMiddleware.name);
129
130 if (res !== undefined) {
131 // short circuit chaining and respond early
132 request.response = res;
133 return;
134 }
135
136 return runMiddlewares(stack, request, plugin);
137};
138
139module.exports = middy;