UNPKG

cloudcms-cli

Version:
526 lines (447 loc) 14.9 kB
var walk = require('fs-walk'); var path = require("path"); var helper = require("../helper"); var realist = require("../../vendor/realist"); var DocsFn = require("../docs/docs"); // dns fix for Node 17 + // see: https://nodejs.org/api/dns.html#dnssetdefaultresultorderorder var dns = require("dns"); dns.setDefaultResultOrder("ipv4first"); var fs = require("fs"); var pkg = require("../../package.json"); var generateSummary = function(schema) { return helper.generateSchemaSummary(schema); }; var COMMAND_PAD_END = 25; var showCommandUsage = function(groupName, command) { var schema = command.schema(); var commandText = " cloudcms"; if (groupName) { commandText += " " + groupName; } commandText += " " + command.name; if (schema) { commandText += generateSummary(schema); } console.log(" Command Usage:"); console.log(""); console.log(commandText); console.log(""); if (schema && schema.properties && schema.properties.length > 0) { console.log(" Command Options:"); console.log(""); for (var i = 0; i < schema.properties.length; i++) { var prop = schema.properties[i]; var propertyName = prop.name; var description = prop.helper; if (!description) { description = prop.description; } var required = (prop.required ? "true": "false"); var type = prop.type; var args = ""; for (var z = 0; z < prop.args.length; z++) { if (z > 0) { args += ", "; } args += "--" + prop.args[z]; } console.log(" " + propertyName); console.log(" - required: " + required); console.log(" - type: " + type); console.log(" - args: " + args); console.log(" - description: " + description); } console.log(""); } }; var showHelp = function(args, groups, commands) { console.log(""); console.log("Cloud CMS Command Line Interface - Version " + pkg.version); console.log(""); console.log(" Usage:"); console.log(""); console.log(" cloudcms <command> [switches...]"); console.log(" cloudcms <group> <command> [switches...]"); console.log(""); // strip out --help from the args list var i = 0; do { if (i < args.length) { if (args[i] === "--help") { args.splice(i, 1); } else { i++; } } } while (i < args.length); if (args.length > 0) { if (args.length > 1) { // we have group + command var groupName = args[0]; var commandName = args[1]; // find all commands in this group var command = null; for (var i = 0; i < commands.length; i++) { if (commands[i].group === groupName && commands[i].name === commandName) { command = commands[i]; } } if (command) { return showCommandUsage(groupName, command); } } // we either couldn't find the group/command or we only have group info or only have command info var name = args[0]; // are there any commands with NO group but where name matches command? var command = null; for (var i = 0; i < commands.length; i++) { if (!commands[i].group && commands[i].name === name) { command = commands[i]; } } if (command) { return showCommandUsage(null, command); } // at this point, we think we have group info // find all commands in this group var groupCommands = []; for (var i = 0; i < commands.length; i++) { if (commands[i].group === name) { groupCommands.push(commands[i]); } } // show commands? if (groupCommands.length > 0) { var groupDescription = null; for (var z = 0; z < groups.length; z++) { if (groups[z].name === name) { groupDescription = groups[z].description; } } console.log(" " + groupDescription + ":"); console.log(""); for (var i = 0; i < groupCommands.length; i++) { console.log(" " + groupCommands[i].name.padEnd(COMMAND_PAD_END) + " - " + groupCommands[i].description); } console.log(""); return; } } // show all groups console.log(" The following command groups are available:"); console.log(""); for (var i = 0; i < groups.length; i++) { console.log(" " + groups[i].name.padEnd(COMMAND_PAD_END) + " - " + groups[i].description); } console.log(""); console.log(" The following root commands are available"); console.log(""); for (var i = 0; i < commands.length; i++) { if (!commands[i].group) { console.log(" " + commands[i].name.padEnd(COMMAND_PAD_END) + " - " + commands[i].description); } } console.log(""); console.log(" Global options"); console.log(""); console.log(" --help - Shows help about a group, command or the tool"); console.log(" --version - Shows the client version"); console.log(" --pretty - Renders JSON output in a more readable format"); console.log(" --metadata - Pulls back system metadata for record(s)"); console.log(" --full - Pulls back full objects for result sets"); console.log(" --last - Automatically applies arguments from last command"); console.log(" --authcode - Supplied an MFA authenticator code for login"); console.log(" --light - Hands back record sets with light properties (_doc, title, etc)"); console.log(" --ids - Hands back an array of IDs for record sets"); console.log(" --profile <profile> - Connects to Cloud CMS using a specific stored profile"); console.log(" --timeout <timeout> - Specifies the HTTP timeout to use (in MS) for network calls"); console.log(""); }; var finishHandler = function(err) { if (err) { //console.trace(); console.log("There was a problem:"); console.log(" -> " + err.message); console.log(""); process.exit(1); } process.exit(0); }; module.exports = function(args) { var basePath = path.resolve(__dirname, "../.."); // scan for groups var groups = []; walk.walkSync(path.join(basePath, "lib/groups/support"), function (basedir, filename, stat) { if (!stat.isDirectory()) { var GroupClass = require(basedir + "/" + filename); groups.push(new GroupClass()); } }); var groupsByName = {}; for (var z = 0; z < groups.length; z++) { groupsByName[groups[z].name] = groups[z]; } // scan for commands var commands = []; walk.walkSync(path.join(basePath, "lib/commands/support"), function (basedir, filename, stat) { if (!stat.isDirectory()) { var CommandClass = require(basedir + "/" + filename); commands.push(new CommandClass()); } }); // sort groups and commands groups.sort(function(a, b) { if(a.name < b.name) { return -1; } if(a.name > b.name) { return 1; } return 0; }); commands.sort(function(a, b) { if(a.name < b.name) { return -1; } if(a.name > b.name) { return 1; } return 0; }); // special case - docs gen if (args.length > 0 && args[0] === "generate-docs") { var text = DocsFn(groups, commands); return console.log(text); } // special case - version if (args.length > 0 && args[0] === "--version") { return console.log(pkg.version); } // parse command line string and find a command handler var command = null; // use first argument only var name = args[0]; for (var i = 0; i < commands.length; i++) { if (!commands[i].group && commands[i].name === name) { command = commands[i]; break; } } if (!command && args.length > 1) { // match on group and name var group = args[0]; var name = args[1]; for (var i = 0; i < commands.length; i++) { if (commands[i].group === group && commands[i].name === name) { command = commands[i]; break; } } } if (!command) { return showHelp(args, groups, commands); } // if --help is provided, show help var doShowHelp = false; for (var i = 0; i < args.length; i++) { if (args[i] === "--help") { doShowHelp = true; } } if (doShowHelp) { return showHelp(args, groups, commands); } var commandGroup = groupsByName[command.group]; var fn = function (commandGroup, command, schema, callback) { return function (opt) { // support for ".rc" file var rcFileJson = readRcFile(); if (rcFileJson) { if (rcFileJson.global) { if (rcFileJson.global.arguments) { for (var name in rcFileJson.global.arguments) { var value = rcFileJson.global.arguments[name]; if (value) { opt[name] = value; } } } } } // whether to use the last arguments if (opt["last"]) { var last = readLastCommandFile(); if (last) { if (last.arguments) { for (var name in last.arguments) { var value = last.arguments[name]; if (value) { opt[name] = value; } } } } } // store this on process if (opt["pretty"]) { process.pretty = true; } // store this on process if (opt["metadata"]) { process.metadata = true; } // store this on process if (opt["full"]) { process.full = true; } // store this on process if (opt["fields"]) { var fieldsString = "" + opt.fields; fieldsString = fieldsString.replace(/'/g, '"'); process.fields = JSON.parse(fieldsString); } // store this on process if (opt["light"]) { process.light = true; process.metadata = true; process.full = true; } // store this on process if (opt["ids"]) { process.ids = true; } // support for credentials profile if (opt["profile"]) { process.cloudcms_profile = opt["profile"]; } // support for timeout if (opt["timeout"]) { try { process.cloudcms_timeout = parseInt("" + opt["timeout"], 10); } catch (e) { // swallow } } // support for a authenticator code process.authenticator_code = opt["authcode"]; // allow for "admin" username and password to be picked up from environment file if (commandGroup && commandGroup.admin) { if (process.env.CLOUDCMS_CLI_ADMIN_USERNAME) { opt["username"] = process.env.CLOUDCMS_CLI_ADMIN_USERNAME; } if (process.env.CLOUDCMS_CLI_ADMIN_PASSWORD) { opt["password"] = process.env.CLOUDCMS_CLI_ADMIN_PASSWORD; } } helper.processOptions(schema, opt, command, function (err, options) { if (err) { return callback(err); } command.handle(options, function (err) { writeLastCommandFile(command, schema, options); callback(err); }); }); } }(commandGroup, command, command.schema(), finishHandler); var writeLastCommandFile = function(command, schema, options) { var last = { "command": { "group": command.config.group, "name": command.config.name }, "arguments": {} }; if (schema) { var properties = schema.properties; if (properties) { for (var i = 0; i < properties.length; i++) { var prop = properties[i]; if (prop.required) { if (prop.args && prop.args.length > 0) { last.arguments[prop.args[0]] = options[prop.name]; } } } } } fs.writeFileSync(".last_command", "" + JSON.stringify(last, null, 2)); }; var readLastCommandFile = function() { var exists = fs.existsSync(".last_command"); if (!exists) { return {}; } var text = "" + fs.readFileSync(".last_command"); return JSON.parse(text); }; var readRcFile = function() { var exists = fs.existsSync(".rc"); if (!exists) { return {}; } var text = "" + fs.readFileSync(".rc"); return JSON.parse(text); }; process.stringArgs = []; process.stringArgs.push("authcode"); realist(fn); };