UNPKG

jsii-release

Version:

Release jsii modules to multiple package managers

294 lines 38.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CodeArtifactRepo = void 0; const client_codeartifact_1 = require("@aws-sdk/client-codeartifact"); const sleep_1 = require("../help/sleep"); const COLLECT_BY_TAG = 'collect-by'; const REPO_LIFETIME_MS = 24 * 3600 * 1000; // One day /** * A CodeArtifact repository */ class CodeArtifactRepo { /** * Create a CodeArtifact repo with a random name */ static async createRandom(options = {}) { const qualifier = Math.random().toString(36).replace(/[^a-z0-9]+/g, ''); const repo = new CodeArtifactRepo(`test-${qualifier}`, options); await repo.create(); return repo; } /** * Create a CodeArtifact repository with a given name */ static async createWithName(name, options = {}) { const repo = new CodeArtifactRepo(name, options); await repo.create(); return repo; } /** * Reference an existing CodeArtifact repository */ static existing(repositoryName, options = {}) { return new CodeArtifactRepo(repositoryName, options); } /** * Garbage collect repositories */ static async gc(options = {}) { var _a, _b; if (!await CodeArtifactRepo.existing('*dummy*').domainExists()) { return; } const codeArtifact = new client_codeartifact_1.CodeartifactClient({ credentials: options.credentials, }); let nextToken; do { const page = await retryThrottled(() => codeArtifact.send(new client_codeartifact_1.ListRepositoriesCommand({ nextToken }))); for (const repo of (_a = page.repositories) !== null && _a !== void 0 ? _a : []) { const tags = await retryThrottled(() => codeArtifact.send(new client_codeartifact_1.ListTagsForResourceCommand({ resourceArn: repo.arn }))); const collectable = (_b = tags === null || tags === void 0 ? void 0 : tags.tags) === null || _b === void 0 ? void 0 : _b.find(t => t.key === COLLECT_BY_TAG && Number(t.value) < Date.now()); if (collectable) { // eslint-disable-next-line no-console console.error('Deleting', repo.name); await retryThrottled(() => codeArtifact.send(new client_codeartifact_1.DeleteRepositoryCommand({ domain: repo.domainName, repository: repo.name, }))); } } nextToken = page.nextToken; } while (nextToken); } constructor(repositoryName, options = {}) { this.repositoryName = repositoryName; this.npmUpstream = 'npm-upstream'; this.pypiUpstream = 'pypi-upstream'; this.nugetUpstream = 'nuget-upstream'; this.mavenUpstream = 'maven-upstream'; this.domain = CodeArtifactRepo.DEFAULT_DOMAIN; this.codeArtifact = new client_codeartifact_1.CodeartifactClient({ credentials: options.credentials }); // Letting the compiler infer the types in this way is the only way to get it to typecheck this.send = (command) => retryThrottled(() => this.codeArtifact.send(command)); } /** * Create the repository */ async create() { 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}`, }, }); } /** * Absorb old login information */ setLoginInformation(loginInfo) { if (loginInfo.repositoryName !== this.repositoryName) { throw new Error(`This login info seems to be for a different repo. '${this.repositoryName}' != '${loginInfo.repositoryName}'`); } this._loginInformation = loginInfo; } async login() { var _a, _b; if (this._loginInformation) { return this._loginInformation; } const durationSeconds = 12 * 3600; const authToken = await this.send(new client_codeartifact_1.GetAuthorizationTokenCommand({ domain: this.domain, durationSeconds })); this._loginInformation = { // eslint-disable-next-line max-len authToken: authToken.authorizationToken, expirationTimeMs: (_b = (_a = authToken.expiration) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : (Date.now() + durationSeconds * 1000), repositoryName: this.repositoryName, npmEndpoint: (await this.send(new client_codeartifact_1.GetRepositoryEndpointCommand({ domain: this.domain, repository: this.repositoryName, format: 'npm' }))).repositoryEndpoint, mavenEndpoint: (await this.send(new client_codeartifact_1.GetRepositoryEndpointCommand({ domain: this.domain, repository: this.repositoryName, format: 'maven' }))).repositoryEndpoint, nugetEndpoint: (await this.send(new client_codeartifact_1.GetRepositoryEndpointCommand({ domain: this.domain, repository: this.repositoryName, format: 'nuget' }))).repositoryEndpoint, pypiEndpoint: (await this.send(new client_codeartifact_1.GetRepositoryEndpointCommand({ domain: this.domain, repository: this.repositoryName, format: 'pypi' }))).repositoryEndpoint, }; return this._loginInformation; } async delete() { try { await this.send(new client_codeartifact_1.DeleteRepositoryCommand({ domain: this.domain, repository: this.repositoryName, })); // eslint-disable-next-line no-console console.error('Deleted', this.repositoryName); } catch (e) { if (!isResourceNotFoundException(e)) { 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 this.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.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) { var _a; if (await this.repositoryExists(name)) { return; } await this.send(new client_codeartifact_1.CreateRepositoryCommand({ domain: this.domain, repository: name, description: options === null || options === void 0 ? void 0 : options.description, upstreams: (_a = options === null || options === void 0 ? void 0 : options.upstreams) === null || _a === void 0 ? void 0 : _a.map(repositoryName => ({ repositoryName })), tags: (options === null || options === void 0 ? void 0 : options.tags) ? Object.entries(options.tags).map(([key, value]) => ({ key, value })) : undefined, })); if (options === null || options === void 0 ? void 0 : options.external) { const externalConnection = options.external; await retry(() => this.send(new client_codeartifact_1.AssociateExternalConnectionCommand({ domain: this.domain, repository: name, externalConnection, }))); } } async domainExists() { try { await this.send(new client_codeartifact_1.DescribeDomainCommand({ domain: this.domain })); return true; } catch (e) { if (!isResourceNotFoundException(e)) { throw e; } return false; } } async repositoryExists(name) { try { await this.send(new client_codeartifact_1.DescribeRepositoryCommand({ domain: this.domain, repository: name })); return true; } catch (e) { if (!isResourceNotFoundException(e)) { throw e; } return false; } } async *listPackages(filter = {}) { var _a; let response = await this.send(new client_codeartifact_1.ListPackagesCommand({ domain: this.domain, repository: this.repositoryName, ...filter, })); while (true) { for (const p of (_a = response.packages) !== null && _a !== void 0 ? _a : []) { yield p; } if (!response.nextToken) { break; } response = await this.send(new client_codeartifact_1.ListPackagesCommand({ domain: this.domain, repository: this.repositoryName, ...filter, nextToken: response.nextToken, })); } } } exports.CodeArtifactRepo = CodeArtifactRepo; CodeArtifactRepo.DEFAULT_DOMAIN = 'publib-ca'; 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, sleep_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); if (!(e instanceof client_codeartifact_1.ThrottlingException) || --attempts === 0) { throw e; } await (0, sleep_1.sleep)(Math.floor(Math.random() * time)); time *= 2; } } } function isResourceNotFoundException(x) { return x instanceof client_codeartifact_1.ResourceNotFoundException; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZWFydGlmYWN0LXJlcG8uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29kZWFydGlmYWN0L2NvZGVhcnRpZmFjdC1yZXBvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHNFQUFxZDtBQUVyZCx5Q0FBc0M7QUFFdEMsTUFBTSxjQUFjLEdBQUcsWUFBWSxDQUFDO0FBQ3BDLE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxVQUFVO0FBTXJEOztHQUVHO0FBQ0gsTUFBYSxnQkFBZ0I7SUFHM0I7O09BRUc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxVQUFtQyxFQUFFO1FBQ3BFLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUV4RSxNQUFNLElBQUksR0FBRyxJQUFJLGdCQUFnQixDQUFDLFFBQVEsU0FBUyxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDaEUsTUFBTSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDcEIsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7O09BRUc7SUFDSSxNQUFNLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxJQUFZLEVBQUUsVUFBbUMsRUFBRTtRQUNwRixNQUFNLElBQUksR0FBRyxJQUFJLGdCQUFnQixDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNqRCxNQUFNLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNwQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7T0FFRztJQUNJLE1BQU0sQ0FBQyxRQUFRLENBQUMsY0FBc0IsRUFBRSxVQUFtQyxFQUFFO1FBQ2xGLE9BQU8sSUFBSSxnQkFBZ0IsQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLENB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QUFLLEVBQUUsQ0FBQztTQUN0QjtRQUFDLE9BQU8sQ0FBTSxFQUFFO1lBQ2YsSUFBSSxRQUFRLEVBQUUsS0FBSyxDQUFDLEVBQUU7Z0JBQUUsTUFBTSxDQUFDLENBQUM7YUFBRTtZQUNsQyxzQ0FBc0M7WUFDdEMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDekIsTUFBTSxJQUFBLGFBQUssRUFBQyxHQUFHLENBQUMsQ0FBQztTQUNsQjtLQUNGO0FBQ0gsQ0FBQztBQUVELEtBQUssVUFBVSxjQUFjLENBQUksS0FBdUI7SUFDdEQsSUFBSSxJQUFJLEdBQUcsR0FBRyxDQUFDO0lBQ2YsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDO0lBQ2xCLE9BQU8sSUFBSSxFQUFFO1FBQ1gsSUFBSTtZQUNGLE9BQU8sTUFBTSxLQUFLLEVBQUUsQ0FBQztTQUN0QjtRQUFDLE9BQU8sQ0FBTSxFQUFFO1lBQ2Ysc0NBQXNDO1lBQ3RDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFFakIsSUFBSSxDQUFDLENBQUMsQ0FBQyxZQUFZLHlDQUFtQixDQUFDLElBQUksRUFBRSxRQUFRLEtBQUssQ0FBQyxFQUFFO2dCQUMzRCxNQUFNLENBQUMsQ0FBQzthQUNUO1lBRUQsTUFBTSxJQUFBLGFBQUssRUFBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzlDLElBQUksSUFBSSxDQUFDLENBQUM7U0FDWDtLQUNGO0FBQ0gsQ0FBQztBQVlELFNBQVMsMkJBQTJCLENBQUMsQ0FBTTtJQUN6QyxPQUFPLENBQUMsWUFBWSwrQ0FBeUIsQ0FBQztBQUNoRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQXNzb2NpYXRlRXh0ZXJuYWxDb25uZWN0aW9uQ29tbWFuZCwgQ29kZWFydGlmYWN0Q2xpZW50LCBDcmVhdGVEb21haW5Db21tYW5kLCBDcmVhdGVSZXBvc2l0b3J5Q29tbWFuZCwgRGVsZXRlUmVwb3NpdG9yeUNvbW1hbmQsIERlc2NyaWJlRG9tYWluQ29tbWFuZCwgRGVzY3JpYmVSZXBvc2l0b3J5Q29tbWFuZCwgR2V0QXV0aG9yaXphdGlvblRva2VuQ29tbWFuZCwgR2V0UmVwb3NpdG9yeUVuZHBvaW50Q29tbWFuZCwgTGlzdFBhY2thZ2VzQ29tbWFuZCwgTGlzdFBhY2thZ2VzQ29tbWFuZElucHV0LCBMaXN0UmVwb3NpdG9yaWVzQ29tbWFuZCwgTGlzdFRhZ3NGb3JSZXNvdXJjZUNvbW1hbmQsIFB1dFBhY2thZ2VPcmlnaW5Db25maWd1cmF0aW9uQ29tbWFuZCwgUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbiwgVGhyb3R0bGluZ0V4Y2VwdGlvbiB9IGZyb20gJ0Bhd3Mtc2RrL2NsaWVudC1jb2RlYXJ0aWZhY3QnO1xuaW1wb3J0IHsgQXdzQ3JlZGVudGlhbElkZW50aXR5UHJvdmlkZXIgfSBmcm9tICdAYXdzLXNkay90eXBlcyc7XG5pbXBvcnQgeyBzbGVlcCB9IGZyb20gJy4uL2hlbHAvc2xlZXAnO1xuXG5jb25zdCBDT0xMRUNUX0JZX1RBRyA9ICdjb2xsZWN0LWJ5JztcbmNvbnN0IFJFUE9fTElGRVRJTUVfTVMgPSAyNCAqIDM2MDAgKiAxMDAwOyAvLyBPbmUgZGF5XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29kZUFydGlmYWN0UmVwb09wdGlvbnMge1xuICByZWFkb25seSBjcmVkZW50aWFscz86IEF3c0NyZWRlbnRpYWxJZGVudGl0eVByb3ZpZGVyO1xufVxuXG4vKipcbiAqIEEgQ29kZUFydGlmYWN0IHJlcG9zaXRvcnlcbiAqL1xuZXhwb3J0IGNsYXNzIENvZGVBcnRpZmFjdFJlcG8ge1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERFRkFVTFRfRE9NQUlOID0gJ3B1YmxpYi1jYSc7XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIENvZGVBcnRpZmFjdCByZXBvIHdpdGggYSByYW5kb20gbmFtZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhc3luYyBjcmVhdGVSYW5kb20ob3B0aW9uczogQ29kZUFydGlmYWN0UmVwb09wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IHF1YWxpZmllciA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnJlcGxhY2UoL1teYS16MC05XSsvZywgJycpO1xuXG4gICAgY29uc3QgcmVwbyA9IG5ldyBDb2RlQXJ0aWZhY3RSZXBvKGB0ZXN0LSR7cXVhbGlmaWVyfWAsIG9wdGlvbnMpO1xuICAgIGF3YWl0IHJlcG8uY3JlYXRlKCk7XG4gICAgcmV0dXJuIHJlcG87XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgQ29kZUFydGlmYWN0IHJlcG9zaXRvcnkgd2l0aCBhIGdpdmVuIG5hbWVcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgY3JlYXRlV2l0aE5hbWUobmFtZTogc3RyaW5nLCBvcHRpb25zOiBDb2RlQXJ0aWZhY3RSZXBvT3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgcmVwbyA9IG5ldyBDb2RlQXJ0aWZhY3RSZXBvKG5hbWUsIG9wdGlvbnMpO1xuICAgIGF3YWl0IHJlcG8uY3JlYXRlKCk7XG4gICAgcmV0dXJuIHJlcG87XG4gIH1cblxuICAvKipcbiAgICogUmVmZXJlbmNlIGFuIGV4aXN0aW5nIENvZGVBcnRpZmFjdCByZXBvc2l0b3J5XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGV4aXN0aW5nKHJlcG9zaXRvcnlOYW1lOiBzdHJpbmcsIG9wdGlvbnM6IENvZGVBcnRpZmFjdFJlcG9PcHRpb25zID0ge30pIHtcbiAgICByZXR1cm4gbmV3IENvZGVBcnRpZmFjdFJlcG8ocmVwb3NpdG9yeU5hbWUsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdhcmJhZ2UgY29sbGVjdCByZXBvc2l0b3JpZXNcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgZ2Mob3B0aW9uczogQ29kZUFydGlmYWN0UmVwb09wdGlvbnMgPSB7fSkge1xuICAgIGlmICghYXdhaXQgQ29kZUFydGlmYWN0UmVwby5leGlzdGluZygnKmR1bW15KicpLmRvbWFpbkV4aXN0cygpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY29kZUFydGlmYWN0ID0gbmV3IENvZGVhcnRpZmFjdENsaWVudCh7XG4gICAgICBjcmVkZW50aWFsczogb3B0aW9ucy5jcmVkZW50aWFscyxcbiAgICB9KTtcblxuICAgIGxldCBuZXh0VG9rZW46IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICBkbyB7XG4gICAgICBjb25zdCBwYWdlID0gYXdhaXQgcmV0cnlUaHJvdHRsZWQoKCkgPT4gY29kZUFydGlmYWN0LnNlbmQobmV3IExpc3RSZXBvc2l0b3JpZXNDb21tYW5kKHsgbmV4dFRva2VuIH0pKSk7XG5cbiAgICAgIGZvciAoY29uc3QgcmVwbyBvZiBwYWdlLnJlcG9zaXRvcmllcyA/PyBbXSkge1xuICAgICAgICBjb25zdCB0YWdzID0gYXdhaXQgcmV0cnlUaHJvdHRsZWQoKCkgPT4gY29kZUFydGlmYWN0LnNlbmQobmV3IExpc3RUYWdzRm9yUmVzb3VyY2VDb21tYW5kKHsgcmVzb3VyY2VBcm46IHJlcG8uYXJuISB9KSkpO1xuICAgICAgICBjb25zdCBjb2xsZWN0YWJsZSA9IHRhZ3M/LnRhZ3M/LmZpbmQodCA9PiB0LmtleSA9PT0gQ09MTEVDVF9CWV9UQUcgJiYgTnVtYmVyKHQudmFsdWUpIDwgRGF0ZS5ub3coKSk7XG4gICAgICAgIGlmIChjb2xsZWN0YWJsZSkge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICAgICAgY29uc29sZS5lcnJvcignRGVsZXRpbmcnLCByZXBvLm5hbWUpO1xuICAgICAgICAgIGF3YWl0IHJldHJ5VGhyb3R0bGVkKCgpID0+IGNvZGVBcnRpZmFjdC5zZW5kKG5ldyBEZWxldGVSZXBvc2l0b3J5Q29tbWFuZCh7XG4gICAgICAgICAgICBkb21haW46IHJlcG8uZG9tYWluTmFtZSEsXG4gICAgICAgICAgICByZXBvc2l0b3J5OiByZXBvLm5hbWUhLFxuICAgICAgICAgIH0pKSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgbmV4dFRva2VuID0gcGFnZS5uZXh0VG9rZW47XG4gICAgfSB3aGlsZSAobmV4dFRva2VuKTtcbiAgfVxuXG4gIHB1YmxpYyByZWFkb25seSBucG1VcHN0cmVhbSA9ICducG0tdXBzdHJlYW0nO1xuICBwdWJsaWMgcmVhZG9ubHkgcHlwaVVwc3RyZWFtID0gJ3B5cGktdXBzdHJlYW0nO1xuICBwdWJsaWMgcmVhZG9ubHkgbnVnZXRVcHN0cmVhbSA9ICdudWdldC11cHN0cmVhbSc7XG4gIHB1YmxpYyByZWFkb25seSBtYXZlblVwc3RyZWFtID0gJ21hdmVuLXVwc3RyZWFtJztcbiAgcHVibGljIHJlYWRvbmx5IGRvbWFpbiA9IENvZGVBcnRpZmFjdFJlcG8uREVGQVVMVF9ET01BSU47XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjb2RlQXJ0aWZhY3Q7XG5cbiAgcHJpdmF0ZSBfbG9naW5JbmZvcm1hdGlvbjogTG9naW5JbmZvcm1hdGlvbiB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBzZW5kOiBDb2RlYXJ0aWZhY3RDbGllbnRbJ3NlbmQnXTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSByZXBvc2l0b3J5TmFtZTogc3RyaW5nLFxuICAgIG9wdGlvbnM6IENvZGVBcnRpZmFjdFJlcG9PcHRpb25zID0ge30sXG4gICkge1xuICAgIHRoaXMuY29kZUFydGlmYWN0ID0gbmV3IENvZGVhcnRpZmFjdENsaWVudCh7IGNyZWRlbnRpYWxzOiBvcHRpb25zLmNyZWRlbnRpYWxzIH0pO1xuXG4gICAgLy8gTGV0dGluZyB0aGUgY29tcGlsZXIgaW5mZXIgdGhlIHR5cGVzIGluIHRoaXMgd2F5IGlzIHRoZSBvbmx5IHdheSB0byBnZXQgaXQgdG8gdHlwZWNoZWNrXG4gICAgdGhpcy5zZW5kID0gKGNvbW1hbmQpID0+IHJldHJ5VGhyb3R0bGVkKCgpID0+IHRoaXMuY29kZUFydGlmYWN0LnNlbmQoY29tbWFuZCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSB0aGUgcmVwb3NpdG9yeVxuICAgKi9cbiAgcHVibGljIGFzeW5jIGNyZWF0ZSgpIHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZURvbWFpbigpO1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlVXBzdHJlYW1zKCk7XG5cbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlcG9zaXRvcnkodGhpcy5yZXBvc2l0b3J5TmFtZSwge1xuICAgICAgZGVzY3JpcHRpb246ICdUZXN0aW5nIHJlcG9zaXRvcnknLFxuICAgICAgdXBzdHJlYW1zOiBbXG4gICAgICAgIHRoaXMubnBtVXBzdHJlYW0sXG4gICAgICAgIHRoaXMucHlwaVVwc3RyZWFtLFxuICAgICAgICB0aGlzLm51Z2V0VXBzdHJlYW0sXG4gICAgICAgIHRoaXMubWF2ZW5VcHN0cmVhbSxcbiAgICAgIF0sXG4gICAgICB0YWdzOiB7XG4gICAgICAgIFtDT0xMRUNUX0JZX1RBR106IGAke0RhdGUubm93KCkgKyBSRVBPX0xJRkVUSU1FX01TfWAsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEFic29yYiBvbGQgbG9naW4gaW5mb3JtYXRpb25cbiAgICovXG4gIHB1YmxpYyBzZXRMb2dpbkluZm9ybWF0aW9uKGxvZ2luSW5mbzogTG9naW5JbmZvcm1hdGlvbikge1xuICAgIGlmIChsb2dpbkluZm8ucmVwb3NpdG9yeU5hbWUgIT09IHRoaXMucmVwb3NpdG9yeU5hbWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhpcyBsb2dpbiBpbmZvIHNlZW1zIHRvIGJlIGZvciBhIGRpZmZlcmVudCByZXBvLiAnJHt0aGlzLnJlcG9zaXRvcnlOYW1lfScgIT0gJyR7bG9naW5JbmZvLnJlcG9zaXRvcnlOYW1lfSdgKTtcbiAgICB9XG4gICAgdGhpcy5fbG9naW5JbmZvcm1hdGlvbiA9IGxvZ2luSW5mbztcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBsb2dpbigpOiBQcm9taXNlPExvZ2luSW5mb3JtYXRpb24+IHtcbiAgICBpZiAodGhpcy5fbG9naW5JbmZvcm1hdGlvbikge1xuICAgICAgcmV0dXJuIHRoaXMuX2xvZ2luSW5mb3JtYXRpb247XG4gICAgfVxuXG4gICAgY29uc3QgZHVyYXRpb25TZWNvbmRzID0gMTIgKiAzNjAwO1xuICAgIGNvbnN0IGF1dGhUb2tlbiA9IGF3YWl0IHRoaXMuc2VuZChuZXcgR2V0QXV0aG9yaXphdGlvblRva2VuQ29tbWFuZCh7IGRvbWFpbjogdGhpcy5kb21haW4sIGR1cmF0aW9uU2Vjb25kcyB9KSk7XG5cbiAgICB0aGlzLl9sb2dpbkluZm9ybWF0aW9uID0ge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1sZW5cbiAgICAgIGF1dGhUb2tlbjogYXV0aFRva2VuLmF1dGhvcml6YXRpb25Ub2tlbiEsXG4gICAgICBleHBpcmF0aW9uVGltZU1zOiBhdXRoVG9rZW4uZXhwaXJhdGlvbj8uZ2V0VGltZSgpID8/IChEYXRlLm5vdygpICsgZHVyYXRpb25TZWNvbmRzICogMTAwMCksXG4gICAgICByZXBvc2l0b3J5TmFtZTogdGhpcy5yZXBvc2l0b3J5TmFtZSxcbiAgICAgIG5wbUVuZHBvaW50OiAoYXdhaXQgdGhpcy5zZW5kKG5ldyBHZXRSZXBvc2l0b3J5RW5kcG9pbnRDb21tYW5kKHsgZG9tYWluOiB0aGlzLmRvbWFpbiwgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSwgZm9ybWF0OiAnbnBtJyB9KSkpLnJlcG9zaXRvcnlFbmRwb2ludCEsXG4gICAgICBtYXZlbkVuZHBvaW50OiAoYXdhaXQgdGhpcy5zZW5kKG5ldyBHZXRSZXBvc2l0b3J5RW5kcG9pbnRDb21tYW5kKHsgZG9tYWluOiB0aGlzLmRvbWFpbiwgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSwgZm9ybWF0OiAnbWF2ZW4nIH0pKSkucmVwb3NpdG9yeUVuZHBvaW50ISxcbiAgICAgIG51Z2V0RW5kcG9pbnQ6IChhd2FpdCB0aGlzLnNlbmQobmV3IEdldFJlcG9zaXRvcnlFbmRwb2ludENvbW1hbmQoeyBkb21haW46IHRoaXMuZG9tYWluLCByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLCBmb3JtYXQ6ICdudWdldCcgfSkpKS5yZXBvc2l0b3J5RW5kcG9pbnQhLFxuICAgICAgcHlwaUVuZHBvaW50OiAoYXdhaXQgdGhpcy5zZW5kKG5ldyBHZXRSZXBvc2l0b3J5RW5kcG9pbnRDb21tYW5kKHsgZG9tYWluOiB0aGlzLmRvbWFpbiwgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSwgZm9ybWF0OiAncHlwaScgfSkpKS5yZXBvc2l0b3J5RW5kcG9pbnQhLFxuICAgIH07XG4gICAgcmV0dXJuIHRoaXMuX2xvZ2luSW5mb3JtYXRpb247XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGVsZXRlKCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnNlbmQobmV3IERlbGV0ZVJlcG9zaXRvcnlDb21tYW5kKHtcbiAgICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgICAgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSxcbiAgICAgIH0pKTtcblxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0RlbGV0ZWQnLCB0aGlzLnJlcG9zaXRvcnlOYW1lKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGlmICghaXNSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uKGUpKSB7IHRocm93IGU7IH1cbiAgICAgIC8vIE9rYXlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTGlzdCBhbGwgcGFja2FnZXMgYW5kIG1hcmsgdGhlbSBhcyBcImFsbG93IHVwc3RyZWFtIHZlcnNpb25zXCIuXG4gICAqXG4gICAqIElmIHdlIGRvbid0IGRvIHRoaXMgYW5kIHdlIHB1Ymxpc2ggYGZvb0AyLjMuNC1yYy4wYCwgdGhlbiB3ZSBjYW4ndFxuICAgKiBkb3dubG9hZCBgZm9vQDIuMy4wYCBhbnltb3JlIGJlY2F1c2UgYnkgZGVmYXVsdCBDb2RlQXJ0aWZhY3Qgd2lsbFxuICAgKiBibG9jayBkaWZmZXJlbnQgdmVyc2lvbnMgZnJvbSB0aGUgc2FtZSBwYWNrYWdlLlxuICAgKi9cbiAgcHVibGljIGFzeW5jIG1hcmtBbGxVcHN0cmVhbUFsbG93KCkge1xuICAgIGZvciBhd2FpdCAoY29uc3QgcGtnIG9mIHRoaXMubGlzdFBhY2thZ2VzKHsgdXBzdHJlYW06ICdCTE9DSycgfSkpIHtcbiAgICAgIGF3YWl0IHRoaXMuc2VuZChuZXcgUHV0UGFja2FnZU9yaWdpbkNvbmZpZ3VyYXRpb25Db21tYW5kKHtcbiAgICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgICAgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSxcblxuICAgICAgICBmb3JtYXQ6IHBrZy5mb3JtYXQhLFxuICAgICAgICBwYWNrYWdlOiBwa2cucGFja2FnZSEsXG4gICAgICAgIG5hbWVzcGFjZTogcGtnLm5hbWVzcGFjZSEsXG4gICAgICAgIHJlc3RyaWN0aW9uczoge1xuICAgICAgICAgIHB1Ymxpc2g6ICdBTExPVycsXG4gICAgICAgICAgdXBzdHJlYW06ICdBTExPVycsXG4gICAgICAgIH0sXG4gICAgICB9KSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVEb21haW4oKSB7XG4gICAgaWYgKGF3YWl0IHRoaXMuZG9tYWluRXhpc3RzKCkpIHsgcmV0dXJuOyB9XG4gICAgYXdhaXQgdGhpcy5zZW5kKG5ldyBDcmVhdGVEb21haW5Db21tYW5kKHtcbiAgICAgIGRvbWFpbjogdGhpcy5kb21haW4sXG4gICAgICB0YWdzOiBbeyBrZXk6ICd0ZXN0aW5nJywgdmFsdWU6ICd0cnVlJyB9XSxcbiAgICB9KSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGVuc3VyZVVwc3RyZWFtcygpIHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlcG9zaXRvcnkodGhpcy5ucG1VcHN0cmVhbSwge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGUgdXBzdHJlYW0gcmVwb3NpdG9yeSBmb3IgTlBNJyxcbiAgICAgIGV4dGVybmFsOiAncHVibGljOm5wbWpzJyxcbiAgICB9KTtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlcG9zaXRvcnkodGhpcy5tYXZlblVwc3RyZWFtLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSB1cHN0cmVhbSByZXBvc2l0b3J5IGZvciBNYXZlbicsXG4gICAgICBleHRlcm5hbDogJ3B1YmxpYzptYXZlbi1jZW50cmFsJyxcbiAgICB9KTtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVJlcG9zaXRvcnkodGhpcy5udWdldFVwc3RyZWFtLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSB1cHN0cmVhbSByZXBvc2l0b3J5IGZvciBOdUdldCcsXG4gICAgICBleHRlcm5hbDogJ3B1YmxpYzpudWdldC1vcmcnLFxuICAgIH0pO1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVwb3NpdG9yeSh0aGlzLnB5cGlVcHN0cmVhbSwge1xuICAgICAgZGVzY3JpcHRpb246ICdUaGUgdXBzdHJlYW0gcmVwb3NpdG9yeSBmb3IgUHlQSScsXG4gICAgICBleHRlcm5hbDogJ3B1YmxpYzpweXBpJyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlUmVwb3NpdG9yeShuYW1lOiBzdHJpbmcsIG9wdGlvbnM/OiB7XG4gICAgcmVhZG9ubHkgZGVzY3JpcHRpb24/OiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgZXh0ZXJuYWw/OiBzdHJpbmc7XG4gICAgcmVhZG9ubHkgdXBzdHJlYW1zPzogc3RyaW5nW107XG4gICAgcmVhZG9ubHkgdGFncz86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gIH0pIHtcbiAgICBpZiAoYXdhaXQgdGhpcy5yZXBvc2l0b3J5RXhpc3RzKG5hbWUpKSB7IHJldHVybjsgfVxuXG4gICAgYXdhaXQgdGhpcy5zZW5kKG5ldyBDcmVhdGVSZXBvc2l0b3J5Q29tbWFuZCh7XG4gICAgICBkb21haW46IHRoaXMuZG9tYWluLFxuICAgICAgcmVwb3NpdG9yeTogbmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiBvcHRpb25zPy5kZXNjcmlwdGlvbixcbiAgICAgIHVwc3RyZWFtczogb3B0aW9ucz8udXBzdHJlYW1zPy5tYXAocmVwb3NpdG9yeU5hbWUgPT4gKHsgcmVwb3NpdG9yeU5hbWUgfSkpLFxuICAgICAgdGFnczogb3B0aW9ucz8udGFncyA/IE9iamVjdC5lbnRyaWVzKG9wdGlvbnMudGFncykubWFwKChba2V5LCB2YWx1ZV0pID0+ICh7IGtleSwgdmFsdWUgfSkpIDogdW5kZWZpbmVkLFxuICAgIH0pKTtcblxuICAgIGlmIChvcHRpb25zPy5leHRlcm5hbCkge1xuICAgICAgY29uc3QgZXh0ZXJuYWxDb25uZWN0aW9uID0gb3B0aW9ucy5leHRlcm5hbDtcbiAgICAgIGF3YWl0IHJldHJ5KCgpID0+IHRoaXMuc2VuZChuZXcgQXNzb2NpYXRlRXh0ZXJuYWxDb25uZWN0aW9uQ29tbWFuZCh7XG4gICAgICAgIGRvbWFpbjogdGhpcy5kb21haW4sXG4gICAgICAgIHJlcG9zaXRvcnk6IG5hbWUsXG4gICAgICAgIGV4dGVybmFsQ29ubmVjdGlvbixcbiAgICAgIH0pKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBkb21haW5FeGlzdHMoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuc2VuZChuZXcgRGVzY3JpYmVEb21haW5Db21tYW5kKHsgZG9tYWluOiB0aGlzLmRvbWFpbiB9KSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGlmICghaXNSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uKGUpKSB7IHRocm93IGU7IH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlcG9zaXRvcnlFeGlzdHMobmFtZTogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuc2VuZChuZXcgRGVzY3JpYmVSZXBvc2l0b3J5Q29tbWFuZCh7IGRvbWFpbjogdGhpcy5kb21haW4sIHJlcG9zaXRvcnk6IG5hbWUgfSkpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoIWlzUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbihlKSkgeyB0aHJvdyBlOyB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyogbGlzdFBhY2thZ2VzKGZpbHRlcjogUGljazxMaXN0UGFja2FnZXNDb21tYW5kSW5wdXQsICd1cHN0cmVhbSd8J3B1Ymxpc2gnfCdmb3JtYXQnPiA9IHt9KSB7XG4gICAgbGV0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5zZW5kKG5ldyBMaXN0UGFja2FnZXNDb21tYW5kKHtcbiAgICAgIGRvbWFpbjogdGhpcy5kb21haW4sXG4gICAgICByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLFxuICAgICAgLi4uZmlsdGVyLFxuICAgIH0pKTtcblxuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBmb3IgKGNvbnN0IHAgb2YgcmVzcG9uc2UucGFja2FnZXMgPz8gW10pIHtcbiAgICAgICAgeWllbGQgcDtcbiAgICAgIH1cblxuICAgICAgaWYgKCFyZXNwb25zZS5uZXh0VG9rZW4pIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5zZW5kKG5ldyBMaXN0UGFja2FnZXNDb21tYW5kKHtcbiAgICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgICAgcmVwb3NpdG9yeTogdGhpcy5yZXBvc2l0b3J5TmFtZSxcbiAgICAgICAgLi4uZmlsdGVyLFxuICAgICAgICBuZXh0VG9rZW46IHJlc3BvbnNlLm5leHRUb2tlbixcbiAgICAgIH0pKTtcbiAgICB9XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gcmV0cnk8QT4oYmxvY2s6ICgpID0+IFByb21pc2U8QT4pIHtcbiAgbGV0IGF0dGVtcHRzID0gMztcbiAgd2hpbGUgKHRydWUpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIGF3YWl0IGJsb2NrKCk7XG4gICAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgICBpZiAoYXR0ZW1wdHMtLSA9PT0gMCkgeyB0aHJvdyBlOyB9XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgY29uc29sZS5kZWJ1ZyhlLm1lc3NhZ2UpO1xuICAgICAgYXdhaXQgc2xlZXAoNTAwKTtcbiAgICB9XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gcmV0cnlUaHJvdHRsZWQ8QT4oYmxvY2s6ICgpID0+IFByb21pc2U8QT4pIHtcbiAgbGV0IHRpbWUgPSAxMDA7XG4gIGxldCBhdHRlbXB0cyA9IDE1O1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgYmxvY2soKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICBjb25zb2xlLmRlYnVnKGUpO1xuXG4gICAgICBpZiAoIShlIGluc3RhbmNlb2YgVGhyb3R0bGluZ0V4Y2VwdGlvbikgfHwgLS1hdHRlbXB0cyA9PT0gMCkge1xuICAgICAgICB0aHJvdyBlO1xuICAgICAgfVxuXG4gICAgICBhd2FpdCBzbGVlcChNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiB0aW1lKSk7XG4gICAgICB0aW1lICo9IDI7XG4gICAgfVxuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTG9naW5JbmZvcm1hdGlvbiB7XG4gIHJlYWRvbmx5IGF1dGhUb2tlbjogc3RyaW5nO1xuICByZWFkb25seSBleHBpcmF0aW9uVGltZU1zOiBudW1iZXI7XG4gIHJlYWRvbmx5IHJlcG9zaXRvcnlOYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IG5wbUVuZHBvaW50OiBzdHJpbmc7XG4gIHJlYWRvbmx5IG1hdmVuRW5kcG9pbnQ6IHN0cmluZztcbiAgcmVhZG9ubHkgbnVnZXRFbmRwb2ludDogc3RyaW5nO1xuICByZWFkb25seSBweXBpRW5kcG9pbnQ6IHN0cmluZztcbn1cblxuZnVuY3Rpb24gaXNSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uKHg6IGFueSk6IHggaXMgUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbiB7XG4gIHJldHVybiB4IGluc3RhbmNlb2YgUmVzb3VyY2VOb3RGb3VuZEV4Y2VwdGlvbjtcbn0iXX0=