voxa-cli
Version:
The Voxa CLI tools
340 lines • 15.9 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/*
* 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 */
const lodash_1 = __importDefault(require("lodash"));
const VoxaSheet_1 = require("./VoxaSheet");
function sheetLocale(voxaSheet, AVAILABLE_LOCALES) {
let locale = AVAILABLE_LOCALES.find((loc) => {
let lastDotIndex = lodash_1.default.lastIndexOf(voxaSheet.spreadsheetTitle, ".");
lastDotIndex = lastDotIndex === -1 ? voxaSheet.spreadsheetTitle.length : lastDotIndex;
const titleWithoutExtension = lodash_1.default.toLower(voxaSheet.spreadsheetTitle.slice(0, lastDotIndex));
return lodash_1.default.endsWith(titleWithoutExtension, lodash_1.default.toLower(loc));
});
locale = locale || AVAILABLE_LOCALES[0];
return locale;
}
exports.sheetLocale = sheetLocale;
function downloadProcessor(voxaSheets, AVAILABLE_LOCALES) {
const voxaSheetsDownloads = voxaSheets.filter(voxaSheet => lodash_1.default.includes([VoxaSheet_1.SheetTypes.DOWNLOAD], VoxaSheet_1.getSheetType(voxaSheet)));
return voxaSheetsDownloads.map((voxaSheet) => {
const locale = sheetLocale(voxaSheet, AVAILABLE_LOCALES);
const sheetPlaceholder = VoxaSheet_1.getSheetType(voxaSheet);
const name = (voxaSheet.sheetTitle = voxaSheet.sheetTitle.replace(sheetPlaceholder, ""));
const data = lodash_1.default.chain(voxaSheet.data)
.filter(item => {
const tempItem = lodash_1.default.omitBy(item, lodash_1.default.isEmpty);
return !lodash_1.default.isEmpty(tempItem);
})
.value();
const download = { name, data, locale };
return download;
});
}
exports.downloadProcessor = downloadProcessor;
function invocationProcessor(voxaSheets, AVAILABLE_LOCALES) {
const voxaSheetsInvocations = voxaSheets.filter(voxaSheet => lodash_1.default.includes([VoxaSheet_1.SheetTypes.INVOCATION], VoxaSheet_1.getSheetType(voxaSheet)));
return voxaSheetsInvocations.reduce((acc, voxaSheet) => {
const locale = sheetLocale(voxaSheet, AVAILABLE_LOCALES);
voxaSheet.data.map((item) => {
const { environment, invocationName } = item;
acc.push({ name: invocationName, environment, locale });
});
return acc;
}, []);
}
exports.invocationProcessor = invocationProcessor;
function viewsProcessor(voxaSheets, AVAILABLE_LOCALES) {
function sanitizeView(text = "") {
return text
.replace(/’/g, "'")
.replace(/’/g, "'")
.replace(/“/g, '"')
.replace(/”/g, '"')
.replace(/&/g, "and");
}
const voxaSheetsViews = voxaSheets.filter(voxaSheet => lodash_1.default.includes([VoxaSheet_1.SheetTypes.VIEWS], VoxaSheet_1.getSheetType(voxaSheet)));
return voxaSheetsViews.map((voxaSheet) => {
const locale = voxaSheet.sheetTitle.split("@")[1] || AVAILABLE_LOCALES[0];
const data = lodash_1.default.chain(voxaSheet.data)
.reduce((acc, view) => {
const { path } = view;
const pathLowerCase = lodash_1.default.toLower(path);
let { value } = view;
if (lodash_1.default.isEmpty(path)) {
return acc;
}
const shouldBeArray = [".text", ".say", ".reprompt", ".tell", ".ask"].find(suffix => path.includes(suffix));
const isGA = [".ga"].find(option => lodash_1.default.endsWith(pathLowerCase, option));
const isASuggestionChip = [".dialogflowsuggestions", ".facebooksuggestionchips"].find(option => lodash_1.default.endsWith(pathLowerCase, option));
if (shouldBeArray && lodash_1.default.isString(value) && !lodash_1.default.isEmpty(value)) {
const temp = lodash_1.default.get(acc, path, []);
temp.push(sanitizeView(value));
value = temp;
}
if (!lodash_1.default.isEmpty(value) && isASuggestionChip) {
value = value.split("\n").map((v) => v.trim());
}
if (!lodash_1.default.isEmpty(value) && isGA) {
value = value.split("\n").reduce((accGA, next, index) => {
if (index === 0) {
accGA.ec = next;
accGA.ea = next;
}
if (index === 1) {
accGA.ea = next;
}
if (index === 2) {
accGA.el = next;
}
return accGA;
}, {});
const temp = lodash_1.default.get(acc, path, []);
temp.push(value);
value = temp;
}
lodash_1.default.set(acc, path, value);
return acc;
}, {})
.value();
const viewResult = { data, locale };
return viewResult;
});
}
exports.viewsProcessor = viewsProcessor;
function slotProcessor(voxaSheets, AVAILABLE_LOCALES) {
const voxaSheetsSlots = voxaSheets.filter(voxaSheet => lodash_1.default.includes([VoxaSheet_1.SheetTypes.SLOTS], VoxaSheet_1.getSheetType(voxaSheet)));
return voxaSheetsSlots.map((voxaSheet) => {
const locale = sheetLocale(voxaSheet, AVAILABLE_LOCALES);
const name = voxaSheet.sheetTitle;
const values = lodash_1.default.chain(voxaSheet.data)
.groupBy("synonym")
.toPairs()
.reduce((acc, slot) => {
const key = slot[0];
const synonyms = slot[1] || [];
if (key === undefined || key === "undefined") {
acc.push(synonyms.map(synonymName => ({ value: synonymName[name], synonyms: [] })));
}
else {
acc.push({ value: key, synonyms: lodash_1.default.map(synonyms, name) });
}
return acc;
}, [])
.flattenDeep()
.filter("value")
.uniq()
.value();
const slotResult = { name, values, locale };
return slotResult;
});
}
exports.slotProcessor = slotProcessor;
function intentUtterProcessor(voxaSheets, AVAILABLE_LOCALES) {
const voxaSheetsIntent = filterSheets(voxaSheets, [VoxaSheet_1.SheetTypes.INTENT]);
const voxaSheetsUtter = lodash_1.default.reduce(filterSheets(voxaSheets, [VoxaSheet_1.SheetTypes.UTTERANCE]), reduceIntent("utterance"), []);
const voxaSheetResponses = lodash_1.default.reduce(filterSheets(voxaSheets, [VoxaSheet_1.SheetTypes.RESPONSES]), reduceIntent("response"), []);
const voxaSheetPrompts = lodash_1.default.reduce(filterSheets(voxaSheets, [VoxaSheet_1.SheetTypes.PROMPTS]), reduceIntent("prompt"), []);
const result = lodash_1.default.chain(voxaSheetsIntent)
.map((voxaSheetIntent) => {
const locale = sheetLocale(voxaSheetIntent, AVAILABLE_LOCALES);
let previousIntent;
voxaSheetIntent.data = lodash_1.default.chain(voxaSheetIntent.data)
.map(row => {
const info = lodash_1.default.pick(row, [
"Intent",
"slotType",
"slotName",
"slotRequired",
"environment",
"platformIntent",
"events",
"canFulfillIntent",
"startIntent",
"signInRequired",
"endIntent",
"platformSlot",
"webhookForSlotFilling",
"webhookUsed",
"delegationStrategy",
"confirmationRequired",
"slotConfirmationRequired",
"slotElicitationRequired",
"parameterName",
"parameterValue"
]);
previousIntent = lodash_1.default.isEmpty(info.Intent) ? previousIntent : info.Intent;
info.Intent = previousIntent;
return info;
})
.uniq()
.groupBy("Intent")
.toPairs()
.reduce((acc, item) => {
const intentName = item[0];
const head = lodash_1.default.head(item[1]);
const events = splitValues(head, "events");
const environments = splitValues(head, "environment");
const platforms = splitValues(head, "platformIntent", true);
const signInRequired = lodash_1.default.get(head, "signInRequired", false);
const webhookForSlotFilling = (lodash_1.default.get(head, "webhookForSlotFilling", false) ||
lodash_1.default.get(head, "useWebhookForSlotFilling", false));
const webhookUsed = !!lodash_1.default.get(head, "webhookUsed", true);
const canFulfillIntent = lodash_1.default.get(head, "canFulfillIntent", false);
const startIntent = lodash_1.default.get(head, "startIntent", false);
const endIntent = lodash_1.default.get(head, "endIntent", false);
const confirmationRequired = !!lodash_1.default.get(head, "confirmationRequired", false);
const delegationStrategy = lodash_1.default.get(head, "delegationStrategy");
const parameterName = lodash_1.default.get(head, "parameterName");
const parameterValue = lodash_1.default.get(head, "parameterValue");
const samples = getIntentValueList(voxaSheetsUtter, voxaSheetIntent.spreadsheetId, intentName, "utterance");
const responses = getIntentValueList(voxaSheetResponses, voxaSheetIntent.spreadsheetId, intentName, "response");
const confirmations = getIntentValueList(voxaSheetPrompts, voxaSheetIntent.spreadsheetId, `${intentName}/confirmation`, "prompt");
const slotsDefinition = lodash_1.default.chain(item[1])
.filter("slotName")
.map((slot) => ({
name: slot.slotName,
type: slot.slotType,
platform: slot.platformSlot,
required: !!slot.slotRequired || false,
requiresConfirmation: !!slot.slotConfirmationRequired || false,
requiresElicitation: !!slot.slotElicitationRequired || false,
samples: getIntentValueList(voxaSheetsUtter, voxaSheetIntent.spreadsheetId, `${intentName}/${slot.slotName}`, "utterance"),
prompts: {
confirmation: getIntentValueList(voxaSheetPrompts, voxaSheetIntent.spreadsheetId, `${intentName}/${slot.slotName}/confirmation`, "prompt"),
elicitation: getIntentValueList(voxaSheetPrompts, voxaSheetIntent.spreadsheetId, `${intentName}/${slot.slotName}/elicitation`, "prompt")
}
}))
.compact()
.uniq()
.value();
const intent = {
name: intentName,
samples,
responses,
slotsDefinition,
webhookForSlotFilling,
webhookUsed,
canFulfillIntent,
startIntent,
endIntent,
events,
confirmations,
environments,
platforms,
locale,
signInRequired,
confirmationRequired,
delegationStrategy,
parameterName,
parameterValue
};
acc.push(intent);
return acc;
}, [])
.value();
return voxaSheetIntent.data;
})
.flattenDeep()
.value();
return result;
}
exports.intentUtterProcessor = intentUtterProcessor;
function publishingProcessor(voxaSheets, AVAILABLE_LOCALES) {
const voxaSheetsPublishing = voxaSheets.filter(voxaSheet => lodash_1.default.includes([
VoxaSheet_1.SheetTypes.SKILL_ENVIRONMENTS,
VoxaSheet_1.SheetTypes.SKILL_LOCALE_INFORMATION,
VoxaSheet_1.SheetTypes.SKILL_GENERAL_INFORMATION
], VoxaSheet_1.getSheetType(voxaSheet)));
return voxaSheetsPublishing.reduce((acc, voxaSheet) => {
voxaSheet.data.map((item) => {
const locale = voxaSheet.sheetTitle.split("@")[1] || AVAILABLE_LOCALES[0];
const environments = lodash_1.default.chain(item)
.get("environment", "")
.split(",")
.map(lodash_1.default.trim)
.compact()
.value();
const key = lodash_1.default.chain(item)
.get("key", "")
.replace("{locale}", locale)
.value();
let value = lodash_1.default.chain(item)
.get("value", "")
.value();
const containsParseNumberKey = ["maxWidth", "minWidth", "maxHeight", "minHeight"].some(s => key.includes(s));
if (containsParseNumberKey && lodash_1.default.toNumber(value)) {
value = lodash_1.default.toNumber(value);
}
const publishInfo = { key, value, environments };
acc.push(publishInfo);
});
return acc;
}, []);
}
exports.publishingProcessor = publishingProcessor;
function filterSheets(voxaSheets, sheetTypes) {
return lodash_1.default.filter(voxaSheets, voxaSheet => lodash_1.default.includes(sheetTypes, VoxaSheet_1.getSheetType(voxaSheet)));
}
exports.filterSheets = filterSheets;
function reduceIntent(propName) {
return (acc, row) => {
row.data = lodash_1.default.chain(row.data)
.reduce((accData, item) => {
lodash_1.default.map(item, (value, key) => {
const obj = { intent: key };
obj[propName] = value;
accData.push(obj);
});
return accData;
}, [])
.groupBy("intent")
.value();
acc.push(row);
return acc;
};
}
function splitValues(head, propertyName, shouldLowerCase) {
let splittedValue = lodash_1.default.chain(head)
.get(propertyName, "")
.split(",")
.map(lodash_1.default.trim);
if (shouldLowerCase) {
splittedValue = splittedValue.map(lodash_1.default.toLower);
}
return splittedValue.compact().value();
}
function getIntentValueList(voxaSheets, spreadsheetId, intentName, key) {
return lodash_1.default(voxaSheets)
.filter(sheet => sheet.spreadsheetId === spreadsheetId)
.map((spreadSheet) => spreadSheet.data[intentName] || [])
.flatten()
.map(key)
.compact()
.uniq()
.value();
}
//# sourceMappingURL=Processor.js.map