express-to-lambda
Version:
Simple package for converting your express application to an AWS Lambda.
123 lines (122 loc) • 4.68 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.adapter = void 0;
const adapter = (app) => (event) => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f;
const request = {
path: (_c = (_b = (_a = event.requestContext) === null || _a === void 0 ? void 0 : _a.http) === null || _b === void 0 ? void 0 : _b.path) !== null && _c !== void 0 ? _c : event.path,
body: event.body ? JSON.parse(event.body) : null,
method: (_f = (_e = (_d = event.requestContext) === null || _d === void 0 ? void 0 : _d.http) === null || _e === void 0 ? void 0 : _e.method) !== null && _f !== void 0 ? _f : 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) => {
var _a;
const ret = [];
if (stack.route) {
ret.push(stack);
}
if ((_a = stack.handle) === null || _a === void 0 ? void 0 : _a.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;
}
yield new Promise((resolve) => middleware(request, response(resolve), resolve));
}
const res = (yield 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,
};
});
exports.adapter = adapter;
;