UNPKG

@aws-cdk/integ-runner

Version:

CDK Integration Testing Tool

240 lines 33.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AssemblyManifestReader = void 0; const path = require("path"); const cdk_assets_lib_1 = require("@aws-cdk/cdk-assets-lib"); const cloud_assembly_schema_1 = require("@aws-cdk/cloud-assembly-schema"); const fs = require("fs-extra"); /** * Reads a Cloud Assembly manifest */ class AssemblyManifestReader { /** * Reads a Cloud Assembly manifest from a file */ static fromFile(fileName) { try { const obj = cloud_assembly_schema_1.Manifest.loadAssemblyManifest(fileName); return new AssemblyManifestReader(path.dirname(fileName), obj, fileName); } catch (e) { throw new Error(`Cannot read integ manifest '${fileName}': ${e.message}`); } } /** * Reads a Cloud Assembly manifest from a file or a directory * If the given filePath is a directory then it will look for * a file within the directory with the DEFAULT_FILENAME */ static fromPath(filePath) { let st; try { st = fs.statSync(filePath); } catch (e) { throw new Error(`Cannot read integ manifest at '${filePath}': ${e.message}`); } if (st.isDirectory()) { return AssemblyManifestReader.fromFile(path.join(filePath, AssemblyManifestReader.DEFAULT_FILENAME)); } return AssemblyManifestReader.fromFile(filePath); } constructor(directory, manifest, manifestFileName) { this.manifest = manifest; this.manifestFileName = manifestFileName; this.directory = directory; } /** * Get the stacks from the manifest * returns a map of artifactId to CloudFormation template */ get stacks() { const stacks = {}; for (const [artifactId, artifact] of Object.entries(this.manifest.artifacts ?? {})) { if (artifact.type !== cloud_assembly_schema_1.ArtifactType.AWS_CLOUDFORMATION_STACK) { continue; } const props = artifact.properties; const template = fs.readJSONSync(path.resolve(this.directory, props.templateFile)); stacks[artifactId] = template; } return stacks; } /** * Get the nested stacks for a given stack * returns a map of artifactId to CloudFormation template */ getNestedStacksForStack(stackId) { const nestedTemplates = this.getAssetManifestsForStack(stackId).flatMap(manifest => manifest.files .filter(asset => asset.source.path?.endsWith('.nested.template.json')) .map(asset => asset.source.path)); const nestedStacks = Object.fromEntries(nestedTemplates.map(templateFile => ([ templateFile.split('.', 1)[0], fs.readJSONSync(path.resolve(this.directory, templateFile)), ]))); return nestedStacks; } /** * Write trace data to the assembly manifest metadata */ recordTrace(trace) { const newManifest = { ...this.manifest, artifacts: this.renderArtifacts(trace), }; cloud_assembly_schema_1.Manifest.saveAssemblyManifest(newManifest, this.manifestFileName); } /** * Return a list of assets for a given stack */ getAssetIdsForStack(stackId) { const assets = []; for (const artifact of Object.values(this.manifest.artifacts ?? {})) { if (artifact.type === cloud_assembly_schema_1.ArtifactType.ASSET_MANIFEST && artifact.properties?.file === `${stackId}.assets.json`) { assets.push(...this.assetsFromAssetManifest(artifact).map(asset => asset.id.assetId)); } else if (artifact.type === cloud_assembly_schema_1.ArtifactType.AWS_CLOUDFORMATION_STACK) { assets.push(...this.assetsFromAssemblyManifest(artifact).map(asset => asset.id)); } } return assets; } /** * For a given stackId return a list of assets that belong to the stack */ getAssetLocationsForStack(stackId) { const assets = []; for (const artifact of Object.values(this.manifest.artifacts ?? {})) { if (artifact.type === cloud_assembly_schema_1.ArtifactType.ASSET_MANIFEST && artifact.properties?.file === `${stackId}.assets.json`) { assets.push(...this.assetsFromAssetManifest(artifact).flatMap(asset => { if (asset.type === 'file' && !asset.source.path?.endsWith('nested.template.json')) { return asset.source.path; } else if (asset.type !== 'file') { return asset.source.directory; } return []; })); } else if (artifact.type === cloud_assembly_schema_1.ArtifactType.AWS_CLOUDFORMATION_STACK) { assets.push(...this.assetsFromAssemblyManifest(artifact).map(asset => asset.path)); } } return assets; } /** * Return a list of asset artifacts for a given stack */ getAssetManifestsForStack(stackId) { return Object.values(this.manifest.artifacts ?? {}) .filter(artifact => artifact.type === cloud_assembly_schema_1.ArtifactType.ASSET_MANIFEST && artifact.properties?.file === `${stackId}.assets.json`) .map(artifact => { const fileName = artifact.properties.file; return cdk_assets_lib_1.AssetManifest.fromFile(path.join(this.directory, fileName)); }); } /** * Get a list of assets from the assembly manifest */ assetsFromAssemblyManifest(artifact) { const assets = []; for (const metadata of Object.values(artifact.metadata ?? {})) { metadata.forEach(data => { if (data.type === cloud_assembly_schema_1.ArtifactMetadataEntryType.ASSET) { const asset = data.data; if (asset.path.startsWith('asset.')) { assets.push(asset); } } }); } return assets; } /** * Get a list of assets from the asset manifest */ assetsFromAssetManifest(artifact) { const assets = []; const fileName = artifact.properties.file; const assetManifest = cdk_assets_lib_1.AssetManifest.fromFile(path.join(this.directory, fileName)); assetManifest.entries.forEach(entry => { if (entry.type === 'file') { const source = entry.source; if (source.path && (source.path.startsWith('asset.') || source.path.endsWith('nested.template.json'))) { assets.push(entry); } } else if (entry.type === 'docker-image') { const source = entry.source; if (source.directory && source.directory.startsWith('asset.')) { assets.push(entry); } } }); return assets; } /** * Clean the manifest of any unneccesary data. Currently that includes * the metadata trace information since this includes trace information like * file system locations and file lines that will change depending on what machine the test is run on */ cleanManifest() { const newManifest = { ...this.manifest, artifacts: this.renderArtifacts(), }; cloud_assembly_schema_1.Manifest.saveAssemblyManifest(newManifest, this.manifestFileName); } renderArtifactMetadata(artifact, trace) { const newMetadata = {}; if (!artifact.metadata) return artifact.metadata; for (const [metadataId, metadataEntry] of Object.entries(artifact.metadata ?? {})) { newMetadata[metadataId] = metadataEntry.map((meta) => { if (meta.type === 'aws:cdk:logicalId' && trace && meta.data) { const traceData = trace.get(meta.data.toString()); if (traceData) { trace.delete(meta.data.toString()); return { type: meta.type, data: meta.data, trace: [traceData], }; } } // return metadata without the trace data return { type: meta.type, data: meta.data, }; }); } if (trace && trace.size > 0) { for (const [id, data] of trace.entries()) { newMetadata[id] = [{ type: 'aws:cdk:logicalId', data: id, trace: [data], }]; } } return newMetadata; } renderArtifacts(trace) { const newArtifacts = {}; for (const [artifactId, artifact] of Object.entries(this.manifest.artifacts ?? {})) { let stackTrace = undefined; if (artifact.type === cloud_assembly_schema_1.ArtifactType.AWS_CLOUDFORMATION_STACK && trace) { stackTrace = trace.get(artifactId); } newArtifacts[artifactId] = { ...artifact, metadata: this.renderArtifactMetadata(artifact, stackTrace), }; } return newArtifacts; } } exports.AssemblyManifestReader = AssemblyManifestReader; AssemblyManifestReader.DEFAULT_FILENAME = 'manifest.json'; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWQtYXNzZW1ibHkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjbG91ZC1hc3NlbWJseS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2QkFBNkI7QUFFN0IsNERBQXdEO0FBRXhELDBFQUFtRztBQUNuRywrQkFBK0I7QUFlL0I7O0dBRUc7QUFDSCxNQUFhLHNCQUFzQjtJQUdqQzs7T0FFRztJQUNJLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBZ0I7UUFDckMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxHQUFHLEdBQUcsZ0NBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNwRCxPQUFPLElBQUksc0JBQXNCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxHQUFHLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDM0UsQ0FBQztRQUFDLE9BQU8sQ0FBTSxFQUFFLENBQUM7WUFDaEIsTUFBTSxJQUFJLEtBQUssQ0FBQywrQkFBK0IsUUFBUSxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQzVFLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNJLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBZ0I7UUFDckMsSUFBSSxFQUFFLENBQUM7UUFDUCxJQUFJLENBQUM7WUFDSCxFQUFFLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM3QixDQUFDO1FBQUMsT0FBTyxDQUFNLEVBQUUsQ0FBQztZQUNoQixNQUFNLElBQUksS0FBSyxDQUFDLGtDQUFrQyxRQUFRLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDL0UsQ0FBQztRQUNELElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxFQUFFLENBQUM7WUFDckIsT0FBTyxzQkFBc0IsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsc0JBQXNCLENBQUMsZ0JBQWdC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QUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO1lBQ25GLElBQUksVUFBVSxHQUEyQixTQUFTLENBQUM7WUFDbkQsSUFBSSxRQUFRLENBQUMsSUFBSSxLQUFLLG9DQUFZLENBQUMsd0JBQXdCLElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQ3JFLFVBQVUsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ3JDLENBQUM7WUFDRCxZQUFZLENBQUMsVUFBVSxDQUFDLEdBQUc7Z0JBQ3pCLEdBQUcsUUFBUTtnQkFDWCxRQUFRLEVBQUUsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFFBQVEsRUFBRSxVQUFVLENBQUM7YUFDNUQsQ0FBQztRQUNKLENBQUM7UUFDRCxPQUFPLFlBQVksQ0FBQztJQUN0QixDQUFDOztBQWxQSCx3REFtUEM7QUFsUHdCLHVDQUFnQixHQUFHLGVBQWUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgdHlwZSB7IEZpbGVNYW5pZmVzdEVudHJ5LCBEb2NrZXJJbWFnZU1hbmlmZXN0RW50cnkgfSBmcm9tICdAYXdzLWNkay9jZGstYXNzZXRzLWxpYic7XG5pbXBvcnQgeyBBc3NldE1hbmlmZXN0IH0gZnJvbSAnQGF3cy1jZGsvY2RrLWFzc2V0cy1saWInO1xuaW1wb3J0IHR5cGUgeyBBc3NlbWJseU1hbmlmZXN0LCBBd3NDbG91ZEZvcm1hdGlvblN0YWNrUHJvcGVydGllcywgQXJ0aWZhY3RNYW5pZmVzdCwgTWV0YWRhdGFFbnRyeSwgQXNzZXRNYW5pZmVzdFByb3BlcnRpZXMsIENvbnRhaW5lckltYWdlQXNzZXRNZXRhZGF0YUVudHJ5LCBGaWxlQXNzZXRNZXRhZGF0YUVudHJ5IH0gZnJvbSAnQGF3cy1jZGsvY2xvdWQtYXNzZW1ibHktc2NoZW1hJztcbmltcG9ydCB7IE1hbmlmZXN0LCBBcnRpZmFjdFR5cGUsIEFydGlmYWN0TWV0YWRhdGFFbnRyeVR5cGUgfSBmcm9tICdAYXdzLWNkay9jbG91ZC1hc3NlbWJseS1zY2hlbWEnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMtZXh0cmEnO1xuXG4vKipcbiAqIFRyYWNlIGluZm9ybWF0aW9uIGZvciBzdGFja1xuICogbWFwIG9mIHJlc291cmNlIGxvZ2ljYWxJZCB0byB0cmFjZSBtZXNzYWdlXG4gKi9cbmV4cG9ydCB0eXBlIFN0YWNrVHJhY2UgPSBNYXA8c3RyaW5nLCBzdHJpbmc+O1xuXG4vKipcbiAqIFRyYWNlIGluZm9ybWF0aW9uIGZvciBhIGFzc2VtYmx5XG4gKlxuICogbWFwIG9mIHN0YWNrSWQgdG8gU3RhY2tUcmFjZVxuICovXG5leHBvcnQgdHlwZSBNYW5pZmVzdFRyYWNlID0gTWFwPHN0cmluZywgU3RhY2tUcmFjZT47XG5cbi8qKlxuICogUmVhZHMgYSBDbG91ZCBBc3NlbWJseSBtYW5pZmVzdFxuICovXG5leHBvcnQgY2xhc3MgQXNzZW1ibHlNYW5pZmVzdFJlYWRlciB7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9GSUxFTkFNRSA9ICdtYW5pZmVzdC5qc29uJztcblxuICAvKipcbiAgICogUmVhZHMgYSBDbG91ZCBBc3NlbWJseSBtYW5pZmVzdCBmcm9tIGEgZmlsZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tRmlsZShmaWxlTmFtZTogc3RyaW5nKTogQXNzZW1ibHlNYW5pZmVzdFJlYWRlciB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IG9iaiA9IE1hbmlmZXN0LmxvYWRBc3NlbWJseU1hbmlmZXN0KGZpbGVOYW1lKTtcbiAgICAgIHJldHVybiBuZXcgQXNzZW1ibHlNYW5pZmVzdFJlYWRlcihwYXRoLmRpcm5hbWUoZmlsZU5hbWUpLCBvYmosIGZpbGVOYW1lKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHJlYWQgaW50ZWcgbWFuaWZlc3QgJyR7ZmlsZU5hbWV9JzogJHtlLm1lc3NhZ2V9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlYWRzIGEgQ2xvdWQgQXNzZW1ibHkgbWFuaWZlc3QgZnJvbSBhIGZpbGUgb3IgYSBkaXJlY3RvcnlcbiAgICogSWYgdGhlIGdpdmVuIGZpbGVQYXRoIGlzIGEgZGlyZWN0b3J5IHRoZW4gaXQgd2lsbCBsb29rIGZvclxuICAgKiBhIGZpbGUgd2l0aGluIHRoZSBkaXJlY3Rvcnkgd2l0aCB0aGUgREVGQVVMVF9GSUxFTkFNRVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tUGF0aChmaWxlUGF0aDogc3RyaW5nKTogQXNzZW1ibHlNYW5pZmVzdFJlYWRlciB7XG4gICAgbGV0IHN0O1xuICAgIHRyeSB7XG4gICAgICBzdCA9IGZzLnN0YXRTeW5jKGZpbGVQYXRoKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IHJlYWQgaW50ZWcgbWFuaWZlc3QgYXQgJyR7ZmlsZVBhdGh9JzogJHtlLm1lc3NhZ2V9YCk7XG4gICAgfVxuICAgIGlmIChzdC5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICByZXR1cm4gQXNzZW1ibHlNYW5pZmVzdFJlYWRlci5mcm9tRmlsZShwYXRoLmpvaW4oZmlsZVBhdGgsIEFzc2VtYmx5TWFuaWZlc3RSZWFkZXIuREVGQVVMVF9GSUxFTkFNRSkpO1xuICAgIH1cbiAgICByZXR1cm4gQXNzZW1ibHlNYW5pZmVzdFJlYWRlci5mcm9tRmlsZShmaWxlUGF0aCk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIGRpcmVjdG9yeSB3aGVyZSB0aGUgbWFuaWZlc3Qgd2FzIGZvdW5kXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZGlyZWN0b3J5OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoZGlyZWN0b3J5OiBzdHJpbmcsIHByaXZhdGUgcmVhZG9ubHkgbWFuaWZlc3Q6IEFzc2VtYmx5TWFuaWZlc3QsIHByaXZhdGUgcmVhZG9ubHkgbWFuaWZlc3RGaWxlTmFtZTogc3RyaW5nKSB7XG4gICAgdGhpcy5kaXJlY3RvcnkgPSBkaXJlY3Rvcnk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IHRoZSBzdGFja3MgZnJvbSB0aGUgbWFuaWZlc3RcbiAgICogcmV0dXJucyBhIG1hcCBvZiBhcnRpZmFjdElkIHRvIENsb3VkRm9ybWF0aW9uIHRlbXBsYXRlXG4gICAqL1xuICBwdWJsaWMgZ2V0IHN0YWNrcygpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgICBjb25zdCBzdGFja3M6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IFthcnRpZmFjdElkLCBhcnRpZmFjdF0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5tYW5pZmVzdC5hcnRpZmFjdHMgPz8ge30pKSB7XG4gICAgICBpZiAoYXJ0aWZhY3QudHlwZSAhPT0gQXJ0aWZhY3RUeXBlLkFXU19DTE9VREZPUk1BVElPTl9TVEFDSykge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHByb3BzID0gYXJ0aWZhY3QucHJvcGVydGllcyBhcyBBd3NDbG91ZEZvcm1hdGlvblN0YWNrUHJvcGVydGllcztcblxuICAgICAgY29uc3QgdGVtcGxhdGUgPSBmcy5yZWFkSlNPTlN5bmMocGF0aC5yZXNvbHZlKHRoaXMuZGlyZWN0b3J5LCBwcm9wcy50ZW1wbGF0ZUZpbGUpKTtcbiAgICAgIHN0YWNrc1thcnRpZmFjdElkXSA9IHRlbXBsYXRlO1xuICAgIH1cbiAgICByZXR1cm4gc3RhY2tzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgbmVzdGVkIHN0YWNrcyBmb3IgYSBnaXZlbiBzdGFja1xuICAgKiByZXR1cm5zIGEgbWFwIG9mIGFydGlmYWN0SWQgdG8gQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGVcbiAgICovXG4gIHB1YmxpYyBnZXROZXN0ZWRTdGFja3NGb3JTdGFjayhzdGFja0lkOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgICBjb25zdCBuZXN0ZWRUZW1wbGF0ZXM6IHN0cmluZ1tdID0gdGhpcy5nZXRBc3NldE1hbmlmZXN0c0ZvclN0YWNrKHN0YWNrSWQpLmZsYXRNYXAoXG4gICAgICBtYW5pZmVzdCA9PiBtYW5pZmVzdC5maWxlc1xuICAgICAgICAuZmlsdGVyKGFzc2V0ID0+IGFzc2V0LnNvdXJjZS5wYXRoPy5lbmRzV2l0aCgnLm5lc3RlZC50ZW1wbGF0ZS5qc29uJykpXG4gICAgICAgIC5tYXAoYXNzZXQgPT4gYXNzZXQuc291cmNlLnBhdGghKSxcbiAgICApO1xuXG4gICAgY29uc3QgbmVzdGVkU3RhY2tzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0gT2JqZWN0LmZyb21FbnRyaWVzKG5lc3RlZFRlbXBsYXRlcy5tYXAodGVtcGxhdGVGaWxlID0+IChbXG4gICAgICB0ZW1wbGF0ZUZpbGUuc3BsaXQoJy4nLCAxKVswXSxcbiAgICAgIGZzLnJlYWRKU09OU3luYyhwYXRoLnJlc29sdmUodGhpcy5kaXJlY3RvcnksIHRlbXBsYXRlRmlsZSkpLFxuICAgIF0pKSk7XG5cbiAgICByZXR1cm4gbmVzdGVkU3RhY2tzO1xuICB9XG5cbiAgLyoqXG4gICAqIFdyaXRlIHRyYWNlIGRhdGEgdG8gdGhlIGFzc2VtYmx5IG1hbmlmZXN0IG1ldGFkYXRhXG4gICAqL1xuICBwdWJsaWMgcmVjb3JkVHJhY2UodHJhY2U6IE1hbmlmZXN0VHJhY2UpOiB2b2lkIHtcbiAgICBjb25zdCBuZXdNYW5pZmVzdCA9IHtcbiAgICAgIC4uLnRoaXMubWFuaWZlc3QsXG4gICAgICBhcnRpZmFjdHM6IHRoaXMucmVuZGVyQXJ0aWZhY3RzKHRyYWNlKSxcbiAgICB9O1xuICAgIE1hbmlmZXN0LnNhdmVBc3NlbWJseU1hbmlmZXN0KG5ld01hbmlmZXN0LCB0aGlzLm1hbmlmZXN0RmlsZU5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIGxpc3Qgb2YgYXNzZXRzIGZvciBhIGdpdmVuIHN0YWNrXG4gICAqL1xuICBwdWJsaWMgZ2V0QXNzZXRJZHNGb3JTdGFjayhzdGFja0lkOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgYXNzZXRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgYXJ0aWZhY3Qgb2YgT2JqZWN0LnZhbHVlcyh0aGlzLm1hbmlmZXN0LmFydGlmYWN0cyA/PyB7fSkpIHtcbiAgICAgIGlmIChhcnRpZmFjdC50eXBlID09PSBBcnRpZmFjdFR5cGUuQVNTRVRfTUFOSUZFU1QgJiYgKGFydGlmYWN0LnByb3BlcnRpZXMgYXMgQXNzZXRNYW5pZmVzdFByb3BlcnRpZXMpPy5maWxlID09PSBgJHtzdGFja0lkfS5hc3NldHMuanNvbmApIHtcbiAgICAgICAgYXNzZXRzLnB1c2goLi4udGhpcy5hc3NldHNGcm9tQXNzZXRNYW5pZmVzdChhcnRpZmFjdCkubWFwKGFzc2V0ID0+IGFzc2V0LmlkLmFzc2V0SWQpKTtcbiAgICAgIH0gZWxzZSBpZiAoYXJ0aWZhY3QudHlwZSA9PT0gQXJ0aWZhY3RUeXBlLkFXU19DTE9VREZPUk1BVElPTl9TVEFDSykge1xuICAgICAgICBhc3NldHMucHVzaCguLi50aGlzLmFzc2V0c0Zyb21Bc3NlbWJseU1hbmlmZXN0KGFydGlmYWN0KS5tYXAoYXNzZXQgPT4gYXNzZXQuaWQpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFzc2V0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3IgYSBnaXZlbiBzdGFja0lkIHJldHVybiBhIGxpc3Qgb2YgYXNzZXRzIHRoYXQgYmVsb25nIHRvIHRoZSBzdGFja1xuICAgKi9cbiAgcHVibGljIGdldEFzc2V0TG9jYXRpb25zRm9yU3RhY2soc3RhY2tJZDogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGFzc2V0czogc3RyaW5nW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGFydGlmYWN0IG9mIE9iamVjdC52YWx1ZXModGhpcy5tYW5pZmVzdC5hcnRpZmFjdHMgPz8ge30pKSB7XG4gICAgICBpZiAoYXJ0aWZhY3QudHlwZSA9PT0gQXJ0aWZhY3RUeXBlLkFTU0VUX01BTklGRVNUICYmIChhcnRpZmFjdC5wcm9wZXJ0aWVzIGFzIEFzc2V0TWFuaWZlc3RQcm9wZXJ0aWVzKT8uZmlsZSA9PT0gYCR7c3RhY2tJZH0uYXNzZXRzLmpzb25gKSB7XG4gICAgICAgIGFzc2V0cy5wdXNoKC4uLnRoaXMuYXNzZXRzRnJvbUFzc2V0TWFuaWZlc3QoYXJ0aWZhY3QpLmZsYXRNYXAoYXNzZXQgPT4ge1xuICAgICAgICAgIGlmIChhc3NldC50eXBlID09PSAnZmlsZScgJiYgIWFzc2V0LnNvdXJjZS5wYXRoPy5lbmRzV2l0aCgnbmVzdGVkLnRlbXBsYXRlLmpzb24nKSkge1xuICAgICAgICAgICAgcmV0dXJuIGFzc2V0LnNvdXJjZS5wYXRoITtcbiAgICAgICAgICB9IGVsc2UgaWYgKGFzc2V0LnR5cGUgIT09ICdmaWxlJykge1xuICAgICAgICAgICAgcmV0dXJuIGFzc2V0LnNvdXJjZS5kaXJlY3RvcnkhO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH0pKTtcbiAgICAgIH0gZWxzZSBpZiAoYXJ0aWZhY3QudHlwZSA9PT0gQXJ0aWZhY3RUeXBlLkFXU19DTE9VREZPUk1BVElPTl9TVEFDSykge1xuICAgICAgICBhc3NldHMucHVzaCguLi50aGlzLmFzc2V0c0Zyb21Bc3NlbWJseU1hbmlmZXN0KGFydGlmYWN0KS5tYXAoYXNzZXQgPT4gYXNzZXQucGF0aCkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYXNzZXRzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhIGxpc3Qgb2YgYXNzZXQgYXJ0aWZhY3RzIGZvciBhIGdpdmVuIHN0YWNrXG4gICAqL1xuICBwdWJsaWMgZ2V0QXNzZXRNYW5pZmVzdHNGb3JTdGFjayhzdGFja0lkOiBzdHJpbmcpOiBBc3NldE1hbmlmZXN0W10ge1xuICAgIHJldHVybiBPYmplY3QudmFsdWVzKHRoaXMubWFuaWZlc3QuYXJ0aWZhY3RzID8/IHt9KVxuICAgICAgLmZpbHRlcihhcnRpZmFjdCA9PlxuICAgICAgICBhcnRpZmFjdC50eXBlID09PSBBcnRpZmFjdFR5cGUuQVNTRVRfTUFOSUZFU1QgJiYgKGFydGlmYWN0LnByb3BlcnRpZXMgYXMgQXNzZXRNYW5pZmVzdFByb3BlcnRpZXMpPy5maWxlID09PSBgJHtzdGFja0lkfS5hc3NldHMuanNvbmApXG4gICAgICAubWFwKGFydGlmYWN0ID0+IHtcbiAgICAgICAgY29uc3QgZmlsZU5hbWUgPSAoYXJ0aWZhY3QucHJvcGVydGllcyBhcyBBc3NldE1hbmlmZXN0UHJvcGVydGllcykuZmlsZTtcbiAgICAgICAgcmV0dXJuIEFzc2V0TWFuaWZlc3QuZnJvbUZpbGUocGF0aC5qb2luKHRoaXMuZGlyZWN0b3J5LCBmaWxlTmFtZSkpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0IGEgbGlzdCBvZiBhc3NldHMgZnJvbSB0aGUgYXNzZW1ibHkgbWFuaWZlc3RcbiAgICovXG4gIHByaXZhdGUgYXNzZXRzRnJvbUFzc2VtYmx5TWFuaWZlc3QoYXJ0aWZhY3Q6IEFydGlmYWN0TWFuaWZlc3QpOiAoQ29udGFpbmVySW1hZ2VBc3NldE1ldGFkYXRhRW50cnkgfCBGaWxlQXNzZXRNZXRhZGF0YUVudHJ5KVtdIHtcbiAgICBjb25zdCBhc3NldHM6IChDb250YWluZXJJbWFnZUFzc2V0TWV0YWRhdGFFbnRyeSB8IEZpbGVBc3NldE1ldGFkYXRhRW50cnkpW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IG1ldGFkYXRhIG9mIE9iamVjdC52YWx1ZXMoYXJ0aWZhY3QubWV0YWRhdGEgPz8ge30pKSB7XG4gICAgICBtZXRhZGF0YS5mb3JFYWNoKGRhdGEgPT4ge1xuICAgICAgICBpZiAoZGF0YS50eXBlID09PSBBcnRpZmFjdE1ldGFkYXRhRW50cnlUeXBlLkFTU0VUKSB7XG4gICAgICAgICAgY29uc3QgYXNzZXQgPSAoZGF0YS5kYXRhIGFzIENvbnRhaW5lckltYWdlQXNzZXRNZXRhZGF0YUVudHJ5IHwgRmlsZUFzc2V0TWV0YWRhdGFFbnRyeSk7XG4gICAgICAgICAgaWYgKGFzc2V0LnBhdGguc3RhcnRzV2l0aCgnYXNzZXQuJykpIHtcbiAgICAgICAgICAgIGFzc2V0cy5wdXNoKGFzc2V0KTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gYXNzZXRzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIGxpc3Qgb2YgYXNzZXRzIGZyb20gdGhlIGFzc2V0IG1hbmlmZXN0XG4gICAqL1xuICBwcml2YXRlIGFzc2V0c0Zyb21Bc3NldE1hbmlmZXN0KGFydGlmYWN0OiBBcnRpZmFjdE1hbmlmZXN0KTogKEZpbGVNYW5pZmVzdEVudHJ5IHwgRG9ja2VySW1hZ2VNYW5pZmVzdEVudHJ5KVtdIHtcbiAgICBjb25zdCBhc3NldHM6IChGaWxlTWFuaWZlc3RFbnRyeSB8IERvY2tlckltYWdlTWFuaWZlc3RFbnRyeSlbXSA9IFtdO1xuICAgIGNvbnN0IGZpbGVOYW1lID0gKGFydGlmYWN0LnByb3BlcnRpZXMgYXMgQXNzZXRNYW5pZmVzdFByb3BlcnRpZXMpLmZpbGU7XG4gICAgY29uc3QgYXNzZXRNYW5pZmVzdCA9IEFzc2V0TWFuaWZlc3QuZnJvbUZpbGUocGF0aC5qb2luKHRoaXMuZGlyZWN0b3J5LCBmaWxlTmFtZSkpO1xuICAgIGFzc2V0TWFuaWZlc3QuZW50cmllcy5mb3JFYWNoKGVudHJ5ID0+IHtcbiAgICAgIGlmIChlbnRyeS50eXBlID09PSAnZmlsZScpIHtcbiAgICAgICAgY29uc3Qgc291cmNlID0gKGVudHJ5IGFzIEZpbGVNYW5pZmVzdEVudHJ5KS5zb3VyY2U7XG4gICAgICAgIGlmIChzb3VyY2UucGF0aCAmJiAoc291cmNlLnBhdGguc3RhcnRzV2l0aCgnYXNzZXQuJykgfHwgc291cmNlLnBhdGguZW5kc1dpdGgoJ25lc3RlZC50ZW1wbGF0ZS5qc29uJykpKSB7XG4gICAgICAgICAgYXNzZXRzLnB1c2goZW50cnkgYXMgRmlsZU1hbmlmZXN0RW50cnkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGVudHJ5LnR5cGUgPT09ICdkb2NrZXItaW1hZ2UnKSB7XG4gICAgICAgIGNvbnN0IHNvdXJjZSA9IChlbnRyeSBhcyBEb2NrZXJJbWFnZU1hbmlmZXN0RW50cnkpLnNvdXJjZTtcbiAgICAgICAgaWYgKHNvdXJjZS5kaXJlY3RvcnkgJiYgc291cmNlLmRpcmVjdG9yeS5zdGFydHNXaXRoKCdhc3NldC4nKSkge1xuICAgICAgICAgIGFzc2V0cy5wdXNoKGVudHJ5IGFzIERvY2tlckltYWdlTWFuaWZlc3RFbnRyeSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gYXNzZXRzO1xuICB9XG5cbiAgLyoqXG4gICAqIENsZWFuIHRoZSBtYW5pZmVzdCBvZiBhbnkgdW5uZWNjZXNhcnkgZGF0YS4gQ3VycmVudGx5IHRoYXQgaW5jbHVkZXNcbiAgICogdGhlIG1ldGFkYXRhIHRyYWNlIGluZm9ybWF0aW9uIHNpbmNlIHRoaXMgaW5jbHVkZXMgdHJhY2UgaW5mb3JtYXRpb24gbGlrZVxuICAgKiBmaWxlIHN5c3RlbSBsb2NhdGlvbnMgYW5kIGZpbGUgbGluZXMgdGhhdCB3aWxsIGNoYW5nZSBkZXBlbmRpbmcgb24gd2hhdCBtYWNoaW5lIHRoZSB0ZXN0IGlzIHJ1biBvblxuICAgKi9cbiAgcHVibGljIGNsZWFuTWFuaWZlc3QoKTogdm9pZCB7XG4gICAgY29uc3QgbmV3TWFuaWZlc3QgPSB7XG4gICAgICAuLi50aGlzLm1hbmlmZXN0LFxuICAgICAgYXJ0aWZhY3RzOiB0aGlzLnJlbmRlckFydGlmYWN0cygpLFxuICAgIH07XG4gICAgTWFuaWZlc3Quc2F2ZUFzc2VtYmx5TWFuaWZlc3QobmV3TWFuaWZlc3QsIHRoaXMubWFuaWZlc3RGaWxlTmFtZSk7XG4gIH1cblxuICBwcml2YXRlIHJlbmRlckFydGlmYWN0TWV0YWRhdGEoYXJ0aWZhY3Q6IEFydGlmYWN0TWFuaWZlc3QsIHRyYWNlPzogU3RhY2tUcmFjZSk6IHsgW2lkOiBzdHJpbmddOiBNZXRhZGF0YUVudHJ5W10gfSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgbmV3TWV0YWRhdGE6IHsgW2lkOiBzdHJpbmddOiBNZXRhZGF0YUVudHJ5W10gfSA9IHt9O1xuICAgIGlmICghYXJ0aWZhY3QubWV0YWRhdGEpIHJldHVybiBhcnRpZmFjdC5tZXRhZGF0YTtcbiAgICBmb3IgKGNvbnN0IFttZXRhZGF0YUlkLCBtZXRhZGF0YUVudHJ5XSBvZiBPYmplY3QuZW50cmllcyhhcnRpZmFjdC5tZXRhZGF0YSA/PyB7fSkpIHtcbiAgICAgIG5ld01ldGFkYXRhW21ldGFkYXRhSWRdID0gbWV0YWRhdGFFbnRyeS5tYXAoKG1ldGE6IE1ldGFkYXRhRW50cnkpID0+IHtcbiAgICAgICAgaWYgKG1ldGEudHlwZSA9PT0gJ2F3czpjZGs6bG9naWNhbElkJyAmJiB0cmFjZSAmJiBtZXRhLmRhdGEpIHtcbiAgICAgICAgICBjb25zdCB0cmFjZURhdGEgPSB0cmFjZS5nZXQobWV0YS5kYXRhLnRvU3RyaW5nKCkpO1xuICAgICAgICAgIGlmICh0cmFjZURhdGEpIHtcbiAgICAgICAgICAgIHRyYWNlLmRlbGV0ZShtZXRhLmRhdGEudG9TdHJpbmcoKSk7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICB0eXBlOiBtZXRhLnR5cGUsXG4gICAgICAgICAgICAgIGRhdGE6IG1ldGEuZGF0YSxcbiAgICAgICAgICAgICAgdHJhY2U6IFt0cmFjZURhdGFdLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgLy8gcmV0dXJuIG1ldGFkYXRhIHdpdGhvdXQgdGhlIHRyYWNlIGRhdGFcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0eXBlOiBtZXRhLnR5cGUsXG4gICAgICAgICAgZGF0YTogbWV0YS5kYXRhLFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICh0cmFjZSAmJiB0cmFjZS5zaXplID4gMCkge1xuICAgICAgZm9yIChjb25zdCBbaWQsIGRhdGFdIG9mIHRyYWNlLmVudHJpZXMoKSkge1xuICAgICAgICBuZXdNZXRhZGF0YVtpZF0gPSBbe1xuICAgICAgICAgIHR5cGU6ICdhd3M6Y2RrOmxvZ2ljYWxJZCcsXG4gICAgICAgICAgZGF0YTogaWQsXG4gICAgICAgICAgdHJhY2U6IFtkYXRhXSxcbiAgICAgICAgfV07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXdNZXRhZGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyQXJ0aWZhY3RzKHRyYWNlPzogTWFuaWZlc3RUcmFjZSk6IHsgW2lkOiBzdHJpbmddOiBBcnRpZmFjdE1hbmlmZXN0IH0gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG5ld0FydGlmYWN0czogeyBbaWQ6IHN0cmluZ106IEFydGlmYWN0TWFuaWZlc3QgfSA9IHt9O1xuICAgIGZvciAoY29uc3QgW2FydGlmYWN0SWQsIGFydGlmYWN0XSBvZiBPYmplY3QuZW50cmllcyh0aGlzLm1hbmlmZXN0LmFydGlmYWN0cyA/PyB7fSkpIHtcbiAgICAgIGxldCBzdGFja1RyYWNlOiBTdGFja1RyYWNlIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgICAgaWYgKGFydGlmYWN0LnR5cGUgPT09IEFydGlmYWN0VHlwZS5BV1NfQ0xPVURGT1JNQVRJT05fU1RBQ0sgJiYgdHJhY2UpIHtcbiAgICAgICAgc3RhY2tUcmFjZSA9IHRyYWNlLmdldChhcnRpZmFjdElkKTtcbiAgICAgIH1cbiAgICAgIG5ld0FydGlmYWN0c1thcnRpZmFjdElkXSA9IHtcbiAgICAgICAgLi4uYXJ0aWZhY3QsXG4gICAgICAgIG1ldGFkYXRhOiB0aGlzLnJlbmRlckFydGlmYWN0TWV0YWRhdGEoYXJ0aWZhY3QsIHN0YWNrVHJhY2UpLFxuICAgICAgfTtcbiAgICB9XG4gICAgcmV0dXJuIG5ld0FydGlmYWN0cztcbiAgfVxufVxuIl19