@middy/core
Version:
🛵 The stylish Node.js middleware engine for AWS Lambda (core package)
131 lines (103 loc) • 4.74 kB
JavaScript
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;
;