assets.test.js
  1  "use strict";
  2  Object.defineProperty(exports, "__esModule", { value: true });
  3  const assets_1 = require("../lib/assets");
  4  const asset_manifest_builder_1 = require("../lib/util/asset-manifest-builder");
  5  const util_1 = require("./util");
  6  const mock_sdk_1 = require("./util/mock-sdk");
  7  const mock_toolkitinfo_1 = require("./util/mock-toolkitinfo");
  8  let toolkit;
  9  let assets;
 10  beforeEach(() => {
 11      toolkit = new mock_toolkitinfo_1.MockToolkitInfo(new mock_sdk_1.MockSdk());
 12      assets = new asset_manifest_builder_1.AssetManifestBuilder();
 13  });
 14  describe('file assets', () => {
 15      test('convert to manifest and parameters', async () => {
 16          // GIVEN
 17          const stack = stackWithAssets([
 18              {
 19                  sourceHash: 'source-hash',
 20                  path: __filename,
 21                  id: 'SomeStackSomeResource4567',
 22                  packaging: 'file',
 23                  s3BucketParameter: 'BucketParameter',
 24                  s3KeyParameter: 'KeyParameter',
 25                  artifactHashParameter: 'ArtifactHashParameter',
 26              },
 27          ]);
 28          // WHEN
 29          const params = await assets_1.addMetadataAssetsToManifest(stack, assets, toolkit);
 30          // THEN
 31          expect(params).toEqual({
 32              BucketParameter: 'MockToolkitBucketName',
 33              KeyParameter: 'assets/SomeStackSomeResource4567/||source-hash.js',
 34              ArtifactHashParameter: 'source-hash',
 35          });
 36          expect(assets.toManifest('.').entries).toEqual([
 37              expect.objectContaining({
 38                  destination: {
 39                      bucketName: 'MockToolkitBucketName',
 40                      objectKey: 'assets/SomeStackSomeResource4567/source-hash.js',
 41                  },
 42                  source: {
 43                      packaging: 'file',
 44                      path: __filename,
 45                  },
 46              }),
 47          ]);
 48      });
 49      test('hash and ID the same => only one path component', async () => {
 50          // GIVEN
 51          const stack = stackWithAssets([
 52              {
 53                  sourceHash: 'source-hash',
 54                  path: __filename,
 55                  id: 'source-hash',
 56                  packaging: 'file',
 57                  s3BucketParameter: 'BucketParameter',
 58                  s3KeyParameter: 'KeyParameter',
 59                  artifactHashParameter: 'ArtifactHashParameter',
 60              },
 61          ]);
 62          // WHEN
 63          await assets_1.addMetadataAssetsToManifest(stack, assets, toolkit);
 64          // THEN
 65          expect(assets.toManifest('.').entries).toEqual([
 66              expect.objectContaining({
 67                  destination: {
 68                      bucketName: 'MockToolkitBucketName',
 69                      objectKey: 'assets/source-hash.js',
 70                  },
 71              }),
 72          ]);
 73      });
 74      test('reuse', async () => {
 75          // GIVEN
 76          const stack = stackWithAssets([
 77              {
 78                  path: __filename,
 79                  id: 'SomeStackSomeResource4567',
 80                  packaging: 'file',
 81                  s3BucketParameter: 'BucketParameter',
 82                  s3KeyParameter: 'KeyParameter',
 83                  artifactHashParameter: 'ArtifactHashParameter',
 84                  sourceHash: 'boom',
 85              },
 86          ]);
 87          // WHEN
 88          const params = await assets_1.addMetadataAssetsToManifest(stack, assets, toolkit, ['SomeStackSomeResource4567']);
 89          // THEN
 90          expect(params).toEqual({});
 91          expect(assets.toManifest('.').entries).toEqual([]);
 92      });
 93  });
 94  describe('docker assets', () => {
 95      test('parameter and no repository name (old)', async () => {
 96          // GIVEN
 97          const stack = stackWithAssets([
 98              {
 99                  id: 'Stack:Construct/ABC123',
100                  imageNameParameter: 'MyParameter',
101                  packaging: 'container-image',
102                  path: '/foo',
103                  sourceHash: '0123456789abcdef',
104              },
105          ]);
106          mockFn(toolkit.prepareEcrRepository).mockResolvedValue({ repositoryUri: 'docker.uri' });
107          // WHEN
108          const params = await assets_1.addMetadataAssetsToManifest(stack, assets, toolkit);
109          // THEN
110          expect(toolkit.prepareEcrRepository).toHaveBeenCalledWith('cdk/stack-construct-abc123');
111          expect(params).toEqual({
112              MyParameter: 'docker.uri:0123456789abcdef',
113          });
114          expect(assets.toManifest('.').entries).toEqual([
115              expect.objectContaining({
116                  type: 'docker-image',
117                  destination: {
118                      imageTag: '0123456789abcdef',
119                      repositoryName: 'cdk/stack-construct-abc123',
120                  },
121                  source: {
122                      directory: '/foo',
123                  },
124              }),
125          ]);
126      });
127      test('if parameter is left out then repo and tag are required', async () => {
128          // GIVEN
129          const stack = stackWithAssets([
130              {
131                  id: 'Stack:Construct/ABC123',
132                  packaging: 'container-image',
133                  path: '/foo',
134                  sourceHash: '0123456789abcdef',
135              },
136          ]);
137          await expect(assets_1.addMetadataAssetsToManifest(stack, assets, toolkit)).rejects.toThrow('Invalid Docker image asset');
138      });
139      test('no parameter and repo/tag name (new)', async () => {
140          // GIVEN
141          const stack = stackWithAssets([
142              {
143                  id: 'Stack:Construct/ABC123',
144                  repositoryName: 'reponame',
145                  imageTag: '12345',
146                  packaging: 'container-image',
147                  path: '/foo',
148                  sourceHash: '0123456789abcdef',
149              },
150          ]);
151          mockFn(toolkit.prepareEcrRepository).mockResolvedValue({ repositoryUri: 'docker.uri' });
152          // WHEN
153          const params = await assets_1.addMetadataAssetsToManifest(stack, assets, toolkit);
154          // THEN
155          expect(toolkit.prepareEcrRepository).toHaveBeenCalledWith('reponame');
156          expect(params).toEqual({}); // No parameters!
157          expect(assets.toManifest('.').entries).toEqual([
158              expect.objectContaining({
159                  type: 'docker-image',
160                  destination: {
161                      imageTag: '12345',
162                      repositoryName: 'reponame',
163                  },
164                  source: {
165                      directory: '/foo',
166                  },
167              }),
168          ]);
169      });
170      test('reuse', async () => {
171          // GIVEN
172          const stack = stackWithAssets([
173              {
174                  path: __dirname,
175                  id: 'SomeStackSomeResource4567',
176                  packaging: 'container-image',
177                  imageNameParameter: 'asdf',
178                  sourceHash: 'source-hash',
179              },
180          ]);
181          // WHEN
182          const params = await assets_1.addMetadataAssetsToManifest(stack, assets, toolkit, ['SomeStackSomeResource4567']);
183          // THEN
184          expect(params).toEqual({});
185          expect(assets.toManifest('.').entries).toEqual([]);
186      });
187  });
188  function stackWithAssets(assetEntries) {
189      return util_1.testStack({
190          stackName: 'SomeStack',
191          assets: assetEntries,
192          template: {
193              Resources: {
194                  SomeResource: {
195                      Type: 'AWS::Something::Something',
196                  },
197              },
198          },
199      });
200  }
201  function mockFn(fn) {
202      if (!jest.isMockFunction(fn)) {
203          throw new Error(`Not a mock function: ${fn}`);
204      }
205      return fn;
206  }
207  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhc3NldHMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLDBDQUE0RDtBQUM1RCwrRUFBMEU7QUFDMUUsaUNBQW1DO0FBQ25DLDhDQUEwQztBQUMxQyw4REFBMEQ7QUFFMUQsSUFBSSxPQUFvQixDQUFDO0FBQ3pCLElBQUksTUFBNEIsQ0FBQztBQUNqQyxVQUFVLENBQUMsR0FBRyxFQUFFO0lBQ2QsT0FBTyxHQUFHLElBQUksa0NBQWUsQ0FBQyxJQUFJLGtCQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sR0FBRyxJQUFJLDZDQUFvQixFQUFFLENBQUM7QUFDdEMsQ0FBQyxDQUFDLENBQUM7QUFFSCxRQUFRLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRTtJQUMzQixJQUFJLENBQUMsb0NBQW9DLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDcEQsUUFBUTtRQUNSLE1BQU0sS0FBSyxHQUFHLGVBQWUsQ0FBQztZQUM1QjtnQkFDRSxVQUFVLEVBQUUsYUFBYTtnQkFDekIsSUFBSSxFQUFFLFVBQVU7Z0JBQ2hCLEVBQUUsRUFBRSwyQkFBMkI7Z0JBQy9CLFNBQVMsRUFBRSxNQUFNO2dCQUNqQixpQkFBaUIsRUFBRSxpQkFBaUI7Z0JBQ3BDLGNBQWMsRUFBRSxjQUFjO2dCQUM5QixxQkFBcUIsRUFBRSx1QkFBdUI7YUFDL0M7U0FDRixDQUFDLENBQUM7UUFFSCxPQUFPO1FBQ1AsTUFBTSxNQUFNLEdBQUcsTUFBTSxvQ0FBMkIsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRXpFLE9BQU87UUFDUCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQ3JCLGVBQWUsRUFBRSx1QkFBdUI7WUFDeEMsWUFBWSxFQUFFLG1EQUFtRDtZQUNqRSxxQkFBcUIsRUFBRSxhQUFhO1NBQ3JDLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUM3QyxNQUFNLENBQUMsZ0JBQWdCLENBQUM7Z0JBQ3RCLFdBQVcsRUFBRTtvQkFDWCxVQUFVLEVBQUUsdUJBQXVCO29CQUNuQyxTQUFTLEVBQUUsaURBQWlEO2lCQUM3RDtnQkFDRCxNQUFNLEVBQUU7b0JBQ04sU0FBUyxFQUFFLE1BQU07b0JBQ2pCLElBQUksRUFBRSxVQUFVO2lCQUNqQjthQUNGLENBQUM7U0FDSCxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyxpREFBaUQsRUFBRSxLQUFLLElBQUksRUFBRTtRQUNqRSxRQUFRO1FBQ1IsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDO1lBQzVCO2dCQUNFLFVBQVUsRUFBRSxhQUFhO2dCQUN6QixJQUFJLEVBQUUsVUFBVTtnQkFDaEIsRUFBRSxFQUFFLGFBQWE7Z0JBQ2pCLFNBQVMsRUFBRSxNQUFNO2dCQUNqQixpQkFBaUIsRUFBRSxpQkFBaUI7Z0JBQ3BDLGNBQWMsRUFBRSxjQUFjO2dCQUM5QixxQkFBcUIsRUFBRSx1QkFBdUI7YUFDL0M7U0FDRixDQUFDLENBQUM7UUFFSCxPQUFPO1FBQ1AsTUFBTSxvQ0FBMkIsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRTFELE9BQU87UUFDUCxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDN0MsTUFBTSxDQUFDLGdCQUFnQixDQUFDO2dCQUN0QixXQUFXLEVBQUU7b0JBQ1gsVUFBVSxFQUFFLHVCQUF1QjtvQkFDbkMsU0FBUyxFQUFFLHVCQUF1QjtpQkFDbkM7YUFDRixDQUFDO1NBQ0gsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3ZCLFFBQVE7UUFDUixNQUFNLEtBQUssR0FBRyxlQUFlLENBQUM7WUFDNUI7Z0JBQ0UsSUFBSSxFQUFFLFVBQVU7Z0JBQ2hCLEVBQUUsRUFBRSwyQkFBMkI7Z0JBQy9CLFNBQVMsRUFBRSxNQUFNO2dCQUNqQixpQkFBaUIsRUFBRSxpQkFBaUI7Z0JBQ3BDLGNBQWMsRUFBRSxjQUFjO2dCQUM5QixxQkFBcUIsRUFBRSx1QkFBdUI7Z0JBQzlDLFVBQVUsRUFBRSxNQUFNO2FBQ25CO1NBQ0YsQ0FBQyxDQUFDO1FBRUgsT0FBTztRQUNQLE1BQU0sTUFBTSxHQUFHLE1BQU0sb0NBQTJCLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDLENBQUM7UUFFeEcsT0FBTztRQUNQLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFDdEIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3JELENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyxDQUFDLENBQUM7QUFFSCxRQUFRLENBQUMsZUFBZSxFQUFFLEdBQUcsRUFBRTtJQUM3QixJQUFJLENBQUMsd0NBQXdDLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDeEQsUUFBUTtRQUNSLE1BQU0sS0FBSyxHQUFHLGVBQWUsQ0FBQztZQUM1QjtnQkFDRSxFQUFFLEVBQUUsd0JBQXdCO2dCQUM1QixrQkFBa0IsRUFBRSxhQUFhO2dCQUNqQyxTQUFTLEVBQUUsaUJBQWlCO2dCQUM1QixJQUFJLEVBQUUsTUFBTTtnQkFDWixVQUFVLEVBQUUsa0JBQWtCO2FBQy9CO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7UUFFeEYsT0FBTztRQUNQLE1BQU0sTUFBTSxHQUFHLE1BQU0sb0NBQTJCLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUV6RSxPQUFPO1FBQ1AsTUFBTSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLDRCQUE0QixDQUFDLENBQUM7UUFDeEYsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUNyQixXQUFXLEVBQUUsNkJBQTZCO1NBQzNDLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUM3QyxNQUFNLENBQUMsZ0JBQWdCLENBQUM7Z0JBQ3RCLElBQUksRUFBRSxjQUFjO2dCQUNwQixXQUFXLEVBQUU7b0JBQ1gsUUFBUSxFQUFFLGtCQUFrQjtvQkFDNUIsY0FBYyxFQUFFLDRCQUE0QjtpQkFDN0M7Z0JBQ0QsTUFBTSxFQUFFO29CQUNOLFNBQVMsRUFBRSxNQUFNO2lCQUNsQjthQUNGLENBQUM7U0FDSCxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUksQ0FBQyx5REFBeUQsRUFBRSxLQUFLLElBQUksRUFBRTtRQUN6RSxRQUFRO1FBQ1IsTUFBTSxLQUFLLEdBQUcsZUFBZSxDQUFDO1lBQzVCO2dCQUNFLEVBQUUsRUFBRSx3QkFBd0I7Z0JBQzVCLFNBQVMsRUFBRSxpQkFBaUI7Z0JBQzVCLElBQUksRUFBRSxNQUFNO2dCQUNaLFVBQVUsRUFBRSxrQkFBa0I7YUFDL0I7U0FDRixDQUFDLENBQUM7UUFFSCxNQUFNLE1BQU0sQ0FBQyxvQ0FBMkIsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyw0QkFBNEIsQ0FBQyxDQUFDO0lBQ2xILENBQUMsQ0FBQyxDQUFDO0lBRUgsSUFBSSxDQUFDLHNDQUFzQyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3RELFFBQVE7UUFDUixNQUFNLEtBQUssR0FBRyxlQUFlLENBQUM7WUFDNUI7Z0JBQ0UsRUFBRSxFQUFFLHdCQUF3QjtnQkFDNUIsY0FBYyxFQUFFLFVBQVU7Z0JBQzFCLFFBQVEsRUFBRSxPQUFPO2dCQUNqQixTQUFTLEVBQUUsaUJBQWlCO2dCQUM1QixJQUFJLEVBQUUsTUFBTTtnQkFDWixVQUFVLEVBQUUsa0JBQWtCO2FBQy9CO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7UUFFeEYsT0FBTztRQUNQLE1BQU0sTUFBTSxHQUFHLE1BQU0sb0NBQTJCLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUV6RSxPQUFPO1FBQ1AsTUFBTSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxpQkFBaUI7UUFDN0MsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQzdDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQztnQkFDdEIsSUFBSSxFQUFFLGNBQWM7Z0JBQ3BCLFdBQVcsRUFBRTtvQkFDWCxRQUFRLEVBQUUsT0FBTztvQkFDakIsY0FBYyxFQUFFLFVBQVU7aUJBQzNCO2dCQUNELE1BQU0sRUFBRTtvQkFDTixTQUFTLEVBQUUsTUFBTTtpQkFDbEI7YUFDRixDQUFDO1NBQ0gsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQ3ZCLFFBQVE7UUFDUixNQUFNLEtBQUssR0FBRyxlQUFlLENBQUM7WUFDNUI7Z0JBQ0UsSUFBSSxFQUFFLFNBQVM7Z0JBQ2YsRUFBRSxFQUFFLDJCQUEyQjtnQkFDL0IsU0FBUyxFQUFFLGlCQUFpQjtnQkFDNUIsa0JBQWtCLEVBQUUsTUFBTTtnQkFDMUIsVUFBVSxFQUFFLGFBQWE7YUFDMUI7U0FDRixDQUFDLENBQUM7UUFFSCxPQUFPO1FBQ1AsTUFBTSxNQUFNLEdBQUcsTUFBTSxvQ0FBMkIsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDLDJCQUEyQixDQUFDLENBQUMsQ0FBQztRQUV4RyxPQUFPO1FBQ1AsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUN0QixDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDckQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQztBQUVILFNBQVMsZUFBZSxDQUFDLFlBQWtDO0lBQ3pELE9BQU8sZ0JBQVMsQ0FBQztRQUNmLFNBQVMsRUFBRSxXQUFXO1FBQ3RCLE1BQU0sRUFBRSxZQUFZO1FBQ3BCLFFBQVEsRUFBRTtZQUNSLFNBQVMsRUFBRTtnQkFDVCxZQUFZLEVBQUU7b0JBQ1osSUFBSSxFQUFFLDJCQUEyQjtpQkFDbEM7YUFDRjtTQUNGO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsTUFBTSxDQUFrQyxFQUFLO0lBQ3BELElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1FBQzVCLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLEVBQUUsRUFBRSxDQUFDLENBQUM7S0FDL0M7SUFDRCxPQUFPLEVBQUUsQ0FBQztBQUNaLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBc3NldE1ldGFkYXRhRW50cnkgfSBmcm9tICdAYXdzLWNkay9jbG91ZC1hc3NlbWJseS1zY2hlbWEnO1xuaW1wb3J0IHsgVG9vbGtpdEluZm8gfSBmcm9tICcuLi9saWIvYXBpJztcbmltcG9ydCB7IGFkZE1ldGFkYXRhQXNzZXRzVG9NYW5pZmVzdCB9IGZyb20gJy4uL2xpYi9hc3NldHMnO1xuaW1wb3J0IHsgQXNzZXRNYW5pZmVzdEJ1aWxkZXIgfSBmcm9tICcuLi9saWIvdXRpbC9hc3NldC1tYW5pZmVzdC1idWlsZGVyJztcbmltcG9ydCB7IHRlc3RTdGFjayB9IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgeyBNb2NrU2RrIH0gZnJvbSAnLi91dGlsL21vY2stc2RrJztcbmltcG9ydCB7IE1vY2tUb29sa2l0SW5mbyB9IGZyb20gJy4vdXRpbC9tb2NrLXRvb2xraXRpbmZvJztcblxubGV0IHRvb2xraXQ6IFRvb2xraXRJbmZvO1xubGV0IGFzc2V0czogQXNzZXRNYW5pZmVzdEJ1aWxkZXI7XG5iZWZvcmVFYWNoKCgpID0+IHtcbiAgdG9vbGtpdCA9IG5ldyBNb2NrVG9vbGtpdEluZm8obmV3IE1vY2tTZGsoKSk7XG4gIGFzc2V0cyA9IG5ldyBBc3NldE1hbmlmZXN0QnVpbGRlcigpO1xufSk7XG5cbmRlc2NyaWJlKCdmaWxlIGFzc2V0cycsICgpID0+IHtcbiAgdGVzdCgnY29udmVydCB0byBtYW5pZmVzdCBhbmQgcGFyYW1ldGVycycsIGFzeW5jICgpID0+IHtcbiAgICAvLyBHSVZFTlxuICAgIGNvbnN0IHN0YWNrID0gc3RhY2tXaXRoQXNzZXRzKFtcbiAgICAgIHtcbiAgICAgICAgc291cmNlSGFzaDogJ3NvdXJjZS1oYXNoJyxcbiAgICAgICAgcGF0aDogX19maWxlbmFtZSxcbiAgICAgICAgaWQ6ICdTb21lU3RhY2tTb21lUmVzb3VyY2U0NTY3JyxcbiAgICAgICAgcGFja2FnaW5nOiAnZmlsZScsXG4gICAgICAgIHMzQnVja2V0UGFyYW1ldGVyOiAnQnVja2V0UGFyYW1ldGVyJyxcbiAgICAgICAgczNLZXlQYXJhbWV0ZXI6ICdLZXlQYXJhbWV0ZXInLFxuICAgICAgICBhcnRpZmFjdEhhc2hQYXJhbWV0ZXI6ICdBcnRpZmFjdEhhc2hQYXJhbWV0ZXInLFxuICAgICAgfSxcbiAgICBdKTtcblxuICAgIC8vIFdIRU5cbiAgICBjb25zdCBwYXJhbXMgPSBhd2FpdCBhZGRNZXRhZGF0YUFzc2V0c1RvTWFuaWZlc3Qoc3RhY2ssIGFzc2V0cywgdG9vbGtpdCk7XG5cbiAgICAvLyBUSEVOXG4gICAgZXhwZWN0KHBhcmFtcykudG9FcXVhbCh7XG4gICAgICBCdWNrZXRQYXJhbWV0ZXI6ICdNb2NrVG9vbGtpdEJ1Y2tldE5hbWUnLFxuICAgICAgS2V5UGFyYW1ldGVyOiAnYXNzZXRzL1NvbWVTdGFja1NvbWVSZXNvdXJjZTQ1NjcvfHxzb3VyY2UtaGFzaC5qcycsXG4gICAgICBBcnRpZmFjdEhhc2hQYXJhbWV0ZXI6ICdzb3VyY2UtaGFzaCcsXG4gICAgfSk7XG5cbiAgICBleHBlY3QoYXNzZXRzLnRvTWFuaWZlc3QoJy4nKS5lbnRyaWVzKS50b0VxdWFsKFtcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgZGVzdGluYXRpb246IHtcbiAgICAgICAgICBidWNrZXROYW1lOiAnTW9ja1Rvb2xraXRCdWNrZXROYW1lJyxcbiAgICAgICAgICBvYmplY3RLZXk6ICdhc3NldHMvU29tZVN0YWNrU29tZVJlc291cmNlNDU2Ny9zb3VyY2UtaGFzaC5qcycsXG4gICAgICAgIH0sXG4gICAgICAgIHNvdXJjZToge1xuICAgICAgICAgIHBhY2thZ2luZzogJ2ZpbGUnLFxuICAgICAgICAgIHBhdGg6IF9fZmlsZW5hbWUsXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICBdKTtcbiAgfSk7XG5cbiAgdGVzdCgnaGFzaCBhbmQgSUQgdGhlIHNhbWUgPT4gb25seSBvbmUgcGF0aCBjb21wb25lbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgLy8gR0lWRU5cbiAgICBjb25zdCBzdGFjayA9IHN0YWNrV2l0aEFzc2V0cyhbXG4gICAgICB7XG4gICAgICAgIHNvdXJjZUhhc2g6ICdzb3VyY2UtaGFzaCcsXG4gICAgICAgIHBhdGg6IF9fZmlsZW5hbWUsXG4gICAgICAgIGlkOiAnc291cmNlLWhhc2gnLFxuICAgICAgICBwYWNrYWdpbmc6ICdmaWxlJyxcbiAgICAgICAgczNCdWNrZXRQYXJhbWV0ZXI6ICdCdWNrZXRQYXJhbWV0ZXInLFxuICAgICAgICBzM0tleVBhcmFtZXRlcjogJ0tleVBhcmFtZXRlcicsXG4gICAgICAgIGFydGlmYWN0SGFzaFBhcmFtZXRlcjogJ0FydGlmYWN0SGFzaFBhcmFtZXRlcicsXG4gICAgICB9LFxuICAgIF0pO1xuXG4gICAgLy8gV0hFTlxuICAgIGF3YWl0IGFkZE1ldGFkYXRhQXNzZXRzVG9NYW5pZmVzdChzdGFjaywgYXNzZXRzLCB0b29sa2l0KTtcblxuICAgIC8vIFRIRU5cbiAgICBleHBlY3QoYXNzZXRzLnRvTWFuaWZlc3QoJy4nKS5lbnRyaWVzKS50b0VxdWFsKFtcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgZGVzdGluYXRpb246IHtcbiAgICAgICAgICBidWNrZXROYW1lOiAnTW9ja1Rvb2xraXRCdWNrZXROYW1lJyxcbiAgICAgICAgICBvYmplY3RLZXk6ICdhc3NldHMvc291cmNlLWhhc2guanMnLFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgXSk7XG4gIH0pO1xuXG4gIHRlc3QoJ3JldXNlJywgYXN5bmMgKCkgPT4ge1xuICAgIC8vIEdJVkVOXG4gICAgY29uc3Qgc3RhY2sgPSBzdGFja1dpdGhBc3NldHMoW1xuICAgICAge1xuICAgICAgICBwYXRoOiBfX2ZpbGVuYW1lLFxuICAgICAgICBpZDogJ1NvbWVTdGFja1NvbWVSZXNvdXJjZTQ1NjcnLFxuICAgICAgICBwYWNrYWdpbmc6ICdmaWxlJyxcbiAgICAgICAgczNCdWNrZXRQYXJhbWV0ZXI6ICdCdWNrZXRQYXJhbWV0ZXInLFxuICAgICAgICBzM0tleVBhcmFtZXRlcjogJ0tleVBhcmFtZXRlcicsXG4gICAgICAgIGFydGlmYWN0SGFzaFBhcmFtZXRlcjogJ0FydGlmYWN0SGFzaFBhcmFtZXRlcicsXG4gICAgICAgIHNvdXJjZUhhc2g6ICdib29tJyxcbiAgICAgIH0sXG4gICAgXSk7XG5cbiAgICAvLyBXSEVOXG4gICAgY29uc3QgcGFyYW1zID0gYXdhaXQgYWRkTWV0YWRhdGFBc3NldHNUb01hbmlmZXN0KHN0YWNrLCBhc3NldHMsIHRvb2xraXQsIFsnU29tZVN0YWNrU29tZVJlc291cmNlNDU2NyddKTtcblxuICAgIC8vIFRIRU5cbiAgICBleHBlY3QocGFyYW1zKS50b0VxdWFsKHtcbiAgICB9KTtcblxuICAgIGV4cGVjdChhc3NldHMudG9NYW5pZmVzdCgnLicpLmVudHJpZXMpLnRvRXF1YWwoW10pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnZG9ja2VyIGFzc2V0cycsICgpID0+IHtcbiAgdGVzdCgncGFyYW1ldGVyIGFuZCBubyByZXBvc2l0b3J5IG5hbWUgKG9sZCknLCBhc3luYyAoKSA9PiB7XG4gICAgLy8gR0lWRU5cbiAgICBjb25zdCBzdGFjayA9IHN0YWNrV2l0aEFzc2V0cyhbXG4gICAgICB7XG4gICAgICAgIGlkOiAnU3RhY2s6Q29uc3RydWN0L0FCQzEyMycsXG4gICAgICAgIGltYWdlTmFtZVBhcmFtZXRlcjogJ015UGFyYW1ldGVyJyxcbiAgICAgICAgcGFja2FnaW5nOiAnY29udGFpbmVyLWltYWdlJyxcbiAgICAgICAgcGF0aDogJy9mb28nLFxuICAgICAgICBzb3VyY2VIYXNoOiAnMDEyMzQ1Njc4OWFiY2RlZicsXG4gICAgICB9LFxuICAgIF0pO1xuICAgIG1vY2tGbih0b29sa2l0LnByZXBhcmVFY3JSZXBvc2l0b3J5KS5tb2NrUmVzb2x2ZWRWYWx1ZSh7IHJlcG9zaXRvcnlVcmk6ICdkb2NrZXIudXJpJyB9KTtcblxuICAgIC8vIFdIRU5cbiAgICBjb25zdCBwYXJhbXMgPSBhd2FpdCBhZGRNZXRhZGF0YUFzc2V0c1RvTWFuaWZlc3Qoc3RhY2ssIGFzc2V0cywgdG9vbGtpdCk7XG5cbiAgICAvLyBUSEVOXG4gICAgZXhwZWN0KHRvb2xraXQucHJlcGFyZUVjclJlcG9zaXRvcnkpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdjZGsvc3RhY2stY29uc3RydWN0LWFiYzEyMycpO1xuICAgIGV4cGVjdChwYXJhbXMpLnRvRXF1YWwoe1xuICAgICAgTXlQYXJhbWV0ZXI6ICdkb2NrZXIudXJpOjAxMjM0NTY3ODlhYmNkZWYnLFxuICAgIH0pO1xuICAgIGV4cGVjdChhc3NldHMudG9NYW5pZmVzdCgnLicpLmVudHJpZXMpLnRvRXF1YWwoW1xuICAgICAgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgICAgICB0eXBlOiAnZG9ja2VyLWltYWdlJyxcbiAgICAgICAgZGVzdGluYXRpb246IHtcbiAgICAgICAgICBpbWFnZVRhZzogJzAxMjM0NTY3ODlhYmNkZWYnLFxuICAgICAgICAgIHJlcG9zaXRvcnlOYW1lOiAnY2RrL3N0YWNrLWNvbnN0cnVjdC1hYmMxMjMnLFxuICAgICAgICB9LFxuICAgICAgICBzb3VyY2U6IHtcbiAgICAgICAgICBkaXJlY3Rvcnk6ICcvZm9vJyxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF0pO1xuICB9KTtcblxuICB0ZXN0KCdpZiBwYXJhbWV0ZXIgaXMgbGVmdCBvdXQgdGhlbiByZXBvIGFuZCB0YWcgYXJlIHJlcXVpcmVkJywgYXN5bmMgKCkgPT4ge1xuICAgIC8vIEdJVkVOXG4gICAgY29uc3Qgc3RhY2sgPSBzdGFja1dpdGhBc3NldHMoW1xuICAgICAge1xuICAgICAgICBpZDogJ1N0YWNrOkNvbnN0cnVjdC9BQkMxMjMnLFxuICAgICAgICBwYWNrYWdpbmc6ICdjb250YWluZXItaW1hZ2UnLFxuICAgICAgICBwYXRoOiAnL2ZvbycsXG4gICAgICAgIHNvdXJjZUhhc2g6ICcwMTIzNDU2Nzg5YWJjZGVmJyxcbiAgICAgIH0sXG4gICAgXSk7XG5cbiAgICBhd2FpdCBleHBlY3QoYWRkTWV0YWRhdGFBc3NldHNUb01hbmlmZXN0KHN0YWNrLCBhc3NldHMsIHRvb2xraXQpKS5yZWplY3RzLnRvVGhyb3coJ0ludmFsaWQgRG9ja2VyIGltYWdlIGFzc2V0Jyk7XG4gIH0pO1xuXG4gIHRlc3QoJ25vIHBhcmFtZXRlciBhbmQgcmVwby90YWcgbmFtZSAobmV3KScsIGFzeW5jICgpID0+IHtcbiAgICAvLyBHSVZFTlxuICAgIGNvbnN0IHN0YWNrID0gc3RhY2tXaXRoQXNzZXRzKFtcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdTdGFjazpDb25zdHJ1Y3QvQUJDMTIzJyxcbiAgICAgICAgcmVwb3NpdG9yeU5hbWU6ICdyZXBvbmFtZScsXG4gICAgICAgIGltYWdlVGFnOiAnMTIzNDUnLFxuICAgICAgICBwYWNrYWdpbmc6ICdjb250YWluZXItaW1hZ2UnLFxuICAgICAgICBwYXRoOiAnL2ZvbycsXG4gICAgICAgIHNvdXJjZUhhc2g6ICcwMTIzNDU2Nzg5YWJjZGVmJyxcbiAgICAgIH0sXG4gICAgXSk7XG4gICAgbW9ja0ZuKHRvb2xraXQucHJlcGFyZUVjclJlcG9zaXRvcnkpLm1vY2tSZXNvbHZlZFZhbHVlKHsgcmVwb3NpdG9yeVVyaTogJ2RvY2tlci51cmknIH0pO1xuXG4gICAgLy8gV0hFTlxuICAgIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFkZE1ldGFkYXRhQXNzZXRzVG9NYW5pZmVzdChzdGFjaywgYXNzZXRzLCB0b29sa2l0KTtcblxuICAgIC8vIFRIRU5cbiAgICBleHBlY3QodG9vbGtpdC5wcmVwYXJlRWNyUmVwb3NpdG9yeSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ3JlcG9uYW1lJyk7XG4gICAgZXhwZWN0KHBhcmFtcykudG9FcXVhbCh7fSk7IC8vIE5vIHBhcmFtZXRlcnMhXG4gICAgZXhwZWN0KGFzc2V0cy50b01hbmlmZXN0KCcuJykuZW50cmllcykudG9FcXVhbChbXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgIHR5cGU6ICdkb2NrZXItaW1hZ2UnLFxuICAgICAgICBkZXN0aW5hdGlvbjoge1xuICAgICAgICAgIGltYWdlVGFnOiAnMTIzNDUnLFxuICAgICAgICAgIHJlcG9zaXRvcnlOYW1lOiAncmVwb25hbWUnLFxuICAgICAgICB9LFxuICAgICAgICBzb3VyY2U6IHtcbiAgICAgICAgICBkaXJlY3Rvcnk6ICcvZm9vJyxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF0pO1xuICB9KTtcblxuICB0ZXN0KCdyZXVzZScsIGFzeW5jICgpID0+IHtcbiAgICAvLyBHSVZFTlxuICAgIGNvbnN0IHN0YWNrID0gc3RhY2tXaXRoQXNzZXRzKFtcbiAgICAgIHtcbiAgICAgICAgcGF0aDogX19kaXJuYW1lLFxuICAgICAgICBpZDogJ1NvbWVTdGFja1NvbWVSZXNvdXJjZTQ1NjcnLFxuICAgICAgICBwYWNrYWdpbmc6ICdjb250YWluZXItaW1hZ2UnLFxuICAgICAgICBpbWFnZU5hbWVQYXJhbWV0ZXI6ICdhc2RmJyxcbiAgICAgICAgc291cmNlSGFzaDogJ3NvdXJjZS1oYXNoJyxcbiAgICAgIH0sXG4gICAgXSk7XG5cbiAgICAvLyBXSEVOXG4gICAgY29uc3QgcGFyYW1zID0gYXdhaXQgYWRkTWV0YWRhdGFBc3NldHNUb01hbmlmZXN0KHN0YWNrLCBhc3NldHMsIHRvb2xraXQsIFsnU29tZVN0YWNrU29tZVJlc291cmNlNDU2NyddKTtcblxuICAgIC8vIFRIRU5cbiAgICBleHBlY3QocGFyYW1zKS50b0VxdWFsKHtcbiAgICB9KTtcblxuICAgIGV4cGVjdChhc3NldHMudG9NYW5pZmVzdCgnLicpLmVudHJpZXMpLnRvRXF1YWwoW10pO1xuICB9KTtcbn0pO1xuXG5mdW5jdGlvbiBzdGFja1dpdGhBc3NldHMoYXNzZXRFbnRyaWVzOiBBc3NldE1ldGFkYXRhRW50cnlbXSkge1xuICByZXR1cm4gdGVzdFN0YWNrKHtcbiAgICBzdGFja05hbWU6ICdTb21lU3RhY2snLFxuICAgIGFzc2V0czogYXNzZXRFbnRyaWVzLFxuICAgIHRlbXBsYXRlOiB7XG4gICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgU29tZVJlc291cmNlOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6U29tZXRoaW5nOjpTb21ldGhpbmcnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbn1cblxuZnVuY3Rpb24gbW9ja0ZuPEYgZXh0ZW5kcyAoLi4ueHM6IGFueVtdKSA9PiBhbnk+KGZuOiBGKTogamVzdC5Nb2NrPFJldHVyblR5cGU8Rj4+IHtcbiAgaWYgKCFqZXN0LmlzTW9ja0Z1bmN0aW9uKGZuKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgTm90IGEgbW9jayBmdW5jdGlvbjogJHtmbn1gKTtcbiAgfVxuICByZXR1cm4gZm47XG59XG4iXX0=