1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.AssetManifestBuilder = void 0;
|
4 | const fs = require("fs");
|
5 | const path = require("path");
|
6 | const cxschema = require("@aws-cdk/cloud-assembly-schema");
|
7 | const assets_1 = require("../assets");
|
8 | const cfn_fn_1 = require("../cfn-fn");
|
9 | const _shared_1 = require("./_shared");
|
10 | /**
|
11 | * Build an manifest from assets added to a stack synthesizer
|
12 | */
|
13 | class AssetManifestBuilder {
|
14 | constructor() {
|
15 | this.files = {};
|
16 | this.dockerImages = {};
|
17 | }
|
18 | addFileAssetDefault(asset, stack, bucketName, bucketPrefix, role) {
|
19 | validateFileAssetSource(asset);
|
20 | const extension = asset.fileName != undefined ? path.extname(asset.fileName) : '';
|
21 | const objectKey = bucketPrefix +
|
22 | asset.sourceHash +
|
23 | (asset.packaging === assets_1.FileAssetPackaging.ZIP_DIRECTORY
|
24 | ? '.zip'
|
25 | : extension);
|
26 | // Add to manifest
|
27 | this.files[asset.sourceHash] = {
|
28 | source: {
|
29 | path: asset.fileName,
|
30 | executable: asset.executable,
|
31 | packaging: asset.packaging,
|
32 | },
|
33 | destinations: {
|
34 | [this.manifestEnvName(stack)]: {
|
35 | bucketName: bucketName,
|
36 | objectKey,
|
37 | region: _shared_1.resolvedOr(stack.region, undefined),
|
38 | assumeRoleArn: role?.assumeRoleArn,
|
39 | assumeRoleExternalId: role?.assumeRoleExternalId,
|
40 | },
|
41 | },
|
42 | };
|
43 | const { region, urlSuffix } = stackLocationOrInstrinsics(stack);
|
44 | const httpUrl = cfnify(`https://s3.${region}.${urlSuffix}/${bucketName}/${objectKey}`);
|
45 | const s3ObjectUrlWithPlaceholders = `s3://${bucketName}/${objectKey}`;
|
46 | // Return CFN expression
|
47 | //
|
48 | // 's3ObjectUrlWithPlaceholders' is intended for the CLI. The CLI ultimately needs a
|
49 | // 'https://s3.REGION.amazonaws.com[.cn]/name/hash' URL to give to CloudFormation.
|
50 | // However, there's no way for us to actually know the URL_SUFFIX in the framework, so
|
51 | // we can't construct that URL. Instead, we record the 's3://.../...' form, and the CLI
|
52 | // transforms it to the correct 'https://.../' URL before calling CloudFormation.
|
53 | return {
|
54 | bucketName: cfnify(bucketName),
|
55 | objectKey,
|
56 | httpUrl,
|
57 | s3ObjectUrl: cfnify(s3ObjectUrlWithPlaceholders),
|
58 | s3ObjectUrlWithPlaceholders,
|
59 | s3Url: httpUrl,
|
60 | };
|
61 | }
|
62 | addDockerImageAssetDefault(asset, stack, repositoryName, dockerTagPrefix, role) {
|
63 | validateDockerImageAssetSource(asset);
|
64 | const imageTag = dockerTagPrefix + asset.sourceHash;
|
65 | // Add to manifest
|
66 | this.dockerImages[asset.sourceHash] = {
|
67 | source: {
|
68 | executable: asset.executable,
|
69 | directory: asset.directoryName,
|
70 | dockerBuildArgs: asset.dockerBuildArgs,
|
71 | dockerBuildTarget: asset.dockerBuildTarget,
|
72 | dockerFile: asset.dockerFile,
|
73 | networkMode: asset.networkMode,
|
74 | platform: asset.platform,
|
75 | },
|
76 | destinations: {
|
77 | [this.manifestEnvName(stack)]: {
|
78 | repositoryName: repositoryName,
|
79 | imageTag,
|
80 | region: _shared_1.resolvedOr(stack.region, undefined),
|
81 | assumeRoleArn: role?.assumeRoleArn,
|
82 | assumeRoleExternalId: role?.assumeRoleExternalId,
|
83 | },
|
84 | },
|
85 | };
|
86 | const { account, region, urlSuffix } = stackLocationOrInstrinsics(stack);
|
87 | // Return CFN expression
|
88 | return {
|
89 | repositoryName: cfnify(repositoryName),
|
90 | imageUri: cfnify(`${account}.dkr.ecr.${region}.${urlSuffix}/${repositoryName}:${imageTag}`),
|
91 | };
|
92 | }
|
93 | /**
|
94 | * Write the manifest to disk, and add it to the synthesis session
|
95 | *
|
96 | * Reutrn the artifact Id
|
97 | */
|
98 | writeManifest(stack, session, additionalProps = {}) {
|
99 | const artifactId = `${stack.artifactId}.assets`;
|
100 | const manifestFile = `${artifactId}.json`;
|
101 | const outPath = path.join(session.assembly.outdir, manifestFile);
|
102 | const manifest = {
|
103 | version: cxschema.Manifest.version(),
|
104 | files: this.files,
|
105 | dockerImages: this.dockerImages,
|
106 | };
|
107 | fs.writeFileSync(outPath, JSON.stringify(manifest, undefined, 2));
|
108 | session.assembly.addArtifact(artifactId, {
|
109 | type: cxschema.ArtifactType.ASSET_MANIFEST,
|
110 | properties: {
|
111 | file: manifestFile,
|
112 | ...additionalProps,
|
113 | },
|
114 | });
|
115 | return artifactId;
|
116 | }
|
117 | manifestEnvName(stack) {
|
118 | return [
|
119 | _shared_1.resolvedOr(stack.account, 'current_account'),
|
120 | _shared_1.resolvedOr(stack.region, 'current_region'),
|
121 | ].join('-');
|
122 | }
|
123 | }
|
124 | exports.AssetManifestBuilder = AssetManifestBuilder;
|
125 | function validateFileAssetSource(asset) {
|
126 | if (!!asset.executable === !!asset.fileName) {
|
127 | throw new Error(`Exactly one of 'fileName' or 'executable' is required, got: ${JSON.stringify(asset)}`);
|
128 | }
|
129 | if (!!asset.packaging !== !!asset.fileName) {
|
130 | throw new Error(`'packaging' is expected in combination with 'fileName', got: ${JSON.stringify(asset)}`);
|
131 | }
|
132 | }
|
133 | function validateDockerImageAssetSource(asset) {
|
134 | if (!!asset.executable === !!asset.directoryName) {
|
135 | throw new Error(`Exactly one of 'directoryName' or 'executable' is required, got: ${JSON.stringify(asset)}`);
|
136 | }
|
137 | check('dockerBuildArgs');
|
138 | check('dockerBuildTarget');
|
139 | check('dockerFile');
|
140 | function check(key) {
|
141 | if (asset[key] && !asset.directoryName) {
|
142 | throw new Error(`'${key}' is only allowed in combination with 'directoryName', got: ${JSON.stringify(asset)}`);
|
143 | }
|
144 | }
|
145 | }
|
146 | /**
|
147 | * Return the stack locations if they're concrete, or the original CFN intrisics otherwise
|
148 | *
|
149 | * We need to return these instead of the tokenized versions of the strings,
|
150 | * since we must accept those same ${AWS::AccountId}/${AWS::Region} placeholders
|
151 | * in bucket names and role names (in order to allow environment-agnostic stacks).
|
152 | *
|
153 | * We'll wrap a single {Fn::Sub} around the final string in order to replace everything,
|
154 | * but we can't have the token system render part of the string to {Fn::Join} because
|
155 | * the CFN specification doesn't allow the {Fn::Sub} template string to be an arbitrary
|
156 | * expression--it must be a string literal.
|
157 | */
|
158 | function stackLocationOrInstrinsics(stack) {
|
159 | return {
|
160 | account: _shared_1.resolvedOr(stack.account, '${AWS::AccountId}'),
|
161 | region: _shared_1.resolvedOr(stack.region, '${AWS::Region}'),
|
162 | urlSuffix: _shared_1.resolvedOr(stack.urlSuffix, '${AWS::URLSuffix}'),
|
163 | };
|
164 | }
|
165 | /**
|
166 | * If the string still contains placeholders, wrap it in a Fn::Sub so they will be substituted at CFN deployment time
|
167 | *
|
168 | * (This happens to work because the placeholders we picked map directly onto CFN
|
169 | * placeholders. If they didn't we'd have to do a transformation here).
|
170 | */
|
171 | function cfnify(s) {
|
172 | return s.indexOf('${') > -1 ? cfn_fn_1.Fn.sub(s) : s;
|
173 | }
|
174 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2Fzc2V0LW1hbmlmZXN0LWJ1aWxkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJfYXNzZXQtbWFuaWZlc3QtYnVpbGRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5QkFBeUI7QUFDekIsNkJBQTZCO0FBRTdCLDJEQUEyRDtBQUMzRCxzQ0FBcUk7QUFDckksc0NBQStCO0FBRy9CLHVDQUF1QztBQUV2Qzs7R0FFRztBQUNILE1BQWEsb0JBQW9CO0lBQWpDO1FBQ21CLFVBQUssR0FBaUQsRUFBRSxDQUFDO1FBQ3pELGlCQUFZLEdBQXdELEVBQUUsQ0FBQztJQStJMUYsQ0FBQztJQTdJUSxtQkFBbUIsQ0FDeEIsS0FBc0IsRUFDdEIsS0FBWSxFQUNaLFVBQWtCLEVBQ2xCLFlBQW9CLEVBQ3BCLElBQWtCO1FBRWxCLHVCQUF1QixDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRS9CLE1BQU0sU0FBUyxHQUNiLEtBQUssQ0FBQyxRQUFRLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ2xFLE1BQU0sU0FBUyxHQUNiLFlBQVk7WUFDWixLQUFLLENBQUMsVUFBVTtZQUNoQixDQUFDLEtBQUssQ0FBQyxTQUFTLEtBQUssMkJBQWtCLENBQUMsYUFBYTtnQkFDbkQsQ0FBQyxDQUFDLE1BQU07Z0JBQ1IsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBRWpCLGtCQUFrQjtRQUNsQixJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRztZQUM3QixNQUFNLEVBQUU7Z0JBQ04sSUFBSSxFQUFFLEtBQUssQ0FBQyxRQUFRO2dCQUNwQixVQUFVLEVBQUUsS0FBSyxDQUFDLFVBQVU7Z0JBQzVCLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUzthQUMzQjtZQUNELFlBQVksRUFBRTtnQkFDWixDQUFDLElBQUks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LENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM5QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcblxuaW1wb3J0ICogYXMgY3hzY2hlbWEgZnJvbSAnQGF3cy1jZGsvY2xvdWQtYXNzZW1ibHktc2NoZW1hJztcbmltcG9ydCB7IEZpbGVBc3NldFNvdXJjZSwgRmlsZUFzc2V0TG9jYXRpb24sIEZpbGVBc3NldFBhY2thZ2luZywgRG9ja2VySW1hZ2VBc3NldFNvdXJjZSwgRG9ja2VySW1hZ2VBc3NldExvY2F0aW9uIH0gZnJvbSAnLi4vYXNzZXRzJztcbmltcG9ydCB7IEZuIH0gZnJvbSAnLi4vY2ZuLWZuJztcbmltcG9ydCB7IElTeW50aGVzaXNTZXNzaW9uIH0gZnJvbSAnLi4vY29uc3RydWN0LWNvbXBhdCc7XG5pbXBvcnQgeyBTdGFjayB9IGZyb20gJy4uL3N0YWNrJztcbmltcG9ydCB7IHJlc29sdmVkT3IgfSBmcm9tICcuL19zaGFyZWQnO1xuXG4vKipcbiAqIEJ1aWxkIGFuIG1hbmlmZXN0IGZyb20gYXNzZXRzIGFkZGVkIHRvIGEgc3RhY2sgc3ludGhlc2l6ZXJcbiAqL1xuZXhwb3J0IGNsYXNzIEFzc2V0TWFuaWZlc3RCdWlsZGVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBmaWxlczogTm9uTnVsbGFibGU8Y3hzY2hlbWEuQXNzZXRNYW5pZmVzdFsnZmlsZXMnXT4gPSB7fTtcbiAgcHJpdmF0ZSByZWFkb25seSBkb2NrZXJJbWFnZXM6IE5vbk51bGxhYmxlPGN4c2NoZW1hLkFzc2V0TWFuaWZlc3RbJ2RvY2tlckltYWdlcyddPiA9IHt9O1xuXG4gIHB1YmxpYyBhZGRGaWxlQXNzZXREZWZhdWx0KFxuICAgIGFzc2V0OiBGaWxlQXNzZXRTb3VyY2UsXG4gICAgc3RhY2s6IFN0YWNrLFxuICAgIGJ1Y2tldE5hbWU6IHN0cmluZyxcbiAgICBidWNrZXRQcmVmaXg6IHN0cmluZyxcbiAgICByb2xlPzogUm9sZU9wdGlvbnMsXG4gICk6IEZpbGVBc3NldExvY2F0aW9uIHtcbiAgICB2YWxpZGF0ZUZpbGVBc3NldFNvdXJjZShhc3NldCk7XG5cbiAgICBjb25zdCBleHRlbnNpb24gPVxuICAgICAgYXNzZXQuZmlsZU5hbWUgIT0gdW5kZWZpbmVkID8gcGF0aC5leHRuYW1lKGFzc2V0LmZpbGVOYW1lKSA6ICcnO1xuICAgIGNvbnN0IG9iamVjdEtleSA9XG4gICAgICBidWNrZXRQcmVmaXggK1xuICAgICAgYXNzZXQuc291cmNlSGFzaCArXG4gICAgICAoYXNzZXQucGFja2FnaW5nID09PSBGaWxlQXNzZXRQYWNrYWdpbmcuWklQX0RJUkVDVE9SWVxuICAgICAgICA/ICcuemlwJ1xuICAgICAgICA6IGV4dGVuc2lvbik7XG5cbiAgICAvLyBBZGQgdG8gbWFuaWZlc3RcbiAgICB0aGlzLmZpbGVzW2Fzc2V0LnNvdXJjZUhhc2hdID0ge1xuICAgICAgc291cmNlOiB7XG4gICAgICAgIHBhdGg6IGFzc2V0LmZpbGVOYW1lLFxuICAgICAgICBleGVjdXRhYmxlOiBhc3NldC5leGVjdXRhYmxlLFxuICAgICAgICBwYWNrYWdpbmc6IGFzc2V0LnBhY2thZ2luZyxcbiAgICAgIH0sXG4gICAgICBkZXN0aW5hdGlvbnM6IHtcbiAgICAgICAgW3RoaXMubWFuaWZlc3RFbnZOYW1lKHN0YWNrKV06IHtcbiAgICAgICAgICBidWNrZXROYW1lOiBidWNrZXROYW1lLFxuICAgICAgICAgIG9iamVjdEtleSxcbiAgICAgICAgICByZWdpb246IHJlc29sdmVkT3Ioc3RhY2sucmVnaW9uLCB1bmRlZmluZWQpLFxuICAgICAgICAgIGFzc3VtZVJvbGVBcm46IHJvbGU/LmFzc3VtZVJvbGVBcm4sXG4gICAgICAgICAgYXNzdW1lUm9sZUV4dGVybmFsSWQ6IHJvbGU/LmFzc3VtZVJvbGVFeHRlcm5hbElkLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgY29uc3QgeyByZWdpb24sIHVybFN1ZmZpeCB9ID0gc3RhY2tMb2NhdGlvbk9ySW5zdHJpbnNpY3Moc3RhY2spO1xuICAgIGNvbnN0IGh0dHBVcmwgPSBjZm5pZnkoXG4gICAgICBgaHR0cHM6Ly9zMy4ke3JlZ2lvbn0uJHt1cmxTdWZmaXh9LyR7YnVja2V0TmFtZX0vJHtvYmplY3RLZXl9YCxcbiAgICApO1xuICAgIGNvbnN0IHMzT2JqZWN0VXJsV2l0aFBsYWNlaG9sZGVycyA9IGBzMzovLyR7YnVja2V0TmFtZX0vJHtvYmplY3RLZXl9YDtcblxuICAgIC8vIFJldHVybiBDRk4gZXhwcmVzc2lvblxuICAgIC8vXG4gICAgLy8gJ3MzT2JqZWN0VXJsV2l0aFBsYWNlaG9sZGVycycgaXMgaW50ZW5kZWQgZm9yIHRoZSBDTEkuIFRoZSBDTEkgdWx0aW1hdGVseSBuZWVkcyBhXG4gICAgLy8gJ2h0dHBzOi8vczMuUkVHSU9OLmFtYXpvbmF3cy5jb21bLmNuXS9uYW1lL2hhc2gnIFVSTCB0byBnaXZlIHRvIENsb3VkRm9ybWF0aW9uLlxuICAgIC8vIEhvd2V2ZXIsIHRoZXJlJ3Mgbm8gd2F5IGZvciB1cyB0byBhY3R1YWxseSBrbm93IHRoZSBVUkxfU1VGRklYIGluIHRoZSBmcmFtZXdvcmssIHNvXG4gICAgLy8gd2UgY2FuJ3QgY29uc3RydWN0IHRoYXQgVVJMLiBJbnN0ZWFkLCB3ZSByZWNvcmQgdGhlICdzMzovLy4uLi8uLi4nIGZvcm0sIGFuZCB0aGUgQ0xJXG4gICAgLy8gdHJhbnNmb3JtcyBpdCB0byB0aGUgY29ycmVjdCAnaHR0cHM6Ly8uLi4vJyBVUkwgYmVmb3JlIGNhbGxpbmcgQ2xvdWRGb3JtYXRpb24uXG4gICAgcmV0dXJuIHtcbiAgICAgIGJ1Y2tldE5hbWU6IGNmbmlmeShidWNrZXROYW1lKSxcbiAgICAgIG9iamVjdEtleSxcbiAgICAgIGh0dHBVcmwsXG4gICAgICBzM09iamVjdFVybDogY2ZuaWZ5KHMzT2JqZWN0VXJsV2l0aFBsYWNlaG9sZGVycyksXG4gICAgICBzM09iamVjdFVybFdpdGhQbGFjZWhvbGRlcnMsXG4gICAgICBzM1VybDogaHR0cFVybCxcbiAgICB9O1xuICB9XG5cbiAgcHVibGljIGFkZERvY2tlckltYWdlQXNzZXREZWZhdWx0KFxuICAgIGFzc2V0OiBEb2NrZXJJbWFnZUFzc2V0U291cmNlLFxuICAgIHN0YWNrOiBTdGFjayxcbiAgICByZXBvc2l0b3J5TmFtZTogc3RyaW5nLFxuICAgIGRvY2tlclRhZ1ByZWZpeDogc3RyaW5nLFxuICAgIHJvbGU/OiBSb2xlT3B0aW9ucyxcbiAgKTogRG9ja2VySW1hZ2VBc3NldExvY2F0aW9uIHtcbiAgICB2YWxpZGF0ZURvY2tlckltYWdlQXNzZXRTb3VyY2UoYXNzZXQpO1xuICAgIGNvbnN0IGltYWdlVGFnID0gZG9ja2VyVGFnUHJlZml4ICsgYXNzZXQuc291cmNlSGFzaDtcblxuICAgIC8vIEFkZCB0byBtYW5pZmVzdFxuICAgIHRoaXMuZG9ja2VySW1hZ2VzW2Fzc2V0LnNvdXJjZUhhc2hdID0ge1xuICAgICAgc291cmNlOiB7XG4gICAgICAgIGV4ZWN1dGFibGU6IGFzc2V0LmV4ZWN1dGFibGUsXG4gICAgICAgIGRpcmVjdG9yeTogYXNzZXQuZGlyZWN0b3J5TmFtZSxcbiAgICAgICAgZG9ja2VyQnVpbGRBcmdzOiBhc3NldC5kb2NrZXJCdWlsZEFyZ3MsXG4gICAgICAgIGRvY2tlckJ1aWxkVGFyZ2V0OiBhc3NldC5kb2NrZXJCdWlsZFRhcmdldCxcbiAgICAgICAgZG9ja2VyRmlsZTogYXNzZXQuZG9ja2VyRmlsZSxcbiAgICAgICAgbmV0d29ya01vZGU6IGFzc2V0Lm5ldHdvcmtNb2RlLFxuICAgICAgICBwbGF0Zm9ybTogYXNzZXQucGxhdGZvcm0sXG4gICAgICB9LFxuICAgICAgZGVzdGluYXRpb25zOiB7XG4gICAgICAgIFt0aGlzLm1hbmlmZXN0RW52TmFtZShzdGFjayldOiB7XG4gICAgICAgICAgcmVwb3NpdG9yeU5hbWU6IHJlcG9zaXRvcnlOYW1lLFxuICAgICAgICAgIGltYWdlVGFnLFxuICAgICAgICAgIHJlZ2lvbjogcmVzb2x2ZWRPcihzdGFjay5yZWdpb24sIHVuZGVmaW5lZCksXG4gICAgICAgICAgYXNzdW1lUm9sZUFybjogcm9sZT8uYXNzdW1lUm9sZUFybixcbiAgICAgICAgICBhc3N1bWVSb2xlRXh0ZXJuYWxJZDogcm9sZT8uYXNzdW1lUm9sZUV4dGVybmFsSWQsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH07XG5cbiAgICBjb25zdCB7IGFjY291bnQsIHJlZ2lvbiwgdXJsU3VmZml4IH0gPSBzdGFja0xvY2F0aW9uT3JJbnN0cmluc2ljcyhzdGFjayk7XG5cbiAgICAvLyBSZXR1cm4gQ0ZOIGV4cHJlc3Npb25cbiAgICByZXR1cm4ge1xuICAgICAgcmVwb3NpdG9yeU5hbWU6IGNmbmlmeShyZXBvc2l0b3J5TmFtZSksXG4gICAgICBpbWFnZVVyaTogY2ZuaWZ5KFxuICAgICAgICBgJHthY2NvdW50fS5ka3IuZWNyLiR7cmVnaW9ufS4ke3VybFN1ZmZpeH0vJHtyZXBvc2l0b3J5TmFtZX06JHtpbWFnZVRhZ31gLFxuICAgICAgKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFdyaXRlIHRoZSBtYW5pZmVzdCB0byBkaXNrLCBhbmQgYWRkIGl0IHRvIHRoZSBzeW50aGVzaXMgc2Vzc2lvblxuICAgKlxuICAgKiBSZXV0cm4gdGhlIGFydGlmYWN0IElkXG4gICAqL1xuICBwdWJsaWMgd3JpdGVNYW5pZmVzdChcbiAgICBzdGFjazogU3RhY2ssXG4gICAgc2Vzc2lvbjogSVN5bnRoZXNpc1Nlc3Npb24sXG4gICAgYWRkaXRpb25hbFByb3BzOiBQYXJ0aWFsPGN4c2NoZW1hLkFzc2V0TWFuaWZlc3RQcm9wZXJ0aWVzPiA9IHt9LFxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IGFydGlmYWN0SWQgPSBgJHtzdGFjay5hcnRpZmFjdElkfS5hc3NldHNgO1xuICAgIGNvbnN0IG1hbmlmZXN0RmlsZSA9IGAke2FydGlmYWN0SWR9Lmpzb25gO1xuICAgIGNvbnN0IG91dFBhdGggPSBwYXRoLmpvaW4oc2Vzc2lvbi5hc3NlbWJseS5vdXRkaXIsIG1hbmlmZXN0RmlsZSk7XG5cbiAgICBjb25zdCBtYW5pZmVzdDogY3hzY2hlbWEuQXNzZXRNYW5pZmVzdCA9IHtcbiAgICAgIHZlcnNpb246IGN4c2NoZW1hLk1hbmlmZXN0LnZlcnNpb24oKSxcbiAgICAgIGZpbGVzOiB0aGlzLmZpbGVzLFxuICAgICAgZG9ja2VySW1hZ2VzOiB0aGlzLmRvY2tlckltYWdlcyxcbiAgICB9O1xuXG4gICAgZnMud3JpdGVGaWxlU3luYyhvdXRQYXRoLCBKU09OLnN0cmluZ2lmeShtYW5pZmVzdCwgdW5kZWZpbmVkLCAyKSk7XG5cbiAgICBzZXNzaW9uLmFzc2VtYmx5LmFkZEFydGlmYWN0KGFydGlmYWN0SWQsIHtcbiAgICAgIHR5cGU6IGN4c2NoZW1hLkFydGlmYWN0VHlwZS5BU1NFVF9NQU5JRkVTVCxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgZmlsZTogbWFuaWZlc3RGaWxlLFxuICAgICAgICAuLi5hZGRpdGlvbmFsUHJvcHMsXG4gICAgICB9LFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGFydGlmYWN0SWQ7XG4gIH1cblxuICBwcml2YXRlIG1hbmlmZXN0RW52TmFtZShzdGFjazogU3RhY2spOiBzdHJpbmcge1xuICAgIHJldHVybiBbXG4gICAgICByZXNvbHZlZE9yKHN0YWNrLmFjY291bnQsICdjdXJyZW50X2FjY291bnQnKSxcbiAgICAgIHJlc29sdmVkT3Ioc3RhY2sucmVnaW9uLCAnY3VycmVudF9yZWdpb24nKSxcbiAgICBdLmpvaW4oJy0nKTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJvbGVPcHRpb25zIHtcbiAgcmVhZG9ubHkgYXNzdW1lUm9sZUFybj86IHN0cmluZztcbiAgcmVhZG9ubHkgYXNzdW1lUm9sZUV4dGVybmFsSWQ/OiBzdHJpbmc7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlRmlsZUFzc2V0U291cmNlKGFzc2V0OiBGaWxlQXNzZXRTb3VyY2UpIHtcbiAgaWYgKCEhYXNzZXQuZXhlY3V0YWJsZSA9PT0gISFhc3NldC5maWxlTmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRXhhY3RseSBvbmUgb2YgJ2ZpbGVOYW1lJyBvciAnZXhlY3V0YWJsZScgaXMgcmVxdWlyZWQsIGdvdDogJHtKU09OLnN0cmluZ2lmeShhc3NldCl9YCk7XG4gIH1cblxuICBpZiAoISFhc3NldC5wYWNrYWdpbmcgIT09ICEhYXNzZXQuZmlsZU5hbWUpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCdwYWNrYWdpbmcnIGlzIGV4cGVjdGVkIGluIGNvbWJpbmF0aW9uIHdpdGggJ2ZpbGVOYW1lJywgZ290OiAke0pTT04uc3RyaW5naWZ5KGFzc2V0KX1gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB2YWxpZGF0ZURvY2tlckltYWdlQXNzZXRTb3VyY2UoYXNzZXQ6IERvY2tlckltYWdlQXNzZXRTb3VyY2UpIHtcbiAgaWYgKCEhYXNzZXQuZXhlY3V0YWJsZSA9PT0gISFhc3NldC5kaXJlY3RvcnlOYW1lKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeGFjdGx5IG9uZSBvZiAnZGlyZWN0b3J5TmFtZScgb3IgJ2V4ZWN1dGFibGUnIGlzIHJlcXVpcmVkLCBnb3Q6ICR7SlNPTi5zdHJpbmdpZnkoYXNzZXQpfWApO1xuICB9XG5cbiAgY2hlY2soJ2RvY2tlckJ1aWxkQXJncycpO1xuICBjaGVjaygnZG9ja2VyQnVpbGRUYXJnZXQnKTtcbiAgY2hlY2soJ2RvY2tlckZpbGUnKTtcblxuICBmdW5jdGlvbiBjaGVjazxLIGV4dGVuZHMga2V5b2YgRG9ja2VySW1hZ2VBc3NldFNvdXJjZT4oa2V5OiBLKSB7XG4gICAgaWYgKGFzc2V0W2tleV0gJiYgIWFzc2V0LmRpcmVjdG9yeU5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJyR7a2V5fScgaXMgb25seSBhbGxvd2VkIGluIGNvbWJpbmF0aW9uIHdpdGggJ2RpcmVjdG9yeU5hbWUnLCBnb3Q6ICR7SlNPTi5zdHJpbmdpZnkoYXNzZXQpfWApO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJldHVybiB0aGUgc3RhY2sgbG9jYXRpb25zIGlmIHRoZXkncmUgY29uY3JldGUsIG9yIHRoZSBvcmlnaW5hbCBDRk4gaW50cmlzaWNzIG90aGVyd2lzZVxuICpcbiAqIFdlIG5lZWQgdG8gcmV0dXJuIHRoZXNlIGluc3RlYWQgb2YgdGhlIHRva2VuaXplZCB2ZXJzaW9ucyBvZiB0aGUgc3RyaW5ncyxcbiAqIHNpbmNlIHdlIG11c3QgYWNjZXB0IHRob3NlIHNhbWUgJHtBV1M6OkFjY291bnRJZH0vJHtBV1M6OlJlZ2lvbn0gcGxhY2Vob2xkZXJzXG4gKiBpbiBidWNrZXQgbmFtZXMgYW5kIHJvbGUgbmFtZXMgKGluIG9yZGVyIHRvIGFsbG93IGVudmlyb25tZW50LWFnbm9zdGljIHN0YWNrcykuXG4gKlxuICogV2UnbGwgd3JhcCBhIHNpbmdsZSB7Rm46OlN1Yn0gYXJvdW5kIHRoZSBmaW5hbCBzdHJpbmcgaW4gb3JkZXIgdG8gcmVwbGFjZSBldmVyeXRoaW5nLFxuICogYnV0IHdlIGNhbid0IGhhdmUgdGhlIHRva2VuIHN5c3RlbSByZW5kZXIgcGFydCBvZiB0aGUgc3RyaW5nIHRvIHtGbjo6Sm9pbn0gYmVjYXVzZVxuICogdGhlIENGTiBzcGVjaWZpY2F0aW9uIGRvZXNuJ3QgYWxsb3cgdGhlIHtGbjo6U3VifSB0ZW1wbGF0ZSBzdHJpbmcgdG8gYmUgYW4gYXJiaXRyYXJ5XG4gKiBleHByZXNzaW9uLS1pdCBtdXN0IGJlIGEgc3RyaW5nIGxpdGVyYWwuXG4gKi9cbmZ1bmN0aW9uIHN0YWNrTG9jYXRpb25Pckluc3RyaW5zaWNzKHN0YWNrOiBTdGFjaykge1xuICByZXR1cm4ge1xuICAgIGFjY291bnQ6IHJlc29sdmVkT3Ioc3RhY2suYWNjb3VudCwgJyR7QVdTOjpBY2NvdW50SWR9JyksXG4gICAgcmVnaW9uOiByZXNvbHZlZE9yKHN0YWNrLnJlZ2lvbiwgJyR7QVdTOjpSZWdpb259JyksXG4gICAgdXJsU3VmZml4OiByZXNvbHZlZE9yKHN0YWNrLnVybFN1ZmZpeCwgJyR7QVdTOjpVUkxTdWZmaXh9JyksXG4gIH07XG59XG5cbi8qKlxuICogSWYgdGhlIHN0cmluZyBzdGlsbCBjb250YWlucyBwbGFjZWhvbGRlcnMsIHdyYXAgaXQgaW4gYSBGbjo6U3ViIHNvIHRoZXkgd2lsbCBiZSBzdWJzdGl0dXRlZCBhdCBDRk4gZGVwbG95bWVudCB0aW1lXG4gKlxuICogKFRoaXMgaGFwcGVucyB0byB3b3JrIGJlY2F1c2UgdGhlIHBsYWNlaG9sZGVycyB3ZSBwaWNrZWQgbWFwIGRpcmVjdGx5IG9udG8gQ0ZOXG4gKiBwbGFjZWhvbGRlcnMuIElmIHRoZXkgZGlkbid0IHdlJ2QgaGF2ZSB0byBkbyBhIHRyYW5zZm9ybWF0aW9uIGhlcmUpLlxuICovXG5mdW5jdGlvbiBjZm5pZnkoczogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHMuaW5kZXhPZignJHsnKSA+IC0xID8gRm4uc3ViKHMpIDogcztcbn0iXX0= |
\ | No newline at end of file |