UNPKG

ask-cli

Version:

Alexa Skills Kit (ASK) Command Line Interfaces

179 lines (178 loc) 8.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeSmapiCommander = void 0; const commander_1 = require("commander"); const ask_smapi_sdk_1 = require("ask-smapi-sdk"); const string_utils_1 = require("../../utils/string-utils"); const cli_customization_processor_1 = require("./cli-customization-processor"); const option_model_json_1 = __importDefault(require("../option-model.json")); const option_validator_1 = require("../option-validator"); const smapi_command_handler_1 = __importDefault(require("./smapi-command-handler")); const parameters_map_1 = require("./customizations/parameters-map"); const metrics_1 = __importDefault(require("../../utils/metrics")); const aliases_json_1 = __importDefault(require("./customizations/aliases.json")); const upload_catalog_1 = require("./appended-commands/upload-catalog"); const export_package_1 = require("./appended-commands/export-package"); const get_task_1 = require("./appended-commands/get-task"); const search_task_1 = require("./appended-commands/search-task"); const defaultOptions = [ { flags: `-${option_model_json_1.default.profile.alias}, --profile <profile>`, description: option_model_json_1.default.profile.description, shortName: option_model_json_1.default.profile.alias, longName: "profile", }, { flags: "--full-response", description: option_model_json_1.default["full-response"].description, shortName: "", longName: "full-response", }, { flags: "--debug", description: option_model_json_1.default.debug.description, shortName: "", longName: "debug", }, ]; const defaultValues = new Map(); defaultValues.set("stage", "development"); const requiredTemplate = { true: "[REQUIRED]", false: "[OPTIONAL]" }; const jsonTemplate = { true: "[JSON]: Option value is JSON string, accepts JSON file by using either:" + '\n- "$(cat {filePath})", use "type" command to replace "cat" command in Windows.' + '\n- "file:{filePath}", file descriptor with either absolute or relative file path.\n', false: "", }; const _makeEnumTemplate = (param) => (param.enum ? `[ENUM]: ${param.enum.join()}.\n` : ""); const _makeArrayTemplate = (param) => (param.isArray ? "[MULTIPLE]: Values can be separated by comma.\n" : ""); const _makeAlias = (kebabName) => (aliases_json_1.default[kebabName] ? `-${aliases_json_1.default[kebabName]},` : ""); const _makeOption = (param) => { const name = parameters_map_1.apiToCommanderMap.get(param.name) || param.name; const defaultValue = defaultValues.get(name); const shouldMakeOptional = param.required && defaultValue; if (shouldMakeOptional) { param.required = false; } const paramName = (0, string_utils_1.kebabCase)(name); const alias = _makeAlias(paramName); const json = param.json || "false"; const enumTemplate = _makeEnumTemplate(param); const arrayTemplate = _makeArrayTemplate(param); return { flags: `${alias}--${paramName} <${paramName}>`, description: (`${requiredTemplate[param.required]} ${(param.description || "").trim()} \n` + `${arrayTemplate}` + `${jsonTemplate[json]}` + `${enumTemplate} `).trim(), defaultValue: shouldMakeOptional ? defaultValue : undefined, shortName: alias, longName: paramName, }; }; /** * Simple validation for options for which rules have been defined * @param options option-value pairs that were specified * @param id option id to lookup and validate * @throws error if no rules found or input was invalid */ const _validateOption = (options, id) => { const model = option_model_json_1.default; const entry = model[id]; if (!entry) throw `No entry with validation rules for ${id}.`; const optionName = (0, string_utils_1.camelCase)(id); try { const value = options[optionName]; if (value) { if (entry.stringInput === "REQUIRED") (0, option_validator_1.validateOptionString)(options, optionName); // validate remaining rules (0, option_validator_1.validateOptionRules)(options, optionName, entry.rule); } } catch (error) { throw `Please provide valid input for option: ${entry.name}. ${error}`; } }; /** * Initialize metrics for smapi operations * @param command the command instance * @param optionsList the list of options */ const _initializeMetrics = (command, optionsList) => { metrics_1.default.startAction("smapi", command.name()); const optionsProvided = command.opts(); optionsList.forEach((option) => { const name = option.longName, value = optionsProvided[(0, string_utils_1.camelCase)(name)]; if (value === undefined) return; // option was not set // metric client requires input validation when storing values try { _validateOption(optionsProvided, name); metrics_1.default.setOption(name, value); } catch (error) { metrics_1.default.setOption(name, ""); } }); }; /** * Creates commander instance for Smapi operations. */ const makeSmapiCommander = () => { const customizationProcessor = new cli_customization_processor_1.CliCustomizationProcessor(); const modelIntrospector = new ask_smapi_sdk_1.ModelIntrospector(null, customizationProcessor); const operations = modelIntrospector.getOperations(); const program = new commander_1.Command(); let commanderInstance; operations.forEach((operation, commandName) => { const commanderToApiCustomizationMap = new Map(); const { apiOperationName, description } = operation; commanderInstance = program.command(commandName).description(description).storeOptionsAsProperties(false); const { flatParamsMap } = operation.customizationMetadata; const optionsList = []; flatParamsMap.forEach((param) => { const customizationValue = parameters_map_1.apiToCommanderMap.get(param.name); if (customizationValue) { commanderToApiCustomizationMap.set(customizationValue, param.name); } const option = _makeOption(param); optionsList.push(option); if (param.required) { commanderInstance.requiredOption(option.flags, option.description); } else { commanderInstance.option(option.flags, option.description, option.defaultValue); } }); defaultOptions.forEach((option) => { commanderInstance.option(option.flags, option.description); optionsList.push(option); }); commanderInstance.action((inputCmdObj) => { _initializeMetrics(inputCmdObj, optionsList); return smapi_command_handler_1.default .smapiCommandHandler(apiOperationName, flatParamsMap, commanderToApiCustomizationMap, inputCmdObj, modelIntrospector) .then((res) => metrics_1.default.sendData().then(() => res)) .catch((err) => metrics_1.default.sendData(err).then(() => Promise.reject(err))); }); }); // register hand-written appended commands (0, upload_catalog_1.createCommand)(program); (0, export_package_1.createCommand)(program); (0, get_task_1.createCommand)(program); (0, search_task_1.createCommand)(program); program.name("ask smapi"); program.description("The smapi command provides a number of sub-commands that " + "enable you to manage Alexa skills associated with your developer account."); program.on("command:*", () => { console.error(`Command not recognized. Please run "ask smapi" to check the user instructions.`); process.exit(1); }); return program; }; exports.makeSmapiCommander = makeSmapiCommander;