UNPKG

jsii-release

Version:

Release jsii modules to multiple package managers

316 lines • 28.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.clone = clone; exports.detectGHE = detectGHE; exports.getToken = getToken; exports.detectSSH = detectSSH; exports.diffIndex = diffIndex; exports.add = add; exports.rm = rm; exports.commit = commit; exports.init = init; exports.tag = tag; exports.push = push; exports.checkout = checkout; exports.username = username; exports.email = email; exports.identify = identify; exports.branchExistsOnRemote = branchExistsOnRemote; exports.repositorySlug = repositorySlug; exports.parseRepositorySlug = parseRepositorySlug; exports.head = head; const shell = __importStar(require("./shell")); /** * Clones a repository from GitHub. Requires a `GITHUB_TOKEN` env variable. * * @param repositoryUrl the repository to clone. * @param targetDir the clone directory. */ function clone(repositoryUrl, targetDir, { depth = 1, tags = false, branch } = {}) { const cmd = ['git', 'clone']; if (depth) { cmd.push(`--depth ${depth}`); } if (branch) { cmd.push(`--branch ${branch}`); } if (tags) { cmd.push('--tags'); } cmd.push(tryDetectRepositoryUrl(repositoryUrl)); cmd.push(targetDir); shell.run(cmd.join(' ')); } function tryDetectRepositoryUrl(repositoryUrl) { const gitHubUseSsh = detectSSH(); if (gitHubUseSsh) { const sshRepositoryUrl = repositoryUrl.replace('/', ':'); return `git@${sshRepositoryUrl}.git`; } const gitHubToken = getToken(detectGHE()); if (!gitHubToken) { throw new Error('GITHUB_TOKEN env variable is required when GITHUB_USE_SSH env variable is not used'); } return `https://x-access-token:${gitHubToken}@${repositoryUrl}.git`; } /** * Checks if the current environment is an GHE environment. * * This check is using GITHUB_API_URL set in GitHub Actions workflow, as well as common gh cli env variables. * https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables * https://cli.github.com/manual/gh_help_environment * * @return - `true` if GH_HOST or GITHUB_API_URL env var are defined and not equal to the public github endpoint, otherwise `false` */ function detectGHE() { const githubApiUrl = process.env.GITHUB_API_URL; const ghHost = process.env.GH_HOST; return (Boolean(ghHost) && ghHost.trim().toLowerCase() != 'github.com') || (Boolean(githubApiUrl) && githubApiUrl.trim().toLowerCase() != 'https://api.github.com'); } /** * Returns an appropriate github token from the environment. * * @return GH_ENTERPRISE_TOKEN or GITHUB_ENTERPRISE_TOKEN or GITHUB_TOKEN if in an GHE environment, otherwise GITHUB_TOKEN */ function getToken(isGHE) { if (isGHE) { const githubEnterpiseToken = process.env.GH_ENTERPRISE_TOKEN ?? process.env.GITHUB_ENTERPRISE_TOKEN ?? process.env.GITHUB_TOKEN; return githubEnterpiseToken; } return process.env.GITHUB_TOKEN; } /** * Checks if SSH should be used to clone repo. * This checks the presence and values of the GIT_USE_SSH env variable and the deprecated GITHUB_USE_SSH for legacy reason. Returns true if either of these env vars are defined and not falsy. */ function detectSSH() { return Boolean(process.env.GIT_USE_SSH ?? process.env.GITHUB_USE_SSH); } /** * Query the git index for changes. * * @return True if changes exist, False otherwise. */ function diffIndex() { try { shell.run('git diff-index --exit-code HEAD --'); return false; } catch (err) { return true; } } /** * Add files to the index. * * @param p the path. */ function add(p) { shell.run(`git add ${p}`); } /** * Remove files from the working tree and from the index * * @param p the path. */ function rm(p, options = {}) { const cmd = ['git', 'rm']; if (options.recursive) { cmd.push('-r'); } cmd.push(p); shell.run(cmd.join(' ')); } /** * Commit. * * @param message the commit message. */ function commit(message) { shell.run(`git commit -m "${message}"`); } /** * Initialize a repository. */ function init() { shell.run('git init'); } /** * Cerate a tag. * * @param name tag name. * @returns true if the tag was created, false if it already exists. */ function tag(name) { try { shell.run(`git tag -a ${name} -m ${name}`, { capture: true }); return true; } catch (e) { if (e instanceof Error && e.message.includes('already exists')) { return false; } throw e; } } /** * Push a ref to origin. * * @param ref the ref */ function push(ref) { shell.run(`git push origin ${ref}`); } /** * Checkout to a new branch. Creates a new one if `options.createIfMissing` is True and the branch doesn't exist. * * @param branch the branch. * @param options options. */ function checkout(branch, options) { if (options.createIfMissing) { try { shell.run(`git show-branch origin/${branch}`, { capture: true }); } catch (e) { if (e instanceof Error && e.message.includes('fatal: bad sha1 reference')) { console.log('Remote branch not found, creating new branch.'); shell.run(`git checkout -B ${branch}`); return; } } } shell.run(`git checkout ${branch}`); } /** * Fetch the configured git user name for the current directory. * Returns undefined if not configured. */ function username() { try { return shell.run('git config user.name', { capture: true }); } catch (err) { if (err instanceof Error) { console.warn(err.message); } return undefined; } } /** * Fetch the configured git user email for the current directory. * Returns undefined if not configured. */ function email() { try { return shell.run('git config user.email', { capture: true }); } catch (err) { if (err instanceof Error) { console.warn(err.message); } return undefined; } } /** * Identify the committer with a username and email. * * @param user the username. * @param email the email address. */ function identify(user, address) { shell.run(`git config user.name "${user}"`); shell.run(`git config user.email "${address}"`); } /** * Does the given branch exists on the remote. */ function branchExistsOnRemote(repositoryUrl, branch) { return shell.check(`git ls-remote --exit-code --heads ${tryDetectRepositoryUrl(repositoryUrl)} ${branch}`, { capture: true }); } /** * Returns the `owner/repo` slug of the `origin` remote in the current * directory, or undefined if it cannot be determined (e.g. not in a git * repository, or no `origin` remote configured). */ function repositorySlug() { try { const url = shell.run('git remote get-url origin', { capture: true }); return parseRepositorySlug(url); } catch { return undefined; } } /** * Extracts the `owner/repo` slug from a git remote URL. * * Supports HTTPS (`https://github.com/owner/repo.git`), SSH * (`git@github.com:owner/repo.git`, `ssh://git@github.com/owner/repo.git`) * and URLs without a `.git` suffix. * * @returns the `owner/repo` slug, or undefined if it cannot be determined */ function parseRepositorySlug(url) { const path = url .trim() .replace(/\.git$/, '') // drop the scheme (https://, ssh://, git+ssh://, ...) .replace(/^[a-z+]+:\/\//, '') // normalize scp-like ssh syntax (git@host:owner/repo) to a path .replace(/^git@[^:/]+[:/]/, '') // strip a leading host segment (github.com/owner/repo) .replace(/^[^/]+\.[^/]+\//, ''); const parts = path.split('/').filter(Boolean); if (parts.length !== 2) { return undefined; } return parts.join('/'); } /** * Returns the commit hash of HEAD in the current directory, or undefined if * it cannot be determined (e.g. not in a git repository). */ function head() { try { return shell.run('git rev-parse HEAD', { capture: true }); } catch { return undefined; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2l0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2hlbHAvZ2l0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBeUJBLHNCQW1CQztBQXlCRCw4QkFNQztBQVFELDRCQU1DO0FBT0QsOEJBRUM7QUFPRCw4QkFPQztBQU9ELGtCQUVDO0FBT0QsZ0JBU0M7QUFPRCx3QkFFQztBQUtELG9CQUVDO0FBUUQsa0JBVUM7QUFPRCxvQkFFQztBQVFELDRCQWFDO0FBTUQsNEJBU0M7QUFNRCxzQkFTQztBQVFELDRCQUdDO0FBS0Qsb0RBRUM7QUFPRCx3Q0FPQztBQVdELGtEQWVDO0FBTUQsb0JBTUM7QUE3U0QsK0NBQWlDO0FBbUJqQzs7Ozs7R0FLRztBQUNILFNBQWdCLEtBQUssQ0FBQyxhQUFxQixFQUFFLFNBQWlCLEVBQUUsRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLElBQUksR0FBRyxLQUFLLEVBQUUsTUFBTSxLQUFtQixFQUFFO0lBQ3BILE1BQU0sR0FBRyxHQUFHLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBRTdCLElBQUksS0FBSyxFQUFFLENBQUM7UUFDVixHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRUQsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUNYLEdBQUcsQ0FBQyxJQUFJLENBQUMsWUFBWSxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRCxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ1QsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNyQixDQUFDO0lBRUQsR0FBRyxDQUFDLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDO0lBQ2hELEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFFcEIsS0FBSyxDQUFDLEdB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Q0FBQztJQUNuQixDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFnQixJQUFJO0lBQ2xCLElBQUksQ0FBQztRQUNILE9BQU8sS0FBSyxDQUFDLEdBQUcsQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHNoZWxsIGZyb20gJy4vc2hlbGwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIENsb25lT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBAZGVmYXVsdCAxXG4gICAqL1xuICByZWFkb25seSBkZXB0aD86IG51bWJlcjtcblxuICAvKipcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHRhZ3M/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBAZGVmYXVsdCAtIGRlZmF1bHQgYnJhbmNoXG4gICAqL1xuICByZWFkb25seSBicmFuY2g/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQ2xvbmVzIGEgcmVwb3NpdG9yeSBmcm9tIEdpdEh1Yi4gUmVxdWlyZXMgYSBgR0lUSFVCX1RPS0VOYCBlbnYgdmFyaWFibGUuXG4gKlxuICogQHBhcmFtIHJlcG9zaXRvcnlVcmwgdGhlIHJlcG9zaXRvcnkgdG8gY2xvbmUuXG4gKiBAcGFyYW0gdGFyZ2V0RGlyIHRoZSBjbG9uZSBkaXJlY3RvcnkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZShyZXBvc2l0b3J5VXJsOiBzdHJpbmcsIHRhcmdldERpcjogc3RyaW5nLCB7IGRlcHRoID0gMSwgdGFncyA9IGZhbHNlLCBicmFuY2ggfTogQ2xvbmVPcHRpb25zID0ge30pIHtcbiAgY29uc3QgY21kID0gWydnaXQnLCAnY2xvbmUnXTtcblxuICBpZiAoZGVwdGgpIHtcbiAgICBjbWQucHVzaChgLS1kZXB0aCAke2RlcHRofWApO1xuICB9XG5cbiAgaWYgKGJyYW5jaCkge1xuICAgIGNtZC5wdXNoKGAtLWJyYW5jaCAke2JyYW5jaH1gKTtcbiAgfVxuXG4gIGlmICh0YWdzKSB7XG4gICAgY21kLnB1c2goJy0tdGFncycpO1xuICB9XG5cbiAgY21kLnB1c2godHJ5RGV0ZWN0UmVwb3NpdG9yeVVybChyZXBvc2l0b3J5VXJsKSk7XG4gIGNtZC5wdXNoKHRhcmdldERpcik7XG5cbiAgc2hlbGwucnVuKGNtZC5qb2luKCcgJykpO1xufVxuXG5mdW5jdGlvbiB0cnlEZXRlY3RSZXBvc2l0b3J5VXJsKHJlcG9zaXRvcnlVcmw6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IGdpdEh1YlVzZVNzaCA9IGRldGVjdFNTSCgpO1xuICBpZiAoZ2l0SHViVXNlU3NoKSB7XG4gICAgY29uc3Qgc3NoUmVwb3NpdG9yeVVybCA9IHJlcG9zaXRvcnlVcmwucmVwbGFjZSgnLycsICc6Jyk7XG4gICAgcmV0dXJuIGBnaXRAJHtzc2hSZXBvc2l0b3J5VXJsfS5naXRgO1xuICB9XG5cbiAgY29uc3QgZ2l0SHViVG9rZW4gPSBnZXRUb2tlbihkZXRlY3RHSEUoKSk7XG4gIGlmICghZ2l0SHViVG9rZW4pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ0dJVEhVQl9UT0tFTiBlbnYgdmFyaWFibGUgaXMgcmVxdWlyZWQgd2hlbiBHSVRIVUJfVVNFX1NTSCBlbnYgdmFyaWFibGUgaXMgbm90IHVzZWQnKTtcbiAgfVxuICByZXR1cm4gYGh0dHBzOi8veC1hY2Nlc3MtdG9rZW46JHtnaXRIdWJUb2tlbn1AJHtyZXBvc2l0b3J5VXJsfS5naXRgO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBpcyBhbiBHSEUgZW52aXJvbm1lbnQuXG4gKlxuICogVGhpcyBjaGVjayBpcyB1c2luZyBHSVRIVUJfQVBJX1VSTCBzZXQgaW4gR2l0SHViIEFjdGlvbnMgd29ya2Zsb3csIGFzIHdlbGwgYXMgY29tbW9uIGdoIGNsaSBlbnYgdmFyaWFibGVzLlxuICogaHR0cHM6Ly9kb2NzLmdpdGh1Yi5jb20vZW4vYWN0aW9ucy9sZWFybi1naXRodWItYWN0aW9ucy92YXJpYWJsZXMjZGVmYXVsdC1lbnZpcm9ubWVudC12YXJpYWJsZXNcbiAqIGh0dHBzOi8vY2xpLmdpdGh1Yi5jb20vbWFudWFsL2doX2hlbHBfZW52aXJvbm1lbnRcbiAqXG4gKiBAcmV0dXJuIC0gYHRydWVgIGlmIEdIX0hPU1Qgb3IgR0lUSFVCX0FQSV9VUkwgZW52IHZhciBhcmUgZGVmaW5lZCBhbmQgbm90IGVxdWFsIHRvIHRoZSBwdWJsaWMgZ2l0aHViIGVuZHBvaW50LCBvdGhlcndpc2UgYGZhbHNlYFxuICovXG5leHBvcnQgZnVuY3Rpb24gZGV0ZWN0R0hFKCk6IGJvb2xlYW4ge1xuICBjb25zdCBnaXRodWJBcGlVcmwgPSBwcm9jZXNzLmVudi5HSVRIVUJfQVBJX1VSTDtcbiAgY29uc3QgZ2hIb3N0ID0gcHJvY2Vzcy5lbnYuR0hfSE9TVDtcblxuICByZXR1cm4gKEJvb2xlYW4oZ2hIb3N0KSAmJiBnaEhvc3QhLnRyaW0oKS50b0xvd2VyQ2FzZSgpICE9ICdnaXRodWIuY29tJylcbiAgICB8fCAoQm9vbGVhbihnaXRodWJBcGlVcmwpICYmIGdpdGh1YkFwaVVybCEudHJpbSgpLnRvTG93ZXJDYXNlKCkgIT0gJ2h0dHBzOi8vYXBpLmdpdGh1Yi5jb20nKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIGFwcHJvcHJpYXRlIGdpdGh1YiB0b2tlbiBmcm9tIHRoZSBlbnZpcm9ubWVudC5cbiAqXG4gKiBAcmV0dXJuIEdIX0VOVEVSUFJJU0VfVE9LRU4gb3IgR0lUSFVCX0VOVEVSUFJJU0VfVE9LRU4gb3IgR0lUSFVCX1RPS0VOIGlmIGluIGFuIEdIRSBlbnZpcm9ubWVudCwgb3RoZXJ3aXNlIEdJVEhVQl9UT0tFTlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUb2tlbihpc0dIRTogYm9vbGVhbik6IChzdHJpbmcgfCB1bmRlZmluZWQpIHtcbiAgaWYgKGlzR0hFKSB7XG4gICAgY29uc3QgZ2l0aHViRW50ZXJwaXNlVG9rZW4gPSBwcm9jZXNzLmVudi5HSF9FTlRFUlBSSVNFX1RPS0VOID8/IHByb2Nlc3MuZW52LkdJVEhVQl9FTlRFUlBSSVNFX1RPS0VOID8/IHByb2Nlc3MuZW52LkdJVEhVQl9UT0tFTjtcbiAgICByZXR1cm4gZ2l0aHViRW50ZXJwaXNlVG9rZW47XG4gIH1cbiAgcmV0dXJuIHByb2Nlc3MuZW52LkdJVEhVQl9UT0tFTjtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgU1NIIHNob3VsZCBiZSB1c2VkIHRvIGNsb25lIHJlcG8uXG4gKiBUaGlzIGNoZWNrcyB0aGUgcHJlc2VuY2UgYW5kIHZhbHVlcyBvZiB0aGUgR0lUX1VTRV9TU0ggZW52IHZhcmlhYmxlIGFuZCB0aGUgZGVwcmVjYXRlZCBHSVRIVUJfVVNFX1NTSCBmb3IgbGVnYWN5IHJlYXNvbi4gUmV0dXJucyB0cnVlIGlmIGVpdGhlciBvZiB0aGVzZSBlbnYgdmFycyBhcmUgZGVmaW5lZCBhbmQgbm90IGZhbHN5LlxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBkZXRlY3RTU0goKTogYm9vbGVhbiB7XG4gIHJldHVybiBCb29sZWFuKHByb2Nlc3MuZW52LkdJVF9VU0VfU1NIID8/IHByb2Nlc3MuZW52LkdJVEhVQl9VU0VfU1NIKTtcbn1cblxuLyoqXG4gKiBRdWVyeSB0aGUgZ2l0IGluZGV4IGZvciBjaGFuZ2VzLlxuICpcbiAqIEByZXR1cm4gVHJ1ZSBpZiBjaGFuZ2VzIGV4aXN0LCBGYWxzZSBvdGhlcndpc2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaWZmSW5kZXgoKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgc2hlbGwucnVuKCdnaXQgZGlmZi1pbmRleCAtLWV4aXQtY29kZSBIRUFEIC0tJyk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuXG4vKipcbiAqIEFkZCBmaWxlcyB0byB0aGUgaW5kZXguXG4gKlxuICogQHBhcmFtIHAgdGhlIHBhdGguXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGQocDogc3RyaW5nKSB7XG4gIHNoZWxsLnJ1bihgZ2l0IGFkZCAke3B9YCk7XG59XG5cbi8qKlxuICogUmVtb3ZlIGZpbGVzIGZyb20gdGhlIHdvcmtpbmcgdHJlZSBhbmQgZnJvbSB0aGUgaW5kZXhcbiAqXG4gKiBAcGFyYW0gcCB0aGUgcGF0aC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJtKHA6IHN0cmluZywgb3B0aW9uczogeyByZWN1cnNpdmU/OiBib29sZWFuIH0gPSB7fSkge1xuICBjb25zdCBjbWQgPSBbJ2dpdCcsICdybSddO1xuICBpZiAob3B0aW9ucy5yZWN1cnNpdmUpIHtcbiAgICBjbWQucHVzaCgnLXInKTtcbiAgfVxuXG4gIGNtZC5wdXNoKHApO1xuXG4gIHNoZWxsLnJ1bihjbWQuam9pbignICcpKTtcbn1cblxuLyoqXG4gKiBDb21taXQuXG4gKlxuICogQHBhcmFtIG1lc3NhZ2UgdGhlIGNvbW1pdCBtZXNzYWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tbWl0KG1lc3NhZ2U6IHN0cmluZykge1xuICBzaGVsbC5ydW4oYGdpdCBjb21taXQgLW0gXCIke21lc3NhZ2V9XCJgKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIGEgcmVwb3NpdG9yeS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluaXQoKSB7XG4gIHNoZWxsLnJ1bignZ2l0IGluaXQnKTtcbn1cblxuLyoqXG4gKiBDZXJhdGUgYSB0YWcuXG4gKlxuICogQHBhcmFtIG5hbWUgdGFnIG5hbWUuXG4gKiBAcmV0dXJucyB0cnVlIGlmIHRoZSB0YWcgd2FzIGNyZWF0ZWQsIGZhbHNlIGlmIGl0IGFscmVhZHkgZXhpc3RzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdGFnKG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICB0cnkge1xuICAgIHNoZWxsLnJ1bihgZ2l0IHRhZyAtYSAke25hbWV9IC1tICR7bmFtZX1gLCB7IGNhcHR1cmU6IHRydWUgfSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBpZiAoZSBpbnN0YW5jZW9mIEVycm9yICYmIGUubWVzc2FnZS5pbmNsdWRlcygnYWxyZWFkeSBleGlzdHMnKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB0aHJvdyBlO1xuICB9XG59XG5cbi8qKlxuICogUHVzaCBhIHJlZiB0byBvcmlnaW4uXG4gKlxuICogQHBhcmFtIHJlZiB0aGUgcmVmXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwdXNoKHJlZjogc3RyaW5nKSB7XG4gIHNoZWxsLnJ1bihgZ2l0IHB1c2ggb3JpZ2luICR7cmVmfWApO1xufVxuXG4vKipcbiAqIENoZWNrb3V0IHRvIGEgbmV3IGJyYW5jaC4gQ3JlYXRlcyBhIG5ldyBvbmUgaWYgYG9wdGlvbnMuY3JlYXRlSWZNaXNzaW5nYCBpcyBUcnVlIGFuZCB0aGUgYnJhbmNoIGRvZXNuJ3QgZXhpc3QuXG4gKlxuICogQHBhcmFtIGJyYW5jaCB0aGUgYnJhbmNoLlxuICogQHBhcmFtIG9wdGlvbnMgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNoZWNrb3V0KGJyYW5jaDogc3RyaW5nLCBvcHRpb25zOiB7IGNyZWF0ZUlmTWlzc2luZz86IGJvb2xlYW4gfSApIHtcbiAgaWYgKG9wdGlvbnMuY3JlYXRlSWZNaXNzaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIHNoZWxsLnJ1bihgZ2l0IHNob3ctYnJhbmNoIG9yaWdpbi8ke2JyYW5jaH1gLCB7IGNhcHR1cmU6IHRydWUgfSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgaWYgKGUgaW5zdGFuY2VvZiBFcnJvciAmJiBlLm1lc3NhZ2UuaW5jbHVkZXMoJ2ZhdGFsOiBiYWQgc2hhMSByZWZlcmVuY2UnKSkge1xuICAgICAgICBjb25zb2xlLmxvZygnUmVtb3RlIGJyYW5jaCBub3QgZm91bmQsIGNyZWF0aW5nIG5ldyBicmFuY2guJyk7XG4gICAgICAgIHNoZWxsLnJ1bihgZ2l0IGNoZWNrb3V0IC1CICR7YnJhbmNofWApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHNoZWxsLnJ1bihgZ2l0IGNoZWNrb3V0ICR7YnJhbmNofWApO1xufVxuXG4vKipcbiAqIEZldGNoIHRoZSBjb25maWd1cmVkIGdpdCB1c2VyIG5hbWUgZm9yIHRoZSBjdXJyZW50IGRpcmVjdG9yeS5cbiAqIFJldHVybnMgdW5kZWZpbmVkIGlmIG5vdCBjb25maWd1cmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlcm5hbWUoKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHNoZWxsLnJ1bignZ2l0IGNvbmZpZyB1c2VyLm5hbWUnLCB7IGNhcHR1cmU6IHRydWUgfSk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGlmIChlcnIgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgY29uc29sZS53YXJuKGVyci5tZXNzYWdlKTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIEZldGNoIHRoZSBjb25maWd1cmVkIGdpdCB1c2VyIGVtYWlsIGZvciB0aGUgY3VycmVudCBkaXJlY3RvcnkuXG4gKiBSZXR1cm5zIHVuZGVmaW5lZCBpZiBub3QgY29uZmlndXJlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGVtYWlsKCkge1xuICB0cnkge1xuICAgIHJldHVybiBzaGVsbC5ydW4oJ2dpdCBjb25maWcgdXNlci5lbWFpbCcsIHsgY2FwdHVyZTogdHJ1ZSB9KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBjb25zb2xlLndhcm4oZXJyLm1lc3NhZ2UpO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbi8qKlxuICogSWRlbnRpZnkgdGhlIGNvbW1pdHRlciB3aXRoIGEgdXNlcm5hbWUgYW5kIGVtYWlsLlxuICpcbiAqIEBwYXJhbSB1c2VyIHRoZSB1c2VybmFtZS5cbiAqIEBwYXJhbSBlbWFpbCB0aGUgZW1haWwgYWRkcmVzcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlkZW50aWZ5KHVzZXI6IHN0cmluZywgYWRkcmVzczogc3RyaW5nKSB7XG4gIHNoZWxsLnJ1bihgZ2l0IGNvbmZpZyB1c2VyLm5hbWUgXCIke3VzZXJ9XCJgKTtcbiAgc2hlbGwucnVuKGBnaXQgY29uZmlnIHVzZXIuZW1haWwgXCIke2FkZHJlc3N9XCJgKTtcbn1cblxuLyoqXG4gKiBEb2VzIHRoZSBnaXZlbiBicmFuY2ggZXhpc3RzIG9uIHRoZSByZW1vdGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBicmFuY2hFeGlzdHNPblJlbW90ZShyZXBvc2l0b3J5VXJsOiBzdHJpbmcsIGJyYW5jaDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBzaGVsbC5jaGVjayhgZ2l0IGxzLXJlbW90ZSAtLWV4aXQtY29kZSAtLWhlYWRzICR7dHJ5RGV0ZWN0UmVwb3NpdG9yeVVybChyZXBvc2l0b3J5VXJsKX0gJHticmFuY2h9YCwgeyBjYXB0dXJlOiB0cnVlIH0pO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGBvd25lci9yZXBvYCBzbHVnIG9mIHRoZSBgb3JpZ2luYCByZW1vdGUgaW4gdGhlIGN1cnJlbnRcbiAqIGRpcmVjdG9yeSwgb3IgdW5kZWZpbmVkIGlmIGl0IGNhbm5vdCBiZSBkZXRlcm1pbmVkIChlLmcuIG5vdCBpbiBhIGdpdFxuICogcmVwb3NpdG9yeSwgb3Igbm8gYG9yaWdpbmAgcmVtb3RlIGNvbmZpZ3VyZWQpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVwb3NpdG9yeVNsdWcoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgdHJ5IHtcbiAgICBjb25zdCB1cmwgPSBzaGVsbC5ydW4oJ2dpdCByZW1vdGUgZ2V0LXVybCBvcmlnaW4nLCB7IGNhcHR1cmU6IHRydWUgfSk7XG4gICAgcmV0dXJuIHBhcnNlUmVwb3NpdG9yeVNsdWcodXJsKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIEV4dHJhY3RzIHRoZSBgb3duZXIvcmVwb2Agc2x1ZyBmcm9tIGEgZ2l0IHJlbW90ZSBVUkwuXG4gKlxuICogU3VwcG9ydHMgSFRUUFMgKGBodHRwczovL2dpdGh1Yi5jb20vb3duZXIvcmVwby5naXRgKSwgU1NIXG4gKiAoYGdpdEBnaXRodWIuY29tOm93bmVyL3JlcG8uZ2l0YCwgYHNzaDovL2dpdEBnaXRodWIuY29tL293bmVyL3JlcG8uZ2l0YClcbiAqIGFuZCBVUkxzIHdpdGhvdXQgYSBgLmdpdGAgc3VmZml4LlxuICpcbiAqIEByZXR1cm5zIHRoZSBgb3duZXIvcmVwb2Agc2x1Zywgb3IgdW5kZWZpbmVkIGlmIGl0IGNhbm5vdCBiZSBkZXRlcm1pbmVkXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVJlcG9zaXRvcnlTbHVnKHVybDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcGF0aCA9IHVybFxuICAgIC50cmltKClcbiAgICAucmVwbGFjZSgvXFwuZ2l0JC8sICcnKVxuICAgIC8vIGRyb3AgdGhlIHNjaGVtZSAoaHR0cHM6Ly8sIHNzaDovLywgZ2l0K3NzaDovLywgLi4uKVxuICAgIC5yZXBsYWNlKC9eW2EteitdKzpcXC9cXC8vLCAnJylcbiAgICAvLyBub3JtYWxpemUgc2NwLWxpa2Ugc3NoIHN5bnRheCAoZ2l0QGhvc3Q6b3duZXIvcmVwbykgdG8gYSBwYXRoXG4gICAgLnJlcGxhY2UoL15naXRAW146L10rWzovXS8sICcnKVxuICAgIC8vIHN0cmlwIGEgbGVhZGluZyBob3N0IHNlZ21lbnQgKGdpdGh1Yi5jb20vb3duZXIvcmVwbylcbiAgICAucmVwbGFjZSgvXlteL10rXFwuW14vXStcXC8vLCAnJyk7XG4gIGNvbnN0IHBhcnRzID0gcGF0aC5zcGxpdCgnLycpLmZpbHRlcihCb29sZWFuKTtcbiAgaWYgKHBhcnRzLmxlbmd0aCAhPT0gMikge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgcmV0dXJuIHBhcnRzLmpvaW4oJy8nKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBjb21taXQgaGFzaCBvZiBIRUFEIGluIHRoZSBjdXJyZW50IGRpcmVjdG9yeSwgb3IgdW5kZWZpbmVkIGlmXG4gKiBpdCBjYW5ub3QgYmUgZGV0ZXJtaW5lZCAoZS5nLiBub3QgaW4gYSBnaXQgcmVwb3NpdG9yeSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoZWFkKCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHNoZWxsLnJ1bignZ2l0IHJldi1wYXJzZSBIRUFEJywgeyBjYXB0dXJlOiB0cnVlIH0pO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG4iXX0=