UNPKG

@zowe/imperative

Version:
228 lines 10.2 kB
"use strict"; /* * This program and the accompanying materials are made available under the terms of the * Eclipse Public License v2.0 which accompanies this distribution, and is available at * https://www.eclipse.org/legal/epl-v20.html * * SPDX-License-Identifier: EPL-2.0 * * Copyright Contributors to the Zowe Project. * */ Object.defineProperty(exports, "__esModule", { value: true }); exports.AbstractHelpGenerator = void 0; const utilities_1 = require("../../../../utilities"); const util_1 = require("util"); const ImperativeError_1 = require("../../../../error/src/ImperativeError"); const Logger_1 = require("../../../../logger/src/Logger"); const constants_1 = require("../../../../constants"); class AbstractHelpGenerator { /** * Get a heading for the CLI / help * @param {string} header - The text you want to display in the header * @param indent - prefix the the heading and dashes with this string (defaults to one space) * @param color - the color to highlight the header in * @returns {string} the formatted/colored header */ static formatHelpHeader(header, indent = " ", color) { if (header == null || header.trim().length === 0) { throw new ImperativeError_1.ImperativeError({ msg: "Null or empty header provided; could not be formatted." }); } const numDashes = header.length + 1; const headerText = utilities_1.TextUtils.formatMessage("{{indent}}{{headerText}}\n{{indent}}{{dashes}}", { headerText: header.toUpperCase(), dashes: Array(numDashes).join("-"), indent }); return utilities_1.TextUtils.chalk[color](headerText); } /** * Get log instance */ get log() { return this.mLog; } // TODO - rework these parameter (and possible the help generator scheme) constructor(defaultParms, commandParms) { /** * Produce markdown - not help text. */ this.mProduceMarkdown = false; /** * The configured experimental command description. * Has a default, generic description which can be overridden through parameters * to the constructor * @type {string} */ this.mExperimentalCommandDescription = constants_1.Constants.DEFAULT_EXPERIMENTAL_COMMAND_EXPLANATION; /** * A map of group names to option names and aliases - useful in help text/doc generation * e.g. this.grouptoOption["job options"] -> [ "--async | -a ", "--activate | -A"] */ this.groupToOption = {}; /** * A map of option names and aliases to their descriptions - useful in help text/doc generation * e.g. this.optionToDescription["--async | a"] -> "Don't wait for this job to complete before returning" */ this.optionToDescription = {}; if (commandParms.commandDefinition == null || commandParms.fullCommandTree == null) { throw new ImperativeError_1.ImperativeError({ msg: "Error initializing help generator. The command definition or command definition tree was null or undefined.", additionalDetails: JSON.stringify(commandParms.commandDefinition) + "\n\n" + JSON.stringify(commandParms.fullCommandTree) }); } this.mCommandDefinition = commandParms.commandDefinition; this.mDefinitionTree = commandParms.fullCommandTree; this.mProduceMarkdown = defaultParms.produceMarkdown; this.mRootCommandName = defaultParms.rootCommandName; this.mPrimaryHighlightColor = defaultParms.primaryHighlightColor; this.mLog = Logger_1.Logger.getImperativeLogger(); if (commandParms.experimentalCommandsDescription != null) { // use the configured experimental command description, if any this.mExperimentalCommandDescription = commandParms.experimentalCommandsDescription; } } getOptionAndAliasesString(option, caseSensitive) { var _a; let aliasString = ""; if (!(option.aliases == null) && option.aliases.length > 0 && option.aliases.join("").trim().length !== 0) { const formattedOptAliases = []; aliasString += " | "; for (const alias of option.aliases) { if (!(alias == null) && alias.length > 0) { formattedOptAliases.push("{{codeBegin}}" + (alias.length === 1 ? "-" : "--") + alias + "{{codeEnd}}"); } else { this.log.warn("The aliases for option " + option.name + " contained a null or empty alias. " + "This has been ignored; please take corrective action in your option definition."); } } aliasString += formattedOptAliases.join(" | "); } const explainedType = this.explainType(option.type); aliasString += " {{italic}}" + this.dimGrey("(" + explainedType + ")") + "{{italic}}"; // if (!option.required) { // aliasString += " {{italic}}" + this.dimGrey("(optional)") + "{{italic}}"; // } if (caseSensitive) { aliasString += " {{italic}}" + this.dimGrey("(case sensitive)") + "{{italic}}"; } return this.renderHelp((0, util_1.format)("{{codeBegin}}%s{{codeEnd}}%s", (((_a = option.name) === null || _a === void 0 ? void 0 : _a.length) === 1 ? "-" : "--") + option.name, aliasString)); } buildOptionMaps() { this.groupToOption = {}; this.optionToDescription = {}; if (this.mCommandDefinition.options == null) { return; } for (const option of this.mCommandDefinition.options.filter(opt => !opt.hidden)) { const group = option.group; if (!this.groupToOption[group]) { this.groupToOption[group] = []; } const caseSensitive = this.getCaseSensitiveFlagByOptionName(option.name); const optionAndAliases = this.getOptionAndAliasesString(option, caseSensitive); this.groupToOption[group].push(optionAndAliases); // build the option help text let optionText = option.description; const defaultValueText = [undefined, null].includes(option.defaultValue) ? "" : this.grey("\nDefault value: " + option.defaultValue); const allowableValuesText = option.allowableValues ? this.grey("\nAllowed values: " + option.allowableValues.values.join(", ")) : ""; if (defaultValueText.length > 0 || allowableValuesText.length > 0) { optionText += "\n"; optionText += defaultValueText + allowableValuesText; } // Place the help text in the map this.optionToDescription[optionAndAliases] = optionText; } } getCaseSensitiveFlagByOptionName(optionName) { if (!(this.mCommandDefinition.customize == null) && !(this.mCommandDefinition.customize.commandStatement == null) && !(this.mCommandDefinition.customize.commandStatement.children == null)) { for (const child of this.mCommandDefinition.customize.commandStatement.children) { if (child.name.toUpperCase() === optionName.toUpperCase()) { return child.caseSensitive; } } } return undefined; } renderHelp(help) { if (help == null) { throw new ImperativeError_1.ImperativeError({ msg: "Help unable to be rendered - the supplied help text was null or undefined." }); } // avoid replacing any literal {{strings like this}} in the help const validTags = ["indent", "space", "italic", "header", "bullet", "codeBegin", "codeEnd"]; const mustachePattern = /\{\{([a-z0-9-]*?)\}\}/ig; help = help.replace(mustachePattern, (fullMatch, variableName) => { if (validTags.indexOf(variableName) >= 0) { return fullMatch; } else { // temporarily change the mustache delimiter to avoid // replacing literal curly braces in the help return "{{=<% %>=}}" + fullMatch + "<%={{ }}=%>"; } }); if (this.mProduceMarkdown) { return utilities_1.TextUtils.renderWithMustache(help, { indent: "\t", space: " ", italic: "*", header: "#", bullet: "*", codeBegin: "`", codeEnd: "`" }); } else { return utilities_1.TextUtils.renderWithMustache(help, { indent: "", space: "", header: "", italic: "", bullet: "", codeBegin: "", codeEnd: "" }); } } explainType(type) { let explainedType = type; if (explainedType === "existingLocalFile") { explainedType = "local file path"; } else if (explainedType === "stringOrEmpty") { explainedType = "string"; } return explainedType; } /** * Highlight text in dim grey (disabled if producing markdown) * @param {string} text - the text you would like to highlight * @returns {string} the highlighted text */ dimGrey(text) { if (this.mProduceMarkdown) { return text; } return utilities_1.TextUtils.chalk.grey.dim(text); } /** * Highlight text in grey (disabled if producing markdown) * @param {string} text - the text you would like to highlight * @returns {string} the highlighted text */ grey(text) { if (this.mProduceMarkdown) { return text; } return utilities_1.TextUtils.chalk.grey(text); } } exports.AbstractHelpGenerator = AbstractHelpGenerator; AbstractHelpGenerator.SHORT_DASH = "-"; AbstractHelpGenerator.LONG_DASH = "--"; //# sourceMappingURL=AbstractHelpGenerator.js.map