@gramio/i18n
Version:
i18n plugin for GramIO with type-safety
86 lines (80 loc) • 2.53 kB
JavaScript
import { FormattableString } from 'gramio';
function buildLanguage(languageRaw) {
const texts = {};
function recursiveAdd(textsRaw, prefix = "") {
for (const [key, value] of Object.entries(textsRaw)) {
const newPrefix = `${prefix}${key}`;
if (typeof value === "object" && !(value instanceof FormattableString)) {
recursiveAdd(value, `${newPrefix}.`);
} else {
texts[newPrefix] = value;
}
}
}
recursiveAdd(languageRaw);
return texts;
}
function buildT(languages, primaryLanguage) {
const languagesTexts = {};
for (const [language, texts] of Object.entries(languages)) {
languagesTexts[language] = buildLanguage(texts);
}
return function t(language, key, ...args) {
const fallbackItem = languagesTexts[primaryLanguage][key];
const item = languagesTexts[language] ? languagesTexts[language][key] ?? fallbackItem : fallbackItem;
if (typeof item === "function") return item(...args);
return item;
};
}
function pluralizeEnglish(n, one, many) {
return n === 1 ? one : many;
}
function pluralizeRussian(count, one, few, many) {
const mod10 = count % 10;
const mod100 = count % 100;
if (mod10 === 1 && mod100 !== 11) return one;
if (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 >= 20)) return few;
return many;
}
function defineI18n({ languages, primaryLanguage }) {
const t = buildT(languages, primaryLanguage);
return {
t,
languages: Object.keys(languages),
primaryLanguage,
buildT: (language) => {
return (key, ...args) => t(language, key, ...args);
},
/**
* Generate a `{ languageCode: description }` record for all non-primary languages.
* Designed for use with `CommandMeta.locales` in `syncCommands()`.
*
* Only includes languages where the key resolves to a plain string (no args).
*
* @example
* ```ts
* bot.command("help", {
* description: i18n.t("en", "cmd.help"),
* locales: i18n.localesFor("cmd.help"),
* }, (ctx) => ctx.send("Help"));
* ```
*/
localesFor(key, ...args) {
const result = {};
for (const lang of Object.keys(languages)) {
if (lang === primaryLanguage) continue;
const value = t(lang, key, ...args);
if (value != null) {
result[lang] = String(value);
}
}
return result;
},
_: {
languages,
primaryLanguage
}
// plugin: () => {},
};
}
export { defineI18n, pluralizeEnglish, pluralizeRussian };