botnaut
Version:
Facebook Messenger Chatbot Framework
133 lines (119 loc) • 3.8 kB
JavaScript
;
const fs = require('fs');
const path = require('path');
let po2json;
try {
po2json = module.require('po2json');
} catch (er) {
po2json = null;
}
/**
* Tool for text translation
*
* @class Translate
*/
class Translate {
/**
*
* @param {object} [options]
* @param {string} [options.sourcePath] - optional source path of translation folder
* @param {string} [options.fileSuffix] - by default `.locale.po`
*/
constructor (options = {}) {
this._options = Object.assign({
sourcePath: path.join(process.cwd(), 'locales'),
fileSuffix: '.locale.po'
}, options);
this._promisedTranslators = {};
if (!po2json) {
throw new Error('Missing po2json module');
}
}
_getTranslator (lang) {
if (lang === null) {
return Promise.resolve(w => w);
}
if (!this._promisedTranslators[lang]) {
this._promisedTranslators[lang] = new Promise(
(resolve, reject) => {
const filePath = path.join(this._options.sourcePath, `${lang}${this._options.fileSuffix}`);
fs.readFile(filePath, 'utf8', (err, data) => {
if (err) {
reject(err);
return;
}
resolve(data);
});
})
.then((content) => {
const messages = po2json.parse(content, { format: 'mf' });
// return translator for the locale
return key => (typeof messages[key] !== 'undefined' ? messages[key] : key);
});
}
return this._promisedTranslators[lang];
}
/**
* Creates static translator for static settings
*
* @param {string[]} languages - list of required languages
* @returns {Promise.<object>}
* @example
* const { Translate } = require('botnaut');
*
* const translate = new Translate({ sourcePath: __dirname });
*
* const t = translate.translator(['cs', 'en']);
*
* // czech
* t.cs.t('requested text');
*
* // english
* t.en.t('requested text');
*/
translator (languages) {
if (!Array.isArray(languages) || typeof languages[0] !== 'string') {
throw new Error('Language list should be non-empty array of strings');
}
return Promise.all(languages.map(lang => this._getTranslator(lang)))
.then(translatorsArray => languages.reduce((obj, lang, index) =>
Object.assign(obj, {
[lang]: {
t: translatorsArray[index]
}
}), {})
);
}
/**
* Bots middleware for text translations
*
* - will be looking for `<lang>.locale.po` by default
*
* @param {Function} languageResolver
* @returns {function(*, *)}
* @example
* const { Translate } = require('botnaut');
*
* const translate = new Translate({ sourcePath: __dirname });
*
* bot.use(translate.middleware((req, res) => 'cs'));
*
* bot.use((req, res) => {
* res.text(res.t('Translated text'));
* });
*/
middleware (languageResolver) {
return (req, res) => {
const lang = languageResolver(req);
return this._getTranslator(lang)
.then((translator) => {
Object.assign(res, {
t: translator,
tq: translator
});
return true; // continue
});
};
}
}
module.exports = Translate;