UNPKG

voxa-cli

Version:
200 lines (184 loc) 6.39 kB
/* * Copyright (c) 2018 Rain Agency <contact@rain.agency> * Author: Rain Agency <contact@rain.agency> * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* tslint:disable:no-submodule-imports no-console */ import colors from "colors"; import fs from "fs-extra"; import inquirer from "inquirer"; import _ from "lodash"; import pad from "pad"; import path from "path"; import { Observable } from "rxjs"; import { DEFAULT_INTERACTION_OPTIONS } from "../InteractionBuilder"; export const name = "init"; export const alias = ""; export const description = "create a new interaction.json"; const ALLOWED_ATTRIBUTES = [ "platforms", "spreadsheets", "dialogflowSpreadsheets", "alexaSpreadsheets", "speechPath", "content", "contentPath", "viewsPath" ]; export async function action() { const interactionFile = path.join(process.cwd(), "interaction.json"); let hasAnInteractionFile = false; try { // a path we KNOW is totally bogus and not a module hasAnInteractionFile = require(interactionFile); } catch (e) { if (e.code === "MODULE_NOT_FOUND") { hasAnInteractionFile = false; } } const observe = Observable.create((obs: any) => { const override = (answers: any) => { return answers.interactionFile; }; const onlyCommaAnswer = (input: string) => { return _.chain(input) .split(",") .map(_.trim) .compact() .value(); }; const noEmptyAnswer = (input: string) => !_.isEmpty(input); const mustBeSpreadsheetURLOrLength30 = async (input: string) => { let result: any = _.chain(input) .split(",") .map(_.trim) .compact() .map((i: string) => { if (i.includes("docs.google.com/spreadsheets")) { const matched = i.match(/docs\.google\.com\/spreadsheets\/d\/(.*)\/.*/); return matched && _.isString(matched[1]) && matched[1].length > 30; } if (i.includes(".sharepoint.com") && i.length > 30) { return true; } const customPath = i.indexOf("/") === 0 ? i : path.join(process.cwd(), i); return fs.pathExists(customPath); }) .value(); result = await Promise.all(result); result = result.every((r: boolean) => r); return noEmptyAnswer(input) && result ? true : "Insert a proper google spreadsheet url, Office 365 sharepoint url, local file or local folder path. e.g. https://docs.google.com/spreadsheets/d/XXXXXXX/edit#gid=0, https://XXXXXX.sharepoint.com/:x:/g/personal/YYYYYY/ZZZZZZZ, /Users/local/file.xlsx or /Users/local/sheets/"; }; const questions = [ { type: "confirm", name: "interactionFile", message: `Do you want to override ${interactionFile}?`, when: () => hasAnInteractionFile, default: true }, { type: "checkbox", name: "platforms", message: "Choose platforms", choices: ["alexa", "dialogflow"], when: override }, { type: "input", name: "spreadsheets", message: "Specify all spreadsheets separated by comma (*)", validate: mustBeSpreadsheetURLOrLength30, filter: onlyCommaAnswer, when: override }, { type: "input", name: "speechPath", message: "Specify folder path to save interaction model and manifest", default: DEFAULT_INTERACTION_OPTIONS.speechPath, when: override }, { type: "input", name: "contentPath", message: "Specify folder path to save all downloable content", when: override, default: DEFAULT_INTERACTION_OPTIONS.contentPath }, { type: "input", name: "viewsPath", message: "Specify folder path to save views file", default: DEFAULT_INTERACTION_OPTIONS.viewsPath, when: override }, { type: "confirm", name: "isCorrect", message: `is Correct?`, when: (answers: any) => { if (override(answers)) { printVariables(_.cloneDeep(answers)); } return override(answers); }, default: true } ]; questions.map(q => obs.next(q)); obs.complete(); }); function printVariables(answers: any) { return _.chain(answers) .toPairs() .filter(item => !!ALLOWED_ATTRIBUTES.find(i => i === item[0])) .map(item => { const key = item[0]; const value = item[1]; console.log(pad(colors.blue(key), 20), colors.grey(value)); return item; }) .compact() .fromPairs() .value(); } async function executePrompt(): Promise<any> { return inquirer.prompt(observe).then((answers: any) => { if (answers.interactionFile && !answers.isCorrect) { return executePrompt(); } if (hasAnInteractionFile && !answers.interactionFile) { answers = hasAnInteractionFile; } if (!answers.interactionFile && !answers.isCorrect) { printVariables(answers); } answers = _.pick(answers, ALLOWED_ATTRIBUTES); return fs.outputFile( path.join(process.cwd(), "interaction.json"), JSON.stringify(answers, null, 2), { flag: "w" } ); }); } await executePrompt(); }