UNPKG

ask-cli

Version:

Alexa Skills Kit (ASK) Command Line Interfaces

225 lines (224 loc) 11.2 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.collectUserCreationProjectInfo = void 0; const messenger_1 = __importDefault(require("../../view/messenger")); const constants_1 = require("../../utils/constants"); const string_utils_1 = __importDefault(require("../../utils/string-utils")); const url_utils_1 = __importDefault(require("../../utils/url-utils")); const ui = __importStar(require("./ui")); const template_helper_1 = require("./template-helper"); const prompt_view_1 = require("../../view/prompt-view"); const _1 = require("."); const sample_template_1 = require("../../model/sample-template"); /** * Ask for user input to create a project * @param {Object} cmd command object * @param {CollectUserCreationProjectInfoCallback} callback callback providing the NewSkillUserInput to the caller */ async function collectUserCreationProjectInfo(cmd, callback) { var _a; const userInput = {}; try { // Make sure the arguments are valid if (cmd.templateUrl && !url_utils_1.default.isValidUrl(cmd.templateUrl)) { throw new Error(`The provided template url ${cmd.templateUrl} is not a valid url.`); } // gets the sample templates from S3 const sampleTemplates = []; await (0, template_helper_1.getSampleTemplatesFromS3)(cmd.doDebug).then((fullSamples) => { sampleTemplates.push(...fullSamples); }); const sampleTemplateFilter = new sample_template_1.SampleTemplatesFilter(sampleTemplates); // MODELING STACK TYPE await promptForModelingStackType().then((modelingStack) => (userInput.modelingStack = modelingStack)); sampleTemplateFilter.filter("stack", (0, template_helper_1.convertUserInputToFilterValue)(userInput.modelingStack || _1.MODELING_STACK_IM)); // CODE LANGUAGE // ignore when template url supplied if (!cmd.templateUrl) { await promptForCodeLanguage(sampleTemplateFilter.getSampleTemplates()).then((language) => (userInput.language = language)); sampleTemplateFilter.filter("lang", (0, template_helper_1.convertUserInputToFilterValue)(userInput.language || _1.CODE_LANGUAGE_NODEJS)); } // DEPLOY TYPE await promptForDeployerType(sampleTemplateFilter.getSampleTemplates()).then((deploymentType) => (userInput.deploymentType = deploymentType)); sampleTemplateFilter.filter("deploy", (0, template_helper_1.convertUserInputToFilterValue)(userInput.deploymentType || constants_1.DEPLOYER_TYPE.CFN.NAME)); if (userInput.deploymentType === constants_1.DEPLOYER_TYPE.HOSTED.NAME) { // HOSTED SKILL LOCALE // FIX hard coding until backend for hosted skills supports locales userInput.locale = "en-US"; // HOSTED SKILL AWS REGION await promptForSkillRegion().then((region) => (userInput.region = region)); } else { // NON HOSTED SKILL requires selecting a sample template from the list // TEMPLATE INFO await promptForTemplateInfo(cmd, sampleTemplateFilter.getSampleTemplates()).then((templateInfo) => (userInput.templateInfo = templateInfo)); } // SKILL NAME await promptForSkillName(((_a = userInput.templateInfo) === null || _a === void 0 ? void 0 : _a.templateUrl) || null).then((skillName) => (userInput.skillName = skillName)); // PROJECT FOLDER NAME await promptForProjectFolderName(userInput.skillName || "").then((projectFolderName) => (userInput.projectFolderName = projectFolderName)); } catch (e) { callback(e, undefined); return; } callback(null, userInput); } exports.collectUserCreationProjectInfo = collectUserCreationProjectInfo; /** * A Promise that fetches and returns the NewSkillCodeLanguage the user wants to leverage * * @param {SampleTemplate[]} samples remaining sample templates to select from * @returns {Promise<NewSkillCodeLanguage>} a Promise that will provide a NewSkillCodeLanguage */ function promptForCodeLanguage(samples) { return new Promise((resolve, reject) => { const remainingLanguages = new Set(samples.map((sample) => { switch (sample.lang) { case "node": return _1.CODE_LANGUAGE_NODEJS; case "python": return _1.CODE_LANGUAGE_PYTHON; case "java": return _1.CODE_LANGUAGE_JAVA; } })); ui.selectSkillCodeLanguage(Array.from(remainingLanguages), (error, language) => (error ? reject(error) : resolve(language))); }); } /** * A Promise that fetches and returns the NewSkillDeployerType the user wants to leverage * * @param {boolean} hasTemplateUrl true or false if the templateUrl was specified as a command line argument * @returns {Promise<NewSkillDeployerType>} a Promise that will provide a NewSkillDeployerType */ function promptForDeployerType(samples) { return new Promise((resolve, reject) => { const remainingDeployerTypes = new Set(samples.map((sample) => { switch (sample.deploy) { case "lambda": return constants_1.DEPLOYER_TYPE.LAMBDA; case "cfn": return constants_1.DEPLOYER_TYPE.CFN; case "hosted": return constants_1.DEPLOYER_TYPE.HOSTED; case "self": return constants_1.DEPLOYER_TYPE.SELF_HOSTED; } })); ui.getDeploymentType(Array.from(remainingDeployerTypes), (error, deploymentType) => (error ? reject(error) : resolve(deploymentType))); }); } /** * A Promise that fetches and returns the NewSkillModelingStackTypes the user wants the samples to use. * i.e. interaction-model vs alexa-conversations * * @returns {Promise<NewSkillModelingStackTypes>} a Promise that will provide a Modeling Stack */ function promptForModelingStackType() { return new Promise((resolve, reject) => { ui.getModelingStackType((error, modelingStack) => (error ? reject(error) : resolve(modelingStack))); }); } /** * A Promise that fetches and returns the default AWS Region to use for deploying the Alexa hosted skill * * @returns {Promise<NewSkillRegion>} Promises to return the default AWS Region the user wants to deploy the skill to */ function promptForSkillRegion() { return new Promise((resolve, reject) => { ui.getSkillDefaultRegion((error, region) => (error ? reject(error) : resolve(region))); }); } /** * A Promise that fetches and returns a string specifying the new skill name to use. * * if a templateUrl is provided the user will be presented with a potentially better suited * skill name default option instead of the generic hello world * * @param {string | null} templateUrl the template url to use for attempting to get a skillname instead of the default hello world */ function promptForSkillName(templateUrl) { return new Promise((resolve, reject) => { ui.getSkillName(templateUrl, (error, skillName) => (error ? reject(error) : resolve(skillName))); }); } /** * A promise that fetches and returns a string specifying the new skill project folder name to use/create * * @param {string} skillName The name of the skill provided by the customer * @returns {Promise<string>} Promises to return the customer provided input string specifying the new skill project folder name to use/create */ function promptForProjectFolderName(skillName) { return new Promise((resolve, reject) => { (0, prompt_view_1.getProjectFolderName)(string_utils_1.default.filterNonAlphanumeric(skillName), (error, folderName) => error ? reject(error) : resolve(folderName)); }); } /** * A Promise that fetches the NewSkillTemplateInfo for non-hosted skill * also confirms download for non Alexa official git repos * * @param {Record<string, any>} cmd command object * @param {SampleTemplate[]} samples the unfiltered skill samples templates to resolve * @returns {Promise<NewSkillTemplateInfo>} a Promise that provides the New Skill Template Info <NewSkillTemplateInfo> */ async function promptForTemplateInfo(cmd, samples) { return new Promise((resolve, reject) => { if (!cmd.templateUrl) { ui.getTargetTemplateName(samples, (err, sampleTemplate) => { err ? reject(err) : resolve({ templateUrl: sampleTemplate === null || sampleTemplate === void 0 ? void 0 : sampleTemplate.url, templateName: sampleTemplate === null || sampleTemplate === void 0 ? void 0 : sampleTemplate.name, templateBranch: sampleTemplate === null || sampleTemplate === void 0 ? void 0 : sampleTemplate.branch, }); }); // handle when templateUrl is present in the the command line arguments } else { const templateInfoFromCmd = { templateUrl: cmd.templateUrl, ...(cmd.templateName ? { templateName: cmd.templateName } : {}), ...(cmd.templateBranch ? { templateBranch: cmd.templateBranch } : {}), }; // no warnings/confirmation of download required for official alexa templates if (url_utils_1.default.isUrlOfficialTemplate(cmd.templateUrl)) { resolve(templateInfoFromCmd); } else { messenger_1.default.getInstance().warn(`CLI is about to download the skill template from unofficial template ${cmd.templateUrl}. ` + "Please make sure you understand the source code to best protect yourself from malicious usage."); ui.confirmUsingUnofficialTemplate((confirmErr, confirmResult) => { confirmErr || !confirmResult ? reject(confirmErr) : resolve(templateInfoFromCmd); }); } } }); }