UNPKG

express-to-lambda

Version:

Simple package for converting your express application to an AWS Lambda.

109 lines (108 loc) 3.5 kB
export const adapter = (app) => async (event) => { const request = { path: event.requestContext?.http?.path ?? event.path, body: event.body ? JSON.parse(event.body) : null, method: event.requestContext?.http?.method ?? event.httpMethod, query: event.queryStringParameters, headers: event.headers, }; request.url = request.path; if (request.query) request.url += "?" + request.query; if (!request.path || !request.method) { return { statusCode: 404, body: "Lambda didn't receive any event which contains a valid path or http method!", }; } // @ts-ignore const response = (callback) => ({ status: function (code) { this.statusVal = code; this.isStatusSet = true; return this; }, send: function (body) { if (!this.isStatusSet) { this.statusVal = 200; this.isStatusSet = true; } if (typeof body === "object") this.bodyVal = body; else this.textVal = body; callback && callback(this); }, json: function (body) { this.send(body); }, end: function () { this.send(""); }, setHeader: function (header, value) { this.headers.push([header, value]); return this; }, isStatusSet: false, statusVal: 0, bodyVal: "", textVal: "", headers: [], }); const middlewares = app._router.stack .filter((s) => s.handle && !s.handle.stack) .map((s) => s.handle); const router = app._router.stack .flatMap((stack) => { const ret = []; if (stack.route) { ret.push(stack); } if (stack.handle?.stack) { ret.push(...stack.handle.stack); } return ret; }) .find(({ route, regexp }) => route && regexp.test(request.path) && route.methods[request.method.toLowerCase()] === true); if (!router) { return { statusCode: 404, body: "Path not found!", }; } const routeRegex = router.route.path; // /path/:id/subpath/:id2 const nonIdParams = routeRegex // [path, subpath] .split("/") .filter((route) => route && !route.startsWith(":")); const idParams = request.path // [<value of :id>, <value of :id2>] .split("/") .filter((path) => path && !nonIdParams.includes(path)); request.params = {}; for (let i = 0; i < router.keys.length; i++) { const { name } = router.keys[i]; request.params[name] = idParams[i]; } let errorMiddleware; for (const middleware of middlewares) { if (middleware .toString() .split("{")[0] .includes("(err, req, res, next)")) { errorMiddleware = middleware; continue; } await new Promise((resolve) => middleware(request, response(resolve), resolve)); } const res = (await new Promise((resolve) => router.handle(request, response(resolve), (err) => errorMiddleware && errorMiddleware(err, request, response(resolve), resolve)))); return { statusCode: res.statusVal, body: res.bodyVal ? JSON.stringify(res.bodyVal) : res.textVal, }; };