jsii-release
Version:
Release jsii modules to multiple package managers
290 lines • 38.1 kB
JavaScript
"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 = {}) {
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 page.repositories ?? []) {
const tags = await retryThrottled(() => 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.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() {
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: authToken.expiration?.getTime() ?? (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) {
if (await this.repositoryExists(name)) {
return;
}
await this.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.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 = {}) {
let response = await this.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 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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QUFZLCtDQUF5QixDQUFDO0FBQ2hELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBc3NvY2lhdGVFeHRlcm5hbENvbm5lY3Rpb25Db21tYW5kLCBDb2RlYXJ0aWZhY3RDbGllbnQsIENyZWF0ZURvbWFpbkNvbW1hbmQsIENyZWF0ZVJlcG9zaXRvcnlDb21tYW5kLCBEZWxldGVSZXBvc2l0b3J5Q29tbWFuZCwgRGVzY3JpYmVEb21haW5Db21tYW5kLCBEZXNjcmliZVJlcG9zaXRvcnlDb21tYW5kLCBHZXRBdXRob3JpemF0aW9uVG9rZW5Db21tYW5kLCBHZXRSZXBvc2l0b3J5RW5kcG9pbnRDb21tYW5kLCBMaXN0UGFja2FnZXNDb21tYW5kLCBMaXN0UGFja2FnZXNDb21tYW5kSW5wdXQsIExpc3RSZXBvc2l0b3JpZXNDb21tYW5kLCBMaXN0VGFnc0ZvclJlc291cmNlQ29tbWFuZCwgUHV0UGFja2FnZU9yaWdpbkNvbmZpZ3VyYXRpb25Db21tYW5kLCBSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uLCBUaHJvdHRsaW5nRXhjZXB0aW9uIH0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LWNvZGVhcnRpZmFjdCc7XG5pbXBvcnQgeyBBd3NDcmVkZW50aWFsSWRlbnRpdHlQcm92aWRlciB9IGZyb20gJ0Bhd3Mtc2RrL3R5cGVzJztcbmltcG9ydCB7IHNsZWVwIH0gZnJvbSAnLi4vaGVscC9zbGVlcCc7XG5cbmNvbnN0IENPTExFQ1RfQllfVEFHID0gJ2NvbGxlY3QtYnknO1xuY29uc3QgUkVQT19MSUZFVElNRV9NUyA9IDI0ICogMzYwMCAqIDEwMDA7IC8vIE9uZSBkYXlcblxuZXhwb3J0IGludGVyZmFjZSBDb2RlQXJ0aWZhY3RSZXBvT3B0aW9ucyB7XG4gIHJlYWRvbmx5IGNyZWRlbnRpYWxzPzogQXdzQ3JlZGVudGlhbElkZW50aXR5UHJvdmlkZXI7XG59XG5cbi8qKlxuICogQSBDb2RlQXJ0aWZhY3QgcmVwb3NpdG9yeVxuICovXG5leHBvcnQgY2xhc3MgQ29kZUFydGlmYWN0UmVwbyB7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgREVGQVVMVF9ET01BSU4gPSAncHVibGliLWNhJztcblxuICAvKipcbiAgICogQ3JlYXRlIGEgQ29kZUFydGlmYWN0IHJlcG8gd2l0aCBhIHJhbmRvbSBuYW1lXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGFzeW5jIGNyZWF0ZVJhbmRvbShvcHRpb25zOiBDb2RlQXJ0aWZhY3RSZXBvT3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgcXVhbGlmaWVyID0gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikucmVwbGFjZSgvW15hLXowLTldKy9nLCAnJyk7XG5cbiAgICBjb25zdCByZXBvID0gbmV3IENvZGVBcnRpZmFjdFJlcG8oYHRlc3QtJHtxdWFsaWZpZXJ9YCwgb3B0aW9ucyk7XG4gICAgYXdhaXQgcmVwby5jcmVhdGUoKTtcbiAgICByZXR1cm4gcmVwbztcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBDb2RlQXJ0aWZhY3QgcmVwb3NpdG9yeSB3aXRoIGEgZ2l2ZW4gbmFtZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhc3luYyBjcmVhdGVXaXRoTmFtZShuYW1lOiBzdHJpbmcsIG9wdGlvbnM6IENvZGVBcnRpZmFjdFJlcG9PcHRpb25zID0ge30pIHtcbiAgICBjb25zdCByZXBvID0gbmV3IENvZGVBcnRpZmFjdFJlcG8obmFtZSwgb3B0aW9ucyk7XG4gICAgYXdhaXQgcmVwby5jcmVhdGUoKTtcbiAgICByZXR1cm4gcmVwbztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWZlcmVuY2UgYW4gZXhpc3RpbmcgQ29kZUFydGlmYWN0IHJlcG9zaXRvcnlcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZXhpc3RpbmcocmVwb3NpdG9yeU5hbWU6IHN0cmluZywgb3B0aW9uczogQ29kZUFydGlmYWN0UmVwb09wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiBuZXcgQ29kZUFydGlmYWN0UmVwbyhyZXBvc2l0b3J5TmFtZSwgb3B0aW9ucyk7XG4gIH1cblxuICAvKipcbiAgICogR2FyYmFnZSBjb2xsZWN0IHJlcG9zaXRvcmllc1xuICAgKi9cbiAgcHVibGljIHN0YXRpYyBhc3luYyBnYyhvcHRpb25zOiBDb2RlQXJ0aWZhY3RSZXBvT3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKCFhd2FpdCBDb2RlQXJ0aWZhY3RSZXBvLmV4aXN0aW5nKCcqZHVtbXkqJykuZG9tYWluRXhpc3RzKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBjb2RlQXJ0aWZhY3QgPSBuZXcgQ29kZWFydGlmYWN0Q2xpZW50KHtcbiAgICAgIGNyZWRlbnRpYWxzOiBvcHRpb25zLmNyZWRlbnRpYWxzLFxuICAgIH0pO1xuXG4gICAgbGV0IG5leHRUb2tlbjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGRvIHtcbiAgICAgIGNvbnN0IHBhZ2UgPSBhd2FpdCByZXRyeVRocm90dGxlZCgoKSA9PiBjb2RlQXJ0aWZhY3Quc2VuZChuZXcgTGlzdFJlcG9zaXRvcmllc0NvbW1hbmQoeyBuZXh0VG9rZW4gfSkpKTtcblxuICAgICAgZm9yIChjb25zdCByZXBvIG9mIHBhZ2UucmVwb3NpdG9yaWVzID8/IFtdKSB7XG4gICAgICAgIGNvbnN0IHRhZ3MgPSBhd2FpdCByZXRyeVRocm90dGxlZCgoKSA9PiBjb2RlQXJ0aWZhY3Quc2VuZChuZXcgTGlzdFRhZ3NGb3JSZXNvdXJjZUNvbW1hbmQoeyByZXNvdXJjZUFybjogcmVwby5hcm4hIH0pKSk7XG4gICAgICAgIGNvbnN0IGNvbGxlY3RhYmxlID0gdGFncz8udGFncz8uZmluZCh0ID0+IHQua2V5ID09PSBDT0xMRUNUX0JZX1RBRyAmJiBOdW1iZXIodC52YWx1ZSkgPCBEYXRlLm5vdygpKTtcbiAgICAgICAgaWYgKGNvbGxlY3RhYmxlKSB7XG4gICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdEZWxldGluZycsIHJlcG8ubmFtZSk7XG4gICAgICAgICAgYXdhaXQgcmV0cnlUaHJvdHRsZWQoKCkgPT4gY29kZUFydGlmYWN0LnNlbmQobmV3IERlbGV0ZVJlcG9zaXRvcnlDb21tYW5kKHtcbiAgICAgICAgICAgIGRvbWFpbjogcmVwby5kb21haW5OYW1lISxcbiAgICAgICAgICAgIHJlcG9zaXRvcnk6IHJlcG8ubmFtZSEsXG4gICAgICAgICAgfSkpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBuZXh0VG9rZW4gPSBwYWdlLm5leHRUb2tlbjtcbiAgICB9IHdoaWxlIChuZXh0VG9rZW4pO1xuICB9XG5cbiAgcHVibGljIHJlYWRvbmx5IG5wbVVwc3RyZWFtID0gJ25wbS11cHN0cmVhbSc7XG4gIHB1YmxpYyByZWFkb25seSBweXBpVXBzdHJlYW0gPSAncHlwaS11cHN0cmVhbSc7XG4gIHB1YmxpYyByZWFkb25seSBudWdldFVwc3RyZWFtID0gJ251Z2V0LXVwc3RyZWFtJztcbiAgcHVibGljIHJlYWRvbmx5IG1hdmVuVXBzdHJlYW0gPSAnbWF2ZW4tdXBzdHJlYW0nO1xuICBwdWJsaWMgcmVhZG9ubHkgZG9tYWluID0gQ29kZUFydGlmYWN0UmVwby5ERUZBVUxUX0RPTUFJTjtcblxuICBwcml2YXRlIHJlYWRvbmx5IGNvZGVBcnRpZmFjdDtcblxuICBwcml2YXRlIF9sb2dpbkluZm9ybWF0aW9uOiBMb2dpbkluZm9ybWF0aW9uIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IHNlbmQ6IENvZGVhcnRpZmFjdENsaWVudFsnc2VuZCddO1xuXG4gIHByaXZhdGUgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IHJlcG9zaXRvcnlOYW1lOiBzdHJpbmcsXG4gICAgb3B0aW9uczogQ29kZUFydGlmYWN0UmVwb09wdGlvbnMgPSB7fSxcbiAgKSB7XG4gICAgdGhpcy5jb2RlQXJ0aWZhY3QgPSBuZXcgQ29kZWFydGlmYWN0Q2xpZW50KHsgY3JlZGVudGlhbHM6IG9wdGlvbnMuY3JlZGVudGlhbHMgfSk7XG5cbiAgICAvLyBMZXR0aW5nIHRoZSBjb21waWxlciBpbmZlciB0aGUgdHlwZXMgaW4gdGhpcyB3YXkgaXMgdGhlIG9ubHkgd2F5IHRvIGdldCBpdCB0byB0eXBlY2hlY2tcbiAgICB0aGlzLnNlbmQgPSAoY29tbWFuZCkgPT4gcmV0cnlUaHJvdHRsZWQoKCkgPT4gdGhpcy5jb2RlQXJ0aWZhY3Quc2VuZChjb21tYW5kKSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIHRoZSByZXBvc2l0b3J5XG4gICAqL1xuICBwdWJsaWMgYXN5bmMgY3JlYXRlKCkge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlRG9tYWluKCk7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVVcHN0cmVhbXMoKTtcblxuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVwb3NpdG9yeSh0aGlzLnJlcG9zaXRvcnlOYW1lLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1Rlc3RpbmcgcmVwb3NpdG9yeScsXG4gICAgICB1cHN0cmVhbXM6IFtcbiAgICAgICAgdGhpcy5ucG1VcHN0cmVhbSxcbiAgICAgICAgdGhpcy5weXBpVXBzdHJlYW0sXG4gICAgICAgIHRoaXMubnVnZXRVcHN0cmVhbSxcbiAgICAgICAgdGhpcy5tYXZlblVwc3RyZWFtLFxuICAgICAgXSxcbiAgICAgIHRhZ3M6IHtcbiAgICAgICAgW0NPTExFQ1RfQllfVEFHXTogYCR7RGF0ZS5ub3coKSArIFJFUE9fTElGRVRJTUVfTVN9YCxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWJzb3JiIG9sZCBsb2dpbiBpbmZvcm1hdGlvblxuICAgKi9cbiAgcHVibGljIHNldExvZ2luSW5mb3JtYXRpb24obG9naW5JbmZvOiBMb2dpbkluZm9ybWF0aW9uKSB7XG4gICAgaWYgKGxvZ2luSW5mby5yZXBvc2l0b3J5TmFtZSAhPT0gdGhpcy5yZXBvc2l0b3J5TmFtZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUaGlzIGxvZ2luIGluZm8gc2VlbXMgdG8gYmUgZm9yIGEgZGlmZmVyZW50IHJlcG8uICcke3RoaXMucmVwb3NpdG9yeU5hbWV9JyAhPSAnJHtsb2dpbkluZm8ucmVwb3NpdG9yeU5hbWV9J2ApO1xuICAgIH1cbiAgICB0aGlzLl9sb2dpbkluZm9ybWF0aW9uID0gbG9naW5JbmZvO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGxvZ2luKCk6IFByb21pc2U8TG9naW5JbmZvcm1hdGlvbj4ge1xuICAgIGlmICh0aGlzLl9sb2dpbkluZm9ybWF0aW9uKSB7XG4gICAgICByZXR1cm4gdGhpcy5fbG9naW5JbmZvcm1hdGlvbjtcbiAgICB9XG5cbiAgICBjb25zdCBkdXJhdGlvblNlY29uZHMgPSAxMiAqIDM2MDA7XG4gICAgY29uc3QgYXV0aFRva2VuID0gYXdhaXQgdGhpcy5zZW5kKG5ldyBHZXRBdXRob3JpemF0aW9uVG9rZW5Db21tYW5kKHsgZG9tYWluOiB0aGlzLmRvbWFpbiwgZHVyYXRpb25TZWNvbmRzIH0pKTtcblxuICAgIHRoaXMuX2xvZ2luSW5mb3JtYXRpb24gPSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgYXV0aFRva2VuOiBhdXRoVG9rZW4uYXV0aG9yaXphdGlvblRva2VuISxcbiAgICAgIGV4cGlyYXRpb25UaW1lTXM6IGF1dGhUb2tlbi5leHBpcmF0aW9uPy5nZXRUaW1lKCkgPz8gKERhdGUubm93KCkgKyBkdXJhdGlvblNlY29uZHMgKiAxMDAwKSxcbiAgICAgIHJlcG9zaXRvcnlOYW1lOiB0aGlzLnJlcG9zaXRvcnlOYW1lLFxuICAgICAgbnBtRW5kcG9pbnQ6IChhd2FpdCB0aGlzLnNlbmQobmV3IEdldFJlcG9zaXRvcnlFbmRwb2ludENvbW1hbmQoeyBkb21haW46IHRoaXMuZG9tYWluLCByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLCBmb3JtYXQ6ICducG0nIH0pKSkucmVwb3NpdG9yeUVuZHBvaW50ISxcbiAgICAgIG1hdmVuRW5kcG9pbnQ6IChhd2FpdCB0aGlzLnNlbmQobmV3IEdldFJlcG9zaXRvcnlFbmRwb2ludENvbW1hbmQoeyBkb21haW46IHRoaXMuZG9tYWluLCByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLCBmb3JtYXQ6ICdtYXZlbicgfSkpKS5yZXBvc2l0b3J5RW5kcG9pbnQhLFxuICAgICAgbnVnZXRFbmRwb2ludDogKGF3YWl0IHRoaXMuc2VuZChuZXcgR2V0UmVwb3NpdG9yeUVuZHBvaW50Q29tbWFuZCh7IGRvbWFpbjogdGhpcy5kb21haW4sIHJlcG9zaXRvcnk6IHRoaXMucmVwb3NpdG9yeU5hbWUsIGZvcm1hdDogJ251Z2V0JyB9KSkpLnJlcG9zaXRvcnlFbmRwb2ludCEsXG4gICAgICBweXBpRW5kcG9pbnQ6IChhd2FpdCB0aGlzLnNlbmQobmV3IEdldFJlcG9zaXRvcnlFbmRwb2ludENvbW1hbmQoeyBkb21haW46IHRoaXMuZG9tYWluLCByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLCBmb3JtYXQ6ICdweXBpJyB9KSkpLnJlcG9zaXRvcnlFbmRwb2ludCEsXG4gICAgfTtcbiAgICByZXR1cm4gdGhpcy5fbG9naW5JbmZvcm1hdGlvbjtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkZWxldGUoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuc2VuZChuZXcgRGVsZXRlUmVwb3NpdG9yeUNvbW1hbmQoe1xuICAgICAgICBkb21haW46IHRoaXMuZG9tYWluLFxuICAgICAgICByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLFxuICAgICAgfSkpO1xuXG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29uc29sZVxuICAgICAgY29uc29sZS5lcnJvcignRGVsZXRlZCcsIHRoaXMucmVwb3NpdG9yeU5hbWUpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKCFpc1Jlc291cmNlTm90Rm91bmRFeGNlcHRpb24oZSkpIHsgdGhyb3cgZTsgfVxuICAgICAgLy8gT2theVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0IGFsbCBwYWNrYWdlcyBhbmQgbWFyayB0aGVtIGFzIFwiYWxsb3cgdXBzdHJlYW0gdmVyc2lvbnNcIi5cbiAgICpcbiAgICogSWYgd2UgZG9uJ3QgZG8gdGhpcyBhbmQgd2UgcHVibGlzaCBgZm9vQDIuMy40LXJjLjBgLCB0aGVuIHdlIGNhbid0XG4gICAqIGRvd25sb2FkIGBmb29AMi4zLjBgIGFueW1vcmUgYmVjYXVzZSBieSBkZWZhdWx0IENvZGVBcnRpZmFjdCB3aWxsXG4gICAqIGJsb2NrIGRpZmZlcmVudCB2ZXJzaW9ucyBmcm9tIHRoZSBzYW1lIHBhY2thZ2UuXG4gICAqL1xuICBwdWJsaWMgYXN5bmMgbWFya0FsbFVwc3RyZWFtQWxsb3coKSB7XG4gICAgZm9yIGF3YWl0IChjb25zdCBwa2cgb2YgdGhpcy5saXN0UGFja2FnZXMoeyB1cHN0cmVhbTogJ0JMT0NLJyB9KSkge1xuICAgICAgYXdhaXQgdGhpcy5zZW5kKG5ldyBQdXRQYWNrYWdlT3JpZ2luQ29uZmlndXJhdGlvbkNvbW1hbmQoe1xuICAgICAgICBkb21haW46IHRoaXMuZG9tYWluLFxuICAgICAgICByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLFxuXG4gICAgICAgIGZvcm1hdDogcGtnLmZvcm1hdCEsXG4gICAgICAgIHBhY2thZ2U6IHBrZy5wYWNrYWdlISxcbiAgICAgICAgbmFtZXNwYWNlOiBwa2cubmFtZXNwYWNlISxcbiAgICAgICAgcmVzdHJpY3Rpb25zOiB7XG4gICAgICAgICAgcHVibGlzaDogJ0FMTE9XJyxcbiAgICAgICAgICB1cHN0cmVhbTogJ0FMTE9XJyxcbiAgICAgICAgfSxcbiAgICAgIH0pKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGVuc3VyZURvbWFpbigpIHtcbiAgICBpZiAoYXdhaXQgdGhpcy5kb21haW5FeGlzdHMoKSkgeyByZXR1cm47IH1cbiAgICBhd2FpdCB0aGlzLnNlbmQobmV3IENyZWF0ZURvbWFpbkNvbW1hbmQoe1xuICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgIHRhZ3M6IFt7IGtleTogJ3Rlc3RpbmcnLCB2YWx1ZTogJ3RydWUnIH1dLFxuICAgIH0pKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZW5zdXJlVXBzdHJlYW1zKCkge1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVwb3NpdG9yeSh0aGlzLm5wbVVwc3RyZWFtLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSB1cHN0cmVhbSByZXBvc2l0b3J5IGZvciBOUE0nLFxuICAgICAgZXh0ZXJuYWw6ICdwdWJsaWM6bnBtanMnLFxuICAgIH0pO1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVwb3NpdG9yeSh0aGlzLm1hdmVuVXBzdHJlYW0sIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIHVwc3RyZWFtIHJlcG9zaXRvcnkgZm9yIE1hdmVuJyxcbiAgICAgIGV4dGVybmFsOiAncHVibGljOm1hdmVuLWNlbnRyYWwnLFxuICAgIH0pO1xuICAgIGF3YWl0IHRoaXMuZW5zdXJlUmVwb3NpdG9yeSh0aGlzLm51Z2V0VXBzdHJlYW0sIHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnVGhlIHVwc3RyZWFtIHJlcG9zaXRvcnkgZm9yIE51R2V0JyxcbiAgICAgIGV4dGVybmFsOiAncHVibGljOm51Z2V0LW9yZycsXG4gICAgfSk7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVSZXBvc2l0b3J5KHRoaXMucHlwaVVwc3RyZWFtLCB7XG4gICAgICBkZXNjcmlwdGlvbjogJ1RoZSB1cHN0cmVhbSByZXBvc2l0b3J5IGZvciBQeVBJJyxcbiAgICAgIGV4dGVybmFsOiAncHVibGljOnB5cGknLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBlbnN1cmVSZXBvc2l0b3J5KG5hbWU6IHN0cmluZywgb3B0aW9ucz86IHtcbiAgICByZWFkb25seSBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgICByZWFkb25seSBleHRlcm5hbD86IHN0cmluZztcbiAgICByZWFkb25seSB1cHN0cmVhbXM/OiBzdHJpbmdbXTtcbiAgICByZWFkb25seSB0YWdzPzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgfSkge1xuICAgIGlmIChhd2FpdCB0aGlzLnJlcG9zaXRvcnlFeGlzdHMobmFtZSkpIHsgcmV0dXJuOyB9XG5cbiAgICBhd2FpdCB0aGlzLnNlbmQobmV3IENyZWF0ZVJlcG9zaXRvcnlDb21tYW5kKHtcbiAgICAgIGRvbWFpbjogdGhpcy5kb21haW4sXG4gICAgICByZXBvc2l0b3J5OiBuYW1lLFxuICAgICAgZGVzY3JpcHRpb246IG9wdGlvbnM/LmRlc2NyaXB0aW9uLFxuICAgICAgdXBzdHJlYW1zOiBvcHRpb25zPy51cHN0cmVhbXM/Lm1hcChyZXBvc2l0b3J5TmFtZSA9PiAoeyByZXBvc2l0b3J5TmFtZSB9KSksXG4gICAgICB0YWdzOiBvcHRpb25zPy50YWdzID8gT2JqZWN0LmVudHJpZXMob3B0aW9ucy50YWdzKS5tYXAoKFtrZXksIHZhbHVlXSkgPT4gKHsga2V5LCB2YWx1ZSB9KSkgOiB1bmRlZmluZWQsXG4gICAgfSkpO1xuXG4gICAgaWYgKG9wdGlvbnM/LmV4dGVybmFsKSB7XG4gICAgICBjb25zdCBleHRlcm5hbENvbm5lY3Rpb24gPSBvcHRpb25zLmV4dGVybmFsO1xuICAgICAgYXdhaXQgcmV0cnkoKCkgPT4gdGhpcy5zZW5kKG5ldyBBc3NvY2lhdGVFeHRlcm5hbENvbm5lY3Rpb25Db21tYW5kKHtcbiAgICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgICAgcmVwb3NpdG9yeTogbmFtZSxcbiAgICAgICAgZXh0ZXJuYWxDb25uZWN0aW9uLFxuICAgICAgfSkpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGRvbWFpbkV4aXN0cygpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5zZW5kKG5ldyBEZXNjcmliZURvbWFpbkNvbW1hbmQoeyBkb21haW46IHRoaXMuZG9tYWluIH0pKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgaWYgKCFpc1Jlc291cmNlTm90Rm91bmRFeGNlcHRpb24oZSkpIHsgdGhyb3cgZTsgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVwb3NpdG9yeUV4aXN0cyhuYW1lOiBzdHJpbmcpIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5zZW5kKG5ldyBEZXNjcmliZVJlcG9zaXRvcnlDb21tYW5kKHsgZG9tYWluOiB0aGlzLmRvbWFpbiwgcmVwb3NpdG9yeTogbmFtZSB9KSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGlmICghaXNSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uKGUpKSB7IHRocm93IGU7IH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jKiBsaXN0UGFja2FnZXMoZmlsdGVyOiBQaWNrPExpc3RQYWNrYWdlc0NvbW1hbmRJbnB1dCwgJ3Vwc3RyZWFtJ3wncHVibGlzaCd8J2Zvcm1hdCc+ID0ge30pIHtcbiAgICBsZXQgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmQobmV3IExpc3RQYWNrYWdlc0NvbW1hbmQoe1xuICAgICAgZG9tYWluOiB0aGlzLmRvbWFpbixcbiAgICAgIHJlcG9zaXRvcnk6IHRoaXMucmVwb3NpdG9yeU5hbWUsXG4gICAgICAuLi5maWx0ZXIsXG4gICAgfSkpO1xuXG4gICAgd2hpbGUgKHRydWUpIHtcbiAgICAgIGZvciAoY29uc3QgcCBvZiByZXNwb25zZS5wYWNrYWdlcyA/PyBbXSkge1xuICAgICAgICB5aWVsZCBwO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXJlc3BvbnNlLm5leHRUb2tlbikge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmQobmV3IExpc3RQYWNrYWdlc0NvbW1hbmQoe1xuICAgICAgICBkb21haW46IHRoaXMuZG9tYWluLFxuICAgICAgICByZXBvc2l0b3J5OiB0aGlzLnJlcG9zaXRvcnlOYW1lLFxuICAgICAgICAuLi5maWx0ZXIsXG4gICAgICAgIG5leHRUb2tlbjogcmVzcG9uc2UubmV4dFRva2VuLFxuICAgICAgfSkpO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiByZXRyeTxBPihibG9jazogKCkgPT4gUHJvbWlzZTxBPikge1xuICBsZXQgYXR0ZW1wdHMgPSAzO1xuICB3aGlsZSAodHJ1ZSkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gYXdhaXQgYmxvY2soKTtcbiAgICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICAgIGlmIChhdHRlbXB0cy0tID09PSAwKSB7IHRocm93IGU7IH1cbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gICAgICBjb25zb2xlLmRlYnVnKGUubWVzc2FnZSk7XG4gICAgICBhd2FpdCBzbGVlcCg1MDApO1xuICAgIH1cbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiByZXRyeVRocm90dGxlZDxBPihibG9jazogKCkgPT4gUHJvbWlzZTxBPikge1xuICBsZXQgdGltZSA9IDEwMDtcbiAgbGV0IGF0dGVtcHRzID0gMTU7XG4gIHdoaWxlICh0cnVlKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBhd2FpdCBibG9jaygpO1xuICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICAgIGNvbnNvbGUuZGVidWcoZSk7XG5cbiAgICAgIGlmICghKGUgaW5zdGFuY2VvZiBUaHJvdHRsaW5nRXhjZXB0aW9uKSB8fCAtLWF0dGVtcHRzID09PSAwKSB7XG4gICAgICAgIHRocm93IGU7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IHNsZWVwKE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIHRpbWUpKTtcbiAgICAgIHRpbWUgKj0gMjtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBMb2dpbkluZm9ybWF0aW9uIHtcbiAgcmVhZG9ubHkgYXV0aFRva2VuOiBzdHJpbmc7XG4gIHJlYWRvbmx5IGV4cGlyYXRpb25UaW1lTXM6IG51bWJlcjtcbiAgcmVhZG9ubHkgcmVwb3NpdG9yeU5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgbnBtRW5kcG9pbnQ6IHN0cmluZztcbiAgcmVhZG9ubHkgbWF2ZW5FbmRwb2ludDogc3RyaW5nO1xuICByZWFkb25seSBudWdldEVuZHBvaW50OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHB5cGlFbmRwb2ludDogc3RyaW5nO1xufVxuXG5mdW5jdGlvbiBpc1Jlc291cmNlTm90Rm91bmRFeGNlcHRpb24oeDogYW55KTogeCBpcyBSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uIHtcbiAgcmV0dXJuIHggaW5zdGFuY2VvZiBSZXNvdXJjZU5vdEZvdW5kRXhjZXB0aW9uO1xufSJdfQ==