mirror of
https://github.com/documenso/documenso.git
synced 2025-11-13 00:03:33 +10:00
87 lines
2.4 KiB
TypeScript
87 lines
2.4 KiB
TypeScript
import type { I18n, MessageDescriptor } from '@lingui/core';
|
|
import { i18n } from '@lingui/core';
|
|
|
|
import type { I18nLocaleData, SupportedLanguageCodes } from '../constants/i18n';
|
|
import { APP_I18N_OPTIONS } from '../constants/i18n';
|
|
import { env } from './env';
|
|
|
|
export async function getTranslations(locale: string) {
|
|
const extension = env('NODE_ENV') === 'development' ? 'po' : 'mjs';
|
|
|
|
const { messages } = await import(`../translations/${locale}/web.${extension}`);
|
|
|
|
return messages;
|
|
}
|
|
|
|
export async function dynamicActivate(locale: string) {
|
|
const messages = await getTranslations(locale);
|
|
|
|
i18n.loadAndActivate({ locale, messages });
|
|
}
|
|
|
|
const parseLanguageFromLocale = (locale: string): SupportedLanguageCodes | null => {
|
|
const [language, _country] = locale.split('-');
|
|
|
|
const foundSupportedLanguage = APP_I18N_OPTIONS.supportedLangs.find(
|
|
(lang): lang is SupportedLanguageCodes => lang === language,
|
|
);
|
|
|
|
if (!foundSupportedLanguage) {
|
|
return null;
|
|
}
|
|
|
|
return foundSupportedLanguage;
|
|
};
|
|
|
|
/**
|
|
* Extracts the language from the `accept-language` header.
|
|
*/
|
|
export const extractLocaleDataFromHeaders = (
|
|
headers: Headers,
|
|
): { lang: SupportedLanguageCodes | null; locales: string[] } => {
|
|
const headerLocales = (headers.get('accept-language') ?? '').split(',');
|
|
|
|
const language = parseLanguageFromLocale(headerLocales[0]);
|
|
|
|
return {
|
|
lang: language,
|
|
locales: [headerLocales[0]],
|
|
};
|
|
};
|
|
|
|
type ExtractLocaleDataOptions = {
|
|
headers: Headers;
|
|
};
|
|
|
|
/**
|
|
* Extract the supported language from the header.
|
|
*
|
|
* Will return the default fallback language if not found.
|
|
*/
|
|
export const extractLocaleData = ({ headers }: ExtractLocaleDataOptions): I18nLocaleData => {
|
|
const headerLocales = (headers.get('accept-language') ?? '').split(',');
|
|
|
|
const unknownLanguages = headerLocales
|
|
.map((locale) => parseLanguageFromLocale(locale))
|
|
.filter((value): value is SupportedLanguageCodes => value !== null);
|
|
|
|
// Filter out locales that are not valid.
|
|
const languages = (unknownLanguages ?? []).filter((language) => {
|
|
try {
|
|
new Intl.Locale(language);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
});
|
|
|
|
return {
|
|
lang: languages[0] || APP_I18N_OPTIONS.sourceLang,
|
|
locales: headerLocales,
|
|
};
|
|
};
|
|
|
|
export const parseMessageDescriptor = (_: I18n['_'], value: string | MessageDescriptor) => {
|
|
return typeof value === 'string' ? value : _(value);
|
|
};
|