@crestron/ch5-shell-utilities-cli
Version:
CH5 Shell Utilities CLI for command scripts
457 lines (456 loc) • 29 kB
JavaScript
"use strict";
// Copyright (C) 2023 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 __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
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 };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Ch5UpdateProjectCli = void 0;
var Ch5BaseClassForProject_1 = require("../base-classes/Ch5BaseClassForProject");
var Ch5DeleteComponentsCli_1 = require("../delete-components/Ch5DeleteComponentsCli");
var Ch5GeneratePageCli_1 = require("../generate-page/Ch5GeneratePageCli");
var Ch5GenerateWidgetCli_1 = require("../generate-widget/Ch5GenerateWidgetCli");
var Ch5UpdateProjectCli = /** @class */ (function (_super) {
__extends(Ch5UpdateProjectCli, _super);
/**
* Constructor
*/
function Ch5UpdateProjectCli(showOutputMessages) {
if (showOutputMessages === void 0) { showOutputMessages = true; }
var _this = _super.call(this) || this; // This processes the input arguments in the parent class.
_this.showOutputMessages = showOutputMessages;
return _this;
}
/**
* Verify input parameters
*/
Ch5UpdateProjectCli.prototype.verifyInputParams = function () {
return __awaiter(this, void 0, void 0, function () {
var updatedDataResponses;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.logger.start("verifyInputParams");
this.logger.log("verifyInputParams - this.inputArgs: ", this.inputArgs);
return [4 /*yield*/, this.isConfigFileValid(this.getCreatedOrUpdateProjectPathProjectConfigJsonFile(), this.getCreatedOrUpdateProjectPathProjectConfigJsonSchemaFile())];
case 1:
// Step 0: Check if json in the project to be updated is valid or not
if (!(_a.sent())) {
throw new Error(this.getText("VERIFY_INPUT_PARAMS.INVALID_PROJECT_CONFIG_JSON"));
}
if (!this.isCreateOrUpdateBasedOnConfigJson()) return [3 /*break*/, 3];
// Step 1: Check file extension for json, valid input for 'config' argument, and config file existence
if (!(this.utils.isValidInput(this.getConfigJsonFilePath()) && this.isConfigFileExist(this.getConfigJsonFilePath()))) {
throw new Error(this.getText("VERIFY_INPUT_PARAMS.INVALID_CONFIG_INPUT"));
}
return [4 /*yield*/, this.isConfigFileValid(this.getConfigJsonFilePath(), this.getConfigFileSchemaPath(), true)];
case 2:
// Step 2: Check if json is as per its schema (.vscode is hidden folder)
if (!(_a.sent())) {
throw new Error(this.getText("VERIFY_INPUT_PARAMS.INVALID_CONFIG_FILE"));
}
return [3 /*break*/, 4];
case 3:
this.logger.log("Project that does not use config json file");
this.validateAndSetReceivedInputValues();
updatedDataResponses = this.getOutputResponse().data.updatedInputs.filter(function (data) { return data.inputReceived === true; });
if (updatedDataResponses.length === 0) {
throw new Error(this.getText("VERIFY_INPUT_PARAMS.MISSING_INPUTS_NEED_ATlEAST_ONE_DATA"));
}
this.printWarningsOnVerifiedInputs();
_a.label = 4;
case 4:
this.logger.end();
return [2 /*return*/];
}
});
});
};
/**
* Check if there are questions to be prompted to the integrator
*/
Ch5UpdateProjectCli.prototype.checkPromptQuestions = function () {
return __awaiter(this, void 0, void 0, function () {
var _a, _b, _c;
return __generator(this, function (_d) {
switch (_d.label) {
case 0:
this.logger.start("checkPromptQuestions");
if (!this.isCreateOrUpdateBasedOnConfigJson()) return [3 /*break*/, 2];
// Identify changes
// const newCheck = new CompareJSON();
// this.logger.log(newCheck.map(oldProjectConfigJSON, newProjectConfigJSON));
_a = this.getOutputResponse();
_c = (_b = this.utils).toBoolean;
return [4 /*yield*/, this.getConfirmation()];
case 1:
// Identify changes
// const newCheck = new CompareJSON();
// this.logger.log(newCheck.map(oldProjectConfigJSON, newProjectConfigJSON));
_a.askConfirmation = _c.apply(_b, [_d.sent()]);
return [3 /*break*/, 4];
case 2: return [4 /*yield*/, this.askQuestionsToUser("update")];
case 3:
_d.sent();
this.getOutputResponse().askConfirmation = true;
_d.label = 4;
case 4:
this.logger.end();
return [2 /*return*/];
}
});
});
};
/**
* Implement this component's main purpose
*/
Ch5UpdateProjectCli.prototype.processRequest = function () {
return __awaiter(this, void 0, void 0, function () {
var inputConfigJSON, templateConfigJSON, k, pagesToBeCreated, pagesToBeUpdated, pagesToBeDeleted, _loop_1, i, _loop_2, i, widgetsToBeCreated, widgetsToBeDeleted, widgetsToBeUpdated, _loop_3, i, _loop_4, i, i, delPage, i, genPage, newPageName, i, i, delWidget, i, genWidget, newWidgetName, i, outputResponse, i, getProjectThemes, isZoomLightThemeAvailable, zoomLightTheme, isZoomDarkThemeAvailable, zoomDarkTheme, isSelectedThemeUpdated, i, getProjectThemes, isZoomLightThemeAvailable, isZoomDarkThemeAvailable, isSelectedThemeUpdated, i;
var _a, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
this.logger.start("processRequest");
this.logger.log("processRequest - this._outputResponse.data.updatedInputs: ", this.getOutputResponse().data.updatedInputs);
this.logger.log("this._outputResponse.askConfirmation", this.getOutputResponse().askConfirmation);
if (this.getOutputResponse().askConfirmation === false) {
throw new Error(this.getText("ERRORS.DO_NOT_MODIFY_PROJECT"));
}
this.setProjectVariables();
this.updateFilesAsPerProjectType();
if (!this.isCreateOrUpdateBasedOnConfigJson()) return [3 /*break*/, 18];
return [4 /*yield*/, this.createBackupForExistingProject()];
case 1:
_c.sent();
inputConfigJSON = JSON.parse(this.utils.readFileContentSync(this.getConfigJsonFilePath()));
templateConfigJSON = JSON.parse(this.utils.readFileContentSync(this.getCreatedOrUpdateProjectPathProjectConfigJsonFile()));
// 1. Project Data
for (k in inputConfigJSON) {
if ((typeof inputConfigJSON[k] !== 'object' && inputConfigJSON[k] !== null)) {
if (templateConfigJSON[k] !== inputConfigJSON[k]) {
templateConfigJSON[k] = inputConfigJSON[k];
this.projectConfig.changeNodeValues(k, templateConfigJSON[k]);
}
}
}
// 2. Themes
templateConfigJSON["themes"] = inputConfigJSON["themes"];
this.projectConfig.changeNodeValues("themes", templateConfigJSON["themes"]);
// 3. Config
templateConfigJSON["config"] = inputConfigJSON["config"];
this.projectConfig.changeNodeValues("config", templateConfigJSON["config"]);
// 4. Header
templateConfigJSON["header"] = inputConfigJSON["header"];
this.projectConfig.changeNodeValues("header", templateConfigJSON["header"]);
// 5. Footer
templateConfigJSON["footer"] = inputConfigJSON["footer"];
this.projectConfig.changeNodeValues("footer", templateConfigJSON["footer"]);
// 6. Content
templateConfigJSON["content"]["triggerViewProperties"] = inputConfigJSON["content"]["triggerViewProperties"];
this.projectConfig.changeNodeValues("content.triggerViewProperties", templateConfigJSON["content"]["triggerViewProperties"]);
// 7. Custom Signal
templateConfigJSON["customSignals"] = inputConfigJSON["customSignals"];
this.projectConfig.changeNodeValues("customSignals", templateConfigJSON["customSignals"]);
templateConfigJSON["content"]["$defaultView"] = inputConfigJSON["content"]["$defaultView"];
this.projectConfig.changeNodeValues("content.$defaultView", templateConfigJSON["content"]["$defaultView"]);
pagesToBeCreated = [];
pagesToBeUpdated = [];
pagesToBeDeleted = [];
_loop_1 = function (i) {
var pageObj = templateConfigJSON["content"]["pages"][i];
var pageInNewSet = inputConfigJSON["content"]["pages"].find(function (page) { return page.pageName.toString().toLowerCase() === pageObj.pageName.toString().toLowerCase(); });
if (pageInNewSet) {
pagesToBeUpdated.push(pageInNewSet);
}
else {
// Exists in Old set but not in new - so create page
pagesToBeDeleted.push(pageObj);
}
};
for (i = 0; i < templateConfigJSON["content"]["pages"].length; i++) {
_loop_1(i);
}
_loop_2 = function (i) {
var pageObj = inputConfigJSON["content"]["pages"][i];
var pageInOldSet = templateConfigJSON["content"]["pages"].find(function (page) { return page.pageName.toString().toLowerCase() === pageObj.pageName.toString().toLowerCase(); });
if (!pageInOldSet) {
// Exists in New set but not in old - so create page
pagesToBeCreated.push(pageObj);
}
};
for (i = 0; i < inputConfigJSON["content"]["pages"].length; i++) {
_loop_2(i);
}
widgetsToBeCreated = [];
widgetsToBeDeleted = [];
widgetsToBeUpdated = [];
_loop_3 = function (i) {
var widgetObj = templateConfigJSON["content"]["widgets"][i];
var pageInNewSet = inputConfigJSON["content"]["widgets"].find(function (widget) { return widget.widgetName.toString().toLowerCase() === widgetObj.widgetName.toString().toLowerCase(); });
if (pageInNewSet) {
widgetsToBeUpdated.push(pageInNewSet);
}
else {
// Exists in Old set but not in new - so create page
widgetsToBeDeleted.push(widgetObj);
}
};
for (i = 0; i < templateConfigJSON["content"]["widgets"].length; i++) {
_loop_3(i);
}
_loop_4 = function (i) {
var widgetObj = inputConfigJSON["content"]["widgets"][i];
var pageInOldSet = templateConfigJSON["content"]["widgets"].find(function (widget) { return widget.widgetName.toString().toLowerCase() === widgetObj.widgetName.toString().toLowerCase(); });
if (!pageInOldSet) {
// Exists in New set but not in old - so create page
widgetsToBeCreated.push(widgetObj);
}
};
for (i = 0; i < inputConfigJSON["content"]["widgets"].length; i++) {
_loop_4(i);
}
this.setValueInPackageJson("name", templateConfigJSON.projectName);
i = 0;
_c.label = 2;
case 2:
if (!(i < pagesToBeDeleted.length)) return [3 /*break*/, 5];
delPage = new Ch5DeleteComponentsCli_1.Ch5DeleteComponentsCli(false);
delPage.setInputArgsForTesting(["--list", pagesToBeDeleted[i].pageName, "--force"]);
return [4 /*yield*/, delPage.run()];
case 3:
_c.sent();
_c.label = 4;
case 4:
i++;
return [3 /*break*/, 2];
case 5:
i = 0;
_c.label = 6;
case 6:
if (!(i < pagesToBeCreated.length)) return [3 /*break*/, 9];
genPage = new Ch5GeneratePageCli_1.Ch5GeneratePageCli(false);
newPageName = pagesToBeCreated[i].fileName.toLowerCase().split(".")[0];
genPage.setInputArgsForTesting(["-n", newPageName, "-m", pagesToBeCreated[i].navigation ? "Y" : "N"]);
return [4 /*yield*/, genPage.run()];
case 7:
_c.sent();
this.projectConfig.replacePageNodeInJSON(pagesToBeCreated[i]);
_c.label = 8;
case 8:
i++;
return [3 /*break*/, 6];
case 9:
for (i = 0; i < pagesToBeUpdated.length; i++) {
// Update in project-config
this.projectConfig.replacePageNodeInJSON(pagesToBeUpdated[i]);
}
i = 0;
_c.label = 10;
case 10:
if (!(i < widgetsToBeDeleted.length)) return [3 /*break*/, 13];
delWidget = new Ch5DeleteComponentsCli_1.Ch5DeleteComponentsCli(false);
delWidget.setInputArgsForTesting(["--list", widgetsToBeDeleted[i].widgetName, "--force"]);
return [4 /*yield*/, delWidget.run()];
case 11:
_c.sent();
_c.label = 12;
case 12:
i++;
return [3 /*break*/, 10];
case 13:
i = 0;
_c.label = 14;
case 14:
if (!(i < widgetsToBeCreated.length)) return [3 /*break*/, 17];
genWidget = new Ch5GenerateWidgetCli_1.Ch5GenerateWidgetCli(false);
newWidgetName = widgetsToBeCreated[i].fileName.toLowerCase().split(".")[0];
genWidget.setInputArgsForTesting(["-n", newWidgetName]);
return [4 /*yield*/, genWidget.run()];
case 15:
_c.sent();
this.projectConfig.removeWidgetFromJSON(widgetsToBeCreated[i]);
_c.label = 16;
case 16:
i++;
return [3 /*break*/, 14];
case 17:
for (i = 0; i < widgetsToBeUpdated.length; i++) {
// Update in project-config
this.projectConfig.replaceWidgetNodeInJSON(widgetsToBeUpdated[i]);
}
return [3 /*break*/, 19];
case 18:
outputResponse = this.getOutputResponse();
for (i = 0; i < outputResponse.data.updatedInputs.length; i++) {
if (outputResponse.data.updatedInputs[i].inputReceived === true) {
this.logger.log("Changed Values", outputResponse.data.updatedInputs[i].key, outputResponse.data.updatedInputs[i].argsValue);
this.projectConfig.changeNodeValues(outputResponse.data.updatedInputs[i].key, outputResponse.data.updatedInputs[i].argsValue);
if (outputResponse.data.updatedInputs[i].key === "projectName") {
this.setValueInPackageJson("name", outputResponse.data.updatedInputs[i].argsValue);
}
}
}
if (((_a = this.projectConfig.getNodeByKey("projectType")) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === "zoomroomcontrol") {
getProjectThemes = this.projectConfig.getNodeByKey("themes");
isZoomLightThemeAvailable = getProjectThemes.filter(function (theme) { return theme.name === "zoom-light-theme"; });
if (isZoomLightThemeAvailable.length === 0) {
zoomLightTheme = {
"name": "zoom-light-theme",
"extends": "zoom-light-theme",
"brandLogo": {
"url": "./app/template/assets/img/ch5-logo-light.svg",
"alt": "Crestron Logo",
"receiveStateUrl": ""
},
"backgroundProperties": {
"backgroundColor": [
"#ffffff"
]
}
};
getProjectThemes.push(zoomLightTheme);
this.projectConfig.changeNodeValues("themes", getProjectThemes);
}
isZoomDarkThemeAvailable = getProjectThemes.filter(function (theme) { return theme.name === "zoom-dark-theme"; });
if (isZoomDarkThemeAvailable.length === 0) {
zoomDarkTheme = {
"name": "zoom-dark-theme",
"extends": "zoom-dark-theme",
"brandLogo": {
"url": "./app/template/assets/img/ch5-logo-dark.svg",
"alt": "Crestron Logo",
"receiveStateUrl": ""
},
"backgroundProperties": {
"backgroundColor": [
"#242424"
]
}
};
getProjectThemes.push(zoomDarkTheme);
this.projectConfig.changeNodeValues("themes", getProjectThemes);
}
isSelectedThemeUpdated = false;
for (i = 0; i < outputResponse.data.updatedInputs.length; i++) {
if (outputResponse.data.updatedInputs[i].inputReceived === true && outputResponse.data.updatedInputs[i].key === "selectedTheme") {
isSelectedThemeUpdated = true;
}
}
if (isSelectedThemeUpdated === false) {
if (this.projectConfig.getNodeByKey("selectedTheme") !== "zoom-light-theme" && this.projectConfig.getNodeByKey("selectedTheme") !== "zoom-dark-theme") {
this.projectConfig.changeNodeValues("selectedTheme", "zoom-light-theme");
}
}
}
else {
getProjectThemes = this.projectConfig.getNodeByKey("themes");
isZoomLightThemeAvailable = getProjectThemes.filter(function (theme) { return theme.name === "zoom-light-theme"; });
if (isZoomLightThemeAvailable.length > 0) {
getProjectThemes = getProjectThemes.filter(function (theme) { return theme.name !== "zoom-light-theme"; });
}
isZoomDarkThemeAvailable = getProjectThemes.filter(function (theme) { return theme.name === "zoom-dark-theme"; });
if (isZoomDarkThemeAvailable.length > 0) {
getProjectThemes = getProjectThemes.filter(function (theme) { return theme.name !== "zoom-dark-theme"; });
}
this.projectConfig.changeNodeValues("themes", JSON.parse(JSON.stringify(getProjectThemes)));
isSelectedThemeUpdated = false;
for (i = 0; i < outputResponse.data.updatedInputs.length; i++) {
if (outputResponse.data.updatedInputs[i].inputReceived === true && outputResponse.data.updatedInputs[i].key === "selectedTheme") {
isSelectedThemeUpdated = true;
}
}
if (isSelectedThemeUpdated === false) {
if (this.projectConfig.getNodeByKey("selectedTheme") === "zoom-light-theme" || this.projectConfig.getNodeByKey("selectedTheme") === "zoom-dark-theme") {
this.projectConfig.changeNodeValues("selectedTheme", "light-theme");
}
}
}
_c.label = 19;
case 19:
if (((_b = this.projectConfig.getNodeByKey("projectType")) === null || _b === void 0 ? void 0 : _b.toLowerCase()) === "zoomroomcontrol") {
this.projectConfig.changeNodeValues("forceDeviceXPanel", true);
}
return [4 /*yield*/, this.isConfigFileValid(this.getCreatedOrUpdateProjectPathProjectConfigJsonFile(), this.getCreatedOrUpdateProjectPathProjectConfigJsonSchemaFile())];
case 20:
// Step 6: Run validate:project-config
if (!(_c.sent())) {
throw new Error(this.getText("PROCESS_REQUEST.PROJECT_CONFIG_VALIDATION_FAILED"));
}
// Step 7: Show proper messages
this.getOutputResponse().result = true;
if (this.isCreateOrUpdateBasedOnConfigJson()) {
this.getOutputResponse().successMessage = this.getText("LOG_OUTPUT.SUCCESS_MESSAGE_WITH_BACKUP", this.getOutputResponse().data.backupFolder);
}
else {
this.getOutputResponse().successMessage = this.getText("LOG_OUTPUT.SUCCESS_MESSAGE");
}
this.logger.end();
return [2 /*return*/];
}
});
});
};
/**
* Do not move this method to base class
* @returns
*/
Ch5UpdateProjectCli.prototype.getCLIExecutionPath = function () {
// This method needs to be available here in order to get the current working directory
return __dirname;
};
return Ch5UpdateProjectCli;
}(Ch5BaseClassForProject_1.Ch5BaseClassForProject));
exports.Ch5UpdateProjectCli = Ch5UpdateProjectCli;