aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
177 lines • 25.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MockCloudExecutable = exports.DEFAULT_FAKE_TEMPLATE = void 0;
exports.testAssembly = testAssembly;
exports.testStack = testStack;
exports.instanceMockFrom = instanceMockFrom;
exports.withMocked = withMocked;
exports.sleep = sleep;
const fs = require("fs");
const path = require("path");
const cloud_assembly_schema_1 = require("@aws-cdk/cloud-assembly-schema");
const cx_api_1 = require("@aws-cdk/cx-api");
const assembly_versions_1 = require("./api/assembly-versions");
const mock_sdk_1 = require("./util/mock-sdk");
const cloud_executable_1 = require("../lib/api/cxapp/cloud-executable");
const user_configuration_1 = require("../lib/cli/user-configuration");
exports.DEFAULT_FAKE_TEMPLATE = { No: 'Resources' };
const SOME_RECENT_SCHEMA_VERSION = '30.0.0';
class MockCloudExecutable extends cloud_executable_1.CloudExecutable {
constructor(assembly, sdkProviderArg) {
const configuration = new user_configuration_1.Configuration();
const sdkProvider = sdkProviderArg ?? new mock_sdk_1.MockSdkProvider();
super({
configuration,
sdkProvider,
synthesizer: () => Promise.resolve(testAssembly(assembly)),
});
this.configuration = configuration;
this.sdkProvider = sdkProvider;
}
}
exports.MockCloudExecutable = MockCloudExecutable;
function clone(obj) {
return JSON.parse(JSON.stringify(obj));
}
function addAttributes(assembly, builder) {
for (const stack of assembly.stacks) {
const templateFile = `${stack.stackName}.template.json`;
const template = stack.template ?? exports.DEFAULT_FAKE_TEMPLATE;
fs.writeFileSync(path.join(builder.outdir, templateFile), JSON.stringify(template, undefined, 2));
addNestedStacks(templateFile, builder.outdir, template);
// we call patchStackTags here to simulate the tags formatter
// that is used when building real manifest files.
const metadata = patchStackTags({ ...stack.metadata });
for (const asset of stack.assets || []) {
metadata[asset.id] = [{ type: cloud_assembly_schema_1.ArtifactMetadataEntryType.ASSET, data: asset }];
}
for (const missing of assembly.missing || []) {
builder.addMissing(missing);
}
const dependencies = [...(stack.depends ?? [])];
if (stack.assetManifest) {
const manifestFile = `${stack.stackName}.assets.json`;
fs.writeFileSync(path.join(builder.outdir, manifestFile), JSON.stringify(stack.assetManifest, undefined, 2));
dependencies.push(`${stack.stackName}.assets`);
builder.addArtifact(`${stack.stackName}.assets`, {
type: cloud_assembly_schema_1.ArtifactType.ASSET_MANIFEST,
environment: stack.env || 'aws://123456789012/here',
properties: {
file: manifestFile,
},
});
}
builder.addArtifact(stack.stackName, {
type: cloud_assembly_schema_1.ArtifactType.AWS_CLOUDFORMATION_STACK,
environment: stack.env || 'aws://123456789012/here',
dependencies,
metadata,
properties: {
...stack.properties,
templateFile,
terminationProtection: stack.terminationProtection,
notificationArns: stack.notificationArns,
},
displayName: stack.displayName,
});
}
}
function addNestedStacks(templatePath, outdir, rootStackTemplate) {
let template = rootStackTemplate;
if (!template) {
const templatePathWithDir = path.join('nested-stack-templates', templatePath);
template = JSON.parse(fs.readFileSync(path.join(__dirname, templatePathWithDir)).toString());
fs.writeFileSync(path.join(outdir, templatePath), JSON.stringify(template, undefined, 2));
}
for (const logicalId in template.Resources) {
if (template.Resources[logicalId].Type === 'AWS::CloudFormation::Stack') {
if (template.Resources[logicalId].Metadata && template.Resources[logicalId].Metadata['aws:asset:path']) {
const nestedTemplatePath = template.Resources[logicalId].Metadata['aws:asset:path'];
addNestedStacks(nestedTemplatePath, outdir);
}
}
}
}
function testAssembly(assembly) {
const builder = new cx_api_1.CloudAssemblyBuilder();
addAttributes(assembly, builder);
if (assembly.nestedAssemblies != null && assembly.nestedAssemblies.length > 0) {
assembly.nestedAssemblies?.forEach((nestedAssembly, i) => {
const nestedAssemblyBuilder = builder.createNestedAssembly(`nested${i}`, `nested${i}`);
addAttributes(nestedAssembly, nestedAssemblyBuilder);
nestedAssemblyBuilder.buildAssembly();
});
}
const asm = builder.buildAssembly();
return (0, assembly_versions_1.cxapiAssemblyWithForcedVersion)(asm, assembly.schemaVersion ?? SOME_RECENT_SCHEMA_VERSION);
}
/**
* Transform stack tags from how they are decalred in source code (lower cased)
* to how they are stored on disk (upper cased). In real synthesis this is done
* by a special tags formatter.
*
* @see aws-cdk-lib/lib/stack.ts
*/
function patchStackTags(metadata) {
const cloned = clone(metadata);
for (const metadataEntries of Object.values(cloned)) {
for (const metadataEntry of metadataEntries) {
if (metadataEntry.type === cloud_assembly_schema_1.ArtifactMetadataEntryType.STACK_TAGS && metadataEntry.data) {
const metadataAny = metadataEntry;
metadataAny.data = metadataAny.data.map((t) => {
return { Key: t.key, Value: t.value };
});
}
}
}
return cloned;
}
function testStack(stack) {
const assembly = testAssembly({ stacks: [stack] });
return assembly.getStackByName(stack.stackName);
}
/**
* Return a mocked instance of a class, given its constructor
*
* I don't understand why jest doesn't provide this by default,
* but there you go.
*
* FIXME: Currently very limited. Doesn't support inheritance, getters or
* automatic detection of properties (as those exist on instances, not
* classes).
*/
function instanceMockFrom(ctr) {
const ret = {};
for (const methodName of Object.getOwnPropertyNames(ctr.prototype)) {
ret[methodName] = jest.fn();
}
return ret;
}
function withMocked(obj, key, block) {
const original = obj[key];
const mockFn = jest.fn();
obj[key] = mockFn;
let asyncFinally = false;
try {
const ret = block(mockFn);
if (!isPromise(ret)) {
return ret;
}
asyncFinally = true;
return ret.finally(() => {
obj[key] = original;
});
}
finally {
if (!asyncFinally) {
obj[key] = original;
}
}
}
function isPromise(object) {
return Promise.resolve(object) === object;
}
async function sleep(ms) {
return new Promise((ok) => setTimeout(ok, ms));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBa0lBLG9DQWNDO0FBNEJELDhCQUdDO0FBWUQsNENBTUM7QUFFRCxnQ0F5QkM7QUFNRCxzQkFFQztBQXBPRCx5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLDBFQUFzTjtBQUN0Tiw0Q0FBaUk7QUFDakksK0RBQXlFO0FBQ3pFLDhDQUFrRDtBQUNsRCx3RUFBb0U7QUFDcEUsc0VBQThEO0FBRWpELFFBQUEscUJBQXFCLEdBQUcsRUFBRSxFQUFFLEVBQUUsV0FBVyxFQUFFLENBQUM7QUFFekQsTUFBTSwwQkFBMEIsR0FBRyxRQUFRLENBQUM7QUEyQjVDLE1BQWEsbUJBQW9CLFNBQVEsa0NBQWU7SUFJdEQsWUFBWSxRQUFzQixFQUFFLGNBQWdDO1FBQ2xFLE1BQU0sYUFBYSxHQUFHLElBQUksa0NBQWEsRUFBRSxDQUFDO1FBQzFDLE1BQU0sV0FBVyxHQUFHLGNBQWMsSUFBSSxJQUFJLDBCQUFlLEVBQUUsQ0FBQztRQUU1RCxLQUFLLENBQUM7WUFDSixhQUFhO1lBQ2IsV0FBVztZQUNYLFdBQVcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUMzRCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztRQUNuQyxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztJQUNqQyxDQUFDO0NBQ0Y7QUFqQkQsa0RBaUJDO0FBRUQsU0FBUyxLQUFLLENBQUMsR0FBUTtJQUNyQixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3pDLENBQUM7QUFFRCxTQUFTLGFBQWEsQ0FBQyxRQUFzQixFQUFFLE9BQTZCO0lBQzFFLEtBQUssTUFBTSxLQUFLLElBQUksUUFBUSxDQUFD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QUFDLEdBQUcsQ0FBQyxHQUFHLFFBQVEsQ0FBQztRQUN0QixDQUFDLENBQVEsQ0FBQztJQUNaLENBQUM7WUFBUyxDQUFDO1FBQ1QsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ2xCLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxRQUFRLENBQUM7UUFDdEIsQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQsU0FBUyxTQUFTLENBQUksTUFBVztJQUMvQixPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssTUFBTSxDQUFDO0FBQzVDLENBQUM7QUFFTSxLQUFLLFVBQVUsS0FBSyxDQUFDLEVBQVU7SUFDcEMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQ2pELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgQXJ0aWZhY3RNZXRhZGF0YUVudHJ5VHlwZSwgQXJ0aWZhY3RUeXBlLCB0eXBlIEFzc2V0TWFuaWZlc3QsIHR5cGUgQXNzZXRNZXRhZGF0YUVudHJ5LCB0eXBlIEF3c0Nsb3VkRm9ybWF0aW9uU3RhY2tQcm9wZXJ0aWVzLCB0eXBlIE1ldGFkYXRhRW50cnksIHR5cGUgTWlzc2luZ0NvbnRleHQgfSBmcm9tICdAYXdzLWNkay9jbG91ZC1hc3NlbWJseS1zY2hlbWEnO1xuaW1wb3J0IHsgdHlwZSBDbG91ZEFzc2VtYmx5LCBDbG91ZEFzc2VtYmx5QnVpbGRlciwgdHlwZSBDbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QsIHR5cGUgU3RhY2tNZXRhZGF0YSB9IGZyb20gJ0Bhd3MtY2RrL2N4LWFwaSc7XG5pbXBvcnQgeyBjeGFwaUFzc2VtYmx5V2l0aEZvcmNlZFZlcnNpb24gfSBmcm9tICcuL2FwaS9hc3NlbWJseS12ZXJzaW9ucyc7XG5pbXBvcnQgeyBNb2NrU2RrUHJvdmlkZXIgfSBmcm9tICcuL3V0aWwvbW9jay1zZGsnO1xuaW1wb3J0IHsgQ2xvdWRFeGVjdXRhYmxlIH0gZnJvbSAnLi4vbGliL2FwaS9jeGFwcC9jbG91ZC1leGVjdXRhYmxlJztcbmltcG9ydCB7IENvbmZpZ3VyYXRpb24gfSBmcm9tICcuLi9saWIvY2xpL3VzZXItY29uZmlndXJhdGlvbic7XG5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0ZBS0VfVEVNUExBVEUgPSB7IE5vOiAnUmVzb3VyY2VzJyB9O1xuXG5jb25zdCBTT01FX1JFQ0VOVF9TQ0hFTUFfVkVSU0lPTiA9ICczMC4wLjAnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRlc3RTdGFja0FydGlmYWN0IHtcbiAgc3RhY2tOYW1lOiBzdHJpbmc7XG4gIHRlbXBsYXRlPzogYW55O1xuICBlbnY/OiBzdHJpbmc7XG4gIGRlcGVuZHM/OiBzdHJpbmdbXTtcbiAgbWV0YWRhdGE/OiBTdGFja01ldGFkYXRhO1xuICBub3RpZmljYXRpb25Bcm5zPzogc3RyaW5nW107XG5cbiAgLyoqIE9sZC1zdHlsZSBhc3NldHMgKi9cbiAgYXNzZXRzPzogQXNzZXRNZXRhZGF0YUVudHJ5W107XG4gIHByb3BlcnRpZXM/OiBQYXJ0aWFsPEF3c0Nsb3VkRm9ybWF0aW9uU3RhY2tQcm9wZXJ0aWVzPjtcbiAgdGVybWluYXRpb25Qcm90ZWN0aW9uPzogYm9vbGVhbjtcbiAgZGlzcGxheU5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqIE5ldy1zdHlsZSBhc3NldHMgKi9cbiAgYXNzZXRNYW5pZmVzdD86IEFzc2V0TWFuaWZlc3Q7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGVzdEFzc2VtYmx5IHtcbiAgc3RhY2tzOiBUZXN0U3RhY2tBcnRpZmFjdFtdO1xuICBtaXNzaW5nPzogTWlzc2luZ0NvbnRleHRbXTtcbiAgbmVzdGVkQXNzZW1ibGllcz86IFRlc3RBc3NlbWJseVtdO1xuICBzY2hlbWFWZXJzaW9uPzogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgTW9ja0Nsb3VkRXhlY3V0YWJsZSBleHRlbmRzIENsb3VkRXhlY3V0YWJsZSB7XG4gIHB1YmxpYyByZWFkb25seSBjb25maWd1cmF0aW9uOiBDb25maWd1cmF0aW9uO1xuICBwdWJsaWMgcmVhZG9ubHkgc2RrUHJvdmlkZXI6IE1vY2tTZGtQcm92aWRlcjtcblxuICBjb25zdHJ1Y3Rvcihhc3NlbWJseTogVGVzdEFzc2VtYmx5LCBzZGtQcm92aWRlckFyZz86IE1vY2tTZGtQcm92aWRlcikge1xuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSBuZXcgQ29uZmlndXJhdGlvbigpO1xuICAgIGNvbnN0IHNka1Byb3ZpZGVyID0gc2RrUHJvdmlkZXJBcmcgPz8gbmV3IE1vY2tTZGtQcm92aWRlcigpO1xuXG4gICAgc3VwZXIoe1xuICAgICAgY29uZmlndXJhdGlvbixcbiAgICAgIHNka1Byb3ZpZGVyLFxuICAgICAgc3ludGhlc2l6ZXI6ICgpID0+IFByb21pc2UucmVzb2x2ZSh0ZXN0QXNzZW1ibHkoYXNzZW1ibHkpKSxcbiAgICB9KTtcblxuICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb247XG4gICAgdGhpcy5zZGtQcm92aWRlciA9IHNka1Byb3ZpZGVyO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNsb25lKG9iajogYW55KSB7XG4gIHJldHVybiBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KG9iaikpO1xufVxuXG5mdW5jdGlvbiBhZGRBdHRyaWJ1dGVzKGFzc2VtYmx5OiBUZXN0QXNzZW1ibHksIGJ1aWxkZXI6IENsb3VkQXNzZW1ibHlCdWlsZGVyKSB7XG4gIGZvciAoY29uc3Qgc3RhY2sgb2YgYXNzZW1ibHkuc3RhY2tzKSB7XG4gICAgY29uc3QgdGVtcGxhdGVGaWxlID0gYCR7c3RhY2suc3RhY2tOYW1lfS50ZW1wbGF0ZS5qc29uYDtcbiAgICBjb25zdCB0ZW1wbGF0ZSA9IHN0YWNrLnRlbXBsYXRlID8/IERFRkFVTFRfRkFLRV9URU1QTEFURTtcbiAgICBmcy53cml0ZUZpbGVTeW5jKHBhdGguam9pbihidWlsZGVyLm91dGRpciwgdGVtcGxhdGVGaWxlKSwgSlNPTi5zdHJpbmdpZnkodGVtcGxhdGUsIHVuZGVmaW5lZCwgMikpO1xuICAgIGFkZE5lc3RlZFN0YWNrcyh0ZW1wbGF0ZUZpbGUsIGJ1aWxkZXIub3V0ZGlyLCB0ZW1wbGF0ZSk7XG5cbiAgICAvLyB3ZSBjYWxsIHBhdGNoU3RhY2tUYWdzIGhlcmUgdG8gc2ltdWxhdGUgdGhlIHRhZ3MgZm9ybWF0dGVyXG4gICAgLy8gdGhhdCBpcyB1c2VkIHdoZW4gYnVpbGRpbmcgcmVhbCBtYW5pZmVzdCBmaWxlcy5cbiAgICBjb25zdCBtZXRhZGF0YTogeyBbcGF0aDogc3RyaW5nXTogTWV0YWRhdGFFbnRyeVtdIH0gPSBwYXRjaFN0YWNrVGFncyh7IC4uLnN0YWNrLm1ldGFkYXRhIH0pO1xuICAgIGZvciAoY29uc3QgYXNzZXQgb2Ygc3RhY2suYXNzZXRzIHx8IFtdKSB7XG4gICAgICBtZXRhZGF0YVthc3NldC5pZF0gPSBbeyB0eXBlOiBBcnRpZmFjdE1ldGFkYXRhRW50cnlUeXBlLkFTU0VULCBkYXRhOiBhc3NldCB9XTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG1pc3Npbmcgb2YgYXNzZW1ibHkubWlzc2luZyB8fCBbXSkge1xuICAgICAgYnVpbGRlci5hZGRNaXNzaW5nKG1pc3NpbmcpO1xuICAgIH1cblxuICAgIGNvbnN0IGRlcGVuZGVuY2llcyA9IFsuLi4oc3RhY2suZGVwZW5kcyA/PyBbXSldO1xuXG4gICAgaWYgKHN0YWNrLmFzc2V0TWFuaWZlc3QpIHtcbiAgICAgIGNvbnN0IG1hbmlmZXN0RmlsZSA9IGAke3N0YWNrLnN0YWNrTmFtZX0uYXNzZXRzLmpzb25gO1xuICAgICAgZnMud3JpdGVGaWxlU3luYyhwYXRoLmpvaW4oYnVpbGRlci5vdXRkaXIsIG1hbmlmZXN0RmlsZSksIEpTT04uc3RyaW5naWZ5KHN0YWNrLmFzc2V0TWFuaWZlc3QsIHVuZGVmaW5lZCwgMikpO1xuICAgICAgZGVwZW5kZW5jaWVzLnB1c2goYCR7c3RhY2suc3RhY2tOYW1lfS5hc3NldHNgKTtcbiAgICAgIGJ1aWxkZXIuYWRkQXJ0aWZhY3QoYCR7c3RhY2suc3RhY2tOYW1lfS5hc3NldHNgLCB7XG4gICAgICAgIHR5cGU6IEFydGlmYWN0VHlwZS5BU1NFVF9NQU5JRkVTVCxcbiAgICAgICAgZW52aXJvbm1lbnQ6IHN0YWNrLmVudiB8fCAnYXdzOi8vMTIzNDU2Nzg5MDEyL2hlcmUnLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgZmlsZTogbWFuaWZlc3RGaWxlLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgYnVpbGRlci5hZGRBcnRpZmFjdChzdGFjay5zdGFja05hbWUsIHtcbiAgICAgIHR5cGU6IEFydGlmYWN0VHlwZS5BV1NfQ0xPVURGT1JNQVRJT05fU1RBQ0ssXG4gICAgICBlbnZpcm9ubWVudDogc3RhY2suZW52IHx8ICdhd3M6Ly8xMjM0NTY3ODkwMTIvaGVyZScsXG5cbiAgICAgIGRlcGVuZGVuY2llcyxcbiAgICAgIG1ldGFkYXRhLFxuICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAuLi5zdGFjay5wcm9wZXJ0aWVzLFxuICAgICAgICB0ZW1wbGF0ZUZpbGUsXG4gICAgICAgIHRlcm1pbmF0aW9uUHJvdGVjdGlvbjogc3RhY2sudGVybWluYXRpb25Qcm90ZWN0aW9uLFxuICAgICAgICBub3RpZmljYXRpb25Bcm5zOiBzdGFjay5ub3RpZmljYXRpb25Bcm5zLFxuICAgICAgfSxcbiAgICAgIGRpc3BsYXlOYW1lOiBzdGFjay5kaXNwbGF5TmFtZSxcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhZGROZXN0ZWRTdGFja3ModGVtcGxhdGVQYXRoOiBzdHJpbmcsIG91dGRpcjogc3RyaW5nLCByb290U3RhY2tUZW1wbGF0ZT86IGFueSkge1xuICBsZXQgdGVtcGxhdGUgPSByb290U3RhY2tUZW1wbGF0ZTtcblxuICBpZiAoIXRlbXBsYXRlKSB7XG4gICAgY29uc3QgdGVtcGxhdGVQYXRoV2l0aERpciA9IHBhdGguam9pbignbmVzdGVkLXN0YWNrLXRlbXBsYXRlcycsIHRlbXBsYXRlUGF0aCk7XG4gICAgdGVtcGxhdGUgPSBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhwYXRoLmpvaW4oX19kaXJuYW1lLCB0ZW1wbGF0ZVBhdGhXaXRoRGlyKSkudG9TdHJpbmcoKSk7XG4gICAgZnMud3JpdGVGaWxlU3luYyhwYXRoLmpvaW4ob3V0ZGlyLCB0ZW1wbGF0ZVBhdGgpLCBKU09OLnN0cmluZ2lmeSh0ZW1wbGF0ZSwgdW5kZWZpbmVkLCAyKSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IGxvZ2ljYWxJZCBpbiB0ZW1wbGF0ZS5SZXNvdXJjZXMpIHtcbiAgICBpZiAodGVtcGxhdGUuUmVzb3VyY2VzW2xvZ2ljYWxJZF0uVHlwZSA9PT0gJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJykge1xuICAgICAgaWYgKHRlbXBsYXRlLlJlc291cmNlc1tsb2dpY2FsSWRdLk1ldGFkYXRhICYmIHRlbXBsYXRlLlJlc291cmNlc1tsb2dpY2FsSWRdLk1ldGFkYXRhWydhd3M6YXNzZXQ6cGF0aCddKSB7XG4gICAgICAgIGNvbnN0IG5lc3RlZFRlbXBsYXRlUGF0aCA9IHRlbXBsYXRlLlJlc291cmNlc1tsb2dpY2FsSWRdLk1ldGFkYXRhWydhd3M6YXNzZXQ6cGF0aCddO1xuICAgICAgICBhZGROZXN0ZWRTdGFja3MobmVzdGVkVGVtcGxhdGVQYXRoLCBvdXRkaXIpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gdGVzdEFzc2VtYmx5KGFzc2VtYmx5OiBUZXN0QXNzZW1ibHkpOiBDbG91ZEFzc2VtYmx5IHtcbiAgY29uc3QgYnVpbGRlciA9IG5ldyBDbG91ZEFzc2VtYmx5QnVpbGRlcigpO1xuICBhZGRBdHRyaWJ1dGVzKGFzc2VtYmx5LCBidWlsZGVyKTtcblxuICBpZiAoYXNzZW1ibHkubmVzdGVkQXNzZW1ibGllcyAhPSBudWxsICYmIGFzc2VtYmx5Lm5lc3RlZEFzc2VtYmxpZXMubGVuZ3RoID4gMCkge1xuICAgIGFzc2VtYmx5Lm5lc3RlZEFzc2VtYmxpZXM/LmZvckVhY2goKG5lc3RlZEFzc2VtYmx5OiBUZXN0QXNzZW1ibHksIGk6IG51bWJlcikgPT4ge1xuICAgICAgY29uc3QgbmVzdGVkQXNzZW1ibHlCdWlsZGVyID0gYnVpbGRlci5jcmVhdGVOZXN0ZWRBc3NlbWJseShgbmVzdGVkJHtpfWAsIGBuZXN0ZWQke2l9YCk7XG4gICAgICBhZGRBdHRyaWJ1dGVzKG5lc3RlZEFzc2VtYmx5LCBuZXN0ZWRBc3NlbWJseUJ1aWxkZXIpO1xuICAgICAgbmVzdGVkQXNzZW1ibHlCdWlsZGVyLmJ1aWxkQXNzZW1ibHkoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGNvbnN0IGFzbSA9IGJ1aWxkZXIuYnVpbGRBc3NlbWJseSgpO1xuICByZXR1cm4gY3hhcGlBc3NlbWJseVdpdGhGb3JjZWRWZXJzaW9uKGFzbSwgYXNzZW1ibHkuc2NoZW1hVmVyc2lvbiA/PyBTT01FX1JFQ0VOVF9TQ0hFTUFfVkVSU0lPTik7XG59XG5cbi8qKlxuICogVHJhbnNmb3JtIHN0YWNrIHRhZ3MgZnJvbSBob3cgdGhleSBhcmUgZGVjYWxyZWQgaW4gc291cmNlIGNvZGUgKGxvd2VyIGNhc2VkKVxuICogdG8gaG93IHRoZXkgYXJlIHN0b3JlZCBvbiBkaXNrICh1cHBlciBjYXNlZCkuIEluIHJlYWwgc3ludGhlc2lzIHRoaXMgaXMgZG9uZVxuICogYnkgYSBzcGVjaWFsIHRhZ3MgZm9ybWF0dGVyLlxuICpcbiAqIEBzZWUgYXdzLWNkay1saWIvbGliL3N0YWNrLnRzXG4gKi9cbmZ1bmN0aW9uIHBhdGNoU3RhY2tUYWdzKG1ldGFkYXRhOiB7IFtwYXRoOiBzdHJpbmddOiBNZXRhZGF0YUVudHJ5W10gfSk6IHtcbiAgW3BhdGg6IHN0cmluZ106IE1ldGFkYXRhRW50cnlbXTtcbn0ge1xuICBjb25zdCBjbG9uZWQgPSBjbG9uZShtZXRhZGF0YSkgYXMgeyBbcGF0aDogc3RyaW5nXTogTWV0YWRhdGFFbnRyeVtdIH07XG5cbiAgZm9yIChjb25zdCBtZXRhZGF0YUVudHJpZXMgb2YgT2JqZWN0LnZhbHVlcyhjbG9uZWQpKSB7XG4gICAgZm9yIChjb25zdCBtZXRhZGF0YUVudHJ5IG9mIG1ldGFkYXRhRW50cmllcykge1xuICAgICAgaWYgKG1ldGFkYXRhRW50cnkudHlwZSA9PT0gQXJ0aWZhY3RNZXRhZGF0YUVudHJ5VHlwZS5TVEFDS19UQUdTICYmIG1ldGFkYXRhRW50cnkuZGF0YSkge1xuICAgICAgICBjb25zdCBtZXRhZGF0YUFueSA9IG1ldGFkYXRhRW50cnkgYXMgYW55O1xuXG4gICAgICAgIG1ldGFkYXRhQW55LmRhdGEgPSBtZXRhZGF0YUFueS5kYXRhLm1hcCgodDogYW55KSA9PiB7XG4gICAgICAgICAgcmV0dXJuIHsgS2V5OiB0LmtleSwgVmFsdWU6IHQudmFsdWUgfTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBjbG9uZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB0ZXN0U3RhY2soc3RhY2s6IFRlc3RTdGFja0FydGlmYWN0KTogQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0IHtcbiAgY29uc3QgYXNzZW1ibHkgPSB0ZXN0QXNzZW1ibHkoeyBzdGFja3M6IFtzdGFja10gfSk7XG4gIHJldHVybiBhc3NlbWJseS5nZXRTdGFja0J5TmFtZShzdGFjay5zdGFja05hbWUpO1xufVxuXG4vKipcbiAqIFJldHVybiBhIG1vY2tlZCBpbnN0YW5jZSBvZiBhIGNsYXNzLCBnaXZlbiBpdHMgY29uc3RydWN0b3JcbiAqXG4gKiBJIGRvbid0IHVuZGVyc3RhbmQgd2h5IGplc3QgZG9lc24ndCBwcm92aWRlIHRoaXMgYnkgZGVmYXVsdCxcbiAqIGJ1dCB0aGVyZSB5b3UgZ28uXG4gKlxuICogRklYTUU6IEN1cnJlbnRseSB2ZXJ5IGxpbWl0ZWQuIERvZXNuJ3Qgc3VwcG9ydCBpbmhlcml0YW5jZSwgZ2V0dGVycyBvclxuICogYXV0b21hdGljIGRldGVjdGlvbiBvZiBwcm9wZXJ0aWVzIChhcyB0aG9zZSBleGlzdCBvbiBpbnN0YW5jZXMsIG5vdFxuICogY2xhc3NlcykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnN0YW5jZU1vY2tGcm9tPEE+KGN0cjogbmV3ICguLi5hcmdzOiBhbnlbXSkgPT4gQSk6IGplc3QuTW9ja2VkPEE+IHtcbiAgY29uc3QgcmV0OiBhbnkgPSB7fTtcbiAgZm9yIChjb25zdCBtZXRob2ROYW1lIG9mIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGN0ci5wcm90b3R5cGUpKSB7XG4gICAgcmV0W21ldGhvZE5hbWVdID0gamVzdC5mbigpO1xuICB9XG4gIHJldHVybiByZXQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB3aXRoTW9ja2VkPEEgZXh0ZW5kcyBvYmplY3QsIEsgZXh0ZW5kcyBrZXlvZiBBLCBCPihcbiAgb2JqOiBBLFxuICBrZXk6IEssXG4gIGJsb2NrOiAoZm46IGplc3QuTW9ja2VkPEE+W0tdKSA9PiBCLFxuKTogQiB7XG4gIGNvbnN0IG9yaWdpbmFsID0gb2JqW2tleV07XG4gIGNvbnN0IG1vY2tGbiA9IGplc3QuZm4oKTtcbiAgKG9iaiBhcyBhbnkpW2tleV0gPSBtb2NrRm47XG5cbiAgbGV0IGFzeW5jRmluYWxseTogYm9vbGVhbiA9IGZhbHNlO1xuICB0cnkge1xuICAgIGNvbnN0IHJldCA9IGJsb2NrKG1vY2tGbiBhcyBhbnkpO1xuICAgIGlmICghaXNQcm9taXNlKHJldCkpIHtcbiAgICAgIHJldHVybiByZXQ7XG4gICAgfVxuXG4gICAgYXN5bmNGaW5hbGx5ID0gdHJ1ZTtcbiAgICByZXR1cm4gcmV0LmZpbmFsbHkoKCkgPT4ge1xuICAgICAgb2JqW2tleV0gPSBvcmlnaW5hbDtcbiAgICB9KSBhcyBhbnk7XG4gIH0gZmluYWxseSB7XG4gICAgaWYgKCFhc3luY0ZpbmFsbHkpIHtcbiAgICAgIG9ialtrZXldID0gb3JpZ2luYWw7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGlzUHJvbWlzZTxBPihvYmplY3Q6IGFueSk6IG9iamVjdCBpcyBQcm9taXNlPEE+IHtcbiAgcmV0dXJuIFByb21pc2UucmVzb2x2ZShvYmplY3QpID09PSBvYmplY3Q7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzbGVlcChtczogbnVtYmVyKSB7XG4gIHJldHVybiBuZXcgUHJvbWlzZSgob2spID0+IHNldFRpbWVvdXQob2ssIG1zKSk7XG59XG4iXX0=