UNPKG

@scloud/lambda-local

Version:

Run typical Lambda handlers locally.

145 lines 17.9 kB
"use strict"; 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