UNPKG

@aws-cdk-testing/cli-integ

Version:

Integration tests for the AWS CDK CLI

280 lines 35.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TestRepository = void 0; const client_codeartifact_1 = require("@aws-sdk/client-codeartifact"); const aws_1 = require("../aws"); const COLLECT_BY_TAG = 'collect-by'; const REPO_LIFETIME_MS = 24 * 3600 * 1000; // One day class TestRepository { repositoryName; static DEFAULT_DOMAIN = 'test-cdk'; static async newRandom() { const qualifier = Math.random() .toString(36) .replace(/[^a-z0-9]+/g, ''); const repo = new TestRepository(`test-${qualifier}`); await repo.prepare(); return repo; } static async newWithName(name) { const repo = new TestRepository(name); await repo.prepare(); return repo; } static existing(repositoryName) { return new TestRepository(repositoryName); } /** * Garbage collect repositories */ static async gc() { if (!(await TestRepository.existing('*dummy*').domainExists())) { return; } const codeArtifact = new client_codeartifact_1.CodeartifactClient(); let nextToken; do { const page = await codeArtifact.send(new client_codeartifact_1.ListRepositoriesCommand({ nextToken: nextToken, })); for (const repo of page.repositories ?? []) { const tags = await codeArtifact.send(new client_codeartifact_1.ListTagsForResourceCommand({ resourceArn: repo.arn, })); const collectable = tags?.tags?.find((t) => t.key === COLLECT_BY_TAG && Number(t.value) < Date.now()); if (collectable) { // eslint-disable-next-line no-console console.log('Deleting', repo.name); await codeArtifact.send(new client_codeartifact_1.DeleteRepositoryCommand({ domain: repo.domainName, repository: repo.name, })); } } nextToken = page.nextToken; } while (nextToken); } npmUpstream = 'npm-upstream'; pypiUpstream = 'pypi-upstream'; nugetUpstream = 'nuget-upstream'; mavenUpstream = 'maven-upstream'; domain = TestRepository.DEFAULT_DOMAIN; codeArtifact = new client_codeartifact_1.CodeartifactClient(); _loginInformation; constructor(repositoryName) { this.repositoryName = repositoryName; } async prepare() { await this.ensureDomain(); await this.ensureUpstreams(); await this.ensureRepository(this.repositoryName, { description: 'Testing repository', upstreams: [this.npmUpstream, this.pypiUpstream, this.nugetUpstream, this.mavenUpstream], tags: { [COLLECT_BY_TAG]: `${Date.now() + REPO_LIFETIME_MS}`, }, }); } async loginInformation() { if (this._loginInformation) { return this._loginInformation; } this._loginInformation = { authToken: (await this.codeArtifact.send(new client_codeartifact_1.GetAuthorizationTokenCommand({ domain: this.domain, durationSeconds: 12 * 3600, }))).authorizationToken, repositoryName: this.repositoryName, npmEndpoint: (await this.codeArtifact.send(new client_codeartifact_1.GetRepositoryEndpointCommand({ domain: this.domain, repository: this.repositoryName, format: 'npm', }))).repositoryEndpoint, mavenEndpoint: (await this.codeArtifact.send(new client_codeartifact_1.GetRepositoryEndpointCommand({ domain: this.domain, repository: this.repositoryName, format: 'maven', }))).repositoryEndpoint, nugetEndpoint: (await this.codeArtifact.send(new client_codeartifact_1.GetRepositoryEndpointCommand({ domain: this.domain, repository: this.repositoryName, format: 'nuget', }))).repositoryEndpoint, pypiEndpoint: (await this.codeArtifact.send(new client_codeartifact_1.GetRepositoryEndpointCommand({ domain: this.domain, repository: this.repositoryName, format: 'pypi', }))).repositoryEndpoint, }; return this._loginInformation; } async delete() { try { await this.codeArtifact.send(new client_codeartifact_1.DeleteRepositoryCommand({ domain: this.domain, repository: this.repositoryName, })); // eslint-disable-next-line no-console console.log('Deleted', this.repositoryName); } catch (e) { if (e.name !== 'ResourceNotFoundException') { throw e; } // Okay } } /** * List all packages and mark them as "allow upstream versions". * * If we don't do this and we publish `foo@2.3.4-rc.0`, then we can't * download `foo@2.3.0` anymore because by default CodeArtifact will * block different versions from the same package. */ async markAllUpstreamAllow() { for await (const pkg of this.listPackages({ upstream: 'BLOCK' })) { await retryThrottled(() => this.codeArtifact.send(new client_codeartifact_1.PutPackageOriginConfigurationCommand({ domain: this.domain, repository: this.repositoryName, format: pkg.format, package: pkg.package, namespace: pkg.namespace, restrictions: { publish: 'ALLOW', upstream: 'ALLOW', }, }))); } } async ensureDomain() { if (await this.domainExists()) { return; } await this.codeArtifact.send(new client_codeartifact_1.CreateDomainCommand({ domain: this.domain, tags: [{ key: 'testing', value: 'true' }], })); } async ensureUpstreams() { await this.ensureRepository(this.npmUpstream, { description: 'The upstream repository for NPM', external: 'public:npmjs', }); await this.ensureRepository(this.mavenUpstream, { description: 'The upstream repository for Maven', external: 'public:maven-central', }); await this.ensureRepository(this.nugetUpstream, { description: 'The upstream repository for NuGet', external: 'public:nuget-org', }); await this.ensureRepository(this.pypiUpstream, { description: 'The upstream repository for PyPI', external: 'public:pypi', }); } async ensureRepository(name, options) { if (await this.repositoryExists(name)) { return; } await this.codeArtifact.send(new client_codeartifact_1.CreateRepositoryCommand({ domain: this.domain, repository: name, description: options?.description, upstreams: options?.upstreams?.map((repositoryName) => ({ repositoryName })), tags: options?.tags ? Object.entries(options.tags).map(([key, value]) => ({ key, value })) : undefined, })); if (options?.external) { const externalConnection = options.external; await retry(() => this.codeArtifact.send(new client_codeartifact_1.AssociateExternalConnectionCommand({ domain: this.domain, repository: name, externalConnection, }))); } } async domainExists() { try { await this.codeArtifact.send(new client_codeartifact_1.DescribeDomainCommand({ domain: this.domain })); return true; } catch (e) { if (e.name !== 'ResourceNotFoundException') { throw e; } return false; } } async repositoryExists(name) { try { await this.codeArtifact.send(new client_codeartifact_1.DescribeRepositoryCommand({ domain: this.domain, repository: name })); return true; } catch (e) { if (e.name !== 'ResourceNotFoundException') { throw e; } return false; } } async *listPackages(filter = {}) { let response = await retryThrottled(() => this.codeArtifact.send(new client_codeartifact_1.ListPackagesCommand({ domain: this.domain, repository: this.repositoryName, ...filter, }))); while (true) { for (const p of response.packages ?? []) { yield p; } if (!response.nextToken) { break; } response = await retryThrottled(() => this.codeArtifact.send(new client_codeartifact_1.ListPackagesCommand({ domain: this.domain, repository: this.repositoryName, ...filter, nextToken: response.nextToken, }))); } } } exports.TestRepository = TestRepository; async function retry(block) { let attempts = 3; while (true) { try { return await block(); } catch (e) { if (attempts-- === 0) { throw e; } // eslint-disable-next-line no-console console.debug(e.message); await (0, aws_1.sleep)(500); } } } async function retryThrottled(block) { let time = 100; let attempts = 15; while (true) { try { return await block(); } catch (e) { // eslint-disable-next-line no-console console.debug(e.message); if (e.name !== 'ThrottlingException') { throw e; } if (attempts-- === 0) { throw e; } await (0, aws_1.sleep)(Math.floor(Math.random() * time)); time *= 2; } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZWFydGlmYWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY29kZWFydGlmYWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHNFQWNzQztBQUN0QyxnQ0FBK0I7QUFFL0IsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFDO0FBQ3BDLE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxVQUFVO0FBRXJELE1BQWEsY0FBYztJQTBFVztJQXpFN0IsTUFBTSxDQUFVLGNBQWMsR0FBRyxVQUFVLENBQUM7SUFFNUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTO1FBQzNCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUU7YUFDNUIsUUFBUSxDQUFDLEVBQUUsQ0FBQzthQUNaLE9BQU8sQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFOUIsTUFBTSxJQUFJLEdBQUcsSUFBSSxjQUFjLENBQUMsUUFBUSxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBQ3JELE1BQU0sSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3JCLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVNLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQVk7UUFDMUMsTUFBTSxJQUFJLEdBQUcsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsTUFBTSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDckIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU0sTUFBTSxDQUFDLFFBQVEsQ0FBQyxjQUFzQjtRQUMzQyxPQUFPLElBQUksY0FBYyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRDs7T0FFRztJQUNJLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUNwQixJQUFJLENBQUMsQ0FBQyxNQUFNLGNBQWMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUMsWUFB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QyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3pCLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxxQkFBcUIsRUFBRSxDQUFDO2dCQUNyQyxNQUFNLENBQUMsQ0FBQztZQUNWLENBQUM7WUFDRCxJQUFJLFFBQVEsRUFBRSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUNyQixNQUFNLENBQUMsQ0FBQztZQUNWLENBQUM7WUFDRCxNQUFNLElBQUEsV0FBSyxFQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDOUMsSUFBSSxJQUFJLENBQUMsQ0FBQztRQUNaLENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgTGlzdFBhY2thZ2VzUmVxdWVzdCB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1jb2RlYXJ0aWZhY3QnO1xuaW1wb3J0IHtcbiAgQXNzb2NpYXRlRXh0ZXJuYWxDb25uZWN0aW9uQ29tbWFuZCxcbiAgQ29kZWFydGlmYWN0Q2xpZW50LFxuICBDcmVhdGVEb21haW5Db21tYW5kLFxuICBDcmVhdGVSZXBvc2l0b3J5Q29tbWFuZCxcbiAgRGVsZXRlUmVwb3NpdG9yeUNvbW1hbmQsXG4gIERlc2NyaWJlRG9tYWluQ29tbWFuZCxcbiAgRGVzY3JpYmVSZXBvc2l0b3J5Q29tbWFuZCxcbiAgR2V0QXV0aG9yaXphdGlvblRva2VuQ29tbWFuZCxcbiAgR2V0UmVwb3NpdG9yeUVuZHBvaW50Q29tbWFuZCxcbiAgTGlzdFBhY2thZ2VzQ29tbWFuZCxcbiAgTGlzdFJlcG9zaXRvcmllc0NvbW1hbmQsXG4gIExpc3RUYWdzRm9yUmVzb3VyY2VDb21tYW5kLFxuICBQdXRQYWNrYWdlT3JpZ2luQ29uZmlndXJhdGlvbkNvbW1hbmQsXG59IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1jb2RlYXJ0aWZhY3QnO1xuaW1wb3J0IHsgc2xlZXAgfSBmcm9tICcuLi9hd3MnO1xuXG5jb25zdCBDT0xMRUNUX0JZX1RBRyA9ICdjb2xsZWN0LWJ5JztcbmNvbnN0IFJFUE9fTElGRVRJTUVfTVMgPSAyNCAqIDM2MDAgKiAxMDAwOyAvLyBPbmUgZGF5XG5cbmV4cG9ydCBjbGFzcyBUZXN0UmVwb3NpdG9yeSB7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9ET01BSU4gPSAndGVzdC1jZGsnO1xuXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgbmV3UmFuZG9tKCkge1xuICAgIGNvbnN0IHF1YWxpZmllciA9IE1hdGgucmFuZG9tKClcbiAgICAgIC50b1N0cmluZygzNilcbiAgICAgIC5yZXBsYWNlKC9bXmEtejAtOV0rL2csICcnKTtcblxuICAgIGNvbnN0IHJlcG8gPSBuZXcgVGVzdFJlcG9zaXRvcnkoYHRlc3QtJHtxdWFsaWZpZXJ9YCk7XG4gICAgYXdhaXQgcmVwby5wcmVwYXJlKCk7XG4gICAgcmV0dXJuIHJlcG87XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGFzeW5jIG5ld1dpdGhOYW1lKG5hbWU6IHN0cmluZykge1xuICAgIGNvbnN0IHJlcG8gPSBuZXcgVGVzdFJlcG9zaXRvcnkobmFtZSk7XG4gICAgYXdhaXQgcmVwby5wcmVwYXJlKCk7XG4gICAgcmV0dXJuIHJlcG87XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIGV4aXN0aW5nKHJlcG9zaXRvcnlOYW1lOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gbmV3IFRlc3RSZXBvc2l0b3J5KHJlcG9zaXRvcnlOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHYXJiYWdlIGNvbGxlY3QgcmVwb3NpdG9yaWVzXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFzeW5jIGdjKCkge1xuICAgIGlmICghKGF3YWl0IFRlc3RSZXBvc2l0b3J5LmV4aXN0aW5nKCcqZHVtbXkqJykuZG9tYWluRXhpc3RzKCkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY29kZUFydGlmYWN0ID0gbmV3IENvZGVhcnRpZmFjdENsaWVudCgpO1xuXG4gICAgbGV0IG5leHRUb2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGRvIHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCBjb2RlQXJ0aWZhY3Quc2VuZChcbiAgICAgICAgbmV3IExpc3RSZXBvc2l0b3JpZXNDb21tYW5kKHtcbiAgICAgICAgICBuZXh0VG9rZW46IG5leHRUb2tlbixcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICBmb3IgKGNvbnN0IHJlcG8gb2YgcGFnZS5yZXBvc2l0b3JpZXMgPz8gW10pIHtcbiAgICAgICAgY29uc3QgdGFncyA9IGF3YWl0IGNvZGVBcnRpZmFjdC5zZW5kKFxuICAgICAgICAgIG5ldyBMaXN0VGFnc0ZvclJlc291cmNlQ29tbWFuZCh7XG4gICAgICAgICAgICByZXNvdXJjZUFybjogcmVwby5hcm4hLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBjb2xsZWN0YWJsZSA9IHRhZ3M/LnRhZ3M/LmZpbmQoKHQpID0+IHQua2V5ID09PSBDT0xMRUNUX0JZX1RBRyAmJiBOdW1iZXIodC52YWx1ZSkgPCBEYXRlLm5vdygpKTtcbiAgICAgICAgaWYgKGNvbGxlY3RhYmxlKSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICBjb25zb2xlLmxvZygnRGVsZXRpbmcnLCByZXBvLm5hbWUpO1xuICAgICAgICAgIGF3YWl0IGNvZGVBcnRpZmFjdC5zZW5kKFxuICAgICAgICAgICAgbmV3IERlbGV0ZVJlcG9zaXRvcnlDb21tYW5kKHtcbiAgICAgICAgICAgICAgZG9tYWluOiByZXBvLmRvbWFpbk5hbWUhLFxuICAgICAgICAgICAgICByZXBvc2l0b3J5OiByZXBvLm5hbWUhLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBuZXh0VG9rZW4gPSBwYWdlLm5leHRUb2tlbjtcbiAgICB9IHdoaWxlIChuZXh0VG9rZW4pO1xuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IG5wbVVwc3RyZWFtID0gJ25wbS11cHN0cmVhbSc7XG4gIHB1YmxpYyByZWFkb25seSBweXBpVXBzdHJlYW0gPSAncHlwaS11cHN0cmVhbSc7XG4gIHB1YmxpYyByZWFkb25seSBudWdldFVwc3RyZWFtID0gJ251Z2V0LXVwc3RyZWFtJztcbiAgcHVibGljIHJlYWRvbmx5IG1hdmVuVXBzdHJlYW0gPSAnbWF2ZW4tdXBzdHJlYW0nO1xuICBwdWJsaWMgcmVhZG9ubHkgZG9tYWluID0gVGVzdFJlcG9zaXRvcnkuREVGQVVMVF9ET01BSU47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjb2RlQXJ0aWZhY3QgPSBuZXcgQ29kZWFydGlmYWN0Q2xpZW50KCk7XG5cbiAgcHJpdmF0ZSBfbG9naW5JbmZvcm1hdGlvbjogTG9naW5JbmZvcm1hdGlvbiB8IHVuZGVmaW5lZDtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKHB1YmxpYyByZWFkb25seSByZXBvc2l0b3J5TmFtZTogc3RyaW5nKSB7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcHJlcGFyZSgpIHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZURvbWFpbigpO1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlVXBzdHJlYW1zKCk7XG5cbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlcG9zaXRvcnkodGhpcy5yZXBvc2l0b3J5TmFtZSwge1xuICAgICAgZGVzY3JpcHRpb246ICdUZXN0aW5nIHJlcG9zaXRvcnknLFxuICAgICAgdXBzdHJlYW1zOiBbdGhpcy5ucG1VcHN0cmVhbSwgdGhpcy5weXBpVXBzdHJlYW0sIHRoaXMubnVnZXRVcHN0cmVhbSwgdGhpcy5tYXZlblVwc3RyZWFtXSxcbiAgICAgIHRhZ3M6IHtcbiAgICAgICAgW0NPTExFQ1RfQllfVEFHXTogYCR7RGF0ZS5ub3coKSArIFJFUE9fTElGRVRJTUVfTVN9YCxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgbG9naW5JbmZvcm1hdGlvbigpOiBQcm9taXNlPExvZ2luSW5mb3JtYXRpb24+IHtcbiAgICBpZiAodGhpcy5fbG9naW5JbmZvcm1hdGlvbikge1xuICAgICAgcmV0dXJuIHRoaXMuX2xvZ2luSW5mb3JtYXRpb247XG4gICAgfVxuXG4gICAgdGhpcy5fbG9naW5JbmZvcm1hdGlvbiA9IHtcbiAgICAgIGF1dGhUb2tlbjogKFxuICAgICAgICBhd2FpdCB0aGlzLmNvZGVBcnRpZmFjdC5zZW5kKFxuICAgICAgICAgIG5ldyBHZXRBdXRob3JpemF0aW9uVG9rZW5Db21tYW5kKHtcbiAgICAgICAgICAgIGRvbWFpbjogdGhpcy5kb21haW4sXG4gICAgICAgICAgICBkdXJhdGlvblNlY29uZHM6IDEyICogMzYwMCxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgKS5hdXRob3JpemF0aW9uVG9rZW4hLFxuICAgICAgcmVwb3NpdG9yeU5hbWU6IHRoaXMucmVwb3NpdG9yeU5hbWUsXG5cbiAgICAgIG5wbUVuZHBvaW50OiAoXG4gICAgICAgIGF3YWl0IHRoaXMuY29kZUFydGlmYWN0LnNlbmQoXG4gICAgICAgICAgbmV3IEdldFJlcG9zaXRvcnlFbmRwb2ludENvbW1hbmQoe1xuICAgICAgICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgICAgICAgIHJlcG9zaXRvcnk6IHRoaXMucmVwb3NpdG9yeU5hbWUsXG4gICAgICAgICAgICBmb3JtYXQ6ICducG0nLFxuICAgICAgICAgIH0pLFxuICAgICAgICApXG4gICAgICApLnJlcG9zaXRvcnlFbmRwb2ludCEsXG5cbiAgICAgIG1hdmVuRW5kcG9pbnQ6IChcbiAgICAgICAgYXdhaXQgdGhpcy5jb2RlQXJ0aWZhY3Quc2VuZChcbiAgICAgICAgICBuZXcgR2V0UmVwb3NpdG9yeUVuZHBvaW50Q29tbWFuZCh7XG4gICAgICAgICAgICBkb21haW46IHRoaXMuZG9tYWluLFxuICAgICAgICAgICAgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSxcbiAgICAgICAgICAgIGZvcm1hdDogJ21hdmVuJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgKS5yZXBvc2l0b3J5RW5kcG9pbnQhLFxuXG4gICAgICBudWdldEVuZHBvaW50OiAoXG4gICAgICAgIGF3YWl0IHRoaXMuY29kZUFydGlmYWN0LnNlbmQoXG4gICAgICAgICAgbmV3IEdldFJlcG9zaXRvcnlFbmRwb2ludENvbW1hbmQoe1xuICAgICAgICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgICAgICAgIHJlcG9zaXRvcnk6IHRoaXMucmVwb3NpdG9yeU5hbWUsXG4gICAgICAgICAgICBmb3JtYXQ6ICdudWdldCcsXG4gICAgICAgICAgfSksXG4gICAgICAgIClcbiAgICAgICkucmVwb3NpdG9yeUVuZHBvaW50ISxcblxuICAgICAgcHlwaUVuZHBvaW50OiAoXG4gICAgICAgIGF3YWl0IHRoaXMuY29kZUFydGlmYWN0LnNlbmQoXG4gICAgICAgICAgbmV3IEdldFJlcG9zaXRvcnlFbmRwb2ludENvbW1hbmQoe1xuICAgICAgICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgICAgICAgIHJlcG9zaXRvcnk6IHRoaXMucmVwb3NpdG9yeU5hbWUsXG4gICAgICAgICAgICBmb3JtYXQ6ICdweXBpJyxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgKS5yZXBvc2l0b3J5RW5kcG9pbnQhLFxuICAgIH07XG4gICAgcmV0dXJuIHRoaXMuX2xvZ2luSW5mb3JtYXRpb247XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGVsZXRlKCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmNvZGVBcnRpZmFjdC5zZW5kKFxuICAgICAgICBuZXcgRGVsZXRlUmVwb3NpdG9yeUNvbW1hbmQoe1xuICAgICAgICAgIGRvbWFpbjogdGhpcy5kb21haW4sXG4gICAgICAgICAgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSxcbiAgICAgICAgfSksXG4gICAgICApO1xuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgY29uc29sZS5sb2coJ0RlbGV0ZWQnLCB0aGlzLnJlcG9zaXRvcnlOYW1lKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGlmIChlLm5hbWUgIT09ICdSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uJykge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgICAgLy8gT2theVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0IGFsbCBwYWNrYWdlcyBhbmQgbWFyayB0aGVtIGFzIFwiYWxsb3cgdXBzdHJlYW0gdmVyc2lvbnNcIi5cbiAgICpcbiAgICogSWYgd2UgZG9uJ3QgZG8gdGhpcyBhbmQgd2UgcHVibGlzaCBgZm9vQDIuMy40LXJjLjBgLCB0aGVuIHdlIGNhbid0XG4gICAqIGRvd25sb2FkIGBmb29AMi4zLjBgIGFueW1vcmUgYmVjYXVzZSBieSBkZWZhdWx0IENvZGVBcnRpZmFjdCB3aWxsXG4gICAqIGJsb2NrIGRpZmZlcmVudCB2ZXJzaW9ucyBmcm9tIHRoZSBzYW1lIHBhY2thZ2UuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgbWFya0FsbFVwc3RyZWFtQWxsb3coKSB7XG4gICAgZm9yIGF3YWl0IChjb25zdCBwa2cgb2YgdGhpcy5saXN0UGFja2FnZXMoeyB1cHN0cmVhbTogJ0JMT0NLJyB9KSkge1xuICAgICAgYXdhaXQgcmV0cnlUaHJvdHRsZWQoKCkgPT5cbiAgICAgICAgdGhpcy5jb2RlQXJ0aWZhY3Quc2VuZChcbiAgICAgICAgICBuZXcgUHV0UGFja2FnZU9yaWdpbkNvbmZpZ3VyYXRpb25Db21tYW5kKHtcbiAgICAgICAgICAgIGRvbWFpbjogdGhpcy5kb21haW4sXG4gICAgICAgICAgICByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLFxuXG4gICAgICAgICAgICBmb3JtYXQ6IHBrZy5mb3JtYXQhLFxuICAgICAgICAgICAgcGFja2FnZTogcGtnLnBhY2thZ2UhLFxuICAgICAgICAgICAgbmFtZXNwYWNlOiBwa2cubmFtZXNwYWNlISxcbiAgICAgICAgICAgIHJlc3RyaWN0aW9uczoge1xuICAgICAgICAgICAgICBwdWJsaXNoOiAnQUxMT1cnLFxuICAgICAgICAgICAgICB1cHN0cmVhbTogJ0FMTE9XJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlRG9tYWluKCkge1xuICAgIGlmIChhd2FpdCB0aGlzLmRvbWFpbkV4aXN0cygpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGF3YWl0IHRoaXMuY29kZUFydGlmYWN0LnNlbmQoXG4gICAgICBuZXcgQ3JlYXRlRG9tYWluQ29tbWFuZCh7XG4gICAgICAgIGRvbWFpbjogdGhpcy5kb21haW4sXG4gICAgICAgIHRhZ3M6IFt7IGtleTogJ3Rlc3RpbmcnLCB2YWx1ZTogJ3RydWUnIH1dLFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlVXBzdHJlYW1zKCkge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVwb3NpdG9yeSh0aGlzLm5wbVVwc3RyZWFtLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSB1cHN0cmVhbSByZXBvc2l0b3J5IGZvciBOUE0nLFxuICAgICAgZXh0ZXJuYWw6ICdwdWJsaWM6bnBtanMnLFxuICAgIH0pO1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVwb3NpdG9yeSh0aGlzLm1hdmVuVXBzdHJlYW0sIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIHVwc3RyZWFtIHJlcG9zaXRvcnkgZm9yIE1hdmVuJyxcbiAgICAgIGV4dGVybmFsOiAncHVibGljOm1hdmVuLWNlbnRyYWwnLFxuICAgIH0pO1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVwb3NpdG9yeSh0aGlzLm51Z2V0VXBzdHJlYW0sIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIHVwc3RyZWFtIHJlcG9zaXRvcnkgZm9yIE51R2V0JyxcbiAgICAgIGV4dGVybmFsOiAncHVibGljOm51Z2V0LW9yZycsXG4gICAgfSk7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVSZXBvc2l0b3J5KHRoaXMucHlwaVVwc3RyZWFtLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSB1cHN0cmVhbSByZXBvc2l0b3J5IGZvciBQeVBJJyxcbiAgICAgIGV4dGVybmFsOiAncHVibGljOnB5cGknLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVSZXBvc2l0b3J5KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBvcHRpb25zPzoge1xuICAgICAgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gICAgICByZWFkb25seSBleHRlcm5hbD86IHN0cmluZztcbiAgICAgIHJlYWRvbmx5IHVwc3RyZWFtcz86IHN0cmluZ1tdO1xuICAgICAgcmVhZG9ubHkgdGFncz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgfSxcbiAgKSB7XG4gICAgaWYgKGF3YWl0IHRoaXMucmVwb3NpdG9yeUV4aXN0cyhuYW1lKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuY29kZUFydGlmYWN0LnNlbmQoXG4gICAgICBuZXcgQ3JlYXRlUmVwb3NpdG9yeUNvbW1hbmQoe1xuICAgICAgICBkb21haW46IHRoaXMuZG9tYWluLFxuICAgICAgICByZXBvc2l0b3J5OiBuYW1lLFxuICAgICAgICBkZXNjcmlwdGlvbjogb3B0aW9ucz8uZGVzY3JpcHRpb24sXG4gICAgICAgIHVwc3RyZWFtczogb3B0aW9ucz8udXBzdHJlYW1zPy5tYXAoKHJlcG9zaXRvcnlOYW1lKSA9PiAoeyByZXBvc2l0b3J5TmFtZSB9KSksXG4gICAgICAgIHRhZ3M6IG9wdGlvbnM/LnRhZ3MgPyBPYmplY3QuZW50cmllcyhvcHRpb25zLnRhZ3MpLm1hcCgoW2tleSwgdmFsdWVdKSA9PiAoeyBrZXksIHZhbHVlIH0pKSA6IHVuZGVmaW5lZCxcbiAgICAgIH0pLFxuICAgICk7XG5cbiAgICBpZiAob3B0aW9ucz8uZXh0ZXJuYWwpIHtcbiAgICAgIGNvbnN0IGV4dGVybmFsQ29ubmVjdGlvbiA9IG9wdGlvbnMuZXh0ZXJuYWw7XG4gICAgICBhd2FpdCByZXRyeSgoKSA9PlxuICAgICAgICB0aGlzLmNvZGVBcnRpZmFjdC5zZW5kKFxuICAgICAgICAgIG5ldyBBc3NvY2lhdGVFeHRlcm5hbENvbm5lY3Rpb25Db21tYW5kKHtcbiAgICAgICAgICAgIGRvbWFpbjogdGhpcy5kb21haW4sXG4gICAgICAgICAgICByZXBvc2l0b3J5OiBuYW1lLFxuICAgICAgICAgICAgZXh0ZXJuYWxDb25uZWN0aW9uLFxuICAgICAgICAgIH0pLFxuICAgICAgICApLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRvbWFpbkV4aXN0cygpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5jb2RlQXJ0aWZhY3Quc2VuZChuZXcgRGVzY3JpYmVEb21haW5Db21tYW5kKHsgZG9tYWluOiB0aGlzLmRvbWFpbiB9KSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGlmIChlLm5hbWUgIT09ICdSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uJykge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVwb3NpdG9yeUV4aXN0cyhuYW1lOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5jb2RlQXJ0aWZhY3Quc2VuZChuZXcgRGVzY3JpYmVSZXBvc2l0b3J5Q29tbWFuZCh7IGRvbWFpbjogdGhpcy5kb21haW4sIHJlcG9zaXRvcnk6IG5hbWUgfSkpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoZS5uYW1lICE9PSAnUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbicpIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jICpsaXN0UGFja2FnZXMoZmlsdGVyOiBQaWNrPExpc3RQYWNrYWdlc1JlcXVlc3QsICd1cHN0cmVhbScgfCAncHVibGlzaCcgfCAnZm9ybWF0Jz4gPSB7fSkge1xuICAgIGxldCByZXNwb25zZSA9IGF3YWl0IHJldHJ5VGhyb3R0bGVkKCgpID0+XG4gICAgICB0aGlzLmNvZGVBcnRpZmFjdC5zZW5kKFxuICAgICAgICBuZXcgTGlzdFBhY2thZ2VzQ29tbWFuZCh7XG4gICAgICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgICAgICByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLFxuICAgICAgICAgIC4uLmZpbHRlcixcbiAgICAgICAgfSksXG4gICAgICApLFxuICAgICk7XG5cbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgZm9yIChjb25zdCBwIG9mIHJlc3BvbnNlLnBhY2thZ2VzID8/IFtdKSB7XG4gICAgICAgIHlpZWxkIHA7XG4gICAgICB9XG5cbiAgICAgIGlmICghcmVzcG9uc2UubmV4dFRva2VuKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICByZXNwb25zZSA9IGF3YWl0IHJldHJ5VGhyb3R0bGVkKCgpID0+XG4gICAgICAgIHRoaXMuY29kZUFydGlmYWN0LnNlbmQoXG4gICAgICAgICAgbmV3IExpc3RQYWNrYWdlc0NvbW1hbmQoe1xuICAgICAgICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgICAgICAgIHJlcG9zaXRvcnk6IHRoaXMucmVwb3NpdG9yeU5hbWUsXG4gICAgICAgICAgICAuLi5maWx0ZXIsXG4gICAgICAgICAgICBuZXh0VG9rZW46IHJlc3BvbnNlLm5leHRUb2tlbixcbiAgICAgICAgICB9KSxcbiAgICAgICAgKSxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJldHJ5PEE+KGJsb2NrOiAoKSA9PiBQcm9taXNlPEE+KSB7XG4gIGxldCBhdHRlbXB0cyA9IDM7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBibG9jaygpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKGF0dGVtcHRzLS0gPT09IDApIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICBjb25zb2xlLmRlYnVnKGUubWVzc2FnZSk7XG4gICAgICBhd2FpdCBzbGVlcCg1MDApO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiByZXRyeVRocm90dGxlZDxBPihibG9jazogKCkgPT4gUHJvbWlzZTxBPikge1xuICBsZXQgdGltZSA9IDEwMDtcbiAgbGV0IGF0dGVtcHRzID0gMTU7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBibG9jaygpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUuZGVidWcoZS5tZXNzYWdlKTtcbiAgICAgIGlmIChlLm5hbWUgIT09ICdUaHJvdHRsaW5nRXhjZXB0aW9uJykge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuICAgICAgaWYgKGF0dGVtcHRzLS0gPT09IDApIHtcbiAgICAgICAgdGhyb3cgZTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHNsZWVwKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHRpbWUpKTtcbiAgICAgIHRpbWUgKj0gMjtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBMb2dpbkluZm9ybWF0aW9uIHtcbiAgcmVhZG9ubHkgYXV0aFRva2VuOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJlcG9zaXRvcnlOYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IG5wbUVuZHBvaW50OiBzdHJpbmc7XG4gIHJlYWRvbmx5IG1hdmVuRW5kcG9pbnQ6IHN0cmluZztcbiAgcmVhZG9ubHkgbnVnZXRFbmRwb2ludDogc3RyaW5nO1xuICByZWFkb25seSBweXBpRW5kcG9pbnQ6IHN0cmluZztcbn1cbiJdfQ==