UNPKG

@crestron/ch5-shell-utilities-cli

Version:
487 lines (486 loc) 24 kB
"use strict"; // Copyright (C) 2021 to the present, Crestron Electronics, Inc. // All rights reserved. // No part of this software may be reproduced in any form, machine // or natural, without the express written consent of Crestron Electronics. // Use of this source code is subject to the terms of the Crestron Software License Agreement // under which you licensed this source code. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Ch5BaseClassForCli = void 0; var Ch5CliUtil_1 = require("./Ch5CliUtil"); var Ch5CliLogger_1 = require("./Ch5CliLogger"); var Ch5CliNamingHelper_1 = require("./Ch5CliNamingHelper"); var Ch5CliProjectConfig_1 = require("./Ch5CliProjectConfig"); var Ch5CliConfigFileReader_1 = require("./Ch5CliConfigFileReader"); var Ch5CliError_1 = require("./Ch5CliError"); var _a = require('enquirer'), Select = _a.Select, Confirm = _a.Confirm, prompt = _a.prompt; var Enquirer = require('enquirer'); var enquirer = new Enquirer(); var MultiSelect = require('enquirer').MultiSelect; var path = require('path'); var fs = require("fs"); var jsonSchema = require('jsonschema'); var child_process = require('child_process'); var Ch5BaseClassForCli = /** @class */ (function () { function Ch5BaseClassForCli(folderPath) { this._folderPath = ""; this._inputArguments = {}; this._folderPath = folderPath; this._cliUtil = new Ch5CliUtil_1.Ch5CliUtil(); this._cliNamingHelper = new Ch5CliNamingHelper_1.Ch5CliNamingHelper(); this._cliProjectConfig = new Ch5CliProjectConfig_1.Ch5CliProjectConfig(); this._cliConfigFileReader = new Ch5CliConfigFileReader_1.Ch5CliConfigFileReader(path.join(__dirname, this._folderPath, "files", "config.json"), JSON.parse(this._cliUtil.readFileContentSync(path.join(__dirname, "files", "environment.json")))); this.CONFIG_FILE = this._cliConfigFileReader.configFile; this._inputArguments = this.processArgs(); this._cliLogger = new Ch5CliLogger_1.Ch5CliLogger(this._inputArguments["verbose"]); this.TRANSLATION_FILE = JSON.parse(this.utils.readFileContentSync(path.join(__dirname, this._folderPath, "i18n", "en.json"))); } Object.defineProperty(Ch5BaseClassForCli.prototype, "getEnquirer", { get: function () { return enquirer; }, enumerable: false, configurable: true }); Object.defineProperty(Ch5BaseClassForCli.prototype, "getMultiSelect", { get: function () { return MultiSelect; }, enumerable: false, configurable: true }); Object.defineProperty(Ch5BaseClassForCli.prototype, "getPrompt", { get: function () { return prompt; }, enumerable: false, configurable: true }); Object.defineProperty(Ch5BaseClassForCli.prototype, "getSelect", { get: function () { return Select; }, enumerable: false, configurable: true }); Object.defineProperty(Ch5BaseClassForCli.prototype, "getConfirm", { get: function () { return Confirm; }, enumerable: false, configurable: true }); Object.defineProperty(Ch5BaseClassForCli.prototype, "inputArguments", { get: function () { return this._inputArguments; }, enumerable: false, configurable: true }); Object.defineProperty(Ch5BaseClassForCli.prototype, "utils", { get: function () { return this._cliUtil; }, enumerable: false, configurable: true }); Object.defineProperty(Ch5BaseClassForCli.prototype, "logger", { get: function () { return this._cliLogger; }, enumerable: false, configurable: true }); Object.defineProperty(Ch5BaseClassForCli.prototype, "configFileReader", { get: function () { return this._cliConfigFileReader; }, enumerable: false, configurable: true }); Object.defineProperty(Ch5BaseClassForCli.prototype, "configFile", { get: function () { return this._cliConfigFileReader.configFile; }, enumerable: false, configurable: true }); Object.defineProperty(Ch5BaseClassForCli.prototype, "configFileArgs", { get: function () { return this._cliConfigFileReader; }, enumerable: false, configurable: true }); Object.defineProperty(Ch5BaseClassForCli.prototype, "namingHelper", { get: function () { return this._cliNamingHelper; }, enumerable: false, configurable: true }); Object.defineProperty(Ch5BaseClassForCli.prototype, "projectConfig", { get: function () { return this._cliProjectConfig; }, enumerable: false, configurable: true }); Ch5BaseClassForCli.prototype.setInputArgsForTesting = function (args) { this._inputArguments = this.processArgsAnalyze(args); }; Ch5BaseClassForCli.prototype.processArgs = function () { var args = process.argv.slice(2); return this.processArgsAnalyze(args); }; Ch5BaseClassForCli.prototype.processArgsAnalyze = function (args) { var completeInputParams = this._cliConfigFileReader.configParamOptions(); var output = {}; var arrayKey = null; var arrayParam = null; var continueProcess = false; args.forEach(function (val, index, array) { if (String(val).indexOf('--') === 0 || String(val).indexOf('-') === 0) { var paramObj = completeInputParams.find(function (tempObj) { return tempObj.alias.map(function (v) { return v.toLowerCase(); }).includes(val.trim().toLowerCase()); }); if (paramObj) { arrayKey = paramObj.key; arrayParam = paramObj.type; if (arrayParam === "array") { output[arrayKey] = []; } else if (arrayParam === "boolean" || arrayParam === "string") { output[arrayKey] = paramObj.default; } continueProcess = true; } else { // Currently we don't do anything here. Some thoughts could be to push the data as a value similar to the // else statement below. Or we could nullify arrayKey and arrayParam. } } else { if (arrayKey != null) { if (arrayParam === "array") { output[arrayKey].push(val); } else if (arrayParam === "boolean" || arrayParam === "string") { if (continueProcess === true) { output[arrayKey] = val; continueProcess = false; } } } } }); for (var i = 0; i < completeInputParams.length; i++) { if (!output[completeInputParams[i]["key"]]) { output[completeInputParams[i]["key"]] = completeInputParams[i]["valueIfNotFound"]; } } return output; }; Ch5BaseClassForCli.prototype.changeConfigParam = function (key, value) { var attrs = key.split('.'); for (var i = 0; i < attrs.length - 1; i++) { this.CONFIG_FILE = this.CONFIG_FILE[attrs[i]]; } this.CONFIG_FILE[attrs[attrs.length - 1]] = value; }; Ch5BaseClassForCli.prototype.mergeJSON = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } var target = {}; // Merge the object into the target object //Loop through each object and conduct a merge for (var i = 0; i < args.length; i++) { target = this.merger(target, args[i]); } return target; }; Ch5BaseClassForCli.prototype.merger = function (target, obj) { for (var prop in obj) { // eslint-disable-next-line no-prototype-builtins if (obj.hasOwnProperty(prop)) { if (Object.prototype.toString.call(obj[prop]) === '[object Object]') { // If we're doing a deep merge and the property is an object target[prop] = this.mergeJSON(target[prop], obj[prop]); // target = merger(target, obj[prop]); } else { // Otherwise, do a regular merge target[prop] = obj[prop]; } } } return target; }; /** * * @param program */ Ch5BaseClassForCli.prototype.setupCommand = function (program) { return __awaiter(this, void 0, void 0, function () { var programObject, i, contentForHelp; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(this.CONFIG_FILE.allowedEnvironments.indexOf(String(this.CONFIG_FILE.settings.environment)) >= 0)) return [3 /*break*/, 3]; programObject = program .command(this.CONFIG_FILE.command) .name(this.CONFIG_FILE.name) .usage(this.CONFIG_FILE.usage) .description(this.CONFIG_FILE.description); for (i = 0; i < this.CONFIG_FILE.options.length; i++) { programObject = programObject.option(this.convertArrayToCommaSeparatedString(this.CONFIG_FILE.options[i].alias), this.CONFIG_FILE.options[i].description); } programObject = programObject.option("--verbose", "Get detailed output of the process. This is helpful incase any errors are found."); if (this.CONFIG_FILE.aliases && this.CONFIG_FILE.aliases.length > 0) { programObject = programObject.aliases(this.CONFIG_FILE.aliases); } if (!(this.CONFIG_FILE.additionalHelp === true)) return [3 /*break*/, 2]; return [4 /*yield*/, this.utils.readFileContent(path.join(__dirname, this._folderPath, "files", "help.txt"))]; case 1: contentForHelp = _a.sent(); programObject = programObject.addHelpText('after', contentForHelp); _a.label = 2; case 2: programObject.allowUnknownOption().action(function (options) { return __awaiter(_this, void 0, void 0, function () { var e_1; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4 /*yield*/, this.run()]; case 1: _a.sent(); return [3 /*break*/, 3]; case 2: e_1 = _a.sent(); this.utils.writeError(e_1); return [3 /*break*/, 3]; case 3: return [2 /*return*/]; } }); }); }); return [2 /*return*/, programObject]; case 3: return [2 /*return*/]; } }); }); }; Ch5BaseClassForCli.prototype.compareVersions = function (cliVersionInput, userVersionInput) { var cliVersion = cliVersionInput.split("."); var userVersion = userVersionInput.split("."); if (Number(userVersion[0]) > Number(cliVersion[0])) { return { version: "MAJOR", isShellCliVersionGreater: false }; } else if (Number(userVersion[0]) < Number(cliVersion[0])) { return { version: "MAJOR", isShellCliVersionGreater: true }; } else { if (Number(userVersion[1]) > Number(cliVersion[1])) { return { version: "MINOR", isShellCliVersionGreater: false }; } else if (Number(userVersion[1]) < Number(cliVersion[1])) { return { version: "MINOR", isShellCliVersionGreater: true }; } else { if (Number(userVersion[2]) > Number(cliVersion[2])) { return { version: "BUILD", isShellCliVersionGreater: false }; } else if (Number(userVersion[2]) < Number(cliVersion[2])) { return { version: "BUILD", isShellCliVersionGreater: true }; } } } return { version: "", isShellCliVersionGreater: false }; }; Ch5BaseClassForCli.prototype.checkVersionToExecute = function () { var nodeVersionInstalled = ""; var npmVersionInstalled = ""; try { nodeVersionInstalled = process.version; nodeVersionInstalled = nodeVersionInstalled.replace(/(\r\n|\n|\r)/gm, ""); nodeVersionInstalled = nodeVersionInstalled.replace("v", ""); this.logger.log("node Version: ", nodeVersionInstalled); var compareVersionOutputForNode = this.compareVersions(this.CONFIG_FILE.settings.minimumNodeVersion, nodeVersionInstalled); this.logger.log("compareVersionOutputForNode: ", compareVersionOutputForNode); if (compareVersionOutputForNode.version === "MAJOR") { if (compareVersionOutputForNode.isShellCliVersionGreater === true) { throw new Ch5CliError_1.Ch5CliError(this.getText("You seem to be using an older version of nodejs (" + nodeVersionInstalled + "). Please upgrade to " + this.CONFIG_FILE.settings.minimumNodeVersion + " version of nodejs.")); } else { this.logger.printWarning("You are currently using the node version " + nodeVersionInstalled + ". ch5-shell-cli has a minimum required node version of " + this.CONFIG_FILE.settings.minimumNodeVersion + "."); } } else if (compareVersionOutputForNode.version === "MINOR") { if (compareVersionOutputForNode.isShellCliVersionGreater === true) { throw new Ch5CliError_1.Ch5CliError(this.getText("You seem to be using an older version of nodejs (" + nodeVersionInstalled + "). Please upgrade to " + this.CONFIG_FILE.settings.minimumNodeVersion + " version of nodejs.")); } else { // warning not required on minor and build versions } } else if (compareVersionOutputForNode.version === "BUILD") { if (compareVersionOutputForNode.isShellCliVersionGreater === true) { throw new Ch5CliError_1.Ch5CliError(this.getText("You seem to be using an older version of nodejs (" + nodeVersionInstalled + "). Please upgrade to " + this.CONFIG_FILE.settings.minimumNodeVersion + " version of nodejs.")); } else { // warning not required on minor and build versions } } npmVersionInstalled = child_process.execSync('npm -v').toString(); npmVersionInstalled = npmVersionInstalled.replace(/(\r\n|\n|\r)/gm, ""); npmVersionInstalled = npmVersionInstalled.replace("v", ""); this.logger.log("npmVersionInstalled: ", npmVersionInstalled); var compareVersionOutputForNPM = this.compareVersions(this.CONFIG_FILE.settings.minimumNPMVersion, npmVersionInstalled); this.logger.log("compareVersionOutputForNPM: ", compareVersionOutputForNPM); if (compareVersionOutputForNPM.version === "MAJOR") { if (compareVersionOutputForNPM.isShellCliVersionGreater === true) { throw new Ch5CliError_1.Ch5CliError(this.getText("You seem to be using an older version of npm (" + npmVersionInstalled + "). Please upgrade to " + this.CONFIG_FILE.settings.minimumNPMVersion + " version of npm.")); } else { this.logger.printWarning("You are currently using the npm version " + npmVersionInstalled + ". ch5-shell-cli has a minimum required npm version of " + this.CONFIG_FILE.settings.minimumNPMVersion + "."); } } else if (compareVersionOutputForNPM.version === "MINOR") { if (compareVersionOutputForNPM.isShellCliVersionGreater === true) { throw new Ch5CliError_1.Ch5CliError(this.getText("You seem to be using an older version of npm (" + npmVersionInstalled + "). Please upgrade to " + this.CONFIG_FILE.settings.minimumNPMVersion + " version of npm.")); } else { // warning not required on minor and build versions } } else if (compareVersionOutputForNPM.version === "BUILD") { if (compareVersionOutputForNPM.isShellCliVersionGreater === true) { throw new Ch5CliError_1.Ch5CliError(this.getText("You seem to be using an older version of npm (" + npmVersionInstalled + "). Please upgrade to " + this.CONFIG_FILE.settings.minimumNPMVersion + " version of npm.")); } else { // warning not required on minor and build versions } } } catch (e) { if (e.name === "Ch5CliError") { this.logger.printError(e.message); process.exit(1); // throw new Error(e.message); } else { if (nodeVersionInstalled === "") { var errorMessage = this.getText("You seem to be using an older version of nodejs. Please upgrade to version " + this.CONFIG_FILE.settings.minimumNodeVersion + " of nodejs."); this.logger.printError(errorMessage); process.exit(1); // throw new Error((errorMessage)); } else if (npmVersionInstalled === "") { var errorMessage = this.getText("You seem to be using an older version of npm. Please upgrade to version " + this.CONFIG_FILE.settings.minimumNPMVersion + " of npm."); this.logger.printError(errorMessage); process.exit(1); // throw new Error((errorMessage)); } else { var errorMessage = this.getText("To use ch5-shell-cli, please ensure that your nodejs version is " + this.CONFIG_FILE.settings.minimumNodeVersion + " and npm version is " + this.CONFIG_FILE.settings.minimumNPMVersion + ""); this.logger.printError(errorMessage); process.exit(1); // throw new Error((errorMessage)); } } } }; Ch5BaseClassForCli.prototype.convertArrayToCommaSeparatedString = function (input) { var output = ""; for (var i = 0; i < input.length; i++) { output += input[i] + ", "; } output = output.trim(); if (output.length > 0) { output = output.substring(0, output.length - 1); } return output; }; /** * DO NOT DELETE */ Ch5BaseClassForCli.prototype.run = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/]; }); }); }; Ch5BaseClassForCli.prototype.getConfigNode = function (nodeName) { return this.CONFIG_FILE[nodeName]; }; /** * Get the String output from default.json file in config * @param {*} key * @param {...any} values */ Ch5BaseClassForCli.prototype.getText = function (key) { var _a; var values = []; for (var _i = 1; _i < arguments.length; _i++) { values[_i - 1] = arguments[_i]; } return (_a = this._cliUtil).getText.apply(_a, __spreadArray([this.TRANSLATION_FILE, key], values, false)); }; Ch5BaseClassForCli.prototype.logError = function (e) { if (e && this.utils.isValidInput(e.message)) { return e.message; } else { return this.getText("ERRORS.SOMETHING_WENT_WRONG"); } }; return Ch5BaseClassForCli; }()); exports.Ch5BaseClassForCli = Ch5BaseClassForCli;