web/i18n: dynamically determine languages from i18n folder contents

This commit is contained in:
dumbmoron 2024-07-03 19:28:44 +00:00
parent 3e9296ac1e
commit 8fd2c66441
No known key found for this signature in database
3 changed files with 50 additions and 114 deletions

View file

@ -1,125 +1,48 @@
import i18n from 'sveltekit-i18n'; import i18n from 'sveltekit-i18n';
import type { Config } from 'sveltekit-i18n';
import type { Config } from 'sveltekit-i18n'
import type {
GenericImport,
StructuredLocfileInfo,
LocalizationContent
} from '$lib/types/i18n';
import languages from '$i18n/languages.json'; import languages from '$i18n/languages.json';
export const defaultLocale = 'en'; const locFiles = import.meta.glob('$i18n/*/**/*.json');
const parsedLocfiles: StructuredLocfileInfo = {};
export const config: Config = { for (const [ path, loader ] of Object.entries(locFiles)) {
translations: { const [,, lang, ...keyComponents ] = path.split('/');
en: { languages }, const key = keyComponents.map(k => k.replace('.json', '')).join('.');
ru: { languages }, parsedLocfiles[lang] = {
}, ...parsedLocfiles[lang],
loaders: [ [key]: loader as GenericImport
{ };
locale: 'en', }
key: 'tabs',
loader: async () => (
await import(`$i18n/en/tabs.json`)
).default,
},
{
locale: 'en',
key: 'a11y.tabs',
loader: async () => (
await import(`$i18n/en/a11y/tabs.json`)
).default,
},
{
locale: 'en',
key: 'save',
loader: async () => (
await import(`$i18n/en/save.json`)
).default,
},
{
locale: 'en',
key: 'a11y.save',
loader: async () => (
await import(`$i18n/en/a11y/save.json`)
).default,
},
{
locale: 'en',
key: 'a11y.meowbalt',
loader: async () => (
await import(`$i18n/en/a11y/meowbalt.json`)
).default,
},
{
locale: 'en',
key: 'settings',
loader: async () => (
await import(`$i18n/en/settings.json`)
).default,
},
{
locale: 'en',
key: 'general',
loader: async () => (
await import(`$i18n/en/general.json`)
).default,
},
{
locale: 'en',
key: 'a11y.general',
loader: async () => (
await import(`$i18n/en/a11y/general.json`)
).default,
},
{ const defaultLocale = 'en';
locale: 'ru', const config: Config = {
key: 'tabs', translations: Object.keys(parsedLocfiles).reduce((obj, lang) => {
loader: async () => ( return {
await import(`$i18n/ru/tabs.json`) ...obj,
).default, [lang]: { languages }
}, }
{ }, {}),
locale: 'ru', loaders: Object.entries(parsedLocfiles).map(([ lang, keys ]) => {
key: 'a11y.tabs', return Object.entries(keys).map(([ key, importer ]) => {
loader: async () => ( return {
await import(`$i18n/ru/a11y/tabs.json`) locale: lang,
).default, key,
}, loader: () => importer().then(
{ l => l.default as LocalizationContent
locale: 'ru', )
key: 'save', }
loader: async () => ( });
await import(`$i18n/ru/save.json`) }).flat()
).default,
},
{
locale: 'ru',
key: 'a11y.save',
loader: async () => (
await import(`$i18n/ru/a11y/save.json`)
).default,
},
{
locale: 'ru',
key: 'a11y.meowbalt',
loader: async () => (
await import(`$i18n/ru/a11y/meowbalt.json`)
).default,
},
{
locale: 'ru',
key: 'general',
loader: async () => (
await import(`$i18n/ru/general.json`)
).default,
},
{
locale: 'ru',
key: 'a11y.general',
loader: async () => (
await import(`$i18n/ru/a11y/general.json`)
).default,
},
],
}; };
export { defaultLocale };
export const { export const {
t, loading, locales, locale, translations, t, loading, locales, locale, translations,
loadTranslations, addTranslations, setLocale, setRoute loadTranslations, addTranslations, setLocale, setRoute

View file

@ -6,3 +6,5 @@ export type RecursivePartial<Type> = {
Type[Key] extends object | undefined ? RecursivePartial<Type[Key]> : Type[Key] extends object | undefined ? RecursivePartial<Type[Key]> :
Type[Key]; Type[Key];
}; };
export type DefaultImport<T> = () => Promise<{ default: T }>;

11
web/src/lib/types/i18n.ts Normal file
View file

@ -0,0 +1,11 @@
import type { DefaultImport } from '$lib/types/generic';
type LanguageCode = string;
type KeyPath = string;
export type GenericImport = DefaultImport<unknown>;
export type LocalizationContent = Record<string, string>;
export type StructuredLocfileInfo = Record<
LanguageCode,
Record<KeyPath, GenericImport>
>;