UNPKG

@scloud/lambda-local

Version:

Run typical Lambda handlers locally.

179 lines 23.2 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.cloudfrontLocal = void 0; const express_1 = __importDefault(require("express")); const eventTemplate = { body: '', headers: {}, multiValueHeaders: {}, httpMethod: '', isBase64Encoded: false, path: '', pathParameters: null, queryStringParameters: {}, multiValueQueryStringParameters: {}, stageVariables: null, resource: '?', requestContext: { accountId: '', apiId: '', authorizer: null, httpMethod: '', identity: { accessKey: null, accountId: null, apiKey: null, apiKeyId: null, caller: null, clientCert: null, cognitoAuthenticationProvider: null, cognitoAuthenticationType: null, cognitoIdentityId: null, cognitoIdentityPoolId: null, principalOrgId: null, sourceIp: '', user: null, userAgent: null, userArn: null, }, path: '', protocol: '', requestId: '', requestTimeEpoch: 0, resourceId: '', resourcePath: '', stage: '', }, }; const contextTemplate = { awsRequestId: '', callbackWaitsForEmptyEventLoop: false, functionName: '', functionVersion: '', invokedFunctionArn: '', logGroupName: '', logStreamName: '', memoryLimitInMB: '', getRemainingTimeInMillis: () => 0, done: () => { }, fail: () => { }, succeed: () => { }, }; // eslint-disable-next-line no-unused-vars function cloudfrontLocal(cloudfrontPathMappings) { 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: '*/*' })); 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 = { ...eventTemplate, body: typeof req.body === 'string' ? req.body : JSON.stringify(req.body), headers, multiValueHeaders, httpMethod: req.method, path: req.path, queryStringParameters, multiValueQueryStringParameters, requestContext: { ...eventTemplate.requestContext, httpMethod: req.method, path: req.path, protocol: req.protocol, }, }; try { // Print out the event that will be sent to the handler console.log('Event:'); Object.keys(event).forEach((key) => { console.log(` - ${key}: ${JSON.stringify(event[key])}`); }); const paths = Object.keys(cloudfrontPathMappings); // Try a simple mapping let handler = cloudfrontPathMappings[event.path]; // Fall back to a '*' match: paths.forEach((path) => { let partialMatch = path; // Strip leading slash: if (partialMatch.startsWith('/')) { partialMatch = path.slice(1); } // Remove trailing '*' wildcard: if (partialMatch.endsWith('*')) { partialMatch = path.slice(0, -1); } // Get the first match: const candidate = event.path.startsWith(partialMatch) ? cloudfrontPathMappings[path] : undefined; handler = handler || candidate; }); // Invoke the function handler: const result = handler ? await handler(event, contextTemplate) : { statusCode: 404, body: `Path not matched: ${event.path} (${paths})` }; // Print out the response if successful if (result) { if (result.statusCode === 404) { console.log(`404: ${event.path}`); } else { console.log('Result:'); Object.keys(result).forEach((key) => { console.log(` - ${key}: ${JSON.stringify(result[key]).slice(0, 100)}`); }); } } // Send the response res.status(result.statusCode); if (result.multiValueHeaders) { Object.keys(result.multiValueHeaders).forEach((key) => { res.set(key, result.multiValueHeaders[key].map((value) => `${value}`)); }); } if (result.headers) { Object.keys(result.headers).forEach((key) => { res.set(key, `${result.headers[key]}`); }); } 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}`); }); } exports.cloudfrontLocal = cloudfrontLocal; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWRmcm9udExvY2FsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Nsb3VkZnJvbnRMb2NhbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFHQSxzREFBcUQ7QUFPckQsTUFBTSxhQUFhLEdBQXlCO0lBQzFDLElBQUksRUFBRSxFQUFFO0lBQ1IsT0FBTyxFQUFFLEVBQUU7SUFDWCxpQkFBaUIsRUFBRSxFQUFFO0lBQ3JCLFVBQVUsRUFBRSxFQUFFO0lBQ2QsZUFBZSxFQUFFLEtBQUs7SUFDdEIsSUFBSSxFQUFFLEVBQUU7SUFDUixjQUFjLEVBQUUsSUFBSTtJQUNwQixxQkFBcUIsRUFBRSxFQUFFO0lBQ3pCLCtCQUErQixFQUFFLEVBQUU7SUFDbkMsY0FBYyxFQUFFLElBQUk7SUFDcEIsUUFBUSxFQUFFLEdBQUc7SUFDYixjQUFjLEVBQUU7UUFDZCxTQUFTLEVBQUUsRUFBRTtRQUNiLEtBQUssRUFBRSxFQUFFO1FBQ1QsVUFBVSxFQUFFLElBQUk7UUFDaEIsVUFBVSxFQUFFLEVBQUU7UUFDZCxRQUFRLEVBQUU7WUFDUixTQUFTLEVBQUUsSUFBSTtZQUNmLFNBQVMsRUFBRSxJQUFJO1lBQ2YsTUFBTSxFQUFFLElBQUk7WUFDWixRQUFRLEVBQUUsSUFBSTtZQUNkLE1BQU0sRUFBRSxJQUFJO1lBQ1osVUFBVSxFQUFFLElBQUk7WUFDaEIsNkJBQTZCLEVBQUUsSUFBSTtZQUNuQyx5QkFBeUIsRUFBRSxJQUFJO1lBQy9CLGlCQUFpQixFQUFFLElBQUk7WUFDdkIscUJBQXFCLEVBQUUsSUFBSTtZQUMzQixjQUFjLEVBQUUsSUFBSTtZQUNwQixRQUFRLEVBQUUsRUFBRTtZQUNaLElBQUksRUFBRSxJQUFJO1lBQ1YsU0FBUyxFQUFFLElBQUk7WUFDZixPQUFPLEVBQUUsSUFBSTtTQUNkO1FBQ0QsSUFBSSxFQUFFLEVBQUU7UUFDUixRQUFRLEVBQUUsRUFBRTtRQUNaLFNBQVMsRUFBRSxFQUFFO1FBQ2IsZ0JBQWdCLEVB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QUMsR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLE9BQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQzFDLENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELEdBQUcsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hCLENBQUM7UUFBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ1gsd0NBQXdDO1lBQ3hDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDZixPQUFPLENBQUMsR0FBRyxDQUFFLENBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNoQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDL0IsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUgsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFO1FBQ3BCLE9BQU8sQ0FBQyxHQUFHLENBQUMscURBQXFELElBQUksRUFBRSxDQUFDLENBQUM7SUFDM0UsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBdkhELDBDQXVIQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXG5pbXBvcnQgeyByZXF1ZXN0IH0gZnJvbSAnaHR0cCc7XG5pbXBvcnQgZXhwcmVzcywgeyBSZXF1ZXN0LCBSZXNwb25zZSB9IGZyb20gJ2V4cHJlc3MnO1xuaW1wb3J0IHsgQVBJR2F0ZXdheVByb3h5RXZlbnQsIEFQSUdhdGV3YXlQcm94eVJlc3VsdCwgQ29udGV4dCB9IGZyb20gJ2F3cy1sYW1iZGEnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENsb3VkZnJvbnRQYXRoTWFwcGluZ3Mge1xuICBba2V5OiBzdHJpbmddOiAoZXZlbnQ6IEFQSUdhdGV3YXlQcm94eUV2ZW50LCBjb250ZXh0OiBDb250ZXh0KSA9PiBQcm9taXNlPEFQSUdhdGV3YXlQcm94eVJlc3VsdD47XG59XG5cbmNvbnN0IGV2ZW50VGVtcGxhdGU6IEFQSUdhdGV3YXlQcm94eUV2ZW50ID0ge1xuICBib2R5OiAnJyxcbiAgaGVhZGVyczoge30sXG4gIG11bHRpVmFsdWVIZWFkZXJzOiB7fSxcbiAgaHR0cE1ldGhvZDogJycsXG4gIGlzQmFzZTY0RW5jb2RlZDogZmFsc2UsXG4gIHBhdGg6ICcnLFxuICBwYXRoUGFyYW1ldGVyczogbnVsbCxcbiAgcXVlcnlTdHJpbmdQYXJhbWV0ZXJzOiB7fSxcbiAgbXVsdGlWYWx1ZVF1ZXJ5U3RyaW5nUGFyYW1ldGVyczoge30sXG4gIHN0YWdlVmFyaWFibGVzOiBudWxsLFxuICByZXNvdXJjZTogJz8nLFxuICByZXF1ZXN0Q29udGV4dDoge1xuICAgIGFjY291bnRJZDogJycsXG4gICAgYXBpSWQ6ICcnLFxuICAgIGF1dGhvcml6ZXI6IG51bGwsXG4gICAgaHR0cE1ldGhvZDogJycsXG4gICAgaWRlbnRpdHk6IHtcbiAgICAgIGFjY2Vzc0tleTogbnVsbCxcbiAgICAgIGFjY291bnRJZDogbnVsbCxcbiAgICAgIGFwaUtleTogbnVsbCxcbiAgICAgIGFwaUtleUlkOiBudWxsLFxuICAgICAgY2FsbGVyOiBudWxsLFxuICAgICAgY2xpZW50Q2VydDogbnVsbCxcbiAgICAgIGNvZ25pdG9BdXRoZW50aWNhdGlvblByb3ZpZGVyOiBudWxsLFxuICAgICAgY29nbml0b0F1dGhlbnRpY2F0aW9uVHlwZTogbnVsbCxcbiAgICAgIGNvZ25pdG9JZGVudGl0eUlkOiBudWxsLFxuICAgICAgY29nbml0b0lkZW50aXR5UG9vbElkOiBudWxsLFxuICAgICAgcHJpbmNpcGFsT3JnSWQ6IG51bGwsXG4gICAgICBzb3VyY2VJcDogJycsXG4gICAgICB1c2VyOiBudWxsLFxuICAgICAgdXNlckFnZW50OiBudWxsLFxuICAgICAgdXNlckFybjogbnVsbCxcbiAgICB9LFxuICAgIHBhdGg6ICcnLFxuICAgIHByb3RvY29sOiAnJyxcbiAgICByZXF1ZXN0SWQ6ICcnLFxuICAgIHJlcXVlc3RUaW1lRXBvY2g6IDAsXG4gICAgcmVzb3VyY2VJZDogJycsXG4gICAgcmVzb3VyY2VQYXRoOiAnJyxcbiAgICBzdGFnZTogJycsXG4gIH0sXG59O1xuY29uc3QgY29udGV4dFRlbXBsYXRlOiBDb250ZXh0ID0ge1xuICBhd3NSZXF1ZXN0SWQ6ICcnLFxuICBjYWxsYmFja1dhaXRzRm9yRW1wdHlFdmVudExvb3A6IGZhbHNlLFxuICBmdW5jdGlvbk5hbWU6ICcnLFxuICBmdW5jdGlvblZlcnNpb246ICcnLFxuICBpbnZva2VkRnVuY3Rpb25Bcm46ICcnLFxuICBsb2dHcm91cE5hbWU6ICcnLFxuICBsb2dTdHJlYW1OYW1lOiAnJyxcbiAgbWVtb3J5TGltaXRJbk1COiAnJyxcbiAgZ2V0UmVtYWluaW5nVGltZUluTWlsbGlzOiAoKSA9PiAwLFxuICBkb25lOiAoKSA9PiB7IH0sXG4gIGZhaWw6ICgpID0+IHsgfSxcbiAgc3VjY2VlZDogKCkgPT4geyB9LFxufTtcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXG5leHBvcnQgZnVuY3Rpb24gY2xvdWRmcm9udExvY2FsKGNsb3VkZnJvbnRQYXRoTWFwcGluZ3M6IENsb3VkZnJvbnRQYXRoTWFwcGluZ3MpIHtcbiAgY29uc3QgcG9ydCA9ICsocHJvY2Vzcy5lbnYucG9ydCB8fCAnMzAwMCcpO1xuICBjb25zdCBhcHAgPSBleHByZXNzKCk7XG5cbiAgLy8gaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMTIzNDUxNjYvaG93LXRvLWZvcmNlLXBhcnNlLXJlcXVlc3QtYm9keS1hcy1wbGFpbi10ZXh0LWluc3RlYWQtb2YtanNvbi1pbi1leHByZXNzXG4gIGFwcC51c2UoZXhwcmVzcy50ZXh0KHsgdHlwZTogJyovKicgfSkpO1xuXG4gIGFwcC5hbGwoJy8qJywgYXN5bmMgKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSkgPT4ge1xuICAgIC8vIGNvbnN0IHVybCA9IG5ldyBVUkwocmVxLm9yaWdpbmFsVXJsLCAnaHR0cHM6Ly9leGFtcGxlLmNvbScpO1xuICAgIC8vIEhlYWRlcnMgLSBOQiBpdCBzZWVtcyB0aGF0IGluIExhbWJkYSBtdWx0aVZhbHVlSGVhZGVycyBhbHdheXMgY29udGFpbnMgdGhlIHZhbHVlcyBmcm9tIGhlYWRlcnNcbiAgICBjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+ID0ge307XG4gICAgY29uc3QgbXVsdGlWYWx1ZUhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZ1tdIHwgdW5kZWZpbmVkPiA9IHt9O1xuICAgIE9iamVjdC5rZXlzKHJlcS5oZWFkZXJzKS5mb3JFYWNoKChoZWFkZXIpID0+IHtcbiAgICAgIGlmIChyZXEuaGVhZGVyc1toZWFkZXJdID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgaGVhZGVyc1toZWFkZXJdID0gdW5kZWZpbmVkO1xuICAgICAgICBtdWx0aVZhbHVlSGVhZGVyc1toZWFkZXJdID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgaWYgKHR5cGVvZiByZXEuaGVhZGVyc1toZWFkZXJdID09PSAnc3RyaW5nJykge1xuICAgICAgICBoZWFkZXJzW2hlYWRlcl0gPSByZXEuaGVhZGVyc1toZWFkZXJdIGFzIHN0cmluZztcbiAgICAgICAgbXVsdGlWYWx1ZUhlYWRlcnNbaGVhZGVyXSA9IFtyZXEuaGVhZGVyc1toZWFkZXJdIGFzIHN0cmluZ107XG4gICAgICB9XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShyZXEuaGVhZGVyc1toZWFkZXJdKSkge1xuICAgICAgICBtdWx0aVZhbHVlSGVhZGVyc1toZWFkZXJdID0gcmVxLmhlYWRlcnNbaGVhZGVyXSBhcyBzdHJpbmdbXTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIC8vIFF1ZXJ5IHN0cmluZyAtIGJhc2ljIHRyYW5zbGF0aW9uXG4gICAgY29uc3QgcXVlcnlTdHJpbmdQYXJhbWV0ZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+ID0ge307XG4gICAgY29uc3QgbXVsdGlWYWx1ZVF1ZXJ5U3RyaW5nUGFyYW1ldGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nW10gfCB1bmRlZmluZWQ+ID0ge307XG4gICAgT2JqZWN0LmtleXMocmVxLnF1ZXJ5KS5mb3JFYWNoKChwYXJhbWV0ZXIpID0+IHtcbiAgICAgIHF1ZXJ5U3RyaW5nUGFyYW1ldGVyc1twYXJhbWV0ZXJdID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKHR5cGVvZiByZXEucXVlcnlbcGFyYW1ldGVyXSA9PT0gJ3N0cmluZycpIHF1ZXJ5U3RyaW5nUGFyYW1ldGVyc1twYXJhbWV0ZXJdID0gcmVxLnF1ZXJ5W3BhcmFtZXRlcl0gYXMgc3RyaW5nO1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkocmVxLnF1ZXJ5W3BhcmFtZXRlcl0pKSBtdWx0aVZhbHVlUXVlcnlTdHJpbmdQYXJhbWV0ZXJzW3BhcmFtZXRlcl0gPSByZXEucXVlcnlbcGFyYW1ldGVyXSBhcyBzdHJpbmdbXTtcbiAgICB9KTtcblxuICAgIGNvbnN0IGV2ZW50ID0ge1xuICAgICAgLi4uZXZlbnRUZW1wbGF0ZSxcbiAgICAgIGJvZHk6IHR5cGVvZiByZXEuYm9keSA9PT0gJ3N0cmluZycgPyByZXEuYm9keSA6IEpTT04uc3RyaW5naWZ5KHJlcS5ib2R5KSxcbiAgICAgIGhlYWRlcnMsXG4gICAgICBtdWx0aVZhbHVlSGVhZGVycyxcbiAgICAgIGh0dHBNZXRob2Q6IHJlcS5tZXRob2QsXG4gICAgICBwYXRoOiByZXEucGF0aCxcbiAgICAgIHF1ZXJ5U3RyaW5nUGFyYW1ldGVycyxcbiAgICAgIG11bHRpVmFsdWVRdWVyeVN0cmluZ1BhcmFtZXRlcnMsXG4gICAgICByZXF1ZXN0Q29udGV4dDoge1xuICAgICAgICAuLi5ldmVudFRlbXBsYXRlLnJlcXVlc3RDb250ZXh0LFxuICAgICAgICBodHRwTWV0aG9kOiByZXEubWV0aG9kLFxuICAgICAgICBwYXRoOiByZXEucGF0aCxcbiAgICAgICAgcHJvdG9jb2w6IHJlcS5wcm90b2NvbCxcbiAgICAgIH0sXG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICAvLyBQcmludCBvdXQgdGhlIGV2ZW50IHRoYXQgd2lsbCBiZSBzZW50IHRvIHRoZSBoYW5kbGVyXG4gICAgICBjb25zb2xlLmxvZygnRXZlbnQ6Jyk7XG4gICAgICBPYmplY3Qua2V5cyhldmVudCkuZm9yRWFjaCgoa2V5KSA9PiB7XG4gICAgICAgIGNvbnNvbGUubG9nKGAgLSAke2tleX06ICR7SlNPTi5zdHJpbmdpZnkoZXZlbnRba2V5IGFzIGtleW9mIEFQSUdhdGV3YXlQcm94eUV2ZW50XSl9YCk7XG4gICAgICB9KTtcblxuICAgICAgY29uc3QgcGF0aHMgPSBPYmplY3Qua2V5cyhjbG91ZGZyb250UGF0aE1hcHBpbmdzKTtcblxuICAgICAgLy8gVHJ5IGEgc2ltcGxlIG1hcHBpbmdcbiAgICAgIGxldCBoYW5kbGVyID0gY2xvdWRmcm9udFBhdGhNYXBwaW5nc1tldmVudC5wYXRoXTtcblxuICAgICAgLy8gRmFsbCBiYWNrIHRvIGEgJyonIG1hdGNoOlxuICAgICAgcGF0aHMuZm9yRWFjaCgocGF0aCkgPT4ge1xuICAgICAgICBsZXQgcGFydGlhbE1hdGNoID0gcGF0aDtcbiAgICAgICAgLy8gU3RyaXAgbGVhZGluZyBzbGFzaDpcbiAgICAgICAgaWYgKHBhcnRpYWxNYXRjaC5zdGFydHNXaXRoKCcvJykpIHtcbiAgICAgICAgICBwYXJ0aWFsTWF0Y2ggPSBwYXRoLnNsaWNlKDEpO1xuICAgICAgICB9XG4gICAgICAgIC8vIFJlbW92ZSB0cmFpbGluZyAnKicgd2lsZGNhcmQ6XG4gICAgICAgIGlmIChwYXJ0aWFsTWF0Y2guZW5kc1dpdGgoJyonKSkge1xuICAgICAgICAgIHBhcnRpYWxNYXRjaCA9IHBhdGguc2xpY2UoMCwgLTEpO1xuICAgICAgICB9XG4gICAgICAgIC8vIEdldCB0aGUgZmlyc3QgbWF0Y2g6XG4gICAgICAgIGNvbnN0IGNhbmRpZGF0ZSA9IGV2ZW50LnBhdGguc3RhcnRzV2l0aChwYXJ0aWFsTWF0Y2gpID8gY2xvdWRmcm9udFBhdGhNYXBwaW5nc1twYXRoXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgaGFuZGxlciA9IGhhbmRsZXIgfHwgY2FuZGlkYXRlO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIEludm9rZSB0aGUgZnVuY3Rpb24gaGFuZGxlcjpcbiAgICAgIGNvbnN0IHJlc3VsdDogQVBJR2F0ZXdheVByb3h5UmVzdWx0ID0gaGFuZGxlciA/IGF3YWl0IGhhbmRsZXIoZXZlbnQsIGNvbnRleHRUZW1wbGF0ZSkgOiB7IHN0YXR1c0NvZGU6IDQwNCwgYm9keTogYFBhdGggbm90IG1hdGNoZWQ6ICR7ZXZlbnQucGF0aH0gKCR7cGF0aHN9KWAgfTtcblxuICAgICAgLy8gUHJpbnQgb3V0IHRoZSByZXNwb25zZSBpZiBzdWNjZXNzZnVsXG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIGlmIChyZXN1bHQuc3RhdHVzQ29kZSA9PT0gNDA0KSB7XG4gICAgICAgICAgY29uc29sZS5sb2coYDQwNDogJHtldmVudC5wYXRofWApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdSZXN1bHQ6Jyk7XG4gICAgICAgICAgT2JqZWN0LmtleXMocmVzdWx0KS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGAgLSAke2tleX06ICR7SlNPTi5zdHJpbmdpZnkocmVzdWx0W2tleSBhcyBrZXlvZiBBUElHYXRld2F5UHJveHlSZXN1bHRdKS5zbGljZSgwLCAxMDApfWApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFNlbmQgdGhlIHJlc3BvbnNlXG4gICAgICByZXMuc3RhdHVzKHJlc3VsdC5zdGF0dXNDb2RlKTtcbiAgICAgIGlmIChyZXN1bHQubXVsdGlWYWx1ZUhlYWRlcnMpIHtcbiAgICAgICAgT2JqZWN0LmtleXMocmVzdWx0Lm11bHRpVmFsdWVIZWFkZXJzKS5mb3JFYWNoKChrZXkpID0+IHtcbiAgICAgICAgICByZXMuc2V0KGtleSwgcmVzdWx0Lm11bHRpVmFsdWVIZWFkZXJzIVtrZXldLm1hcCgodmFsdWUpID0+IGAke3ZhbHVlfWApKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBpZiAocmVzdWx0LmhlYWRlcnMpIHtcbiAgICAgICAgT2JqZWN0LmtleXMocmVzdWx0LmhlYWRlcnMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgICAgICAgIHJlcy5zZXQoa2V5LCBgJHtyZXN1bHQuaGVhZGVycyFba2V5XX1gKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICByZXMuc2VuZChyZXN1bHQuYm9keSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gTG9nIHRoZSBlcnJvciBhbmQgc2VuZCBhIDUwMCByZXNwb25zZVxuICAgICAgY29uc29sZS5sb2coZSk7XG4gICAgICBjb25zb2xlLmxvZygoZSBhcyBFcnJvcikuc3RhY2spO1xuICAgICAgcmVzLnN0YXR1cyg1MDApLnNlbmQoYCR7ZX1gKTtcbiAgICB9XG4gIH0pO1xuXG4gIGFwcC5saXN0ZW4ocG9ydCwgKCkgPT4ge1xuICAgIGNvbnNvbGUubG9nKGBMYW1iZGEgaGFuZGxlciBjYW4gYmUgaW52b2tlZCBhdCBodHRwOi8vbG9jYWxob3N0OiR7cG9ydH1gKTtcbiAgfSk7XG59XG4iXX0=