UNPKG

@middy/core

Version:

🛵 The stylish Node.js middleware engine for AWS Lambda (core package)

131 lines (103 loc) • 4.74 kB
"use strict"; const middy = (baseHandler = () => {}, plugin) => { var _plugin$beforePrefetc; plugin === null || plugin === void 0 ? void 0 : (_plugin$beforePrefetc = plugin.beforePrefetch) === null || _plugin$beforePrefetc === void 0 ? void 0 : _plugin$beforePrefetc.call(plugin); const beforeMiddlewares = []; const afterMiddlewares = []; const onErrorMiddlewares = []; const instance = (event = {}, context = {}) => { var _plugin$requestStart; plugin === null || plugin === void 0 ? void 0 : (_plugin$requestStart = plugin.requestStart) === null || _plugin$requestStart === void 0 ? void 0 : _plugin$requestStart.call(plugin); const request = { event, context, response: undefined, error: undefined, internal: {} }; return runRequest(request, [...beforeMiddlewares], baseHandler, [...afterMiddlewares], [...onErrorMiddlewares], plugin); }; instance.use = middlewares => { if (Array.isArray(middlewares)) { for (const middleware of middlewares) { instance.applyMiddleware(middleware); } return instance; } return instance.applyMiddleware(middlewares); }; instance.applyMiddleware = middleware => { const { before, after, onError } = middleware; if (!before && !after && !onError) { throw new Error('Middleware must be an object containing at least one key among "before", "after", "onError"'); } if (before) instance.before(before); if (after) instance.after(after); if (onError) instance.onError(onError); return instance; }; // Inline Middlewares instance.before = beforeMiddleware => { beforeMiddlewares.push(beforeMiddleware); return instance; }; instance.after = afterMiddleware => { afterMiddlewares.unshift(afterMiddleware); return instance; }; instance.onError = onErrorMiddleware => { onErrorMiddlewares.push(onErrorMiddleware); return instance; }; instance.__middlewares = { before: beforeMiddlewares, after: afterMiddlewares, onError: onErrorMiddlewares }; return instance; }; const runRequest = async (request, beforeMiddlewares, baseHandler, afterMiddlewares, onErrorMiddlewares, plugin) => { try { await runMiddlewares(request, beforeMiddlewares, plugin); // Check if before stack hasn't exit early if (request.response === undefined) { var _plugin$beforeHandler, _plugin$afterHandler; plugin === null || plugin === void 0 ? void 0 : (_plugin$beforeHandler = plugin.beforeHandler) === null || _plugin$beforeHandler === void 0 ? void 0 : _plugin$beforeHandler.call(plugin); request.response = await baseHandler(request.event, request.context); plugin === null || plugin === void 0 ? void 0 : (_plugin$afterHandler = plugin.afterHandler) === null || _plugin$afterHandler === void 0 ? void 0 : _plugin$afterHandler.call(plugin); await runMiddlewares(request, afterMiddlewares, plugin); } } catch (e) { // Reset response changes made by after stack before error thrown request.response = undefined; request.error = e; try { await runMiddlewares(request, onErrorMiddlewares, plugin); } catch (e) { // Save error that wasn't handled e.originalError = request.error; request.error = e; throw request.error; } // Catch if onError stack hasn't handled the error if (request.response === undefined) throw request.error; } finally { var _plugin$requestEnd; await (plugin === null || plugin === void 0 ? void 0 : (_plugin$requestEnd = plugin.requestEnd) === null || _plugin$requestEnd === void 0 ? void 0 : _plugin$requestEnd.call(plugin, request)); } return request.response; }; const runMiddlewares = async (request, middlewares, plugin) => { for (const nextMiddleware of middlewares) { var _plugin$beforeMiddlew, _plugin$afterMiddlewa; 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); const res = await (nextMiddleware === null || nextMiddleware === void 0 ? void 0 : nextMiddleware(request)); 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); // short circuit chaining and respond early if (res !== undefined) { request.response = res; return; } } }; module.exports = middy;