UNPKG

@gramio/i18n

Version:

i18n plugin for GramIO with type-safety

77 lines (73 loc) 2.74 kB
import { Plugin } from 'gramio'; import fs from 'node:fs'; import path from 'node:path'; import { FluentBundle, FluentResource } from '@fluent/bundle'; function getFluentClient(options) { const directory = options?.directory ?? "locales"; const bundles = /* @__PURE__ */ new Map(); for (const entry of fs.readdirSync(directory, { withFileTypes: true })) { if (!entry.isFile() || !entry.name.endsWith(".ftl")) continue; const lang = entry.name.slice(0, -4); const source = fs.readFileSync(path.resolve(directory, entry.name)).toString(); const bundle = new FluentBundle(lang); const resource = new FluentResource(source); bundle.addResource(resource); bundles.set(lang, bundle); } const defaultLocale = options?.defaultLocale ?? bundles.keys().next().value; if (!defaultLocale) throw new Error("Please specify one or more translations"); let currentLanguage = defaultLocale; return { languages: { bundles, fallback: defaultLocale, all: Array.from(bundles.keys()), current: currentLanguage, change: (language) => { if (!bundles.has(language)) throw new Error(`No ${language} language found`); currentLanguage = language; } }, t: (id, args) => { const bundle = bundles.get(currentLanguage); if (!bundle) throw new Error(`No ${currentLanguage} language found`); const message = bundle.getMessage(id); if (!message?.value) throw new Error(`No message found for ${id}`); return bundle.formatPattern(message.value, args); } }; } function i18n(options) { const client = options && "t" in options ? options : getFluentClient(options); return new Plugin("@gramio/i18n").derive(() => { let language = client.languages.current; return { /** Object with localization utils and settings */ i18n: { /** All languages */ locales: client.languages.all, /** Current user locale */ locale: language, /** Set locale to current user */ setLocale: (lang, strict = false) => { if (!client.languages.all.includes(lang)) { if (strict) throw new Error(`No ${language} language found`); language = client.languages.fallback; return; } language = lang; } }, t: (id, args) => { const bundle = client.languages.bundles.get(language); if (!bundle) throw new Error(`No ${language} language found`); const message = bundle.getMessage(id); if (!message?.value) throw new Error(`No message found for ${id}`); return bundle.formatPattern(message.value, args); } }; }); } export { getFluentClient, i18n };