UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

174 lines 23.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AssetManifestBuilder = void 0; const fs = require("fs"); const path = require("path"); const cxschema = require("@aws-cdk/cloud-assembly-schema"); const assets_1 = require("../assets"); const cfn_fn_1 = require("../cfn-fn"); const _shared_1 = require("./_shared"); /** * Build an manifest from assets added to a stack synthesizer */ class AssetManifestBuilder { constructor() { this.files = {}; this.dockerImages = {}; } addFileAssetDefault(asset, stack, bucketName, bucketPrefix, role) { validateFileAssetSource(asset); const extension = asset.fileName != undefined ? path.extname(asset.fileName) : ''; const objectKey = bucketPrefix + asset.sourceHash + (asset.packaging === assets_1.FileAssetPackaging.ZIP_DIRECTORY ? '.zip' : extension); // Add to manifest this.files[asset.sourceHash] = { source: { path: asset.fileName, executable: asset.executable, packaging: asset.packaging, }, destinations: { [this.manifestEnvName(stack)]: { bucketName: bucketName, objectKey, region: _shared_1.resolvedOr(stack.region, undefined), assumeRoleArn: role?.assumeRoleArn, assumeRoleExternalId: role?.assumeRoleExternalId, }, }, }; const { region, urlSuffix } = stackLocationOrInstrinsics(stack); const httpUrl = cfnify(`https://s3.${region}.${urlSuffix}/${bucketName}/${objectKey}`); const s3ObjectUrlWithPlaceholders = `s3://${bucketName}/${objectKey}`; // Return CFN expression // // 's3ObjectUrlWithPlaceholders' is intended for the CLI. The CLI ultimately needs a // 'https://s3.REGION.amazonaws.com[.cn]/name/hash' URL to give to CloudFormation. // However, there's no way for us to actually know the URL_SUFFIX in the framework, so // we can't construct that URL. Instead, we record the 's3://.../...' form, and the CLI // transforms it to the correct 'https://.../' URL before calling CloudFormation. return { bucketName: cfnify(bucketName), objectKey, httpUrl, s3ObjectUrl: cfnify(s3ObjectUrlWithPlaceholders), s3ObjectUrlWithPlaceholders, s3Url: httpUrl, }; } addDockerImageAssetDefault(asset, stack, repositoryName, dockerTagPrefix, role) { validateDockerImageAssetSource(asset); const imageTag = dockerTagPrefix + asset.sourceHash; // Add to manifest this.dockerImages[asset.sourceHash] = { source: { executable: asset.executable, directory: asset.directoryName, dockerBuildArgs: asset.dockerBuildArgs, dockerBuildTarget: asset.dockerBuildTarget, dockerFile: asset.dockerFile, networkMode: asset.networkMode, platform: asset.platform, }, destinations: { [this.manifestEnvName(stack)]: { repositoryName: repositoryName, imageTag, region: _shared_1.resolvedOr(stack.region, undefined), assumeRoleArn: role?.assumeRoleArn, assumeRoleExternalId: role?.assumeRoleExternalId, }, }, }; const { account, region, urlSuffix } = stackLocationOrInstrinsics(stack); // Return CFN expression return { repositoryName: cfnify(repositoryName), imageUri: cfnify(`${account}.dkr.ecr.${region}.${urlSuffix}/${repositoryName}:${imageTag}`), }; } /** * Write the manifest to disk, and add it to the synthesis session * * Reutrn the artifact Id */ writeManifest(stack, session, additionalProps = {}) { const artifactId = `${stack.artifactId}.assets`; const manifestFile = `${artifactId}.json`; const outPath = path.join(session.assembly.outdir, manifestFile); const manifest = { version: cxschema.Manifest.version(), files: this.files, dockerImages: this.dockerImages, }; fs.writeFileSync(outPath, JSON.stringify(manifest, undefined, 2)); session.assembly.addArtifact(artifactId, { type: cxschema.ArtifactType.ASSET_MANIFEST, properties: { file: manifestFile, ...additionalProps, }, }); return artifactId; } manifestEnvName(stack) { return [ _shared_1.resolvedOr(stack.account, 'current_account'), _shared_1.resolvedOr(stack.region, 'current_region'), ].join('-'); } } exports.AssetManifestBuilder = AssetManifestBuilder; function validateFileAssetSource(asset) { if (!!asset.executable === !!asset.fileName) { throw new Error(`Exactly one of 'fileName' or 'executable' is required, got: ${JSON.stringify(asset)}`); } if (!!asset.packaging !== !!asset.fileName) { throw new Error(`'packaging' is expected in combination with 'fileName', got: ${JSON.stringify(asset)}`); } } function validateDockerImageAssetSource(asset) { if (!!asset.executable === !!asset.directoryName) { throw new Error(`Exactly one of 'directoryName' or 'executable' is required, got: ${JSON.stringify(asset)}`); } check('dockerBuildArgs'); check('dockerBuildTarget'); check('dockerFile'); function check(key) { if (asset[key] && !asset.directoryName) { throw new Error(`'${key}' is only allowed in combination with 'directoryName', got: ${JSON.stringify(asset)}`); } } } /** * Return the stack locations if they're concrete, or the original CFN intrisics otherwise * * We need to return these instead of the tokenized versions of the strings, * since we must accept those same ${AWS::AccountId}/${AWS::Region} placeholders * in bucket names and role names (in order to allow environment-agnostic stacks). * * We'll wrap a single {Fn::Sub} around the final string in order to replace everything, * but we can't have the token system render part of the string to {Fn::Join} because * the CFN specification doesn't allow the {Fn::Sub} template string to be an arbitrary * expression--it must be a string literal. */ function stackLocationOrInstrinsics(stack) { return { account: _shared_1.resolvedOr(stack.account, '${AWS::AccountId}'), region: _shared_1.resolvedOr(stack.region, '${AWS::Region}'), urlSuffix: _shared_1.resolvedOr(stack.urlSuffix, '${AWS::URLSuffix}'), }; } /** * If the string still contains placeholders, wrap it in a Fn::Sub so they will be substituted at CFN deployment time * * (This happens to work because the placeholders we picked map directly onto CFN * placeholders. If they didn't we'd have to do a transformation here). */ function cfnify(s) { return s.indexOf('${') > -1 ? cfn_fn_1.Fn.sub(s) : s; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2Fzc2V0LW1hbmlmZXN0LWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJfYXNzZXQtbWFuaWZlc3QtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5QkFBeUI7QUFDekIsNkJBQTZCO0FBRTdCLDJEQUEyRDtBQUMzRCxzQ0FBcUk7QUFDckksc0NBQStCO0FBRy9CLHVDQUF1QztBQUV2Qzs7R0FFRztBQUNILE1BQWEsb0JBQW9CO0lBQWpDO1FBQ21CLFVBQUssR0FBaUQsRUFBRSxDQUFDO1FBQ3pELGlCQUFZLEdBQXdELEVBQUUsQ0FBQztJQStJMUYsQ0FBQztJQTdJUSxtQkFBbUIsQ0FDeEIsS0FBc0IsRUFDdEIsS0FBWSxFQUNaLFVBQWtCLEVBQ2xCLFlBQW9CLEVBQ3BCLElBQWtCO1FBRWxCLHVCQUF1QixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRS9CLE1BQU0sU0FBUyxHQUNiLEtBQUssQ0FBQyxRQUFRLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ2xFLE1BQU0sU0FBUyxHQUNiLFlBQVk7WUFDWixLQUFLLENBQUMsVUFBVTtZQUNoQixDQUFDLEtBQUssQ0FBQyxTQUFTLEtBQUssMkJBQWtCLENBQUMsYUFBYTtnQkFDbkQsQ0FBQyxDQUFDLE1BQU07Z0JBQ1IsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRWpCLGtCQUFrQjtRQUNsQixJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRztZQUM3QixNQUFNLEVBQUU7Z0JBQ04sSUFBSSxFQUFFLEtBQUssQ0FBQyxRQUFRO2dCQUNwQixVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7Z0JBQzVCLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUzthQUMzQjtZQUNELFlBQVksRUFBRTtnQkFDWixDQUFDLElBQUks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LENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcblxuaW1wb3J0ICogYXMgY3hzY2hlbWEgZnJvbSAnQGF3cy1jZGsvY2xvdWQtYXNzZW1ibHktc2NoZW1hJztcbmltcG9ydCB7IEZpbGVBc3NldFNvdXJjZSwgRmlsZUFzc2V0TG9jYXRpb24sIEZpbGVBc3NldFBhY2thZ2luZywgRG9ja2VySW1hZ2VBc3NldFNvdXJjZSwgRG9ja2VySW1hZ2VBc3NldExvY2F0aW9uIH0gZnJvbSAnLi4vYXNzZXRzJztcbmltcG9ydCB7IEZuIH0gZnJvbSAnLi4vY2ZuLWZuJztcbmltcG9ydCB7IElTeW50aGVzaXNTZXNzaW9uIH0gZnJvbSAnLi4vY29uc3RydWN0LWNvbXBhdCc7XG5pbXBvcnQgeyBTdGFjayB9IGZyb20gJy4uL3N0YWNrJztcbmltcG9ydCB7IHJlc29sdmVkT3IgfSBmcm9tICcuL19zaGFyZWQnO1xuXG4vKipcbiAqIEJ1aWxkIGFuIG1hbmlmZXN0IGZyb20gYXNzZXRzIGFkZGVkIHRvIGEgc3RhY2sgc3ludGhlc2l6ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIEFzc2V0TWFuaWZlc3RCdWlsZGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBmaWxlczogTm9uTnVsbGFibGU8Y3hzY2hlbWEuQXNzZXRNYW5pZmVzdFsnZmlsZXMnXT4gPSB7fTtcbiAgcHJpdmF0ZSByZWFkb25seSBkb2NrZXJJbWFnZXM6IE5vbk51bGxhYmxlPGN4c2NoZW1hLkFzc2V0TWFuaWZlc3RbJ2RvY2tlckltYWdlcyddPiA9IHt9O1xuXG4gIHB1YmxpYyBhZGRGaWxlQXNzZXREZWZhdWx0KFxuICAgIGFzc2V0OiBGaWxlQXNzZXRTb3VyY2UsXG4gICAgc3RhY2s6IFN0YWNrLFxuICAgIGJ1Y2tldE5hbWU6IHN0cmluZyxcbiAgICBidWNrZXRQcmVmaXg6IHN0cmluZyxcbiAgICByb2xlPzogUm9sZU9wdGlvbnMsXG4gICk6IEZpbGVBc3NldExvY2F0aW9uIHtcbiAgICB2YWxpZGF0ZUZpbGVBc3NldFNvdXJjZShhc3NldCk7XG5cbiAgICBjb25zdCBleHRlbnNpb24gPVxuICAgICAgYXNzZXQuZmlsZU5hbWUgIT0gdW5kZWZpbmVkID8gcGF0aC5leHRuYW1lKGFzc2V0LmZpbGVOYW1lKSA6ICcnO1xuICAgIGNvbnN0IG9iamVjdEtleSA9XG4gICAgICBidWNrZXRQcmVmaXggK1xuICAgICAgYXNzZXQuc291cmNlSGFzaCArXG4gICAgICAoYXNzZXQucGFja2FnaW5nID09PSBGaWxlQXNzZXRQYWNrYWdpbmcuWklQX0RJUkVDVE9SWVxuICAgICAgICA/ICcuemlwJ1xuICAgICAgICA6IGV4dGVuc2lvbik7XG5cbiAgICAvLyBBZGQgdG8gbWFuaWZlc3RcbiAgICB0aGlzLmZpbGVzW2Fzc2V0LnNvdXJjZUhhc2hdID0ge1xuICAgICAgc291cmNlOiB7XG4gICAgICAgIHBhdGg6IGFzc2V0LmZpbGVOYW1lLFxuICAgICAgICBleGVjdXRhYmxlOiBhc3NldC5leGVjdXRhYmxlLFxuICAgICAgICBwYWNrYWdpbmc6IGFzc2V0LnBhY2thZ2luZyxcbiAgICAgIH0sXG4gICAgICBkZXN0aW5hdGlvbnM6IHtcbiAgICAgICAgW3RoaXMubWFuaWZlc3RFbnZOYW1lKHN0YWNrKV06IHtcbiAgICAgICAgICBidWNrZXROYW1lOiBidWNrZXROYW1lLFxuICAgICAgICAgIG9iamVjdEtleSxcbiAgICAgICAgICByZWdpb246IHJlc29sdmVkT3Ioc3RhY2sucmVnaW9uLCB1bmRlZmluZWQpLFxuICAgICAgICAgIGFzc3VtZVJvbGVBcm46IHJvbGU/LmFzc3VtZVJvbGVBcm4sXG4gICAgICAgICAgYXNzdW1lUm9sZUV4dGVybmFsSWQ6IHJvbGU/LmFzc3VtZVJvbGVFeHRlcm5hbElkLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgeyByZWdpb24sIHVybFN1ZmZpeCB9ID0gc3RhY2tMb2NhdGlvbk9ySW5zdHJpbnNpY3Moc3RhY2spO1xuICAgIGNvbnN0IGh0dHBVcmwgPSBjZm5pZnkoXG4gICAgICBgaHR0cHM6Ly9zMy4ke3JlZ2lvbn0uJHt1cmxTdWZmaXh9LyR7YnVja2V0TmFtZX0vJHtvYmplY3RLZXl9YCxcbiAgICApO1xuICAgIGNvbnN0IHMzT2JqZWN0VXJsV2l0aFBsYWNlaG9sZGVycyA9IGBzMzovLyR7YnVja2V0TmFtZX0vJHtvYmplY3RLZXl9YDtcblxuICAgIC8vIFJldHVybiBDRk4gZXhwcmVzc2lvblxuICAgIC8vXG4gICAgLy8gJ3MzT2JqZWN0VXJsV2l0aFBsYWNlaG9sZGVycycgaXMgaW50ZW5kZWQgZm9yIHRoZSBDTEkuIFRoZSBDTEkgdWx0aW1hdGVseSBuZWVkcyBhXG4gICAgLy8gJ2h0dHBzOi8vczMuUkVHSU9OLmFtYXpvbmF3cy5jb21bLmNuXS9uYW1lL2hhc2gnIFVSTCB0byBnaXZlIHRvIENsb3VkRm9ybWF0aW9uLlxuICAgIC8vIEhvd2V2ZXIsIHRoZXJlJ3Mgbm8gd2F5IGZvciB1cyB0byBhY3R1YWxseSBrbm93IHRoZSBVUkxfU1VGRklYIGluIHRoZSBmcmFtZXdvcmssIHNvXG4gICAgLy8gd2UgY2FuJ3QgY29uc3RydWN0IHRoYXQgVVJMLiBJbnN0ZWFkLCB3ZSByZWNvcmQgdGhlICdzMzovLy4uLi8uLi4nIGZvcm0sIGFuZCB0aGUgQ0xJXG4gICAgLy8gdHJhbnNmb3JtcyBpdCB0byB0aGUgY29ycmVjdCAnaHR0cHM6Ly8uLi4vJyBVUkwgYmVmb3JlIGNhbGxpbmcgQ2xvdWRGb3JtYXRpb24uXG4gICAgcmV0dXJuIHtcbiAgICAgIGJ1Y2tldE5hbWU6IGNmbmlmeShidWNrZXROYW1lKSxcbiAgICAgIG9iamVjdEtleSxcbiAgICAgIGh0dHBVcmwsXG4gICAgICBzM09iamVjdFVybDogY2ZuaWZ5KHMzT2JqZWN0VXJsV2l0aFBsYWNlaG9sZGVycyksXG4gICAgICBzM09iamVjdFVybFdpdGhQbGFjZWhvbGRlcnMsXG4gICAgICBzM1VybDogaHR0cFVybCxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIGFkZERvY2tlckltYWdlQXNzZXREZWZhdWx0KFxuICAgIGFzc2V0OiBEb2NrZXJJbWFnZUFzc2V0U291cmNlLFxuICAgIHN0YWNrOiBTdGFjayxcbiAgICByZXBvc2l0b3J5TmFtZTogc3RyaW5nLFxuICAgIGRvY2tlclRhZ1ByZWZpeDogc3RyaW5nLFxuICAgIHJvbGU/OiBSb2xlT3B0aW9ucyxcbiAgKTogRG9ja2VySW1hZ2VBc3NldExvY2F0aW9uIHtcbiAgICB2YWxpZGF0ZURvY2tlckltYWdlQXNzZXRTb3VyY2UoYXNzZXQpO1xuICAgIGNvbnN0IGltYWdlVGFnID0gZG9ja2VyVGFnUHJlZml4ICsgYXNzZXQuc291cmNlSGFzaDtcblxuICAgIC8vIEFkZCB0byBtYW5pZmVzdFxuICAgIHRoaXMuZG9ja2VySW1hZ2VzW2Fzc2V0LnNvdXJjZUhhc2hdID0ge1xuICAgICAgc291cmNlOiB7XG4gICAgICAgIGV4ZWN1dGFibGU6IGFzc2V0LmV4ZWN1dGFibGUsXG4gICAgICAgIGRpcmVjdG9yeTogYXNzZXQuZGlyZWN0b3J5TmFtZSxcbiAgICAgICAgZG9ja2VyQnVpbGRBcmdzOiBhc3NldC5kb2NrZXJCdWlsZEFyZ3MsXG4gICAgICAgIGRvY2tlckJ1aWxkVGFyZ2V0OiBhc3NldC5kb2NrZXJCdWlsZFRhcmdldCxcbiAgICAgICAgZG9ja2VyRmlsZTogYXNzZXQuZG9ja2VyRmlsZSxcbiAgICAgICAgbmV0d29ya01vZGU6IGFzc2V0Lm5ldHdvcmtNb2RlLFxuICAgICAgICBwbGF0Zm9ybTogYXNzZXQucGxhdGZvcm0sXG4gICAgICB9LFxuICAgICAgZGVzdGluYXRpb25zOiB7XG4gICAgICAgIFt0aGlzLm1hbmlmZXN0RW52TmFtZShzdGFjayldOiB7XG4gICAgICAgICAgcmVwb3NpdG9yeU5hbWU6IHJlcG9zaXRvcnlOYW1lLFxuICAgICAgICAgIGltYWdlVGFnLFxuICAgICAgICAgIHJlZ2lvbjogcmVzb2x2ZWRPcihzdGFjay5yZWdpb24sIHVuZGVmaW5lZCksXG4gICAgICAgICAgYXNzdW1lUm9sZUFybjogcm9sZT8uYXNzdW1lUm9sZUFybixcbiAgICAgICAgICBhc3N1bWVSb2xlRXh0ZXJuYWxJZDogcm9sZT8uYXNzdW1lUm9sZUV4dGVybmFsSWQsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBjb25zdCB7IGFjY291bnQsIHJlZ2lvbiwgdXJsU3VmZml4IH0gPSBzdGFja0xvY2F0aW9uT3JJbnN0cmluc2ljcyhzdGFjayk7XG5cbiAgICAvLyBSZXR1cm4gQ0ZOIGV4cHJlc3Npb25cbiAgICByZXR1cm4ge1xuICAgICAgcmVwb3NpdG9yeU5hbWU6IGNmbmlmeShyZXBvc2l0b3J5TmFtZSksXG4gICAgICBpbWFnZVVyaTogY2ZuaWZ5KFxuICAgICAgICBgJHthY2NvdW50fS5ka3IuZWNyLiR7cmVnaW9ufS4ke3VybFN1ZmZpeH0vJHtyZXBvc2l0b3J5TmFtZX06JHtpbWFnZVRhZ31gLFxuICAgICAgKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFdyaXRlIHRoZSBtYW5pZmVzdCB0byBkaXNrLCBhbmQgYWRkIGl0IHRvIHRoZSBzeW50aGVzaXMgc2Vzc2lvblxuICAgKlxuICAgKiBSZXV0cm4gdGhlIGFydGlmYWN0IElkXG4gICAqL1xuICBwdWJsaWMgd3JpdGVNYW5pZmVzdChcbiAgICBzdGFjazogU3RhY2ssXG4gICAgc2Vzc2lvbjogSVN5bnRoZXNpc1Nlc3Npb24sXG4gICAgYWRkaXRpb25hbFByb3BzOiBQYXJ0aWFsPGN4c2NoZW1hLkFzc2V0TWFuaWZlc3RQcm9wZXJ0aWVzPiA9IHt9LFxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IGFydGlmYWN0SWQgPSBgJHtzdGFjay5hcnRpZmFjdElkfS5hc3NldHNgO1xuICAgIGNvbnN0IG1hbmlmZXN0RmlsZSA9IGAke2FydGlmYWN0SWR9Lmpzb25gO1xuICAgIGNvbnN0IG91dFBhdGggPSBwYXRoLmpvaW4oc2Vzc2lvbi5hc3NlbWJseS5vdXRkaXIsIG1hbmlmZXN0RmlsZSk7XG5cbiAgICBjb25zdCBtYW5pZmVzdDogY3hzY2hlbWEuQXNzZXRNYW5pZmVzdCA9IHtcbiAgICAgIHZlcnNpb246IGN4c2NoZW1hLk1hbmlmZXN0LnZlcnNpb24oKSxcbiAgICAgIGZpbGVzOiB0aGlzLmZpbGVzLFxuICAgICAgZG9ja2VySW1hZ2VzOiB0aGlzLmRvY2tlckltYWdlcyxcbiAgICB9O1xuXG4gICAgZnMud3JpdGVGaWxlU3luYyhvdXRQYXRoLCBKU09OLnN0cmluZ2lmeShtYW5pZmVzdCwgdW5kZWZpbmVkLCAyKSk7XG5cbiAgICBzZXNzaW9uLmFzc2VtYmx5LmFkZEFydGlmYWN0KGFydGlmYWN0SWQsIHtcbiAgICAgIHR5cGU6IGN4c2NoZW1hLkFydGlmYWN0VHlwZS5BU1NFVF9NQU5JRkVTVCxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgZmlsZTogbWFuaWZlc3RGaWxlLFxuICAgICAgICAuLi5hZGRpdGlvbmFsUHJvcHMsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGFydGlmYWN0SWQ7XG4gIH1cblxuICBwcml2YXRlIG1hbmlmZXN0RW52TmFtZShzdGFjazogU3RhY2spOiBzdHJpbmcge1xuICAgIHJldHVybiBbXG4gICAgICByZXNvbHZlZE9yKHN0YWNrLmFjY291bnQsICdjdXJyZW50X2FjY291bnQnKSxcbiAgICAgIHJlc29sdmVkT3Ioc3RhY2sucmVnaW9uLCAnY3VycmVudF9yZWdpb24nKSxcbiAgICBdLmpvaW4oJy0nKTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJvbGVPcHRpb25zIHtcbiAgcmVhZG9ubHkgYXNzdW1lUm9sZUFybj86IHN0cmluZztcbiAgcmVhZG9ubHkgYXNzdW1lUm9sZUV4dGVybmFsSWQ/OiBzdHJpbmc7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlRmlsZUFzc2V0U291cmNlKGFzc2V0OiBGaWxlQXNzZXRTb3VyY2UpIHtcbiAgaWYgKCEhYXNzZXQuZXhlY3V0YWJsZSA9PT0gISFhc3NldC5maWxlTmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRXhhY3RseSBvbmUgb2YgJ2ZpbGVOYW1lJyBvciAnZXhlY3V0YWJsZScgaXMgcmVxdWlyZWQsIGdvdDogJHtKU09OLnN0cmluZ2lmeShhc3NldCl9YCk7XG4gIH1cblxuICBpZiAoISFhc3NldC5wYWNrYWdpbmcgIT09ICEhYXNzZXQuZmlsZU5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCdwYWNrYWdpbmcnIGlzIGV4cGVjdGVkIGluIGNvbWJpbmF0aW9uIHdpdGggJ2ZpbGVOYW1lJywgZ290OiAke0pTT04uc3RyaW5naWZ5KGFzc2V0KX1gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZURvY2tlckltYWdlQXNzZXRTb3VyY2UoYXNzZXQ6IERvY2tlckltYWdlQXNzZXRTb3VyY2UpIHtcbiAgaWYgKCEhYXNzZXQuZXhlY3V0YWJsZSA9PT0gISFhc3NldC5kaXJlY3RvcnlOYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeGFjdGx5IG9uZSBvZiAnZGlyZWN0b3J5TmFtZScgb3IgJ2V4ZWN1dGFibGUnIGlzIHJlcXVpcmVkLCBnb3Q6ICR7SlNPTi5zdHJpbmdpZnkoYXNzZXQpfWApO1xuICB9XG5cbiAgY2hlY2soJ2RvY2tlckJ1aWxkQXJncycpO1xuICBjaGVjaygnZG9ja2VyQnVpbGRUYXJnZXQnKTtcbiAgY2hlY2soJ2RvY2tlckZpbGUnKTtcblxuICBmdW5jdGlvbiBjaGVjazxLIGV4dGVuZHMga2V5b2YgRG9ja2VySW1hZ2VBc3NldFNvdXJjZT4oa2V5OiBLKSB7XG4gICAgaWYgKGFzc2V0W2tleV0gJiYgIWFzc2V0LmRpcmVjdG9yeU5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJyR7a2V5fScgaXMgb25seSBhbGxvd2VkIGluIGNvbWJpbmF0aW9uIHdpdGggJ2RpcmVjdG9yeU5hbWUnLCBnb3Q6ICR7SlNPTi5zdHJpbmdpZnkoYXNzZXQpfWApO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgc3RhY2sgbG9jYXRpb25zIGlmIHRoZXkncmUgY29uY3JldGUsIG9yIHRoZSBvcmlnaW5hbCBDRk4gaW50cmlzaWNzIG90aGVyd2lzZVxuICpcbiAqIFdlIG5lZWQgdG8gcmV0dXJuIHRoZXNlIGluc3RlYWQgb2YgdGhlIHRva2VuaXplZCB2ZXJzaW9ucyBvZiB0aGUgc3RyaW5ncyxcbiAqIHNpbmNlIHdlIG11c3QgYWNjZXB0IHRob3NlIHNhbWUgJHtBV1M6OkFjY291bnRJZH0vJHtBV1M6OlJlZ2lvbn0gcGxhY2Vob2xkZXJzXG4gKiBpbiBidWNrZXQgbmFtZXMgYW5kIHJvbGUgbmFtZXMgKGluIG9yZGVyIHRvIGFsbG93IGVudmlyb25tZW50LWFnbm9zdGljIHN0YWNrcykuXG4gKlxuICogV2UnbGwgd3JhcCBhIHNpbmdsZSB7Rm46OlN1Yn0gYXJvdW5kIHRoZSBmaW5hbCBzdHJpbmcgaW4gb3JkZXIgdG8gcmVwbGFjZSBldmVyeXRoaW5nLFxuICogYnV0IHdlIGNhbid0IGhhdmUgdGhlIHRva2VuIHN5c3RlbSByZW5kZXIgcGFydCBvZiB0aGUgc3RyaW5nIHRvIHtGbjo6Sm9pbn0gYmVjYXVzZVxuICogdGhlIENGTiBzcGVjaWZpY2F0aW9uIGRvZXNuJ3QgYWxsb3cgdGhlIHtGbjo6U3VifSB0ZW1wbGF0ZSBzdHJpbmcgdG8gYmUgYW4gYXJiaXRyYXJ5XG4gKiBleHByZXNzaW9uLS1pdCBtdXN0IGJlIGEgc3RyaW5nIGxpdGVyYWwuXG4gKi9cbmZ1bmN0aW9uIHN0YWNrTG9jYXRpb25Pckluc3RyaW5zaWNzKHN0YWNrOiBTdGFjaykge1xuICByZXR1cm4ge1xuICAgIGFjY291bnQ6IHJlc29sdmVkT3Ioc3RhY2suYWNjb3VudCwgJyR7QVdTOjpBY2NvdW50SWR9JyksXG4gICAgcmVnaW9uOiByZXNvbHZlZE9yKHN0YWNrLnJlZ2lvbiwgJyR7QVdTOjpSZWdpb259JyksXG4gICAgdXJsU3VmZml4OiByZXNvbHZlZE9yKHN0YWNrLnVybFN1ZmZpeCwgJyR7QVdTOjpVUkxTdWZmaXh9JyksXG4gIH07XG59XG5cbi8qKlxuICogSWYgdGhlIHN0cmluZyBzdGlsbCBjb250YWlucyBwbGFjZWhvbGRlcnMsIHdyYXAgaXQgaW4gYSBGbjo6U3ViIHNvIHRoZXkgd2lsbCBiZSBzdWJzdGl0dXRlZCBhdCBDRk4gZGVwbG95bWVudCB0aW1lXG4gKlxuICogKFRoaXMgaGFwcGVucyB0byB3b3JrIGJlY2F1c2UgdGhlIHBsYWNlaG9sZGVycyB3ZSBwaWNrZWQgbWFwIGRpcmVjdGx5IG9udG8gQ0ZOXG4gKiBwbGFjZWhvbGRlcnMuIElmIHRoZXkgZGlkbid0IHdlJ2QgaGF2ZSB0byBkbyBhIHRyYW5zZm9ybWF0aW9uIGhlcmUpLlxuICovXG5mdW5jdGlvbiBjZm5pZnkoczogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHMuaW5kZXhPZignJHsnKSA+IC0xID8gRm4uc3ViKHMpIDogcztcbn0iXX0=