cdk8s-cli
Version:
This is the command line tool for Cloud Development Kit (CDK) for Kubernetes (cdk8s).
186 lines • 31.8 kB
JavaScript
"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 (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const os = __importStar(require("os"));
const path_1 = __importDefault(require("path"));
const fs = __importStar(require("fs-extra"));
const semver = __importStar(require("semver"));
const sscaff_1 = require("sscaff");
const yaml = __importStar(require("yaml"));
const config_1 = require("../../config");
const dispatch_1 = require("../../import/dispatch");
const _manager_1 = require("../../plugins/_manager");
const util_1 = require("../../util");
const CHART_YAML_FILE = 'Chart.yaml';
const README = 'README.md';
const DEFAULT_OUTPUT_DIR = 'dist';
const DEFAULT_PLUGINS_DIR = path_1.default.join(os.homedir(), '.cdk8s', 'plugins');
const config = (0, config_1.readConfigSync)();
class Command {
constructor() {
this.command = 'synth';
this.describe = 'Synthesizes Kubernetes manifests for all charts in your app.';
this.aliases = ['synthesize'];
this.builder = (args) => args
.option('app', { required: true, default: config?.app, desc: 'Command to use in order to execute cdk8s app', alias: 'a' })
.option('output', { required: false, desc: 'Output directory', alias: 'o' })
.option('stdout', { type: 'boolean', required: false, desc: 'Write synthesized manifests to STDOUT instead of the output directory', alias: 'p' })
.option('plugins-dir', { required: false, desc: 'Directory to store cdk8s plugins.' })
.option('validate', { type: 'boolean', required: false, desc: 'Apply validation plugins on the resulting manifests (use --no-validate to disable)' })
.option('validation-reports-output-file', { required: false, desc: 'File to write a JSON representation of the validation reports to' })
.option('format', { required: false, desc: 'Synthesis format for Kubernetes manifests. The default synthesis format is plain kubernetes manifests.', type: 'string' })
.option('chart-api-version', { required: false, desc: 'Chart API version of helm chart. The default value would be \'v2\' api version when synthesis format is helm. There is no default set when synthesis format is plain.', type: 'string' })
.option('chart-version', { required: false, desc: 'Chart version of helm chart. This is required if synthesis format is helm.' });
}
async handler(argv) {
const command = argv.app;
const stdout = argv.stdout;
const outdir = argv.output ?? config?.output ?? (!stdout ? DEFAULT_OUTPUT_DIR : undefined);
const validate = argv.validate ?? true;
const reportFile = argv.validationReportsOutputFile;
const pluginsDir = argv.pluginsDir ?? config?.pluginsDirectory ?? DEFAULT_PLUGINS_DIR;
const format = argv.format ?? config?.synthConfig?.format ?? config_1.SynthesisFormat.PLAIN;
const chartVersion = argv.chartVersion ?? config?.synthConfig?.chartVersion;
const chartApiVersion = argv.chartApiVersion ?? config?.synthConfig?.chartApiVersion ?? getDefaultChartApiVersion(format);
if (outdir && outdir !== config?.output && stdout) {
throw new Error('\'--output\' and \'--stdout\' are mutually exclusive. Please only use one.');
}
if (outdir) {
fs.rmSync(outdir, { recursive: true, force: true });
}
if (format != config_1.SynthesisFormat.PLAIN && format != config_1.SynthesisFormat.HELM) {
throw new Error(`You need to specify synthesis format either as ${config_1.SynthesisFormat.PLAIN} or ${config_1.SynthesisFormat.HELM} but received: ${format}`);
}
if (chartApiVersion && (chartApiVersion != config_1.HelmChartApiVersion.V1 && chartApiVersion != config_1.HelmChartApiVersion.V2)) {
throw new Error(`You need to specify helm chart api version either as ${config_1.HelmChartApiVersion.V1} or ${config_1.HelmChartApiVersion.V2} but received: ${chartApiVersion}`);
}
if (format === config_1.SynthesisFormat.HELM && !chartVersion) {
throw new Error('You need to specify \'--chart-version\' when \'--format\' is set as \'helm\'.');
}
if (chartVersion && !semver.valid(chartVersion)) {
throw new Error(`The value specified for '--chart-version': ${chartVersion} does not follow SemVer-2(https://semver.org/).`);
}
if (stdout && format === config_1.SynthesisFormat.HELM) {
throw new Error('Helm format synthesis does not support \'stdout\'. Please use \'outdir\' instead.');
}
if (format === config_1.SynthesisFormat.PLAIN && chartApiVersion) {
throw new Error('You need to specify \'--format\' as \'helm\' when \'--chart-api-version\' is set.');
}
if (format === config_1.SynthesisFormat.PLAIN && chartVersion) {
throw new Error('You need to specify \'--format\' as \'helm\' when \'--chart-version\' is set.');
}
if (chartApiVersion === config_1.HelmChartApiVersion.V1 && (0, util_1.crdsArePresent)(config?.imports)) {
throw new Error(`Your application uses CRDs, which are not supported when '--chart-api-version' is set to ${config_1.HelmChartApiVersion.V1}. Please either set '--chart-api-version' to ${config_1.HelmChartApiVersion.V2}, or remove the CRDs from your cdk8s.yaml configuration file`);
}
const validations = validate ? await fetchValidations() : undefined;
const recordConstructMetadata = !(validations == undefined || validations.length == 0);
if (stdout) {
await (0, util_1.mkdtemp)(async (tempDir) => {
const app = await (0, util_1.synthApp)(command, tempDir, stdout, recordConstructMetadata);
for (const f of app.manifests) {
fs.createReadStream(f).pipe(process.stdout);
}
if (validations) {
const pluginManager = new _manager_1.PluginManager(pluginsDir);
await (0, util_1.validateApp)(app, stdout, validations, pluginManager, reportFile);
}
});
}
else {
let manifests;
if (format === config_1.SynthesisFormat.HELM) {
await createHelmScaffolding(chartApiVersion, chartVersion, outdir);
const templateDir = path_1.default.join(outdir, 'templates');
manifests = await (0, util_1.synthApp)(command, templateDir, stdout, recordConstructMetadata);
}
else {
manifests = await (0, util_1.synthApp)(command, outdir, stdout, recordConstructMetadata);
}
if (validations) {
const pluginManager = new _manager_1.PluginManager(pluginsDir);
await (0, util_1.validateApp)(manifests, stdout, validations, pluginManager, reportFile);
}
}
}
}
async function fetchValidations() {
if (typeof (config?.validations) === 'string') {
const content = await (0, util_1.download)(config.validations);
return yaml.parse(content);
}
else {
return config?.validations;
}
}
async function createHelmScaffolding(apiVersion, chartVersion, outdir) {
const tempHelmStructure = createFolderStructure();
const substituteValues = {
apiVersion: apiVersion,
version: chartVersion,
app: path_1.default.basename(path_1.default.resolve()),
};
try {
await (0, sscaff_1.sscaff)(tempHelmStructure, outdir, substituteValues);
}
finally {
fs.rmSync(tempHelmStructure, { recursive: true });
}
if (apiVersion === config_1.HelmChartApiVersion.V2 && (0, util_1.crdsArePresent)(config?.imports)) {
await addCrdsToHelmChart(outdir);
}
function createFolderStructure() {
const root = fs.mkdtempSync(path_1.default.join(os.tmpdir(), 'helm-scaffolding-'));
fs.mkdirSync(path_1.default.join(root, 'templates'));
const chartYamlFile = {
apiVersion: '{{ apiVersion }}',
name: '{{ app }}',
version: '{{ version }}',
description: 'Generated chart for {{ app }}',
type: 'application',
};
fs.outputFileSync(path_1.default.join(root, CHART_YAML_FILE), yaml.stringify(chartYamlFile));
const readmeFile = 'This Helm chart is generated using cdk8s. Any manual changes to the chart would be discarded once cdk8s app is synthesized again with `--format helm`.';
fs.outputFileSync(path_1.default.join(root, README), readmeFile);
return root;
}
}
async function addCrdsToHelmChart(chartDir) {
const crds = (config?.imports ?? []).filter((imprt) => (!(0, util_1.isK8sImport)(imprt) && !(0, util_1.isHelmImport)(imprt)));
for (const crd of crds) {
const importSpec = (0, util_1.parseImports)(crd);
const importedCrdDef = await (0, dispatch_1.matchImporter)(importSpec, process.argv);
const manifest = importedCrdDef.rawManifest;
const filename = (0, util_1.deriveFileName)(importSpec.source);
fs.outputFileSync(path_1.default.join(chartDir, 'crds', `${filename}.yaml`), manifest);
}
}
function getDefaultChartApiVersion(synthFormat) {
return (synthFormat === config_1.SynthesisFormat.HELM) ? config_1.HelmChartApiVersion.V2 : undefined;
}
module.exports = new Command();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3ludGguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY2xpL2NtZHMvc3ludGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVDQUF5QjtBQUN6QixnREFBd0I7QUFDeEIsNkNBQStCO0FBQy9CLCtDQUFpQztBQUNqQyxtQ0FBZ0M7QUFDaEMsMkNBQTZCO0FBRTdCLHlDQUFzRztBQUV0RyxvREFBc0Q7QUFDdEQscURBQXVEO0FBQ3ZELHFDQUErSjtBQUUvSixNQUFNLGVBQWUsR0FBRyxZQUFZLENBQUM7QUFDckMsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDO0FBQzNCLE1BQU0sa0JBQWtCLEdBQUcsTUFBTSxDQUFDO0FBQ2xDLE1BQU0sbUJBQW1CLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBRXpFLE1BQU0sTUFBTSxHQUFHLElBQUEsdUJBQWMsR0FBRSxDQUFDO0FBRWhDLE1BQU0sT0FBTztJQUFiO1FBQ2tCLFlBQU8sR0FBRyxPQUFPLENBQUM7UUFDbEIsYUFBUSxHQUFHLDhEQUE4RCxDQUFDO1FBQzFFLFlBQU8sR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRXpCLFlBQU8sR0FBRyxDQUFDLElBQWdCLEVBQUUsRUFBRSxDQUFDLElBQUk7YUFDakQsTUFBTSxDQUFDLEtBQUssRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLDhDQUE4QyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQzthQUN6SCxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsa0JBQWtCLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDO2FBQzNFLE1BQU0sQ0FB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QSxtQkFBWSxFQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUV0RyxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRTtRQUN0QixNQUFNLFVBQVUsR0FBRyxJQUFBLG1CQUFZLEVBQUMsR0FBRyxDQUFDLENBQUM7UUFDckMsTUFBTSxjQUFjLEdBQUcsTUFBTSxJQUFBLHdCQUFhLEVBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQW1DLENBQUM7UUFDdkcsTUFBTSxRQUFRLEdBQUcsY0FBYyxDQUFDLFdBQVcsQ0FBQztRQUU1QyxNQUFNLFFBQVEsR0FBRyxJQUFBLHFCQUFjLEVBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRW5ELEVBQUUsQ0FBQyxjQUFjLENBQUMsY0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLEdBQUcsUUFBUSxPQUFPLENBQUMsRUFBRSxRQUFRLENBQUMsQ0FBQztLQUM5RTtBQUNILENBQUM7QUFFRCxTQUFTLHlCQUF5QixDQUFDLFdBQW1CO0lBQ3BELE9BQU8sQ0FBQyxXQUFXLEtBQUssd0JBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsNEJBQW1CLENBQUMsRUFBRSxDQUFBLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDcEYsQ0FBQztBQUVELE1BQU0sQ0FBQyxPQUFPLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIG9zIGZyb20gJ29zJztcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0ICogYXMgc2VtdmVyIGZyb20gJ3NlbXZlcic7XG5pbXBvcnQgeyBzc2NhZmYgfSBmcm9tICdzc2NhZmYnO1xuaW1wb3J0ICogYXMgeWFtbCBmcm9tICd5YW1sJztcbmltcG9ydCAqIGFzIHlhcmdzIGZyb20gJ3lhcmdzJztcbmltcG9ydCB7IEhlbG1DaGFydEFwaVZlcnNpb24sIFN5bnRoZXNpc0Zvcm1hdCwgVmFsaWRhdGlvbkNvbmZpZywgcmVhZENvbmZpZ1N5bmMgfSBmcm9tICcuLi8uLi9jb25maWcnO1xuaW1wb3J0IHsgSW1wb3J0Q3VzdG9tUmVzb3VyY2VEZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vaW1wb3J0L2NyZCc7XG5pbXBvcnQgeyBtYXRjaEltcG9ydGVyIH0gZnJvbSAnLi4vLi4vaW1wb3J0L2Rpc3BhdGNoJztcbmltcG9ydCB7IFBsdWdpbk1hbmFnZXIgfSBmcm9tICcuLi8uLi9wbHVnaW5zL19tYW5hZ2VyJztcbmltcG9ydCB7IFN5bnRoZXNpemVkQXBwLCBjcmRzQXJlUHJlc2VudCwgZGVyaXZlRmlsZU5hbWUsIGRvd25sb2FkLCBpc0hlbG1JbXBvcnQsIGlzSzhzSW1wb3J0LCBta2R0ZW1wLCBwYXJzZUltcG9ydHMsIHN5bnRoQXBwLCB2YWxpZGF0ZUFwcCB9IGZyb20gJy4uLy4uL3V0aWwnO1xuXG5jb25zdCBDSEFSVF9ZQU1MX0ZJTEUgPSAnQ2hhcnQueWFtbCc7XG5jb25zdCBSRUFETUUgPSAnUkVBRE1FLm1kJztcbmNvbnN0IERFRkFVTFRfT1VUUFVUX0RJUiA9ICdkaXN0JztcbmNvbnN0IERFRkFVTFRfUExVR0lOU19ESVIgPSBwYXRoLmpvaW4ob3MuaG9tZWRpcigpLCAnLmNkazhzJywgJ3BsdWdpbnMnKTtcblxuY29uc3QgY29uZmlnID0gcmVhZENvbmZpZ1N5bmMoKTtcblxuY2xhc3MgQ29tbWFuZCBpbXBsZW1lbnRzIHlhcmdzLkNvbW1hbmRNb2R1bGUge1xuICBwdWJsaWMgcmVhZG9ubHkgY29tbWFuZCA9ICdzeW50aCc7XG4gIHB1YmxpYyByZWFkb25seSBkZXNjcmliZSA9ICdTeW50aGVzaXplcyBLdWJlcm5ldGVzIG1hbmlmZXN0cyBmb3IgYWxsIGNoYXJ0cyBpbiB5b3VyIGFwcC4nO1xuICBwdWJsaWMgcmVhZG9ubHkgYWxpYXNlcyA9IFsnc3ludGhlc2l6ZSddO1xuXG4gIHB1YmxpYyByZWFkb25seSBidWlsZGVyID0gKGFyZ3M6IHlhcmdzLkFyZ3YpID0+IGFyZ3NcbiAgICAub3B0aW9uKCdhcHAnLCB7IHJlcXVpcmVkOiB0cnVlLCBkZWZhdWx0OiBjb25maWc/LmFwcCwgZGVzYzogJ0NvbW1hbmQgdG8gdXNlIGluIG9yZGVyIHRvIGV4ZWN1dGUgY2RrOHMgYXBwJywgYWxpYXM6ICdhJyB9KVxuICAgIC5vcHRpb24oJ291dHB1dCcsIHsgcmVxdWlyZWQ6IGZhbHNlLCBkZXNjOiAnT3V0cHV0IGRpcmVjdG9yeScsIGFsaWFzOiAnbycgfSlcbiAgICAub3B0aW9uKCdzdGRvdXQnLCB7IHR5cGU6ICdib29sZWFuJywgcmVxdWlyZWQ6IGZhbHNlLCBkZXNjOiAnV3JpdGUgc3ludGhlc2l6ZWQgbWFuaWZlc3RzIHRvIFNURE9VVCBpbnN0ZWFkIG9mIHRoZSBvdXRwdXQgZGlyZWN0b3J5JywgYWxpYXM6ICdwJyB9KVxuICAgIC5vcHRpb24oJ3BsdWdpbnMtZGlyJywgeyByZXF1aXJlZDogZmFsc2UsIGRlc2M6ICdEaXJlY3RvcnkgdG8gc3RvcmUgY2RrOHMgcGx1Z2lucy4nIH0pXG4gICAgLm9wdGlvbigndmFsaWRhdGUnLCB7IHR5cGU6ICdib29sZWFuJywgcmVxdWlyZWQ6IGZhbHNlLCBkZXNjOiAnQXBwbHkgdmFsaWRhdGlvbiBwbHVnaW5zIG9uIHRoZSByZXN1bHRpbmcgbWFuaWZlc3RzICh1c2UgLS1uby12YWxpZGF0ZSB0byBkaXNhYmxlKScgfSlcbiAgICAub3B0aW9uKCd2YWxpZGF0aW9uLXJlcG9ydHMtb3V0cHV0LWZpbGUnLCB7IHJlcXVpcmVkOiBmYWxzZSwgZGVzYzogJ0ZpbGUgdG8gd3JpdGUgYSBKU09OIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB2YWxpZGF0aW9uIHJlcG9ydHMgdG8nIH0pXG4gICAgLm9wdGlvbignZm9ybWF0JywgeyByZXF1aXJlZDogZmFsc2UsIGRlc2M6ICdTeW50aGVzaXMgZm9ybWF0IGZvciBLdWJlcm5ldGVzIG1hbmlmZXN0cy4gVGhlIGRlZmF1bHQgc3ludGhlc2lzIGZvcm1hdCBpcyBwbGFpbiBrdWJlcm5ldGVzIG1hbmlmZXN0cy4nLCB0eXBlOiAnc3RyaW5nJyB9KVxuICAgIC5vcHRpb24oJ2NoYXJ0LWFwaS12ZXJzaW9uJywgeyByZXF1aXJlZDogZmFsc2UsIGRlc2M6ICdDaGFydCBBUEkgdmVyc2lvbiBvZiBoZWxtIGNoYXJ0LiBUaGUgZGVmYXVsdCB2YWx1ZSB3b3VsZCBiZSBcXCd2MlxcJyBhcGkgdmVyc2lvbiB3aGVuIHN5bnRoZXNpcyBmb3JtYXQgaXMgaGVsbS4gVGhlcmUgaXMgbm8gZGVmYXVsdCBzZXQgd2hlbiBzeW50aGVzaXMgZm9ybWF0IGlzIHBsYWluLicsIHR5cGU6ICdzdHJpbmcnIH0pXG4gICAgLm9wdGlvbignY2hhcnQtdmVyc2lvbicsIHsgcmVxdWlyZWQ6IGZhbHNlLCBkZXNjOiAnQ2hhcnQgdmVyc2lvbiBvZiBoZWxtIGNoYXJ0LiBUaGlzIGlzIHJlcXVpcmVkIGlmIHN5bnRoZXNpcyBmb3JtYXQgaXMgaGVsbS4nIH0pO1xuXG4gIHB1YmxpYyBhc3luYyBoYW5kbGVyKGFyZ3Y6IGFueSkge1xuXG4gICAgY29uc3QgY29tbWFuZCA9IGFyZ3YuYXBwO1xuICAgIGNvbnN0IHN0ZG91dCA9IGFyZ3Yuc3Rkb3V0O1xuICAgIGNvbnN0IG91dGRpciA9IGFyZ3Yub3V0cHV0ID8/IGNvbmZpZz8ub3V0cHV0ID8/ICghc3Rkb3V0ID8gREVGQVVMVF9PVVRQVVRfRElSIDogdW5kZWZpbmVkKTtcbiAgICBjb25zdCB2YWxpZGF0ZSA9IGFyZ3YudmFsaWRhdGUgPz8gdHJ1ZTtcbiAgICBjb25zdCByZXBvcnRGaWxlID0gYXJndi52YWxpZGF0aW9uUmVwb3J0c091dHB1dEZpbGU7XG4gICAgY29uc3QgcGx1Z2luc0RpciA9IGFyZ3YucGx1Z2luc0RpciA/PyBjb25maWc/LnBsdWdpbnNEaXJlY3RvcnkgPz8gREVGQVVMVF9QTFVHSU5TX0RJUjtcbiAgICBjb25zdCBmb3JtYXQgPSBhcmd2LmZvcm1hdCA/PyBjb25maWc/LnN5bnRoQ29uZmlnPy5mb3JtYXQgPz8gU3ludGhlc2lzRm9ybWF0LlBMQUlOO1xuICAgIGNvbnN0IGNoYXJ0VmVyc2lvbiA9IGFyZ3YuY2hhcnRWZXJzaW9uID8/IGNvbmZpZz8uc3ludGhDb25maWc/LmNoYXJ0VmVyc2lvbjtcbiAgICBjb25zdCBjaGFydEFwaVZlcnNpb24gPSBhcmd2LmNoYXJ0QXBpVmVyc2lvbiA/PyBjb25maWc/LnN5bnRoQ29uZmlnPy5jaGFydEFwaVZlcnNpb24gPz8gZ2V0RGVmYXVsdENoYXJ0QXBpVmVyc2lvbihmb3JtYXQpO1xuXG4gICAgaWYgKG91dGRpciAmJiBvdXRkaXIgIT09IGNvbmZpZz8ub3V0cHV0ICYmIHN0ZG91dCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdcXCctLW91dHB1dFxcJyBhbmQgXFwnLS1zdGRvdXRcXCcgYXJlIG11dHVhbGx5IGV4Y2x1c2l2ZS4gUGxlYXNlIG9ubHkgdXNlIG9uZS4nKTtcbiAgICB9XG5cbiAgICBpZiAob3V0ZGlyKSB7XG4gICAgICBmcy5ybVN5bmMob3V0ZGlyLCB7IHJlY3Vyc2l2ZTogdHJ1ZSwgZm9yY2U6IHRydWUgfSk7XG4gICAgfVxuXG4gICAgaWYgKGZvcm1hdCAhPSBTeW50aGVzaXNGb3JtYXQuUExBSU4gJiYgZm9ybWF0ICE9IFN5bnRoZXNpc0Zvcm1hdC5IRUxNKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFlvdSBuZWVkIHRvIHNwZWNpZnkgc3ludGhlc2lzIGZvcm1hdCBlaXRoZXIgYXMgJHtTeW50aGVzaXNGb3JtYXQuUExBSU59IG9yICR7U3ludGhlc2lzRm9ybWF0LkhFTE19IGJ1dCByZWNlaXZlZDogJHtmb3JtYXR9YCk7XG4gICAgfVxuXG4gICAgaWYgKGNoYXJ0QXBpVmVyc2lvbiAmJiAoY2hhcnRBcGlWZXJzaW9uICE9IEhlbG1DaGFydEFwaVZlcnNpb24uVjEgJiYgY2hhcnRBcGlWZXJzaW9uICE9IEhlbG1DaGFydEFwaVZlcnNpb24uVjIpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFlvdSBuZWVkIHRvIHNwZWNpZnkgaGVsbSBjaGFydCBhcGkgdmVyc2lvbiBlaXRoZXIgYXMgJHtIZWxtQ2hhcnRBcGlWZXJzaW9uLlYxfSBvciAke0hlbG1DaGFydEFwaVZlcnNpb24uVjJ9IGJ1dCByZWNlaXZlZDogJHtjaGFydEFwaVZlcnNpb259YCk7XG4gICAgfVxuXG4gICAgaWYgKGZvcm1hdCA9PT0gU3ludGhlc2lzRm9ybWF0LkhFTE0gJiYgIWNoYXJ0VmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgbmVlZCB0byBzcGVjaWZ5IFxcJy0tY2hhcnQtdmVyc2lvblxcJyB3aGVuIFxcJy0tZm9ybWF0XFwnIGlzIHNldCBhcyBcXCdoZWxtXFwnLicpO1xuICAgIH1cblxuICAgIGlmIChjaGFydFZlcnNpb24gJiYgIXNlbXZlci52YWxpZChjaGFydFZlcnNpb24pKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFRoZSB2YWx1ZSBzcGVjaWZpZWQgZm9yICctLWNoYXJ0LXZlcnNpb24nOiAke2NoYXJ0VmVyc2lvbn0gZG9lcyBub3QgZm9sbG93IFNlbVZlci0yKGh0dHBzOi8vc2VtdmVyLm9yZy8pLmApO1xuICAgIH1cblxuICAgIGlmIChzdGRvdXQgJiYgZm9ybWF0ID09PSBTeW50aGVzaXNGb3JtYXQuSEVMTSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdIZWxtIGZvcm1hdCBzeW50aGVzaXMgZG9lcyBub3Qgc3VwcG9ydCBcXCdzdGRvdXRcXCcuIFBsZWFzZSB1c2UgXFwnb3V0ZGlyXFwnIGluc3RlYWQuJyk7XG4gICAgfVxuXG4gICAgaWYgKGZvcm1hdCA9PT0gU3ludGhlc2lzRm9ybWF0LlBMQUlOICYmIGNoYXJ0QXBpVmVyc2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdZb3UgbmVlZCB0byBzcGVjaWZ5IFxcJy0tZm9ybWF0XFwnIGFzIFxcJ2hlbG1cXCcgd2hlbiBcXCctLWNoYXJ0LWFwaS12ZXJzaW9uXFwnIGlzIHNldC4nKTtcbiAgICB9XG5cbiAgICBpZiAoZm9ybWF0ID09PSBTeW50aGVzaXNGb3JtYXQuUExBSU4gJiYgY2hhcnRWZXJzaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1lvdSBuZWVkIHRvIHNwZWNpZnkgXFwnLS1mb3JtYXRcXCcgYXMgXFwnaGVsbVxcJyB3aGVuIFxcJy0tY2hhcnQtdmVyc2lvblxcJyBpcyBzZXQuJyk7XG4gICAgfVxuXG4gICAgaWYgKGNoYXJ0QXBpVmVyc2lvbiA9PT0gSGVsbUNoYXJ0QXBpVmVyc2lvbi5WMSAmJiBjcmRzQXJlUHJlc2VudChjb25maWc/LmltcG9ydHMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFlvdXIgYXBwbGljYXRpb24gdXNlcyBDUkRzLCB3aGljaCBhcmUgbm90IHN1cHBvcnRlZCB3aGVuICctLWNoYXJ0LWFwaS12ZXJzaW9uJyBpcyBzZXQgdG8gJHtIZWxtQ2hhcnRBcGlWZXJzaW9uLlYxfS4gUGxlYXNlIGVpdGhlciBzZXQgJy0tY2hhcnQtYXBpLXZlcnNpb24nIHRvICR7SGVsbUNoYXJ0QXBpVmVyc2lvbi5WMn0sIG9yIHJlbW92ZSB0aGUgQ1JEcyBmcm9tIHlvdXIgY2RrOHMueWFtbCBjb25maWd1cmF0aW9uIGZpbGVgKTtcbiAgICB9XG5cbiAgICBjb25zdCB2YWxpZGF0aW9ucyA9IHZhbGlkYXRlID8gYXdhaXQgZmV0Y2hWYWxpZGF0aW9ucygpIDogdW5kZWZpbmVkO1xuICAgIGNvbnN0IHJlY29yZENvbnN0cnVjdE1ldGFkYXRhID0gISh2YWxpZGF0aW9ucyA9PSB1bmRlZmluZWQgfHwgdmFsaWRhdGlvbnMubGVuZ3RoID09IDApO1xuXG4gICAgaWYgKHN0ZG91dCkge1xuICAgICAgYXdhaXQgbWtkdGVtcChhc3luYyB0ZW1wRGlyID0+IHtcbiAgICAgICAgY29uc3QgYXBwID0gYXdhaXQgc3ludGhBcHAoY29tbWFuZCwgdGVtcERpciwgc3Rkb3V0LCByZWNvcmRDb25zdHJ1Y3RNZXRhZGF0YSk7XG4gICAgICAgIGZvciAoY29uc3QgZiBvZiBhcHAubWFuaWZlc3RzKSB7XG4gICAgICAgICAgZnMuY3JlYXRlUmVhZFN0cmVhbShmKS5waXBlKHByb2Nlc3Muc3Rkb3V0KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodmFsaWRhdGlvbnMpIHtcbiAgICAgICAgICBjb25zdCBwbHVnaW5NYW5hZ2VyID0gbmV3IFBsdWdpbk1hbmFnZXIocGx1Z2luc0Rpcik7XG4gICAgICAgICAgYXdhaXQgdmFsaWRhdGVBcHAoYXBwLCBzdGRvdXQsIHZhbGlkYXRpb25zLCBwbHVnaW5NYW5hZ2VyLCByZXBvcnRGaWxlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBtYW5pZmVzdHM6IFN5bnRoZXNpemVkQXBwO1xuXG4gICAgICBpZiAoZm9ybWF0ID09PSBTeW50aGVzaXNGb3JtYXQuSEVMTSkge1xuICAgICAgICBhd2FpdCBjcmVhdGVIZWxtU2NhZmZvbGRpbmcoY2hhcnRBcGlWZXJzaW9uLCBjaGFydFZlcnNpb24sIG91dGRpcik7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlRGlyID0gcGF0aC5qb2luKG91dGRpciwgJ3RlbXBsYXRlcycpO1xuXG4gICAgICAgIG1hbmlmZXN0cyA9IGF3YWl0IHN5bnRoQXBwKGNvbW1hbmQsIHRlbXBsYXRlRGlyLCBzdGRvdXQsIHJlY29yZENvbnN0cnVjdE1ldGFkYXRhKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG1hbmlmZXN0cyA9IGF3YWl0IHN5bnRoQXBwKGNvbW1hbmQsIG91dGRpciwgc3Rkb3V0LCByZWNvcmRDb25zdHJ1Y3RNZXRhZGF0YSk7XG4gICAgICB9XG5cbiAgICAgIGlmICh2YWxpZGF0aW9ucykge1xuICAgICAgICBjb25zdCBwbHVnaW5NYW5hZ2VyID0gbmV3IFBsdWdpbk1hbmFnZXIocGx1Z2luc0Rpcik7XG4gICAgICAgIGF3YWl0IHZhbGlkYXRlQXBwKG1hbmlmZXN0cywgc3Rkb3V0LCB2YWxpZGF0aW9ucywgcGx1Z2luTWFuYWdlciwgcmVwb3J0RmlsZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hWYWxpZGF0aW9ucygpOiBQcm9taXNlPFZhbGlkYXRpb25Db25maWdbXSB8IHVuZGVmaW5lZD4ge1xuICBpZiAodHlwZW9mKGNvbmZpZz8udmFsaWRhdGlvbnMpID09PSAnc3RyaW5nJykge1xuICAgIGNvbnN0IGNvbnRlbnQgPSBhd2FpdCBkb3dubG9hZChjb25maWcudmFsaWRhdGlvbnMpO1xuICAgIHJldHVybiB5YW1sLnBhcnNlKGNvbnRlbnQpIGFzIFZhbGlkYXRpb25Db25maWdbXTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gY29uZmlnPy52YWxpZGF0aW9ucztcbiAgfVxufVxuXG5hc3luYyBmdW5jdGlvbiBjcmVhdGVIZWxtU2NhZmZvbGRpbmcoYXBpVmVyc2lvbjogc3RyaW5nLCBjaGFydFZlcnNpb246IHN0cmluZywgb3V0ZGlyOiBzdHJpbmcpIHtcbiAgY29uc3QgdGVtcEhlbG1TdHJ1Y3R1cmUgPSBjcmVhdGVGb2xkZXJTdHJ1Y3R1cmUoKTtcblxuICBjb25zdCBzdWJzdGl0dXRlVmFsdWVzID0ge1xuICAgIGFwaVZlcnNpb246IGFwaVZlcnNpb24sXG4gICAgdmVyc2lvbjogY2hhcnRWZXJzaW9uLFxuICAgIGFwcDogcGF0aC5iYXNlbmFtZShwYXRoLnJlc29sdmUoKSksXG4gIH07XG5cbiAgdHJ5IHtcbiAgICBhd2FpdCBzc2NhZmYodGVtcEhlbG1TdHJ1Y3R1cmUsIG91dGRpciwgc3Vic3RpdHV0ZVZhbHVlcyk7XG4gIH0gZmluYWxseSB7XG4gICAgZnMucm1TeW5jKHRlbXBIZWxtU3RydWN0dXJlLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgfVxuXG5cbiAgaWYgKGFwaVZlcnNpb24gPT09IEhlbG1DaGFydEFwaVZlcnNpb24uVjIgJiYgY3Jkc0FyZVByZXNlbnQoY29uZmlnPy5pbXBvcnRzKSkge1xuICAgIGF3YWl0IGFkZENyZHNUb0hlbG1DaGFydChvdXRkaXIpO1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlRm9sZGVyU3RydWN0dXJlKCk6IHN0cmluZyB7XG4gICAgY29uc3Qgcm9vdCA9IGZzLm1rZHRlbXBTeW5jKHBhdGguam9pbihvcy50bXBkaXIoKSwgJ2hlbG0tc2NhZmZvbGRpbmctJykpO1xuXG4gICAgZnMubWtkaXJTeW5jKHBhdGguam9pbihyb290LCAndGVtcGxhdGVzJykpO1xuXG4gICAgY29uc3QgY2hhcnRZYW1sRmlsZSA9IHtcbiAgICAgIGFwaVZlcnNpb246ICd7eyBhcGlWZXJzaW9uIH19JyxcbiAgICAgIG5hbWU6ICd7eyBhcHAgfX0nLFxuICAgICAgdmVyc2lvbjogJ3t7IHZlcnNpb24gfX0nLFxuICAgICAgZGVzY3JpcHRpb246ICdHZW5lcmF0ZWQgY2hhcnQgZm9yIHt7IGFwcCB9fScsXG4gICAgICB0eXBlOiAnYXBwbGljYXRpb24nLFxuICAgIH07XG5cbiAgICBmcy5vdXRwdXRGaWxlU3luYyhwYXRoLmpvaW4ocm9vdCwgQ0hBUlRfWUFNTF9GSUxFKSwgeWFtbC5zdHJpbmdpZnkoY2hhcnRZYW1sRmlsZSkpO1xuXG4gICAgY29uc3QgcmVhZG1lRmlsZSA9ICdUaGlzIEhlbG0gY2hhcnQgaXMgZ2VuZXJhdGVkIHVzaW5nIGNkazhzLiBBbnkgbWFudWFsIGNoYW5nZXMgdG8gdGhlIGNoYXJ0IHdvdWxkIGJlIGRpc2NhcmRlZCBvbmNlIGNkazhzIGFwcCBpcyBzeW50aGVzaXplZCBhZ2FpbiB3aXRoIGAtLWZvcm1hdCBoZWxtYC4nO1xuXG4gICAgZnMub3V0cHV0RmlsZVN5bmMocGF0aC5qb2luKHJvb3QsIFJFQURNRSksIHJlYWRtZUZpbGUpO1xuXG4gICAgcmV0dXJuIHJvb3Q7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gYWRkQ3Jkc1RvSGVsbUNoYXJ0KGNoYXJ0RGlyOiBzdHJpbmcpIHtcbiAgY29uc3QgY3JkcyA9IChjb25maWc/LmltcG9ydHMgPz8gW10pLmZpbHRlcigoaW1wcnQpID0+ICghaXNLOHNJbXBvcnQoaW1wcnQpICYmICFpc0hlbG1JbXBvcnQoaW1wcnQpKSk7XG5cbiAgZm9yIChjb25zdCBjcmQgb2YgY3Jkcykge1xuICAgIGNvbnN0IGltcG9ydFNwZWMgPSBwYXJzZUltcG9ydHMoY3JkKTtcbiAgICBjb25zdCBpbXBvcnRlZENyZERlZiA9IGF3YWl0IG1hdGNoSW1wb3J0ZXIoaW1wb3J0U3BlYywgcHJvY2Vzcy5hcmd2KSBhcyBJbXBvcnRDdXN0b21SZXNvdXJjZURlZmluaXRpb247XG4gICAgY29uc3QgbWFuaWZlc3QgPSBpbXBvcnRlZENyZERlZi5yYXdNYW5pZmVzdDtcblxuICAgIGNvbnN0IGZpbGVuYW1lID0gZGVyaXZlRmlsZU5hbWUoaW1wb3J0U3BlYy5zb3VyY2UpO1xuXG4gICAgZnMub3V0cHV0RmlsZVN5bmMocGF0aC5qb2luKGNoYXJ0RGlyLCAnY3JkcycsIGAke2ZpbGVuYW1lfS55YW1sYCksIG1hbmlmZXN0KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXREZWZhdWx0Q2hhcnRBcGlWZXJzaW9uKHN5bnRoRm9ybWF0OiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gKHN5bnRoRm9ybWF0ID09PSBTeW50aGVzaXNGb3JtYXQuSEVMTSkgPyBIZWxtQ2hhcnRBcGlWZXJzaW9uLlYyOiB1bmRlZmluZWQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gbmV3IENvbW1hbmQoKTsiXX0=