mostly because code is being autogenerated by all the AI stuff using this prefix. it's also used in the stack trace.
76 lines
2.6 KiB
JavaScript
76 lines
2.6 KiB
JavaScript
'use strict';
|
|
|
|
exports = module.exports = {
|
|
translate,
|
|
getTranslations,
|
|
listLanguages
|
|
};
|
|
|
|
const assert = require('node:assert'),
|
|
cloudron = require('./cloudron.js'),
|
|
debug = require('debug')('box:translation'),
|
|
fs = require('node:fs'),
|
|
path = require('node:path'),
|
|
paths = require('./paths.js'),
|
|
safe = require('safetydance');
|
|
|
|
// to be used together with getTranslations() => { translations, fallback }
|
|
function translate(input, assets) {
|
|
assert.strictEqual(typeof input, 'string');
|
|
assert.strictEqual(typeof assets, 'object');
|
|
assert.strictEqual(typeof assets.translations, 'object');
|
|
assert.strictEqual(typeof assets.fallback, 'object');
|
|
|
|
const { translations, fallback } = assets;
|
|
|
|
const tokens = input.match(/{{(.*?)}}/gm);
|
|
if (!tokens) return input;
|
|
|
|
let output = input;
|
|
for (const token of tokens) {
|
|
const key = token.slice(2).slice(0, -2).trim();
|
|
let value = key.split('.').reduce(function (acc, cur) {
|
|
if (acc === null) return null;
|
|
return typeof acc[cur] !== 'undefined' ? acc[cur] : null;
|
|
}, translations);
|
|
|
|
// try fallback
|
|
if (value === null) value = key.split('.').reduce(function (acc, cur) {
|
|
if (acc === null) return null;
|
|
return typeof acc[cur] !== 'undefined' ? acc[cur] : null;
|
|
}, fallback);
|
|
|
|
if (value === null) value = token;
|
|
|
|
output = output.replace(token, value);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
async function getTranslations() {
|
|
const fallbackData = fs.readFileSync(path.join(paths.TRANSLATIONS_DIR, 'en.json'), 'utf8');
|
|
if (!fallbackData) debug(`getTranslations: Fallback language en not found. ${safe.error.message}`);
|
|
const fallback = safe.JSON.parse(fallbackData) || {};
|
|
|
|
const lang = await cloudron.getLanguage();
|
|
|
|
const translationData = safe.fs.readFileSync(path.join(paths.TRANSLATIONS_DIR, `${lang}.json`), 'utf8');
|
|
if (!translationData) debug(`getTranslations: Requested language ${lang} not found. ${safe.error.message}`);
|
|
const translations = safe.JSON.parse(translationData) || {};
|
|
|
|
return { translations, fallback };
|
|
}
|
|
|
|
async function listLanguages() {
|
|
const [error, result] = await safe(fs.promises.readdir(paths.TRANSLATIONS_DIR));
|
|
if (error) {
|
|
debug(`listLanguages: Failed to list translations. %${error.message}`);
|
|
return [ 'en' ]; // we always return english to avoid dashboard breakage
|
|
}
|
|
|
|
const jsonFiles = result.filter(function (file) { return path.extname(file) === '.json'; });
|
|
const languages = jsonFiles.map(function (file) { return path.basename(file, '.json'); });
|
|
return languages;
|
|
}
|