UNPKG

ask-cli-x

Version:

Alexa Skills Kit (ASK) Command Line Interfaces

208 lines (207 loc) 9.61 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createCommand = exports.DialogCommand = void 0; const path = __importStar(require("path")); const smapi_client_1 = require("../../clients/smapi-client"); const abstract_command_1 = require("../../commands/abstract-command"); const optionModel = __importStar(require("../../commands/option-model.json")); const cli_error_1 = __importDefault(require("../../exceptions/cli-error")); const dialog_replay_file_1 = __importDefault(require("../../model/dialog-replay-file")); const resources_config_1 = __importDefault(require("../../model/resources-config")); const jsonView = __importStar(require("../../view/json-view")); const CONSTANTS = __importStar(require("../../utils/constants")); const profileHelper = __importStar(require("../../utils/profile-helper")); const messenger_1 = __importDefault(require("../../view/messenger")); const spinner_view_1 = __importDefault(require("../../view/spinner-view")); const stringUtils = __importStar(require("../../utils/string-utils")); const interactive_mode_1 = require("./interactive-mode"); const replay_mode_1 = require("./replay-mode"); const helper_1 = require("./helper"); const evaluate_mode_1 = require("./evaluate-mode"); const evaluate_view_1 = require("../../view/evaluate-view"); class DialogCommand extends abstract_command_1.AbstractCommand { constructor(smapiClient, optionModel) { super(optionModel); this.smapiClient = smapiClient; this.messenger = messenger_1.default.getInstance(); } name() { return "dialog"; } description() { return "simulate your skill via an interactive dialog with Alexa"; } requiredOptions() { return []; } optionalOptions() { return ["skill-id", "evaluate", "locale", "stage", "replay", "save-skill-io", "verbose", "profile", "debug"]; } async handle(cmd) { try { const dialogMode = await this._dialogModeFactory(cmd); const spinner = new spinner_view_1.default(); spinner.start("Checking if skill is ready to simulate..."); try { await (0, helper_1.validateDialogArgs)(dialogMode); } catch (err) { spinner.terminate(spinner_view_1.default.TERMINATE_STYLE.FAIL, "Failed to validate command options"); throw err; } spinner.terminate(); await dialogMode.start(); } catch (err) { this.messenger.error(err); throw err; } } /** * Function processes dialog arguments and returns a consolidated object. * @param {Object} cmd encapsulates arguments provided to the dialog command. * @return { skillId, locale, stage, profile, debug, replayFile, smapiClient, userInputs <for replay mode> } */ async _getDialogConfig(cmd) { var _a, _b; const { skillId: cmdSkillId, locale: cmdLocale, stage: cmdStage, profile: cmdProfile } = cmd; const { evaluate, saveSkillIo, verbose, debug } = cmd; const profile = profileHelper.runtimeProfile(cmdProfile); const stage = cmdStage || CONSTANTS.SKILL.STAGE.DEVELOPMENT; const smapiClient = this.smapiClient.withConfiguration({ profile, doDebug: !!cmd.debug, }); const { skillId = cmdSkillId, locale = cmdLocale, userInputs } = this._resolvedArguments(cmd, profile); const manifestResult = await smapiClient.skill.manifest.getManifest(skillId, stage); if ((0, smapi_client_1.isSmapiError)(manifestResult)) { throw jsonView.toString(manifestResult.body); } const [firstLocaleFromManifest] = Object.keys(((_b = (_a = manifestResult.body.manifest) === null || _a === void 0 ? void 0 : _a.publishingInformation) === null || _b === void 0 ? void 0 : _b.locales) || {}); if (!locale && !process.env.ASK_DEFAULT_DEVICE_LOCALE && firstLocaleFromManifest) { this.messenger.info(`Defaulting locale to the first value from the skill manifest: ${firstLocaleFromManifest}`); } return { skillId, locale: locale || process.env.ASK_DEFAULT_DEVICE_LOCALE || firstLocaleFromManifest, stage, profile, debug, replay: cmd.replay, evaluate, verbose, saveSkillIo, smapiClient, userInputs, }; } _resolvedArguments(cmd, profile) { const { evaluate, verbose, skillId: cmdSkillId, locale } = cmd; if (verbose && !evaluate) { throw new cli_error_1.default("--verbose cannot be used without --evaluate"); } if (cmd.replay) { // try { if (evaluate) { throw new cli_error_1.default("Must not use both --replay and --evaluate, which are two modes working separately"); } if (verbose) { throw new cli_error_1.default("Must not use both --replay and --verbose as explanation must be turn based"); } const dialogReplayConfig = new dialog_replay_file_1.default(cmd.replay); const skillId = dialogReplayConfig.getSkillId(); if (!stringUtils.isNonBlankString(skillId)) { throw new cli_error_1.default("Replay file must contain skillId"); } const locale = dialogReplayConfig.getLocale(); if (!stringUtils.isNonBlankString(locale)) { throw new cli_error_1.default("Replay file must contain locale"); } return { userInputs: this._validateUserInputs(dialogReplayConfig.getUserInput()), skillId, locale }; } else if (evaluate) { if (locale) { throw new cli_error_1.default("--locale cannot be used with --evaluate, as only en-US locale is supported now"); } if (process.env.ASK_DEFAULT_DEVICE_LOCALE) { throw new cli_error_1.default('Please unset environmental variable "ASK_DEFAULT_DEVICE_LOCALE" as locale is not supported in evaluate mode'); } if (cmdSkillId) { throw new cli_error_1.default("Please run --evaluate from a deployed skill project, where CLI can load the project and skillId"); } const skillId = this._getSkillIdFromProfile(profile); return { skillId }; } else if (!stringUtils.isNonBlankString(cmdSkillId)) { const skillId = this._getSkillIdFromProfile(profile); return { skillId }; } return {}; } _getSkillIdFromProfile(profile) { let skillId; try { new resources_config_1.default(path.join(process.cwd(), CONSTANTS.FILE_PATH.ASK_RESOURCES_JSON_CONFIG)); skillId = resources_config_1.default.getInstance().getSkillId(profile); } catch (err) { throw new cli_error_1.default("Failed to read project resource file. " + "Please run the command within a ask-cli project."); } if (!stringUtils.isNonBlankString(skillId)) { throw new cli_error_1.default("Failed to obtain skill-id from project " + `resource file ${CONSTANTS.FILE_PATH.ASK_RESOURCES_JSON_CONFIG}`); } return skillId; } async _dialogModeFactory(cmd) { const config = await this._getDialogConfig(cmd); if (config.replay) { return new replay_mode_1.ReplayMode(config); } else if (config.evaluate) { return new evaluate_mode_1.EvaluateMode({ ...config, view: (0, evaluate_view_1.createView)(this.messenger, config.verbose), }); } else { return new interactive_mode_1.InteractiveMode(config); } } _validateUserInputs(userInputs) { return userInputs.map((input) => { const trimmedInput = input.trim(); if (!stringUtils.isNonBlankString(trimmedInput)) { throw new cli_error_1.default("Replay file's userInput cannot contain empty string."); } return trimmedInput; }); } } exports.DialogCommand = DialogCommand; exports.createCommand = new DialogCommand(new smapi_client_1.SmapiClientLateBound(), optionModel).createCommand();