aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
123 lines • 18.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.HotswapMockSdkProvider = exports.STACK_ID = void 0;
exports.setupHotswapTests = setupHotswapTests;
exports.setupHotswapNestedStackTests = setupHotswapNestedStackTests;
exports.cdkStackArtifactOf = cdkStackArtifactOf;
exports.pushStackResourceSummaries = pushStackResourceSummaries;
exports.pushNestedStackResourceSummaries = pushNestedStackResourceSummaries;
exports.setCurrentCfnStackTemplate = setCurrentCfnStackTemplate;
exports.addTemplateToCloudFormationLookupMock = addTemplateToCloudFormationLookupMock;
exports.stackSummaryOf = stackSummaryOf;
const client_cloudformation_1 = require("@aws-sdk/client-cloudformation");
const client_lambda_1 = require("@aws-sdk/client-lambda");
const deployments_1 = require("../../../lib/api/deployments");
const deployments = require("../../../lib/api/deployments/hotswap-deployments");
const common_1 = require("../../../lib/api/hotswap/common");
const util_1 = require("../../util");
const mock_sdk_1 = require("../../util/mock-sdk");
const fake_cloudformation_stack_1 = require("../fake-cloudformation-stack");
const STACK_NAME = 'withouterrors';
exports.STACK_ID = 'stackId';
let hotswapMockSdkProvider;
let currentCfnStack;
const currentCfnStackResources = [];
let stackTemplates;
let currentNestedCfnStackResources;
function setupHotswapTests() {
(0, mock_sdk_1.restoreSdkMocksToDefault)();
(0, mock_sdk_1.setDefaultSTSMocks)();
jest.resetAllMocks();
// clear the array
currentCfnStackResources.splice(0);
hotswapMockSdkProvider = new HotswapMockSdkProvider();
currentCfnStack = new fake_cloudformation_stack_1.FakeCloudformationStack({
stackName: STACK_NAME,
stackId: exports.STACK_ID,
});
deployments_1.CloudFormationStack.lookup = async (_, _stackName) => {
return currentCfnStack;
};
return hotswapMockSdkProvider;
}
function setupHotswapNestedStackTests(rootStackName) {
(0, mock_sdk_1.restoreSdkMocksToDefault)();
(0, mock_sdk_1.setDefaultSTSMocks)();
jest.resetAllMocks();
currentNestedCfnStackResources = {};
hotswapMockSdkProvider = new HotswapMockSdkProvider(rootStackName);
currentCfnStack = new fake_cloudformation_stack_1.FakeCloudformationStack({
stackName: rootStackName,
stackId: exports.STACK_ID,
});
stackTemplates = {};
deployments_1.CloudFormationStack.lookup = async (_, stackName) => {
currentCfnStack.template = async () => stackTemplates[stackName];
return currentCfnStack;
};
return hotswapMockSdkProvider;
}
function cdkStackArtifactOf(testStackArtifact = {}) {
return (0, util_1.testStack)({
stackName: STACK_NAME,
...testStackArtifact,
});
}
function pushStackResourceSummaries(...items) {
currentCfnStackResources.push(...items);
}
function pushNestedStackResourceSummaries(stackName, ...items) {
if (!currentNestedCfnStackResources[stackName]) {
currentNestedCfnStackResources[stackName] = [];
}
currentNestedCfnStackResources[stackName].push(...items);
}
function setCurrentCfnStackTemplate(template) {
const templateDeepCopy = JSON.parse(JSON.stringify(template)); // deep copy the template, so our tests can mutate one template instead of creating two
currentCfnStack.setTemplate(templateDeepCopy);
}
function addTemplateToCloudFormationLookupMock(stackArtifact) {
const templateDeepCopy = JSON.parse(JSON.stringify(stackArtifact.template)); // deep copy the template, so our tests can mutate one template instead of creating two
stackTemplates[stackArtifact.stackName] = templateDeepCopy;
}
function stackSummaryOf(logicalId, resourceType, physicalResourceId) {
return {
LogicalResourceId: logicalId,
PhysicalResourceId: physicalResourceId,
ResourceType: resourceType,
ResourceStatus: client_cloudformation_1.StackStatus.CREATE_COMPLETE,
LastUpdatedTimestamp: new Date(),
};
}
class HotswapMockSdkProvider extends mock_sdk_1.MockSdkProvider {
constructor(rootStackName) {
super();
mock_sdk_1.mockLambdaClient.on(client_lambda_1.GetFunctionCommand).resolves({
Configuration: {
LastUpdateStatus: 'Successful',
},
});
mock_sdk_1.mockCloudFormationClient.on(client_cloudformation_1.ListStackResourcesCommand).callsFake((input) => {
if (rootStackName) {
const knownStackNames = Object.keys(currentNestedCfnStackResources);
if (input.StackName !== rootStackName && !knownStackNames.includes(input.StackName)) {
throw new Error(`Expected Stack name in listStackResources() call to be a member of ['${rootStackName}, ${knownStackNames}'], but received: '${input.StackName}'`);
}
}
else if (input.StackName !== STACK_NAME) {
throw new Error(`Expected Stack name in listStackResources() call to be: '${STACK_NAME}', but received: '${input.StackName}'`);
}
return {
StackResourceSummaries: rootStackName
? currentNestedCfnStackResources[input.StackName]
: currentCfnStackResources,
};
});
}
tryHotswapDeployment(hotswapMode, stackArtifact, assetParams = {}, hotswapPropertyOverrides) {
let hotswapProps = hotswapPropertyOverrides || new common_1.HotswapPropertyOverrides();
return deployments.tryHotswapDeployment(this, assetParams, currentCfnStack, stackArtifact, hotswapMode, hotswapProps);
}
}
exports.HotswapMockSdkProvider = HotswapMockSdkProvider;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG90c3dhcC10ZXN0LXNldHVwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiaG90c3dhcC10ZXN0LXNldHVwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQTBCQSw4Q0FnQkM7QUFFRCxvRUFpQkM7QUFFRCxnREFPQztBQUVELGdFQUVDO0FBRUQsNEVBS0M7QUFFRCxnRUFHQztBQUVELHNGQUdDO0FBRUQsd0NBWUM7QUF4R0QsMEVBQThHO0FBQzlHLDBEQUE0RDtBQUU1RCw4REFBNkU7QUFDN0UsZ0ZBQWdGO0FBQ2hGLDREQUF3RjtBQUN4RixxQ0FBMEQ7QUFDMUQsa0RBTTZCO0FBQzdCLDRFQUF1RTtBQUV2RSxNQUFNLFVBQVUsR0FBRyxlQUFlLENBQUM7QUFDdEIsUUFBQSxRQUFRLEdBQUcsU0FBUyxDQUFDO0FBRWxDLElBQUksc0JBQThDLENBQUM7QUFDbkQsSUFBSSxlQUF3QyxDQUFDO0FBQzdDLE1BQU0sd0JBQXdCLEdBQTJCLEVBQUUsQ0FBQztBQUM1RCxJQUFJLGNBQTRDLENBQUM7QUFDakQsSUFBSSw4QkFBK0UsQ0FBQztBQUVwRixTQUFnQixpQkFBaUI7SUFDL0IsSUFBQSxtQ0FBd0IsR0FBRSxDQUFDO0lBQzNCLElBQUEsNkJBQWtCLEdBQUUsQ0FBQztJQUNyQixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDckIsa0JBQWtCO0lBQ2xCLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNuQyxzQkFBc0IsR0FBRyxJQUFJLHNCQUFzQixFQUFFLENBQUM7SUFDdEQsZUFBZSxHQUFHLElBQUksbURBQXVCLENBQUM7UUFDNUMsU0FBUyxFQUFFLFVBQVU7UUFDckIsT0FBTyxFQUFFLGdCQUFRO0tBQ2xCLENBQUMsQ0FBQztJQUNILGlDQUFtQixDQUFDLE1BQU0sR0FBRyxLQUFLLEVBQUUsQ0FBd0IsRUFBRSxVQUFrQixFQUFFLEVBQUU7UUFDbEYsT0FBTyxlQUFlLENBQUM7SUFDekIsQ0FBQyxDQUFDO0lB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d3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgeyBMaXN0U3RhY2tSZXNvdXJjZXNDb21tYW5kLCBTdGFja1Jlc291cmNlU3VtbWFyeSwgU3RhY2tTdGF0dXMgfSBmcm9tICdAYXdzLXNkay9jbGllbnQtY2xvdWRmb3JtYXRpb24nO1xuaW1wb3J0IHsgR2V0RnVuY3Rpb25Db21tYW5kIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWxhbWJkYSc7XG5pbXBvcnQgeyBJQ2xvdWRGb3JtYXRpb25DbGllbnQsIFN1Y2Nlc3NmdWxEZXBsb3lTdGFja1Jlc3VsdCB9IGZyb20gJy4uLy4uLy4uL2xpYi9hcGknO1xuaW1wb3J0IHsgQ2xvdWRGb3JtYXRpb25TdGFjaywgVGVtcGxhdGUgfSBmcm9tICcuLi8uLi8uLi9saWIvYXBpL2RlcGxveW1lbnRzJztcbmltcG9ydCAqIGFzIGRlcGxveW1lbnRzIGZyb20gJy4uLy4uLy4uL2xpYi9hcGkvZGVwbG95bWVudHMvaG90c3dhcC1kZXBsb3ltZW50cyc7XG5pbXBvcnQgeyBIb3Rzd2FwTW9kZSwgSG90c3dhcFByb3BlcnR5T3ZlcnJpZGVzIH0gZnJvbSAnLi4vLi4vLi4vbGliL2FwaS9ob3Rzd2FwL2NvbW1vbic7XG5pbXBvcnQgeyB0ZXN0U3RhY2ssIFRlc3RTdGFja0FydGlmYWN0IH0gZnJvbSAnLi4vLi4vdXRpbCc7XG5pbXBvcnQge1xuICBtb2NrQ2xvdWRGb3JtYXRpb25DbGllbnQsXG4gIG1vY2tMYW1iZGFDbGllbnQsXG4gIE1vY2tTZGtQcm92aWRlcixcbiAgcmVzdG9yZVNka01vY2tzVG9EZWZhdWx0LFxuICBzZXREZWZhdWx0U1RTTW9ja3MsXG59IGZyb20gJy4uLy4uL3V0aWwvbW9jay1zZGsnO1xuaW1wb3J0IHsgRmFrZUNsb3VkZm9ybWF0aW9uU3RhY2sgfSBmcm9tICcuLi9mYWtlLWNsb3VkZm9ybWF0aW9uLXN0YWNrJztcblxuY29uc3QgU1RBQ0tfTkFNRSA9ICd3aXRob3V0ZXJyb3JzJztcbmV4cG9ydCBjb25zdCBTVEFDS19JRCA9ICdzdGFja0lkJztcblxubGV0IGhvdHN3YXBNb2NrU2RrUHJvdmlkZXI6IEhvdHN3YXBNb2NrU2RrUHJvdmlkZXI7XG5sZXQgY3VycmVudENmblN0YWNrOiBGYWtlQ2xvdWRmb3JtYXRpb25TdGFjaztcbmNvbnN0IGN1cnJlbnRDZm5TdGFja1Jlc291cmNlczogU3RhY2tSZXNvdXJjZVN1bW1hcnlbXSA9IFtdO1xubGV0IHN0YWNrVGVtcGxhdGVzOiB7IFtzdGFja05hbWU6IHN0cmluZ106IGFueSB9O1xubGV0IGN1cnJlbnROZXN0ZWRDZm5TdGFja1Jlc291cmNlczogeyBbc3RhY2tOYW1lOiBzdHJpbmddOiBTdGFja1Jlc291cmNlU3VtbWFyeVtdIH07XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXR1cEhvdHN3YXBUZXN0cygpOiBIb3Rzd2FwTW9ja1Nka1Byb3ZpZGVyIHtcbiAgcmVzdG9yZVNka01vY2tzVG9EZWZhdWx0KCk7XG4gIHNldERlZmF1bHRTVFNNb2NrcygpO1xuICBqZXN0LnJlc2V0QWxsTW9ja3MoKTtcbiAgLy8gY2xlYXIgdGhlIGFycmF5XG4gIGN1cnJlbnRDZm5TdGFja1Jlc291cmNlcy5zcGxpY2UoMCk7XG4gIGhvdHN3YXBNb2NrU2RrUHJvdmlkZXIgPSBuZXcgSG90c3dhcE1vY2tTZGtQcm92aWRlcigpO1xuICBjdXJyZW50Q2ZuU3RhY2sgPSBuZXcgRmFrZUNsb3VkZm9ybWF0aW9uU3RhY2soe1xuICAgIHN0YWNrTmFtZTogU1RBQ0tfTkFNRSxcbiAgICBzdGFja0lkOiBTVEFDS19JRCxcbiAgfSk7XG4gIENsb3VkRm9ybWF0aW9uU3RhY2subG9va3VwID0gYXN5bmMgKF86IElDbG91ZEZvcm1hdGlvbkNsaWVudCwgX3N0YWNrTmFtZTogc3RyaW5nKSA9PiB7XG4gICAgcmV0dXJuIGN1cnJlbnRDZm5TdGFjaztcbiAgfTtcblxuICByZXR1cm4gaG90c3dhcE1vY2tTZGtQcm92aWRlcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHNldHVwSG90c3dhcE5lc3RlZFN0YWNrVGVzdHMocm9vdFN0YWNrTmFtZTogc3RyaW5nKSB7XG4gIHJlc3RvcmVTZGtNb2Nrc1RvRGVmYXVsdCgpO1xuICBzZXREZWZhdWx0U1RTTW9ja3MoKTtcbiAgamVzdC5yZXNldEFsbE1vY2tzKCk7XG4gIGN1cnJlbnROZXN0ZWRDZm5TdGFja1Jlc291cmNlcyA9IHt9O1xuICBob3Rzd2FwTW9ja1Nka1Byb3ZpZGVyID0gbmV3IEhvdHN3YXBNb2NrU2RrUHJvdmlkZXIocm9vdFN0YWNrTmFtZSk7XG4gIGN1cnJlbnRDZm5TdGFjayA9IG5ldyBGYWtlQ2xvdWRmb3JtYXRpb25TdGFjayh7XG4gICAgc3RhY2tOYW1lOiByb290U3RhY2tOYW1lLFxuICAgIHN0YWNrSWQ6IFNUQUNLX0lELFxuICB9KTtcbiAgc3RhY2tUZW1wbGF0ZXMgPSB7fTtcbiAgQ2xvdWRGb3JtYXRpb25TdGFjay5sb29rdXAgPSBhc3luYyAoXzogSUNsb3VkRm9ybWF0aW9uQ2xpZW50LCBzdGFja05hbWU6IHN0cmluZykgPT4ge1xuICAgIGN1cnJlbnRDZm5TdGFjay50ZW1wbGF0ZSA9IGFzeW5jICgpID0+IHN0YWNrVGVtcGxhdGVzW3N0YWNrTmFtZV07XG4gICAgcmV0dXJuIGN1cnJlbnRDZm5TdGFjaztcbiAgfTtcblxuICByZXR1cm4gaG90c3dhcE1vY2tTZGtQcm92aWRlcjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNka1N0YWNrQXJ0aWZhY3RPZihcbiAgdGVzdFN0YWNrQXJ0aWZhY3Q6IFBhcnRpYWw8VGVzdFN0YWNrQXJ0aWZhY3Q+ID0ge30sXG4pOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3Qge1xuICByZXR1cm4gdGVzdFN0YWNrKHtcbiAgICBzdGFja05hbWU6IFNUQUNLX05BTUUsXG4gICAgLi4udGVzdFN0YWNrQXJ0aWZhY3QsXG4gIH0pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHVzaFN0YWNrUmVzb3VyY2VTdW1tYXJpZXMoLi4uaXRlbXM6IFN0YWNrUmVzb3VyY2VTdW1tYXJ5W10pIHtcbiAgY3VycmVudENmblN0YWNrUmVzb3VyY2VzLnB1c2goLi4uaXRlbXMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcHVzaE5lc3RlZFN0YWNrUmVzb3VyY2VTdW1tYXJpZXMoc3RhY2tOYW1lOiBzdHJpbmcsIC4uLml0ZW1zOiBTdGFja1Jlc291cmNlU3VtbWFyeVtdKSB7XG4gIGlmICghY3VycmVudE5lc3RlZENmblN0YWNrUmVzb3VyY2VzW3N0YWNrTmFtZV0pIHtcbiAgICBjdXJyZW50TmVzdGVkQ2ZuU3RhY2tSZXNvdXJjZXNbc3RhY2tOYW1lXSA9IFtdO1xuICB9XG4gIGN1cnJlbnROZXN0ZWRDZm5TdGFja1Jlc291cmNlc1tzdGFja05hbWVdLnB1c2goLi4uaXRlbXMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2V0Q3VycmVudENmblN0YWNrVGVtcGxhdGUodGVtcGxhdGU6IFRlbXBsYXRlKSB7XG4gIGNvbnN0IHRlbXBsYXRlRGVlcENvcHkgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRlbXBsYXRlKSk7IC8vIGRlZXAgY29weSB0aGUgdGVtcGxhdGUsIHNvIG91ciB0ZXN0cyBjYW4gbXV0YXRlIG9uZSB0ZW1wbGF0ZSBpbnN0ZWFkIG9mIGNyZWF0aW5nIHR3b1xuICBjdXJyZW50Q2ZuU3RhY2suc2V0VGVtcGxhdGUodGVtcGxhdGVEZWVwQ29weSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhZGRUZW1wbGF0ZVRvQ2xvdWRGb3JtYXRpb25Mb29rdXBNb2NrKHN0YWNrQXJ0aWZhY3Q6IGN4YXBpLkNsb3VkRm9ybWF0aW9uU3RhY2tBcnRpZmFjdCkge1xuICBjb25zdCB0ZW1wbGF0ZURlZXBDb3B5ID0gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShzdGFja0FydGlmYWN0LnRlbXBsYXRlKSk7IC8vIGRlZXAgY29weSB0aGUgdGVtcGxhdGUsIHNvIG91ciB0ZXN0cyBjYW4gbXV0YXRlIG9uZSB0ZW1wbGF0ZSBpbnN0ZWFkIG9mIGNyZWF0aW5nIHR3b1xuICBzdGFja1RlbXBsYXRlc1tzdGFja0FydGlmYWN0LnN0YWNrTmFtZV0gPSB0ZW1wbGF0ZURlZXBDb3B5O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc3RhY2tTdW1tYXJ5T2YoXG4gIGxvZ2ljYWxJZDogc3RyaW5nLFxuICByZXNvdXJjZVR5cGU6IHN0cmluZyxcbiAgcGh5c2ljYWxSZXNvdXJjZUlkOiBzdHJpbmcsXG4pOiBTdGFja1Jlc291cmNlU3VtbWFyeSB7XG4gIHJldHVybiB7XG4gICAgTG9naWNhbFJlc291cmNlSWQ6IGxvZ2ljYWxJZCxcbiAgICBQaHlzaWNhbFJlc291cmNlSWQ6IHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgICBSZXNvdXJjZVR5cGU6IHJlc291cmNlVHlwZSxcbiAgICBSZXNvdXJjZVN0YXR1czogU3RhY2tTdGF0dXMuQ1JFQVRFX0NPTVBMRVRFLFxuICAgIExhc3RVcGRhdGVkVGltZXN0YW1wOiBuZXcgRGF0ZSgpLFxuICB9O1xufVxuXG5leHBvcnQgY2xhc3MgSG90c3dhcE1vY2tTZGtQcm92aWRlciBleHRlbmRzIE1vY2tTZGtQcm92aWRlciB7XG4gIGNvbnN0cnVjdG9yKHJvb3RTdGFja05hbWU/OiBzdHJpbmcpIHtcbiAgICBzdXBlcigpO1xuXG4gICAgbW9ja0xhbWJkYUNsaWVudC5vbihHZXRGdW5jdGlvbkNvbW1hbmQpLnJlc29sdmVzKHtcbiAgICAgIENvbmZpZ3VyYXRpb246IHtcbiAgICAgICAgTGFzdFVwZGF0ZVN0YXR1czogJ1N1Y2Nlc3NmdWwnLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIG1vY2tDbG91ZEZvcm1hdGlvbkNsaWVudC5vbihMaXN0U3RhY2tSZXNvdXJjZXNDb21tYW5kKS5jYWxsc0Zha2UoKGlucHV0KSA9PiB7XG4gICAgICBpZiAocm9vdFN0YWNrTmFtZSkge1xuICAgICAgICBjb25zdCBrbm93blN0YWNrTmFtZXMgPSBPYmplY3Qua2V5cyhjdXJyZW50TmVzdGVkQ2ZuU3RhY2tSZXNvdXJjZXMpO1xuICAgICAgICBpZiAoaW5wdXQuU3RhY2tOYW1lICE9PSByb290U3RhY2tOYW1lICYmICFrbm93blN0YWNrTmFtZXMuaW5jbHVkZXMoaW5wdXQuU3RhY2tOYW1lKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgIGBFeHBlY3RlZCBTdGFjayBuYW1lIGluIGxpc3RTdGFja1Jlc291cmNlcygpIGNhbGwgdG8gYmUgYSBtZW1iZXIgb2YgWycke3Jvb3RTdGFja05hbWV9LCAke2tub3duU3RhY2tOYW1lc30nXSwgYnV0IHJlY2VpdmVkOiAnJHtpbnB1dC5TdGFja05hbWV9J2AsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpbnB1dC5TdGFja05hbWUgIT09IFNUQUNLX05BTUUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBFeHBlY3RlZCBTdGFjayBuYW1lIGluIGxpc3RTdGFja1Jlc291cmNlcygpIGNhbGwgdG8gYmU6ICcke1NUQUNLX05BTUV9JywgYnV0IHJlY2VpdmVkOiAnJHtpbnB1dC5TdGFja05hbWV9J2AsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBTdGFja1Jlc291cmNlU3VtbWFyaWVzOiByb290U3RhY2tOYW1lXG4gICAgICAgICAgPyBjdXJyZW50TmVzdGVkQ2ZuU3RhY2tSZXNvdXJjZXNbaW5wdXQuU3RhY2tOYW1lXVxuICAgICAgICAgIDogY3VycmVudENmblN0YWNrUmVzb3VyY2VzLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyB0cnlIb3Rzd2FwRGVwbG95bWVudChcbiAgICBob3Rzd2FwTW9kZTogSG90c3dhcE1vZGUsXG4gICAgc3RhY2tBcnRpZmFjdDogY3hhcGkuQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0LFxuICAgIGFzc2V0UGFyYW1zOiB7IFtrZXk6IHN0cmluZ106IHN0cmluZyB9ID0ge30sXG4gICAgaG90c3dhcFByb3BlcnR5T3ZlcnJpZGVzPzogSG90c3dhcFByb3BlcnR5T3ZlcnJpZGVzLFxuICApOiBQcm9taXNlPFN1Y2Nlc3NmdWxEZXBsb3lTdGFja1Jlc3VsdCB8IHVuZGVmaW5lZD4ge1xuICAgIGxldCBob3Rzd2FwUHJvcHMgPSBob3Rzd2FwUHJvcGVydHlPdmVycmlkZXMgfHwgbmV3IEhvdHN3YXBQcm9wZXJ0eU92ZXJyaWRlcygpO1xuICAgIHJldHVybiBkZXBsb3ltZW50cy50cnlIb3Rzd2FwRGVwbG95bWVudCh0aGlzLCBhc3NldFBhcmFtcywgY3VycmVudENmblN0YWNrLCBzdGFja0FydGlmYWN0LCBob3Rzd2FwTW9kZSwgaG90c3dhcFByb3BzKTtcbiAgfVxufVxuIl19