@decaf-ts/fabric-weaver
Version:
template for ts projects
220 lines • 25.1 kB
JavaScript
;
/**
* @module fabric-cli
* @description Command-line interface for Fabric setup and update operations
* @summary This module provides a CLI for managing Hyperledger Fabric installations.
* It exposes commands for updating the Fabric install script and setting up Fabric
* components. The module uses the Commander.js library to parse command-line
* arguments and execute the appropriate actions.
*
* Key exports:
* - {@link updateFabric}: Function to update the Fabric install script
* - {@link setupFabric}: Function to set up Fabric components
*
* @example
* // Update Fabric install script
* node fabric.js update
*
* // Setup Fabric components
* node fabric.js setup --fabric-version 2.5.12 --ca-version 1.5.15 --components binary docker
*
* @mermaid
* sequenceDiagram
* participant User
* participant CLI
* participant UpdateFabric
* participant SetupFabric
* User->>CLI: Run command
* CLI->>CLI: Parse arguments
* alt update command
* CLI->>UpdateFabric: Call updateFabric()
* UpdateFabric->>UpdateFabric: Download install script
* UpdateFabric->>UpdateFabric: Make script executable
* else setup command
* CLI->>SetupFabric: Call setupFabric(config)
* SetupFabric->>SetupFabric: Install components
* end
* CLI->>User: Display result
*/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const axios_1 = __importDefault(require("axios"));
const child_process_1 = require("child_process");
const commander_1 = require("commander");
const index_1 = require("../index.cjs");
const INSTALL_SCRIPT = path_1.default.join(__dirname, "..", "bin", "install-fabric.sh");
// Default configuration
const defaultConfig = {
fabricVersion: "2.5.12",
caVersion: "1.5.15",
components: ["binary"],
};
const program = new commander_1.Command();
program.version(index_1.VERSION).description("Fabric setup and update utility");
program
.command("update")
.description("Update the Fabric install script")
.action(async () => {
await updateFabric();
});
program
.command("setup")
.description("Set up Fabric components")
.option("-f, --fabric-version <version>", "Fabric version", defaultConfig.fabricVersion)
.option("-c, --ca-version <version>", "Fabric CA version", defaultConfig.caVersion)
.option("--components <components...>", "Components to install (binary, docker, podman, samples)", index_1.safeParseCSV, defaultConfig.components)
.action(async (options) => {
const config = {
fabricVersion: options.fabricVersion || defaultConfig.fabricVersion,
caVersion: options.caVersion || defaultConfig.caVersion,
components: options.components || defaultConfig.components,
};
await setupFabric(config);
});
program.parse(process.argv);
/**
* @function updateFabric
* @description Updates the Fabric install script by downloading the latest version
* @summary This function removes the existing install script (if present), downloads
* the latest version from the Hyperledger Fabric GitHub repository, and makes it executable.
* @returns {Promise<void>}
* @throws {Error} If the download fails or file operations encounter issues
* @memberOf module:fabric-cli
*
* @example
* await updateFabric();
*
* @mermaid
* sequenceDiagram
* participant Function
* participant FileSystem
* participant GitHub
* Function->>FileSystem: Check if script exists
* alt Script exists
* Function->>FileSystem: Remove existing script
* end
* Function->>GitHub: Download latest script
* GitHub-->>Function: Return script content
* Function->>FileSystem: Write new script
* Function->>FileSystem: Make script executable
*/
async function updateFabric() {
console.log("Executing update...");
const SCRIPT_URL = "https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh";
// Remove the existing file if it exists
if (fs_1.default.existsSync(INSTALL_SCRIPT)) {
console.log("Removing existing install-fabric.sh...");
fs_1.default.unlinkSync(INSTALL_SCRIPT);
}
// Download the new file
console.log("Downloading new install-fabric.sh...");
try {
const response = await axios_1.default.get(SCRIPT_URL, {
responseType: "arraybuffer",
});
fs_1.default.writeFileSync(INSTALL_SCRIPT, response.data);
console.log("Download successful.");
// Make the file executable
fs_1.default.chmodSync(INSTALL_SCRIPT, "755");
console.log("Made install-fabric.sh executable.");
}
catch (error) {
console.error("Error: Failed to download the file.");
console.error(error);
process.exit(1);
}
}
/**
* @function setupFabric
* @description Sets up Fabric components based on the provided configuration
* @summary This function installs the specified Fabric components using the
* install-fabric.sh script. It iterates through the components list and executes
* the script for each component with the specified Fabric and CA versions.
* After installation, it copies configuration files to the root config folder.
* @param {Object} config - Configuration object for Fabric setup
* @param {string} config.fabricVersion - Fabric version to install
* @param {string} config.caVersion - Fabric CA version to install
* @param {string[]} config.components - List of components to install
* @returns {Promise<void>}
* @throws {Error} If the install script is not found, component installation fails, or file copying fails
* @memberOf module:fabric-cli
*
* @example
* const config = {
* fabricVersion: "2.5.12",
* caVersion: "1.5.15",
* components: ["binary", "docker"]
* };
* await setupFabric(config);
*
* @mermaid
* sequenceDiagram
* participant Function
* participant FileSystem
* participant InstallScript
* Function->>FileSystem: Check if install script exists
* alt Script not found
* Function->>Function: Log error and exit
* else Script found
* loop For each component
* Function->>InstallScript: Execute install script
* InstallScript-->>Function: Installation result
* alt Installation failed
* Function->>Function: Log error and exit
* end
* end
* Function->>FileSystem: Copy config files
* alt Copy failed
* Function->>Function: Log error
* end
* end
* Function->>Function: Log success message
*/
async function setupFabric(config) {
console.log("Executing setup...");
if (fs_1.default.existsSync(INSTALL_SCRIPT)) {
console.log("Executing install-fabric.sh...");
for (const component of config.components) {
console.log(`Installing component: ${component}`);
try {
(0, child_process_1.execSync)(`bash "${INSTALL_SCRIPT}" "${component}" -f "${config.fabricVersion}" -c "${config.caVersion}"`, { stdio: "inherit" });
}
catch (error) {
console.error(`Error installing component: ${component}`);
console.error(error);
process.exit(1);
}
}
try {
const srcConfigDir = path_1.default.join(__dirname, "..", "src", "configs");
const destConfigDir = path_1.default.join(__dirname, "..", "config");
// Create the destination directory if it doesn't exist
if (!fs_1.default.existsSync(destConfigDir)) {
fs_1.default.mkdirSync(destConfigDir, { recursive: true });
}
// Copy files from src/configs to rootDir/config
fs_1.default.readdirSync(srcConfigDir).forEach((file) => {
const srcPath = path_1.default.join(srcConfigDir, file);
const destPath = path_1.default.join(destConfigDir, file);
fs_1.default.copyFileSync(srcPath, destPath);
console.log(`Copied ${file} to ${destConfigDir}`);
});
console.log("Configuration files copied successfully.");
}
catch (error) {
console.error("Error copying configuration files:");
console.error(error);
}
console.log("All components installed successfully.");
}
else {
console.error("Error: install-fabric.sh not found. Please run the update command first.");
console.error(INSTALL_SCRIPT);
process.exit(1);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFicmljLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2Jpbi9mYWJyaWMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQ0c7Ozs7O0FBRUgsNENBQW9CO0FBQ3BCLGdEQUF3QjtBQUN4QixrREFBMEI7QUFDMUIsaURBQXlDO0FBQ3pDLHlDQUFvQztBQUNwQyxvQ0FBaUQ7QUFFakQsTUFBTSxjQUFjLEdBQUcsY0FBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO0FBRTlFLHdCQUF3QjtBQUN4QixNQUFNLGFBQWEsR0FBRztJQUNwQixhQUFhLEVBQUUsUUFBUTtJQUN2QixTQUFTLEVBQUUsUUFBUTtJQUNuQixVQUFVLEVBQUUsQ0FBQyxRQUFRLENBQUM7Q0FDdkIsQ0FBQztBQUVGLE1BQU0sT0FBTyxHQUFHLElBQUksbUJBQU8sRUFBRSxDQUFDO0FBRTlCLE9BQU8sQ0FBQyxPQUFPLENBQUMsZUFBTyxDQUFDLENBQUMsV0FBVyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFFeEUsT0FBTztLQUNKLE9BQU8sQ0FBQyxRQUFRLENBQUM7S0FDakIsV0FBVyxDQUFDLGtDQUFrQyxDQUFDO0tBQy9DLE1BQU0sQ0FBQyxLQUFLLElBQUksRUFBRTtJQUNqQixNQUFNLFlBQVksRUFBRSxDQUFDO0FBQ3ZCLENBQUMsQ0FBQyxDQUFDO0FBRUwsT0FBTztLQUNKLE9BQU8sQ0FBQyxPQUFPLENBQUM7S0FDaEIsV0FBVyxDQUFDLDBCQUEwQixDQUFDO0tBQ3ZDLE1BQU0sQ0FDTCxnQ0FBZ0MsRUFDaEMsZ0JBQWdCLEVBQ2hCLGFBQWEsQ0FBQyxhQUFhLENBQzVCO0tBQ0EsTUFBTSxDQUNMLDRCQUE0QixFQUM1QixtQkFBbUIsRUFDbkIsYUFBYSxDQUFDLFNBQVMsQ0FDeEI7S0FDQSxNQUFNLENBQ0wsOEJB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RCxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3ZCLENBQUM7UUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLHdDQUF3QyxDQUFDLENBQUM7SUFDeEQsQ0FBQztTQUFNLENBQUM7UUFDTixPQUFPLENBQUMsS0FBSyxDQUNYLDBFQUEwRSxDQUMzRSxDQUFDO1FBQ0YsT0FBTyxDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUM5QixPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ2xCLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbW9kdWxlIGZhYnJpYy1jbGlcbiAqIEBkZXNjcmlwdGlvbiBDb21tYW5kLWxpbmUgaW50ZXJmYWNlIGZvciBGYWJyaWMgc2V0dXAgYW5kIHVwZGF0ZSBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBUaGlzIG1vZHVsZSBwcm92aWRlcyBhIENMSSBmb3IgbWFuYWdpbmcgSHlwZXJsZWRnZXIgRmFicmljIGluc3RhbGxhdGlvbnMuXG4gKiBJdCBleHBvc2VzIGNvbW1hbmRzIGZvciB1cGRhdGluZyB0aGUgRmFicmljIGluc3RhbGwgc2NyaXB0IGFuZCBzZXR0aW5nIHVwIEZhYnJpY1xuICogY29tcG9uZW50cy4gVGhlIG1vZHVsZSB1c2VzIHRoZSBDb21tYW5kZXIuanMgbGlicmFyeSB0byBwYXJzZSBjb21tYW5kLWxpbmVcbiAqIGFyZ3VtZW50cyBhbmQgZXhlY3V0ZSB0aGUgYXBwcm9wcmlhdGUgYWN0aW9ucy5cbiAqXG4gKiBLZXkgZXhwb3J0czpcbiAqIC0ge0BsaW5rIHVwZGF0ZUZhYnJpY306IEZ1bmN0aW9uIHRvIHVwZGF0ZSB0aGUgRmFicmljIGluc3RhbGwgc2NyaXB0XG4gKiAtIHtAbGluayBzZXR1cEZhYnJpY306IEZ1bmN0aW9uIHRvIHNldCB1cCBGYWJyaWMgY29tcG9uZW50c1xuICpcbiAqIEBleGFtcGxlXG4gKiAvLyBVcGRhdGUgRmFicmljIGluc3RhbGwgc2NyaXB0XG4gKiBub2RlIGZhYnJpYy5qcyB1cGRhdGVcbiAqXG4gKiAvLyBTZXR1cCBGYWJyaWMgY29tcG9uZW50c1xuICogbm9kZSBmYWJyaWMuanMgc2V0dXAgLS1mYWJyaWMtdmVyc2lvbiAyLjUuMTIgLS1jYS12ZXJzaW9uIDEuNS4xNSAtLWNvbXBvbmVudHMgYmluYXJ5IGRvY2tlclxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgVXNlclxuICogICBwYXJ0aWNpcGFudCBDTElcbiAqICAgcGFydGljaXBhbnQgVXBkYXRlRmFicmljXG4gKiAgIHBhcnRpY2lwYW50IFNldHVwRmFicmljXG4gKiAgIFVzZXItPj5DTEk6IFJ1biBjb21tYW5kXG4gKiAgIENMSS0+PkNMSTogUGFyc2UgYXJndW1lbnRzXG4gKiAgIGFsdCB1cGRhdGUgY29tbWFuZFxuICogICAgIENMSS0+PlVwZGF0ZUZhYnJpYzogQ2FsbCB1cGRhdGVGYWJyaWMoKVxuICogICAgIFVwZGF0ZUZhYnJpYy0+PlVwZGF0ZUZhYnJpYzogRG93bmxvYWQgaW5zdGFsbCBzY3JpcHRcbiAqICAgICBVcGRhdGVGYWJyaWMtPj5VcGRhdGVGYWJyaWM6IE1ha2Ugc2NyaXB0IGV4ZWN1dGFibGVcbiAqICAgZWxzZSBzZXR1cCBjb21tYW5kXG4gKiAgICAgQ0xJLT4+U2V0dXBGYWJyaWM6IENhbGwgc2V0dXBGYWJyaWMoY29uZmlnKVxuICogICAgIFNldHVwRmFicmljLT4+U2V0dXBGYWJyaWM6IEluc3RhbGwgY29tcG9uZW50c1xuICogICBlbmRcbiAqICAgQ0xJLT4+VXNlcjogRGlzcGxheSByZXN1bHRcbiAqL1xuXG5pbXBvcnQgZnMgZnJvbSBcImZzXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IGF4aW9zIGZyb20gXCJheGlvc1wiO1xuaW1wb3J0IHsgZXhlY1N5bmMgfSBmcm9tIFwiY2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgQ29tbWFuZCB9IGZyb20gXCJjb21tYW5kZXJcIjtcbmltcG9ydCB7IHNhZmVQYXJzZUNTViwgVkVSU0lPTiB9IGZyb20gXCIuLi9pbmRleFwiO1xuXG5jb25zdCBJTlNUQUxMX1NDUklQVCA9IHBhdGguam9pbihfX2Rpcm5hbWUsIFwiLi5cIiwgXCJiaW5cIiwgXCJpbnN0YWxsLWZhYnJpYy5zaFwiKTtcblxuLy8gRGVmYXVsdCBjb25maWd1cmF0aW9uXG5jb25zdCBkZWZhdWx0Q29uZmlnID0ge1xuICBmYWJyaWNWZXJzaW9uOiBcIjIuNS4xMlwiLFxuICBjYVZlcnNpb246IFwiMS41LjE1XCIsXG4gIGNvbXBvbmVudHM6IFtcImJpbmFyeVwiXSxcbn07XG5cbmNvbnN0IHByb2dyYW0gPSBuZXcgQ29tbWFuZCgpO1xuXG5wcm9ncmFtLnZlcnNpb24oVkVSU0lPTikuZGVzY3JpcHRpb24oXCJGYWJyaWMgc2V0dXAgYW5kIHVwZGF0ZSB1dGlsaXR5XCIpO1xuXG5wcm9ncmFtXG4gIC5jb21tYW5kKFwidXBkYXRlXCIpXG4gIC5kZXNjcmlwdGlvbihcIlVwZGF0ZSB0aGUgRmFicmljIGluc3RhbGwgc2NyaXB0XCIpXG4gIC5hY3Rpb24oYXN5bmMgKCkgPT4ge1xuICAgIGF3YWl0IHVwZGF0ZUZhYnJpYygpO1xuICB9KTtcblxucHJvZ3JhbVxuICAuY29tbWFuZChcInNldHVwXCIpXG4gIC5kZXNjcmlwdGlvbihcIlNldCB1cCBGYWJyaWMgY29tcG9uZW50c1wiKVxuICAub3B0aW9uKFxuICAgIFwiLWYsIC0tZmFicmljLXZlcnNpb24gPHZlcnNpb24+XCIsXG4gICAgXCJGYWJyaWMgdmVyc2lvblwiLFxuICAgIGRlZmF1bHRDb25maWcuZmFicmljVmVyc2lvblxuICApXG4gIC5vcHRpb24oXG4gICAgXCItYywgLS1jYS12ZXJzaW9uIDx2ZXJzaW9uPlwiLFxuICAgIFwiRmFicmljIENBIHZlcnNpb25cIixcbiAgICBkZWZhdWx0Q29uZmlnLmNhVmVyc2lvblxuICApXG4gIC5vcHRpb24oXG4gICAgXCItLWNvbXBvbmVudHMgPGNvbXBvbmVudHMuLi4+XCIsXG4gICAgXCJDb21wb25lbnRzIHRvIGluc3RhbGwgKGJpbmFyeSwgZG9ja2VyLCBwb2RtYW4sIHNhbXBsZXMpXCIsXG4gICAgc2FmZVBhcnNlQ1NWLFxuICAgIGRlZmF1bHRDb25maWcuY29tcG9uZW50c1xuICApXG4gIC5hY3Rpb24oYXN5bmMgKG9wdGlvbnMpID0+IHtcbiAgICBjb25zdCBjb25maWcgPSB7XG4gICAgICBmYWJyaWNWZXJzaW9uOiBvcHRpb25zLmZhYnJpY1ZlcnNpb24gfHwgZGVmYXVsdENvbmZpZy5mYWJyaWNWZXJzaW9uLFxuICAgICAgY2FWZXJzaW9uOiBvcHRpb25zLmNhVmVyc2lvbiB8fCBkZWZhdWx0Q29uZmlnLmNhVmVyc2lvbixcbiAgICAgIGNvbXBvbmVudHM6IG9wdGlvbnMuY29tcG9uZW50cyB8fCBkZWZhdWx0Q29uZmlnLmNvbXBvbmVudHMsXG4gICAgfTtcbiAgICBhd2FpdCBzZXR1cEZhYnJpYyhjb25maWcpO1xuICB9KTtcblxucHJvZ3JhbS5wYXJzZShwcm9jZXNzLmFyZ3YpO1xuXG4vKipcbiAqIEBmdW5jdGlvbiB1cGRhdGVGYWJyaWNcbiAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIHRoZSBGYWJyaWMgaW5zdGFsbCBzY3JpcHQgYnkgZG93bmxvYWRpbmcgdGhlIGxhdGVzdCB2ZXJzaW9uXG4gKiBAc3VtbWFyeSBUaGlzIGZ1bmN0aW9uIHJlbW92ZXMgdGhlIGV4aXN0aW5nIGluc3RhbGwgc2NyaXB0IChpZiBwcmVzZW50KSwgZG93bmxvYWRzXG4gKiB0aGUgbGF0ZXN0IHZlcnNpb24gZnJvbSB0aGUgSHlwZXJsZWRnZXIgRmFicmljIEdpdEh1YiByZXBvc2l0b3J5LCBhbmQgbWFrZXMgaXQgZXhlY3V0YWJsZS5cbiAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBkb3dubG9hZCBmYWlscyBvciBmaWxlIG9wZXJhdGlvbnMgZW5jb3VudGVyIGlzc3Vlc1xuICogQG1lbWJlck9mIG1vZHVsZTpmYWJyaWMtY2xpXG4gKlxuICogQGV4YW1wbGVcbiAqIGF3YWl0IHVwZGF0ZUZhYnJpYygpO1xuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgRnVuY3Rpb25cbiAqICAgcGFydGljaXBhbnQgRmlsZVN5c3RlbVxuICogICBwYXJ0aWNpcGFudCBHaXRIdWJcbiAqICAgRnVuY3Rpb24tPj5GaWxlU3lzdGVtOiBDaGVjayBpZiBzY3JpcHQgZXhpc3RzXG4gKiAgIGFsdCBTY3JpcHQgZXhpc3RzXG4gKiAgICAgRnVuY3Rpb24tPj5GaWxlU3lzdGVtOiBSZW1vdmUgZXhpc3Rpbmcgc2NyaXB0XG4gKiAgIGVuZFxuICogICBGdW5jdGlvbi0+PkdpdEh1YjogRG93bmxvYWQgbGF0ZXN0IHNjcmlwdFxuICogICBHaXRIdWItLT4+RnVuY3Rpb246IFJldHVybiBzY3JpcHQgY29udGVudFxuICogICBGdW5jdGlvbi0+PkZpbGVTeXN0ZW06IFdyaXRlIG5ldyBzY3JpcHRcbiAqICAgRnVuY3Rpb24tPj5GaWxlU3lzdGVtOiBNYWtlIHNjcmlwdCBleGVjdXRhYmxlXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZUZhYnJpYygpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc29sZS5sb2coXCJFeGVjdXRpbmcgdXBkYXRlLi4uXCIpO1xuICBjb25zdCBTQ1JJUFRfVVJMID1cbiAgICBcImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9oeXBlcmxlZGdlci9mYWJyaWMvbWFpbi9zY3JpcHRzL2luc3RhbGwtZmFicmljLnNoXCI7XG5cbiAgLy8gUmVtb3ZlIHRoZSBleGlzdGluZyBmaWxlIGlmIGl0IGV4aXN0c1xuICBpZiAoZnMuZXhpc3RzU3luYyhJTlNUQUxMX1NDUklQVCkpIHtcbiAgICBjb25zb2xlLmxvZyhcIlJlbW92aW5nIGV4aXN0aW5nIGluc3RhbGwtZmFicmljLnNoLi4uXCIpO1xuICAgIGZzLnVubGlua1N5bmMoSU5TVEFMTF9TQ1JJUFQpO1xuICB9XG5cbiAgLy8gRG93bmxvYWQgdGhlIG5ldyBmaWxlXG4gIGNvbnNvbGUubG9nKFwiRG93bmxvYWRpbmcgbmV3IGluc3RhbGwtZmFicmljLnNoLi4uXCIpO1xuICB0cnkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgYXhpb3MuZ2V0KFNDUklQVF9VUkwsIHtcbiAgICAgIHJlc3BvbnNlVHlwZTogXCJhcnJheWJ1ZmZlclwiLFxuICAgIH0pO1xuXG4gICAgZnMud3JpdGVGaWxlU3luYyhJTlNUQUxMX1NDUklQVCwgcmVzcG9uc2UuZGF0YSk7XG4gICAgY29uc29sZS5sb2coXCJEb3dubG9hZCBzdWNjZXNzZnVsLlwiKTtcblxuICAgIC8vIE1ha2UgdGhlIGZpbGUgZXhlY3V0YWJsZVxuICAgIGZzLmNobW9kU3luYyhJTlNUQUxMX1NDUklQVCwgXCI3NTVcIik7XG4gICAgY29uc29sZS5sb2coXCJNYWRlIGluc3RhbGwtZmFicmljLnNoIGV4ZWN1dGFibGUuXCIpO1xuICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvcjogRmFpbGVkIHRvIGRvd25sb2FkIHRoZSBmaWxlLlwiKTtcbiAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICBwcm9jZXNzLmV4aXQoMSk7XG4gIH1cbn1cblxuLyoqXG4gKiBAZnVuY3Rpb24gc2V0dXBGYWJyaWNcbiAqIEBkZXNjcmlwdGlvbiBTZXRzIHVwIEZhYnJpYyBjb21wb25lbnRzIGJhc2VkIG9uIHRoZSBwcm92aWRlZCBjb25maWd1cmF0aW9uXG4gKiBAc3VtbWFyeSBUaGlzIGZ1bmN0aW9uIGluc3RhbGxzIHRoZSBzcGVjaWZpZWQgRmFicmljIGNvbXBvbmVudHMgdXNpbmcgdGhlXG4gKiBpbnN0YWxsLWZhYnJpYy5zaCBzY3JpcHQuIEl0IGl0ZXJhdGVzIHRocm91Z2ggdGhlIGNvbXBvbmVudHMgbGlzdCBhbmQgZXhlY3V0ZXNcbiAqIHRoZSBzY3JpcHQgZm9yIGVhY2ggY29tcG9uZW50IHdpdGggdGhlIHNwZWNpZmllZCBGYWJyaWMgYW5kIENBIHZlcnNpb25zLlxuICogQWZ0ZXIgaW5zdGFsbGF0aW9uLCBpdCBjb3BpZXMgY29uZmlndXJhdGlvbiBmaWxlcyB0byB0aGUgcm9vdCBjb25maWcgZm9sZGVyLlxuICogQHBhcmFtIHtPYmplY3R9IGNvbmZpZyAtIENvbmZpZ3VyYXRpb24gb2JqZWN0IGZvciBGYWJyaWMgc2V0dXBcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb25maWcuZmFicmljVmVyc2lvbiAtIEZhYnJpYyB2ZXJzaW9uIHRvIGluc3RhbGxcbiAqIEBwYXJhbSB7c3RyaW5nfSBjb25maWcuY2FWZXJzaW9uIC0gRmFicmljIENBIHZlcnNpb24gdG8gaW5zdGFsbFxuICogQHBhcmFtIHtzdHJpbmdbXX0gY29uZmlnLmNvbXBvbmVudHMgLSBMaXN0IG9mIGNvbXBvbmVudHMgdG8gaW5zdGFsbFxuICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gKiBAdGhyb3dzIHtFcnJvcn0gSWYgdGhlIGluc3RhbGwgc2NyaXB0IGlzIG5vdCBmb3VuZCwgY29tcG9uZW50IGluc3RhbGxhdGlvbiBmYWlscywgb3IgZmlsZSBjb3B5aW5nIGZhaWxzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmZhYnJpYy1jbGlcbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgY29uZmlnID0ge1xuICogICBmYWJyaWNWZXJzaW9uOiBcIjIuNS4xMlwiLFxuICogICBjYVZlcnNpb246IFwiMS41LjE1XCIsXG4gKiAgIGNvbXBvbmVudHM6IFtcImJpbmFyeVwiLCBcImRvY2tlclwiXVxuICogfTtcbiAqIGF3YWl0IHNldHVwRmFicmljKGNvbmZpZyk7XG4gKlxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBGdW5jdGlvblxuICogICBwYXJ0aWNpcGFudCBGaWxlU3lzdGVtXG4gKiAgIHBhcnRpY2lwYW50IEluc3RhbGxTY3JpcHRcbiAqICAgRnVuY3Rpb24tPj5GaWxlU3lzdGVtOiBDaGVjayBpZiBpbnN0YWxsIHNjcmlwdCBleGlzdHNcbiAqICAgYWx0IFNjcmlwdCBub3QgZm91bmRcbiAqICAgICBGdW5jdGlvbi0+PkZ1bmN0aW9uOiBMb2cgZXJyb3IgYW5kIGV4aXRcbiAqICAgZWxzZSBTY3JpcHQgZm91bmRcbiAqICAgICBsb29wIEZvciBlYWNoIGNvbXBvbmVudFxuICogICAgICAgRnVuY3Rpb24tPj5JbnN0YWxsU2NyaXB0OiBFeGVjdXRlIGluc3RhbGwgc2NyaXB0XG4gKiAgICAgICBJbnN0YWxsU2NyaXB0LS0+PkZ1bmN0aW9uOiBJbnN0YWxsYXRpb24gcmVzdWx0XG4gKiAgICAgICBhbHQgSW5zdGFsbGF0aW9uIGZhaWxlZFxuICogICAgICAgICBGdW5jdGlvbi0+PkZ1bmN0aW9uOiBMb2cgZXJyb3IgYW5kIGV4aXRcbiAqICAgICAgIGVuZFxuICogICAgIGVuZFxuICogICAgIEZ1bmN0aW9uLT4+RmlsZVN5c3RlbTogQ29weSBjb25maWcgZmlsZXNcbiAqICAgICBhbHQgQ29weSBmYWlsZWRcbiAqICAgICAgIEZ1bmN0aW9uLT4+RnVuY3Rpb246IExvZyBlcnJvclxuICogICAgIGVuZFxuICogICBlbmRcbiAqICAgRnVuY3Rpb24tPj5GdW5jdGlvbjogTG9nIHN1Y2Nlc3MgbWVzc2FnZVxuICovXG5hc3luYyBmdW5jdGlvbiBzZXR1cEZhYnJpYyhjb25maWc6IHR5cGVvZiBkZWZhdWx0Q29uZmlnKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnNvbGUubG9nKFwiRXhlY3V0aW5nIHNldHVwLi4uXCIpO1xuICBpZiAoZnMuZXhpc3RzU3luYyhJTlNUQUxMX1NDUklQVCkpIHtcbiAgICBjb25zb2xlLmxvZyhcIkV4ZWN1dGluZyBpbnN0YWxsLWZhYnJpYy5zaC4uLlwiKTtcblxuICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIGNvbmZpZy5jb21wb25lbnRzKSB7XG4gICAgICBjb25zb2xlLmxvZyhgSW5zdGFsbGluZyBjb21wb25lbnQ6ICR7Y29tcG9uZW50fWApO1xuICAgICAgdHJ5IHtcbiAgICAgICAgZXhlY1N5bmMoXG4gICAgICAgICAgYGJhc2ggXCIke0lOU1RBTExfU0NSSVBUfVwiIFwiJHtjb21wb25lbnR9XCIgLWYgXCIke2NvbmZpZy5mYWJyaWNWZXJzaW9ufVwiIC1jIFwiJHtjb25maWcuY2FWZXJzaW9ufVwiYCxcbiAgICAgICAgICB7IHN0ZGlvOiBcImluaGVyaXRcIiB9XG4gICAgICAgICk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBFcnJvciBpbnN0YWxsaW5nIGNvbXBvbmVudDogJHtjb21wb25lbnR9YCk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHNyY0NvbmZpZ0RpciA9IHBhdGguam9pbihfX2Rpcm5hbWUsIFwiLi5cIiwgXCJzcmNcIiwgXCJjb25maWdzXCIpO1xuICAgICAgY29uc3QgZGVzdENvbmZpZ0RpciA9IHBhdGguam9pbihfX2Rpcm5hbWUsIFwiLi5cIiwgXCJjb25maWdcIik7XG5cbiAgICAgIC8vIENyZWF0ZSB0aGUgZGVzdGluYXRpb24gZGlyZWN0b3J5IGlmIGl0IGRvZXNuJ3QgZXhpc3RcbiAgICAgIGlmICghZnMuZXhpc3RzU3luYyhkZXN0Q29uZmlnRGlyKSkge1xuICAgICAgICBmcy5ta2RpclN5bmMoZGVzdENvbmZpZ0RpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIENvcHkgZmlsZXMgZnJvbSBzcmMvY29uZmlncyB0byByb290RGlyL2NvbmZpZ1xuICAgICAgZnMucmVhZGRpclN5bmMoc3JjQ29uZmlnRGlyKS5mb3JFYWNoKChmaWxlKSA9PiB7XG4gICAgICAgIGNvbnN0IHNyY1BhdGggPSBwYXRoLmpvaW4oc3JjQ29uZmlnRGlyLCBmaWxlKTtcbiAgICAgICAgY29uc3QgZGVzdFBhdGggPSBwYXRoLmpvaW4oZGVzdENvbmZpZ0RpciwgZmlsZSk7XG4gICAgICAgIGZzLmNvcHlGaWxlU3luYyhzcmNQYXRoLCBkZXN0UGF0aCk7XG4gICAgICAgIGNvbnNvbGUubG9nKGBDb3BpZWQgJHtmaWxlfSB0byAke2Rlc3RDb25maWdEaXJ9YCk7XG4gICAgICB9KTtcblxuICAgICAgY29uc29sZS5sb2coXCJDb25maWd1cmF0aW9uIGZpbGVzIGNvcGllZCBzdWNjZXNzZnVsbHkuXCIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgY29weWluZyBjb25maWd1cmF0aW9uIGZpbGVzOlwiKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKFwiQWxsIGNvbXBvbmVudHMgaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseS5cIik7XG4gIH0gZWxzZSB7XG4gICAgY29uc29sZS5lcnJvcihcbiAgICAgIFwiRXJyb3I6IGluc3RhbGwtZmFicmljLnNoIG5vdCBmb3VuZC4gUGxlYXNlIHJ1biB0aGUgdXBkYXRlIGNvbW1hbmQgZmlyc3QuXCJcbiAgICApO1xuICAgIGNvbnNvbGUuZXJyb3IoSU5TVEFMTF9TQ1JJUFQpO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxufVxuIl19