@scloud/lambda-api
Version:
Lambda handler for API Gateway proxy requests
182 lines • 20.7 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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.standardPath = standardPath;
exports.standardQueryParameters = standardQueryParameters;
exports.standardHeaders = standardHeaders;
exports.parseBody = parseBody;
exports.parseCookie = parseCookie;
exports.buildCookie = buildCookie;
exports.parseRequest = parseRequest;
exports.matchRoute = matchRoute;
const cookie = __importStar(require("cookie"));
/**
* Ensures the path is lowercased, always has a leading slash and never a trailing slash
* @param path APIGatewayProxyEvent.path
*/
function standardPath(path) {
// Get path segments, filtering out any blanks
const segments = path.split('/').filter((segment) => segment);
// Return path
return `/${segments.join('/').toLowerCase()}`;
}
/**
* Ensures a non-null object containing only query-string parameters that have a value.
* @param query APIGatewayProxyEvent.query
*/
function standardQueryParameters(query) {
if (!query)
return {};
const result = {};
Object.keys(query).forEach((parameter) => {
const value = query[parameter];
if (value)
result[parameter] = value;
});
return result;
}
/**
* Ensures all header names are lowercased for ease of access.
* @param headers APIGatewayProxyEvent.headers
*/
function standardHeaders(headers) {
const result = {};
Object.keys(headers).forEach((name) => {
const value = headers[name];
if (value) {
// Provide both original-case and lowercased (standardised) header names for ease of access:
result[name] = value;
result[name.toLowerCase()] = value;
}
});
return result;
}
/**
* Parses the body (if present) from application/x-www-form-urlencoded or JSON string.
* If the body fails to parse as JSOn, the raw body is returned.
* @param body APIGatewayProxyEvent.body
*/
function parseBody(body, isBase64Encoded, contentType = 'application/json') {
if (!body)
return {};
const content = isBase64Encoded ? Buffer.from(body, 'base64').toString('utf8') : body;
try {
if ((contentType || '').toLowerCase() === 'application/x-www-form-urlencoded') {
return Object.fromEntries(new URLSearchParams(content));
}
else {
// Default to parsing as JSON:
return JSON.parse(content);
}
}
catch (e) {
console.error(`Error parsing request body: ${e}`);
}
// Fallback to returning the raw body
return content;
}
/**
* Parses the cookie, if any, returning at minimum an empty object.
* @param headers APIGatewayProxyEvent.headers
*/
function parseCookie(headers) {
const header = headers.cookie || headers.Cookie || '';
return cookie.parse(header);
}
function buildCookie(values) {
if (!values)
return undefined;
const header = [];
const oneYear = 60 * 60 * 24 * 365;
Object.keys(values).forEach((key) => {
const value = values[key];
if (value === '') {
// If explicitly unset, expire the cookie value
header.push(cookie.serialize(key, '', {
expires: new Date(), secure: true, httpOnly: true, sameSite: 'strict',
}));
}
else if (value) {
// Otherwise, set it only if a value was given
header.push(cookie.serialize(key, value, {
maxAge: oneYear, secure: true, httpOnly: true, sameSite: 'strict',
}));
}
});
return header;
}
function parseRequest(event) {
return {
method: event.httpMethod,
path: standardPath(event.path),
query: standardQueryParameters(event.queryStringParameters),
headers: standardHeaders(event.headers),
body: parseBody(event.body, event.isBase64Encoded, event.headers['content-type']),
cookies: parseCookie(event.headers),
pathParameters: {}, // These need to be parsed as part of route matching
context: {}, // You can add any custom values you need to the request via this context
};
}
function matchRoute(routes, path) {
// Simple match
if (routes[path])
return { route: routes[path], params: {} };
// List paths to check
const paths = Object.keys(routes);
// Case-insensitive match
for (let p = 0; p < paths.length; p++) {
const candidate = paths[p];
if (candidate.toLowerCase() === path.toLowerCase())
return { route: routes[candidate], params: {} };
}
// Path-parameter matching
const pathSegments = path.split('/');
for (let p = 0; p < paths.length; p++) {
const candidate = paths[p];
const candidateSegments = candidate.split('/');
// First check: length match
if (pathSegments.length !== candidateSegments.length)
continue;
for (let s = 0; s < pathSegments.length; s++) {
const params = {};
const pathSegment = pathSegments[s];
const candidateSegment = candidateSegments[s];
if (candidateSegment.startsWith('{') && candidateSegment.endsWith('}')) {
// Path parameter
const name = candidateSegment.slice(1, -1);
params[name] = pathSegment;
}
else if (pathSegment !== candidateSegment) {
break;
}
if (s === pathSegments.length - 1) {
// Matched all segments
return { route: routes[candidate], params };
}
}
}
return { route: undefined, params: {} };
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFRQSxvQ0FLQztBQU1ELDBEQVFDO0FBTUQsMENBV0M7QUFPRCw4QkFrQkM7QUFNRCxrQ0FHQztBQUVELGtDQXNCQztBQUVELG9DQVdDO0FBRUQsZ0NBMkNDO0FBL0pELCtDQUFpQztBQUdqQzs7O0dBR0c7QUFDSCxTQUFnQixZQUFZLENBQUMsSUFBWTtJQUN2Qyw4Q0FBOEM7SUFDOUMsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzlELGNBQWM7SUFDZCxPQUFPLElBQUksUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDO0FBQ2hELENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQix1QkFBdUIsQ0FBQyxLQUFxRDtJQUMzRixJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3RCLE1BQU0sTUFBTSxHQUFnQyxFQUFFLENBQUM7SUFDL0MsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtRQUN2QyxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDL0IsSUFBSSxLQUFLO1lBQUUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEtBQUssQ0FBQztJQUN2QyxDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQixlQUFlLENBQUMsT0FBZ0Q7SUFDOUUsTUFBTSxNQUFNLEdBQWdDLEVBQUUsQ0FBQztJQUMv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QztZQUM3QixDQUFDO2lCQUFNLElBQUksV0FBVyxLQUFLLGdCQUFnQixFQUFFLENBQUM7Z0JBQzVDLE1BQU07WUFDUixDQUFDO1lBRUQsSUFBSSxDQUFDLEtBQUssWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDbEMsdUJBQXVCO2dCQUN2QixPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQztZQUM5QyxDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLENBQUM7QUFDMUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFQSUdhdGV3YXlQcm94eUV2ZW50IH0gZnJvbSAnYXdzLWxhbWJkYSc7XG5pbXBvcnQgKiBhcyBjb29raWUgZnJvbSAnY29va2llJztcbmltcG9ydCB7IFJlcXVlc3QsIFJvdXRlLCBSb3V0ZXMgfSBmcm9tICcuL3R5cGVzJztcblxuLyoqXG4gKiBFbnN1cmVzIHRoZSBwYXRoIGlzIGxvd2VyY2FzZWQsIGFsd2F5cyBoYXMgYSBsZWFkaW5nIHNsYXNoIGFuZCBuZXZlciBhIHRyYWlsaW5nIHNsYXNoXG4gKiBAcGFyYW0gcGF0aCBBUElHYXRld2F5UHJveHlFdmVudC5wYXRoXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGFuZGFyZFBhdGgocGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgLy8gR2V0IHBhdGggc2VnbWVudHMsIGZpbHRlcmluZyBvdXQgYW55IGJsYW5rc1xuICBjb25zdCBzZWdtZW50cyA9IHBhdGguc3BsaXQoJy8nKS5maWx0ZXIoKHNlZ21lbnQpID0+IHNlZ21lbnQpO1xuICAvLyBSZXR1cm4gcGF0aFxuICByZXR1cm4gYC8ke3NlZ21lbnRzLmpvaW4oJy8nKS50b0xvd2VyQ2FzZSgpfWA7XG59XG5cbi8qKlxuICogRW5zdXJlcyBhIG5vbi1udWxsIG9iamVjdCBjb250YWluaW5nIG9ubHkgcXVlcnktc3RyaW5nIHBhcmFtZXRlcnMgdGhhdCBoYXZlIGEgdmFsdWUuXG4gKiBAcGFyYW0gcXVlcnkgQVBJR2F0ZXdheVByb3h5RXZlbnQucXVlcnlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YW5kYXJkUXVlcnlQYXJhbWV0ZXJzKHF1ZXJ5OiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQ7IH0gfCBudWxsKTogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9IHtcbiAgaWYgKCFxdWVyeSkgcmV0dXJuIHt9O1xuICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZzsgfSA9IHt9O1xuICBPYmplY3Qua2V5cyhxdWVyeSkuZm9yRWFjaCgocGFyYW1ldGVyKSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBxdWVyeVtwYXJhbWV0ZXJdO1xuICAgIGlmICh2YWx1ZSkgcmVzdWx0W3BhcmFtZXRlcl0gPSB2YWx1ZTtcbiAgfSk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogRW5zdXJlcyBhbGwgaGVhZGVyIG5hbWVzIGFyZSBsb3dlcmNhc2VkIGZvciBlYXNlIG9mIGFjY2Vzcy5cbiAqIEBwYXJhbSBoZWFkZXJzIEFQSUdhdGV3YXlQcm94eUV2ZW50LmhlYWRlcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0YW5kYXJkSGVhZGVycyhoZWFkZXJzOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfCB1bmRlZmluZWQ7IH0pOiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmc7IH0ge1xuICBjb25zdCByZXN1bHQ6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZzsgfSA9IHt9O1xuICBPYmplY3Qua2V5cyhoZWFkZXJzKS5mb3JFYWNoKChuYW1lKSA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSBoZWFkZXJzW25hbWVdO1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgLy8gUHJvdmlkZSBib3RoIG9yaWdpbmFsLWNhc2UgYW5kIGxvd2VyY2FzZWQgKHN0YW5kYXJkaXNlZCkgaGVhZGVyIG5hbWVzIGZvciBlYXNlIG9mIGFjY2VzczpcbiAgICAgIHJlc3VsdFtuYW1lXSA9IHZhbHVlO1xuICAgICAgcmVzdWx0W25hbWUudG9Mb3dlckNhc2UoKV0gPSB2YWx1ZTtcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIFBhcnNlcyB0aGUgYm9keSAoaWYgcHJlc2VudCkgZnJvbSBhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQgb3IgSlNPTiBzdHJpbmcuXG4gKiBJZiB0aGUgYm9keSBmYWlscyB0byBwYXJzZSBhcyBKU09uLCB0aGUgcmF3IGJvZHkgaXMgcmV0dXJuZWQuXG4gKiBAcGFyYW0gYm9keSBBUElHYXRld2F5UHJveHlFdmVudC5ib2R5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJvZHkoYm9keTogc3RyaW5nIHwgbnVsbCwgaXNCYXNlNjRFbmNvZGVkOiBib29sZWFuLCBjb250ZW50VHlwZTogc3RyaW5nID0gJ2FwcGxpY2F0aW9uL2pzb24nKTogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBzdHJpbmcge1xuICBpZiAoIWJvZHkpIHJldHVybiB7fTtcblxuICBjb25zdCBjb250ZW50ID0gaXNCYXNlNjRFbmNvZGVkID8gQnVmZmVyLmZyb20oYm9keSwgJ2Jhc2U2NCcpLnRvU3RyaW5nKCd1dGY4JykgOiBib2R5O1xuXG4gIHRyeSB7XG4gICAgaWYgKChjb250ZW50VHlwZSB8fCAnJykudG9Mb3dlckNhc2UoKSA9PT0gJ2FwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZCcpIHtcbiAgICAgIHJldHVybiBPYmplY3QuZnJvbUVudHJpZXMobmV3IFVSTFNlYXJjaFBhcmFtcyhjb250ZW50KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIERlZmF1bHQgdG8gcGFyc2luZyBhcyBKU09OOlxuICAgICAgcmV0dXJuIEpTT04ucGFyc2UoY29udGVudCk7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc29sZS5lcnJvcihgRXJyb3IgcGFyc2luZyByZXF1ZXN0IGJvZHk6ICR7ZX1gKTtcbiAgfVxuXG4gIC8vIEZhbGxiYWNrIHRvIHJldHVybmluZyB0aGUgcmF3IGJvZHlcbiAgcmV0dXJuIGNvbnRlbnQ7XG59XG5cbi8qKlxuICogUGFyc2VzIHRoZSBjb29raWUsIGlmIGFueSwgcmV0dXJuaW5nIGF0IG1pbmltdW0gYW4gZW1wdHkgb2JqZWN0LlxuICogQHBhcmFtIGhlYWRlcnMgQVBJR2F0ZXdheVByb3h5RXZlbnQuaGVhZGVyc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VDb29raWUoaGVhZGVyczogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nIHwgdW5kZWZpbmVkOyB9KTogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9IHtcbiAgY29uc3QgaGVhZGVyID0gaGVhZGVycy5jb29raWUgfHwgaGVhZGVycy5Db29raWUgfHwgJyc7XG4gIHJldHVybiBjb29raWUucGFyc2UoaGVhZGVyKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQ29va2llKHZhbHVlczogeyBba2V5OiBzdHJpbmddOiBzdHJpbmc7IH0gfCB1bmRlZmluZWQpOiBzdHJpbmdbXSB8IHVuZGVmaW5lZCB7XG4gIGlmICghdmFsdWVzKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGhlYWRlcjogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgb25lWWVhciA9IDYwICogNjAgKiAyNCAqIDM2NTtcblxuICBPYmplY3Qua2V5cyh2YWx1ZXMpLmZvckVhY2goKGtleSkgPT4ge1xuICAgIGNvbnN0IHZhbHVlID0gdmFsdWVzW2tleV07XG4gICAgaWYgKHZhbHVlID09PSAnJykge1xuICAgICAgLy8gSWYgZXhwbGljaXRseSB1bnNldCwgZXhwaXJlIHRoZSBjb29raWUgdmFsdWVcbiAgICAgIGhlYWRlci5wdXNoKGNvb2tpZS5zZXJpYWxpemUoa2V5LCAnJywge1xuICAgICAgICBleHBpcmVzOiBuZXcgRGF0ZSgpLCBzZWN1cmU6IHRydWUsIGh0dHBPbmx5OiB0cnVlLCBzYW1lU2l0ZTogJ3N0cmljdCcsXG4gICAgICB9KSk7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSkge1xuICAgICAgLy8gT3RoZXJ3aXNlLCBzZXQgaXQgb25seSBpZiBhIHZhbHVlIHdhcyBnaXZlblxuICAgICAgaGVhZGVyLnB1c2goY29va2llLnNlcmlhbGl6ZShrZXksIHZhbHVlLCB7XG4gICAgICAgIG1heEFnZTogb25lWWVhciwgc2VjdXJlOiB0cnVlLCBodHRwT25seTogdHJ1ZSwgc2FtZVNpdGU6ICdzdHJpY3QnLFxuICAgICAgfSkpO1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGhlYWRlcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUmVxdWVzdChldmVudDogQVBJR2F0ZXdheVByb3h5RXZlbnQpOiBSZXF1ZXN0IHtcbiAgcmV0dXJuIHtcbiAgICBtZXRob2Q6IGV2ZW50Lmh0dHBNZXRob2QsXG4gICAgcGF0aDogc3RhbmRhcmRQYXRoKGV2ZW50LnBhdGgpLFxuICAgIHF1ZXJ5OiBzdGFuZGFyZFF1ZXJ5UGFyYW1ldGVycyhldmVudC5xdWVyeVN0cmluZ1BhcmFtZXRlcnMpLFxuICAgIGhlYWRlcnM6IHN0YW5kYXJkSGVhZGVycyhldmVudC5oZWFkZXJzKSxcbiAgICBib2R5OiBwYXJzZUJvZHkoZXZlbnQuYm9keSwgZXZlbnQuaXNCYXNlNjRFbmNvZGVkLCBldmVudC5oZWFkZXJzWydjb250ZW50LXR5cGUnXSksXG4gICAgY29va2llczogcGFyc2VDb29raWUoZXZlbnQuaGVhZGVycyksXG4gICAgcGF0aFBhcmFtZXRlcnM6IHt9LCAvLyBUaGVzZSBuZWVkIHRvIGJlIHBhcnNlZCBhcyBwYXJ0IG9mIHJvdXRlIG1hdGNoaW5nXG4gICAgY29udGV4dDoge30sIC8vIFlvdSBjYW4gYWRkIGFueSBjdXN0b20gdmFsdWVzIHlvdSBuZWVkIHRvIHRoZSByZXF1ZXN0IHZpYSB0aGlzIGNvbnRleHRcbiAgfTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1hdGNoUm91dGUocm91dGVzOiBSb3V0ZXMsIHBhdGg6IHN0cmluZyk6IHsgcm91dGU6IFJvdXRlIHwgdW5kZWZpbmVkLCBwYXJhbXM6IHsgW25hbWU6IHN0cmluZ106IHN0cmluZzsgfTsgfSB7XG4gIC8vIFNpbXBsZSBtYXRjaFxuICBpZiAocm91dGVzW3BhdGhdKSByZXR1cm4geyByb3V0ZTogcm91dGVzW3BhdGhdLCBwYXJhbXM6IHt9IH07XG5cbiAgLy8gTGlzdCBwYXRocyB0byBjaGVja1xuICBjb25zdCBwYXRocyA9IE9iamVjdC5rZXlzKHJvdXRlcyk7XG5cbiAgLy8gQ2FzZS1pbnNlbnNpdGl2ZSBtYXRjaFxuICBmb3IgKGxldCBwID0gMDsgcCA8IHBhdGhzLmxlbmd0aDsgcCsrKSB7XG4gICAgY29uc3QgY2FuZGlkYXRlID0gcGF0aHNbcF07XG4gICAgaWYgKGNhbmRpZGF0ZS50b0xvd2VyQ2FzZSgpID09PSBwYXRoLnRvTG93ZXJDYXNlKCkpIHJldHVybiB7IHJvdXRlOiByb3V0ZXNbY2FuZGlkYXRlXSwgcGFyYW1zOiB7fSB9O1xuICB9XG5cbiAgLy8gUGF0aC1wYXJhbWV0ZXIgbWF0Y2hpbmdcbiAgY29uc3QgcGF0aFNlZ21lbnRzID0gcGF0aC5zcGxpdCgnLycpO1xuXG4gIGZvciAobGV0IHAgPSAwOyBwIDwgcGF0aHMubGVuZ3RoOyBwKyspIHtcbiAgICBjb25zdCBjYW5kaWRhdGUgPSBwYXRoc1twXTtcbiAgICBjb25zdCBjYW5kaWRhdGVTZWdtZW50cyA9IGNhbmRpZGF0ZS5zcGxpdCgnLycpO1xuXG4gICAgLy8gRmlyc3QgY2hlY2s6IGxlbmd0aCBtYXRjaFxuICAgIGlmIChwYXRoU2VnbWVudHMubGVuZ3RoICE9PSBjYW5kaWRhdGVTZWdtZW50cy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgZm9yIChsZXQgcyA9IDA7IHMgPCBwYXRoU2VnbWVudHMubGVuZ3RoOyBzKyspIHtcbiAgICAgIGNvbnN0IHBhcmFtczogeyBbbmFtZTogc3RyaW5nXTogc3RyaW5nOyB9ID0ge307XG4gICAgICBjb25zdCBwYXRoU2VnbWVudCA9IHBhdGhTZWdtZW50c1tzXTtcbiAgICAgIGNvbnN0IGNhbmRpZGF0ZVNlZ21lbnQgPSBjYW5kaWRhdGVTZWdtZW50c1tzXTtcbiAgICAgIGlmIChjYW5kaWRhdGVTZWdtZW50LnN0YXJ0c1dpdGgoJ3snKSAmJiBjYW5kaWRhdGVTZWdtZW50LmVuZHNXaXRoKCd9JykpIHtcbiAgICAgICAgLy8gUGF0aCBwYXJhbWV0ZXJcbiAgICAgICAgY29uc3QgbmFtZSA9IGNhbmRpZGF0ZVNlZ21lbnQuc2xpY2UoMSwgLTEpO1xuICAgICAgICBwYXJhbXNbbmFtZV0gPSBwYXRoU2VnbWVudDtcbiAgICAgIH0gZWxzZSBpZiAocGF0aFNlZ21lbnQgIT09IGNhbmRpZGF0ZVNlZ21lbnQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGlmIChzID09PSBwYXRoU2VnbWVudHMubGVuZ3RoIC0gMSkge1xuICAgICAgICAvLyBNYXRjaGVkIGFsbCBzZWdtZW50c1xuICAgICAgICByZXR1cm4geyByb3V0ZTogcm91dGVzW2NhbmRpZGF0ZV0sIHBhcmFtcyB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IHJvdXRlOiB1bmRlZmluZWQsIHBhcmFtczoge30gfTtcbn1cbiJdfQ==