jovo-cli
Version:
jovo command line tool (beta)
285 lines • 10.1 kB
JavaScript
;
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const command_1 = require("@oclif/command");
const chalk_1 = __importDefault(require("chalk"));
const csvtojson_1 = __importDefault(require("csvtojson"));
const fs_extra_1 = require("fs-extra");
const lodash_1 = __importDefault(require("lodash"));
const Listr = require("listr");
const utils_1 = require("../utils");
class Convert extends command_1.Command {
async run() {
const { args, flags } = this.parse(Convert);
const origin = flags.from;
let target = flags.to;
if (!isValidOrigin(origin)) {
return;
}
this.log(`\n jovo convert: ${Convert.description}`);
this.log(chalk_1.default.grey(' >> Learn more: https://jovo.tech/docs/cli/convert\n'));
target = target ? target.replace(/\/?$/, '/') : target;
const tasksArr = [];
let successMsg, failMsg = '';
switch (args.fn) {
case 'i18nToCsv':
{
tasksArr.push({
title: 'Converting to .csv file...',
async task(ctx) {
ctx.csv = await new Promise((res) => setTimeout(() => {
const model = toCsv(fromI18N(origin));
res(model);
}, 500));
},
}, {
title: 'Writing .csv file...',
async task(ctx) {
await new Promise((res) => setTimeout(() => {
fs_extra_1.writeFileSync(`${target || './'}responses.csv`, ctx.csv);
res();
}, 500));
},
});
successMsg = 'Successfully converted i18n to csv.';
failMsg = 'Something went wrong while converting from i18n. Check the logs below:\n';
}
break;
case 'csvToI18n':
{
tasksArr.push({
title: 'Converting to i18n files...',
async task(ctx) {
ctx.model = await new Promise((res) => setTimeout(async () => {
const model = toI18N(await fromCsv(origin));
res(model);
}, 500));
},
}, {
title: 'Writing i18n files...',
async task(ctx) {
await new Promise((res) => setTimeout(() => {
const { model } = ctx;
for (const locale of Object.keys(model)) {
const dest = target || './src/i18n/';
if (!fs_extra_1.existsSync(dest)) {
fs_extra_1.mkdirSync(dest);
}
fs_extra_1.writeFileSync(`${dest}${locale}.json`, JSON.stringify(model[locale], null, 4));
}
res();
}, 500));
},
});
successMsg = 'Successfully converted csv to i18n.';
failMsg = 'Something went wrong while converting from csv. Check the logs below:\n';
}
break;
default: {
}
}
const tasks = new Listr(tasksArr, {
renderer: new utils_1.JovoCliRenderer(),
collapse: false,
});
try {
await tasks.run();
this.log();
this.log(successMsg);
this.log();
}
catch (err) {
this.error(`${failMsg}\n${err}`);
}
}
}
exports.Convert = Convert;
Convert.description = 'Converts .csv-files to i18n.json-files and vice versa.';
Convert.examples = [
'jovo convert i18nToCsv --from ./i18n/',
'jovo convert csvToI18n --from ./responses.csv',
];
Convert.flags = {
from: command_1.flags.string({
description: 'The path to your src file.',
}),
to: command_1.flags.string({
description: 'Destination path.',
}),
};
Convert.args = [{ name: 'fn', options: ['i18nToCsv', 'csvToI18n'], required: true }];
function isValidOrigin(origin) {
if (!origin) {
console.log('\nThe path from your originating files has to be set.\n\nYou can choose between setting a single file or an entire folder.');
return false;
}
return true;
}
async function fromCsv(path) {
return await csvtojson_1.default().fromFile(path);
}
function toCsv(model) {
if (!model) {
throw new Error('Something went wrong!');
}
const keys = Object.keys(model[0]);
let csv = keys.join(',');
for (const keyValue of model) {
csv += `\n${Object.values(keyValue).join(',')}`;
}
return csv;
}
function fromI18N(path) {
let files = [];
if (path.indexOf('.json', path.length - 5) !== -1) {
const pathArr = path.split('/');
files.push(pathArr.pop());
path = pathArr.join('/');
}
else {
files = fs_extra_1.readdirSync(path);
}
const model = [];
for (const entry of files) {
const i18nModel = JSON.parse(fs_extra_1.readFileSync(`${path}/${entry}`, 'utf8'));
const locale = entry.replace('.json', '');
parseI18nModel(locale, i18nModel, model);
}
return model;
}
function parseI18nModel(locale, i18nModel, model) {
for (const prop of Object.keys(i18nModel)) {
if (prop === 'translation') {
for (const key of Object.keys(i18nModel[prop])) {
const value = i18nModel[prop][key];
switch (value.constructor) {
case Array:
{
for (const v of value) {
writeToJson(locale, key, v, model);
}
}
break;
case String:
{
writeToJson(locale, key, value, model);
}
break;
case Object: {
for (const subKey of Object.keys(value)) {
writeToJson(locale, `${key}.${subKey}`, value[subKey], model);
}
}
default: {
}
}
}
}
else {
parseI18nModel(`${locale}-${prop}`, i18nModel[prop], model);
}
}
return model;
}
function writeToJson(locale, key, value, model) {
if (value.includes(',')) {
value = `"${value}"`;
}
let index;
for (const [i, keyValue] of model.entries()) {
if (!keyValue[locale]) {
keyValue[locale] = '';
}
if (keyValue.key === key) {
index = i;
if (keyValue[locale] && keyValue[locale] !== '') {
index = undefined;
continue;
}
}
}
if (index) {
model[index][locale] = value;
}
else {
const entry = {};
if (model[0]) {
for (const k of Object.keys(model[0])) {
if (k === 'key') {
entry[k] = key;
}
else {
entry[k] = '';
}
}
entry[locale] = value;
}
else {
entry.key = key;
entry[locale] = value;
}
model.push(entry);
}
}
function toI18N(model) {
const i18n = {};
for (const keyValue of model) {
const { key } = keyValue, locales = __rest(keyValue, ["key"]);
for (const locale of Object.keys(locales)) {
if (!i18n[locale]) {
i18n[locale] = {
translation: {},
};
}
const value = keyValue[locale];
let existingValue = i18n[locale].translation[key];
if (!value && !existingValue) {
continue;
}
if (!existingValue) {
existingValue = value;
}
else {
switch (existingValue.constructor) {
case String:
{
existingValue = [existingValue, value];
}
break;
case Array:
{
existingValue.push(value);
}
break;
default: {
}
}
}
lodash_1.default.set(i18n[locale].translation, key, existingValue);
}
}
for (const key of Object.keys(i18n)) {
for (const platform of ['AlexaSkill', 'GoogleAction']) {
const locale = `${key}-${platform}`;
if (i18n[locale]) {
i18n[key][platform] = i18n[locale];
delete i18n[locale];
}
}
}
return i18n;
}
//# sourceMappingURL=convert.js.map