@scloud/lambda-local
Version:
Run typical Lambda handlers locally.
145 lines • 17.9 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.webappLocal = webappLocal;
const fs = __importStar(require("fs"));
const express_1 = __importDefault(require("express"));
const cors_1 = __importDefault(require("cors"));
function webappLocal(handler, staticContent, debug = false) {
if (staticContent?.sourceDirectory) {
if (!fs.existsSync(staticContent.sourceDirectory)) {
throw new Error(`Static directory not found: ${staticContent.sourceDirectory}`);
}
}
const port = +(process.env.PORT || '3000');
const app = (0, express_1.default)();
// https://stackoverflow.com/questions/12345166/how-to-force-parse-request-body-as-plain-text-instead-of-json-in-express
app.use(express_1.default.text({ type: '*/*', limit: '6mb' }));
// Allow all origins for local development
app.use((0, cors_1.default)({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
origin: (origin, callback) => callback(null, origin),
credentials: true,
}));
// "Static bucket" serving
if (staticContent)
app.use(staticContent.appPath, express_1.default.static(staticContent.sourceDirectory));
// Route everything else to the Lambda handler function
app.all('/*', async (req, res) => {
// const url = new URL(req.originalUrl, 'https://example.com');
// Headers - NB it seems that in Lambda multiValueHeaders always contains the values from headers
const headers = {};
const multiValueHeaders = {};
Object.keys(req.headers).forEach((header) => {
if (req.headers[header] === undefined) {
headers[header] = undefined;
multiValueHeaders[header] = undefined;
}
if (typeof req.headers[header] === 'string') {
headers[header] = req.headers[header];
multiValueHeaders[header] = [req.headers[header]];
}
if (Array.isArray(req.headers[header])) {
multiValueHeaders[header] = req.headers[header];
}
});
// Query string - basic translation
const queryStringParameters = {};
const multiValueQueryStringParameters = {};
Object.keys(req.query).forEach((parameter) => {
queryStringParameters[parameter] = undefined;
if (typeof req.query[parameter] === 'string')
queryStringParameters[parameter] = req.query[parameter];
if (Array.isArray(req.query[parameter]))
multiValueQueryStringParameters[parameter] = req.query[parameter];
});
const event = {
body: typeof req.body === 'string' ? req.body : JSON.stringify(req.body),
headers,
multiValueHeaders,
httpMethod: req.method,
path: req.path,
queryStringParameters,
multiValueQueryStringParameters,
requestContext: {
httpMethod: req.method,
path: req.path,
protocol: req.protocol,
},
};
try {
// Print out the event that will be sent to the handler
if (debug) {
console.log('Event:');
console.log(event.httpMethod, event.path);
console.log(JSON.stringify(event, null, 2));
}
// Invoke the function handler:
const result = await handler(event, {});
// Print out the response if successful
if (debug) {
console.log('Result:');
console.log(event.httpMethod, event.path, result.statusCode);
console.log(JSON.stringify(result, null, 2));
}
// Headers
res.status(result.statusCode);
for (const key of Object.keys(result.multiValueHeaders || [])) {
res.set(key, result.multiValueHeaders[key].map((value) => `${value}`));
}
;
for (const key of Object.keys(result.headers || [])) {
res.set(key, `${result.headers[key]}`);
}
;
// Body
res.send(result.body);
}
catch (e) {
// Log the error and send a 500 response
console.log(e);
console.log(e.stack);
res.status(500).send(`${e}`);
}
;
});
app.listen(port, () => {
console.log(`Lambda handler can be invoked at http://localhost:${port}`);
});
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViYXBwTG9jYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd2ViYXBwTG9jYWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFLQSxrQ0FtSEM7QUF4SEQsdUNBQXlCO0FBQ3pCLHNEQUFxRDtBQUVyRCxnREFBd0I7QUFFeEIsU0FBZ0IsV0FBVyxDQUN6QixPQUEwRixFQUMxRixhQUE2RCxFQUM3RCxLQUFLLEdBQUcsS0FBSztJQUViLElBQUksYUFBYSxFQUFFLGVBQWUsRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDO1lBQ2xELE1BQU0sSUFBSSxLQUFLLENBQUMsK0JBQStCLGFBQWEsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDO1FBQ2xGLENBQUM7SUFDSCxDQUFDO0lBRUQsTUFBTSxJQUFJLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLE1BQU0sQ0FBQyxDQUFDO0lBQzNDLE1BQU0sR0FBRyxHQUFHLElBQUEsaUJBQU8sR0FBRSxDQUFDO0lBRXRCLHdIQUF3SDtJQUN4SCxHQUFHLENBQUMsR0FBRyxDQUFDLGlCQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRXJELDBDQUEwQztJQUMxQyxHQUFHLENBQUMsR0FBRyxDQUNMLElBQUEsY0FBSSxFQUFDO1FBQ0gsOERBQThEO1FBQzlELE1BQU0sRUFBRSxDQUFDLE1BQVcsRUFBRSxRQUFhLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDO1FBQzlELFdBQVcsRUFBRSxJQUFJO0tBQ2xCLENBQUMsQ0FDSCxDQUFDO0lBRUEsMEJBQTBCO0lBQzVCLElBQUks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O1lBRUYsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDcEQsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsT0FBUSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMxQyxDQUFDO1lBQUEsQ0FBQztZQUVGLE9BQU87WUFDUCxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV4QixDQUFDO1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNYLHdDQUF3QztZQUN4QyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2YsT0FBTyxDQUFDLEdBQUcsQ0FBRSxDQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQy9CLENBQUM7UUFBQSxDQUFDO0lBQ0osQ0FBQyxDQUFDLENBQUM7SUFFSCxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUU7UUFDcEIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxREFBcUQsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMzRSxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgZXhwcmVzcywgeyBSZXF1ZXN0LCBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgQVBJR2F0ZXdheVByb3h5RXZlbnQsIEFQSUdhdGV3YXlQcm94eVJlc3VsdCwgQ29udGV4dCB9IGZyb20gJ2F3cy1sYW1iZGEnO1xuaW1wb3J0IGNvcnMgZnJvbSAnY29ycyc7XG5cbmV4cG9ydCBmdW5jdGlvbiB3ZWJhcHBMb2NhbChcbiAgaGFuZGxlcjogKGV2ZW50OiBBUElHYXRld2F5UHJveHlFdmVudCwgY29udGV4dDogQ29udGV4dCkgPT4gUHJvbWlzZTxBUElHYXRld2F5UHJveHlSZXN1bHQ+LFxuICBzdGF0aWNDb250ZW50PzogeyBzb3VyY2VEaXJlY3Rvcnk6IHN0cmluZywgYXBwUGF0aDogc3RyaW5nOyB9LFxuICBkZWJ1ZyA9IGZhbHNlLFxuKSB7XG4gIGlmIChzdGF0aWNDb250ZW50Py5zb3VyY2VEaXJlY3RvcnkpIHtcbiAgICBpZiAoIWZzLmV4aXN0c1N5bmMoc3RhdGljQ29udGVudC5zb3VyY2VEaXJlY3RvcnkpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFN0YXRpYyBkaXJlY3Rvcnkgbm90IGZvdW5kOiAke3N0YXRpY0NvbnRlbnQuc291cmNlRGlyZWN0b3J5fWApO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHBvcnQgPSArKHByb2Nlc3MuZW52LlBPUlQgfHwgJzMwMDAnKTtcbiAgY29uc3QgYXBwID0gZXhwcmVzcygpO1xuXG4gIC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEyMzQ1MTY2L2hvdy10by1mb3JjZS1wYXJzZS1yZXF1ZXN0LWJvZHktYXMtcGxhaW4tdGV4dC1pbnN0ZWFkLW9mLWpzb24taW4tZXhwcmVzc1xuICBhcHAudXNlKGV4cHJlc3MudGV4dCh7IHR5cGU6ICcqLyonLCBsaW1pdDogJzZtYicgfSkpO1xuXG4gIC8vIEFsbG93IGFsbCBvcmlnaW5zIGZvciBsb2NhbCBkZXZlbG9wbWVudFxuICBhcHAudXNlKFxuICAgIGNvcnMoe1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnlcbiAgICAgIG9yaWdpbjogKG9yaWdpbjogYW55LCBjYWxsYmFjazogYW55KSA9PiBjYWxsYmFjayhudWxsLCBvcmlnaW4pLFxuICAgICAgY3JlZGVudGlhbHM6IHRydWUsXG4gICAgfSksXG4gICk7XG5cbiAgICAvLyBcIlN0YXRpYyBidWNrZXRcIiBzZXJ2aW5nXG4gIGlmIChzdGF0aWNDb250ZW50KSBhcHAudXNlKHN0YXRpY0NvbnRlbnQuYXBwUGF0aCwgZXhwcmVzcy5zdGF0aWMoc3RhdGljQ29udGVudC5zb3VyY2VEaXJlY3RvcnkpKTtcblxuICAvLyBSb3V0ZSBldmVyeXRoaW5nIGVsc2UgdG8gdGhlIExhbWJkYSBoYW5kbGVyIGZ1bmN0aW9uXG4gIGFwcC5hbGwoJy8qJywgYXN5bmMgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgIC8vIGNvbnN0IHVybCA9IG5ldyBVUkwocmVxLm9yaWdpbmFsVXJsLCAnaHR0cHM6Ly9leGFtcGxlLmNvbScpO1xuICAgIC8vIEhlYWRlcnMgLSBOQiBpdCBzZWVtcyB0aGF0IGluIExhbWJkYSBtdWx0aVZhbHVlSGVhZGVycyBhbHdheXMgY29udGFpbnMgdGhlIHZhbHVlcyBmcm9tIGhlYWRlcnNcbiAgICBjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+ID0ge307XG4gICAgY29uc3QgbXVsdGlWYWx1ZUhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdIHwgdW5kZWZpbmVkPiA9IHt9O1xuICAgIE9iamVjdC5rZXlzKHJlcS5oZWFkZXJzKS5mb3JFYWNoKChoZWFkZXIpID0+IHtcbiAgICAgIGlmIChyZXEuaGVhZGVyc1toZWFkZXJdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaGVhZGVyc1toZWFkZXJdID0gdW5kZWZpbmVkO1xuICAgICAgICBtdWx0aVZhbHVlSGVhZGVyc1toZWFkZXJdID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiByZXEuaGVhZGVyc1toZWFkZXJdID09PSAnc3RyaW5nJykge1xuICAgICAgICBoZWFkZXJzW2hlYWRlcl0gPSByZXEuaGVhZGVyc1toZWFkZXJdIGFzIHN0cmluZztcbiAgICAgICAgbXVsdGlWYWx1ZUhlYWRlcnNbaGVhZGVyXSA9IFtyZXEuaGVhZGVyc1toZWFkZXJdIGFzIHN0cmluZ107XG4gICAgICB9XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShyZXEuaGVhZGVyc1toZWFkZXJdKSkge1xuICAgICAgICBtdWx0aVZhbHVlSGVhZGVyc1toZWFkZXJdID0gcmVxLmhlYWRlcnNbaGVhZGVyXSBhcyBzdHJpbmdbXTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFF1ZXJ5IHN0cmluZyAtIGJhc2ljIHRyYW5zbGF0aW9uXG4gICAgY29uc3QgcXVlcnlTdHJpbmdQYXJhbWV0ZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+ID0ge307XG4gICAgY29uc3QgbXVsdGlWYWx1ZVF1ZXJ5U3RyaW5nUGFyYW1ldGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nW10gfCB1bmRlZmluZWQ+ID0ge307XG4gICAgT2JqZWN0LmtleXMocmVxLnF1ZXJ5KS5mb3JFYWNoKChwYXJhbWV0ZXIpID0+IHtcbiAgICAgIHF1ZXJ5U3RyaW5nUGFyYW1ldGVyc1twYXJhbWV0ZXJdID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKHR5cGVvZiByZXEucXVlcnlbcGFyYW1ldGVyXSA9PT0gJ3N0cmluZycpIHF1ZXJ5U3RyaW5nUGFyYW1ldGVyc1twYXJhbWV0ZXJdID0gcmVxLnF1ZXJ5W3BhcmFtZXRlcl0gYXMgc3RyaW5nO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVxLnF1ZXJ5W3BhcmFtZXRlcl0pKSBtdWx0aVZhbHVlUXVlcnlTdHJpbmdQYXJhbWV0ZXJzW3BhcmFtZXRlcl0gPSByZXEucXVlcnlbcGFyYW1ldGVyXSBhcyBzdHJpbmdbXTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGV2ZW50OiBBUElHYXRld2F5UHJveHlFdmVudCA9IHtcbiAgICAgIGJvZHk6IHR5cGVvZiByZXEuYm9keSA9PT0gJ3N0cmluZycgPyByZXEuYm9keSA6IEpTT04uc3RyaW5naWZ5KHJlcS5ib2R5KSxcbiAgICAgIGhlYWRlcnMsXG4gICAgICBtdWx0aVZhbHVlSGVhZGVycyxcbiAgICAgIGh0dHBNZXRob2Q6IHJlcS5tZXRob2QsXG4gICAgICBwYXRoOiByZXEucGF0aCxcbiAgICAgIHF1ZXJ5U3RyaW5nUGFyYW1ldGVycyxcbiAgICAgIG11bHRpVmFsdWVRdWVyeVN0cmluZ1BhcmFtZXRlcnMsXG4gICAgICByZXF1ZXN0Q29udGV4dDoge1xuICAgICAgICBodHRwTWV0aG9kOiByZXEubWV0aG9kLFxuICAgICAgICBwYXRoOiByZXEucGF0aCxcbiAgICAgICAgcHJvdG9jb2w6IHJlcS5wcm90b2NvbCxcbiAgICAgIH0gYXMgdW5rbm93biBhcyBBUElHYXRld2F5UHJveHlFdmVudFsncmVxdWVzdENvbnRleHQnXSxcbiAgICB9IGFzIHVua25vd24gYXMgQVBJR2F0ZXdheVByb3h5RXZlbnQ7XG5cbiAgICB0cnkge1xuICAgICAgLy8gUHJpbnQgb3V0IHRoZSBldmVudCB0aGF0IHdpbGwgYmUgc2VudCB0byB0aGUgaGFuZGxlclxuICAgICAgaWYgKGRlYnVnKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdFdmVudDonKTtcbiAgICAgICAgY29uc29sZS5sb2coZXZlbnQuaHR0cE1ldGhvZCwgZXZlbnQucGF0aCk7XG4gICAgICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KGV2ZW50LCBudWxsLCAyKSk7XG4gICAgICB9XG5cbiAgICAgIC8vIEludm9rZSB0aGUgZnVuY3Rpb24gaGFuZGxlcjpcbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGhhbmRsZXIoZXZlbnQsIHt9IGFzIENvbnRleHQpO1xuXG4gICAgICAvLyBQcmludCBvdXQgdGhlIHJlc3BvbnNlIGlmIHN1Y2Nlc3NmdWxcbiAgICAgIGlmIChkZWJ1Zykge1xuICAgICAgICBjb25zb2xlLmxvZygnUmVzdWx0OicpO1xuICAgICAgICBjb25zb2xlLmxvZyhldmVudC5odHRwTWV0aG9kLCBldmVudC5wYXRoLCByZXN1bHQuc3RhdHVzQ29kZSk7XG4gICAgICAgIGNvbnNvbGUubG9nKEpTT04uc3RyaW5naWZ5KHJlc3VsdCwgbnVsbCwgMikpO1xuICAgICAgfVxuXG4gICAgICAvLyBIZWFkZXJzXG4gICAgICByZXMuc3RhdHVzKHJlc3VsdC5zdGF0dXNDb2RlKTtcbiAgICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKHJlc3VsdC5tdWx0aVZhbHVlSGVhZGVycyB8fCBbXSkpIHtcbiAgICAgICAgcmVzLnNldChrZXksIHJlc3VsdC5tdWx0aVZhbHVlSGVhZGVycyFba2V5XS5tYXAoKHZhbHVlKSA9PiBgJHt2YWx1ZX1gKSk7XG4gICAgICB9O1xuXG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhyZXN1bHQuaGVhZGVycyB8fCBbXSkpIHtcbiAgICAgICAgcmVzLnNldChrZXksIGAke3Jlc3VsdC5oZWFkZXJzIVtrZXldfWApO1xuICAgICAgfTtcblxuICAgICAgLy8gQm9keVxuICAgICAgcmVzLnNlbmQocmVzdWx0LmJvZHkpO1xuXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gTG9nIHRoZSBlcnJvciBhbmQgc2VuZCBhIDUwMCByZXNwb25zZVxuICAgICAgY29uc29sZS5sb2coZSk7XG4gICAgICBjb25zb2xlLmxvZygoZSBhcyBFcnJvcikuc3RhY2spO1xuICAgICAgcmVzLnN0YXR1cyg1MDApLnNlbmQoYCR7ZX1gKTtcbiAgICB9O1xuICB9KTtcblxuICBhcHAubGlzdGVuKHBvcnQsICgpID0+IHtcbiAgICBjb25zb2xlLmxvZyhgTGFtYmRhIGhhbmRsZXIgY2FuIGJlIGludm9rZWQgYXQgaHR0cDovL2xvY2FsaG9zdDoke3BvcnR9YCk7XG4gIH0pO1xufVxuIl19