Skip to content

Commit

Permalink
feat: make translations extensible
Browse files Browse the repository at this point in the history
  • Loading branch information
paring-chan committed Mar 20, 2024
1 parent ccbaa89 commit c7fdbab
Showing 1 changed file with 40 additions and 49 deletions.
89 changes: 40 additions & 49 deletions src/lib/utils/translation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,45 +11,61 @@ export const availableLanguages: LangResponse[] = langs

export const fallbackLang = 'en'

export type ExtraLangSections = []
const registeredLangSections: string[] = []

const langSections = ['common', 'footer', 'nav'] as const

export type LangSection = (typeof langSections)[number]
export type LangData = Record<LangSection, FluentBundle>
export type LangSection = (typeof langSections)[number] | ExtraLangSections[number]
export type LangData = Record<string, FluentBundle>
// eslint-disable-next-line @typescript-eslint/ban-types
export type StringTranslationKey = `${LangSection}:` | (`${LangSection}:${string & {}}` & {})
export type ArrayTranslationKey = [LangSection, string]
export type TranslationKey = StringTranslationKey | ArrayTranslationKey

const sourceResources = Object.fromEntries(
langSections.map((x) => [x, new FluentResource(translationData[`en/${x}`])])
)

const buildLangBundle = (lang: string): LangData => {
const result: LangData = {} as LangData
export const langData: Record<string, LangData> = {}

export const registerTranslations = (data: Record<string, string>, sections: string[]) => {
const sourceResources = Object.fromEntries(
sections.map((x) => [x, new FluentResource(data[`en/${x}`])])
)
const buildLangBundle = (lang: string): LangData => {
const result: LangData = {} as LangData

for (const section of sections) {
if (registeredLangSections.includes(section)) {
throw new Error(`Section ${section} is already registered`)
}

const bundle = new FluentBundle(lang)
setupFunctions(bundle)

bundle.addResource(sourceResources[section])
const rawData = data[`${lang}/${section}`]
const errors = bundle.addResource(new FluentResource(rawData), { allowOverrides: true })
for (const error of errors) {
console.warn('Fluent resource load error:', error)
}
result[section] = bundle
}

for (const section of langSections) {
const bundle = new FluentBundle(lang)
setupFunctions(bundle)
return result
}

bundle.addResource(sourceResources[section])
const rawData = translationData[`${lang}/${section}`]
const errors = bundle.addResource(new FluentResource(rawData), { allowOverrides: true })
for (const error of errors) {
console.warn('Fluent resource load error:', error)
}
result[section] = bundle
for (const lang of langs) {
const existingData = langData[lang.code] ?? {}
langData[lang.code] = Object.assign(existingData, buildLangBundle(lang.code))
}

return result
registeredLangSections.push(...sections)
}

const setupFunctions = (bundle: FluentBundle) => {
bundle._functions.FORUM_LINK = (text) => `[forumLink]${text}[/forumLink]`
}

export const langData: Record<string, LangData> = Object.fromEntries(
langs.map((lang) => [lang.code, buildLangBundle(lang.code)])
)
// export const langData: Record<string, LangData> = Object.fromEntries(
// langs.map((lang) => [lang.code, buildLangBundle(lang.code)])
// )

export const getLangCode = (code: string) => {
const lang = availableLanguages.find((x) => x.code === code || x.aliases.includes(code))
Expand Down Expand Up @@ -103,29 +119,4 @@ export const translate = (
})
}

// export const translate = (
// rawKey: TranslationKey,
// args: Record<string, FluentVariable> = {},
// escape = true,
// l: string
// ) => {
// let key: string
// let sectionName: LangSection

// if (typeof rawKey === 'string') {
// ;[sectionName, key] = rawKey.split(':') as ArrayTranslationKey
// } else {
// ;[sectionName, key] = rawKey
// }

// if (!l) return key
// const lang = langData[l]
// if (!lang) return key
// const section = lang[sectionName]
// if (!section) return key
// const message = section.getMessage(key)
// if (!message?.value) return key
// const result = section.formatPattern(message.value, args)
// if (escape) escapeHtmlTags(result)
// return result
// }
registerTranslations(translationData, [...langSections] as string[])

0 comments on commit c7fdbab

Please sign in to comment.