From 2232f0291ce3ab73fdb6ccc93d0f0539068985b7 Mon Sep 17 00:00:00 2001 From: Anwarul Islam Date: Fri, 16 May 2025 17:28:38 +0600 Subject: [PATCH] feat(common): add support for registering and merging additional locale messages (#5072) Co-authored-by: jamesgeorge007 <25279263+jamesgeorge007@users.noreply.github.com> --- .../hoppscotch-common/src/modules/i18n.ts | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/packages/hoppscotch-common/src/modules/i18n.ts b/packages/hoppscotch-common/src/modules/i18n.ts index f06d056f..caebd036 100644 --- a/packages/hoppscotch-common/src/modules/i18n.ts +++ b/packages/hoppscotch-common/src/modules/i18n.ts @@ -3,6 +3,7 @@ import { pipe } from "fp-ts/function" import * as O from "fp-ts/Option" import * as R from "fp-ts/Record" import { createI18n, I18n, I18nOptions } from "vue-i18n" +import { merge } from "lodash-es" import { HoppModule } from "." import languages from "../../languages.json" @@ -73,6 +74,59 @@ let i18nInstance: I18n< true > | null = null +// Store additional message registrations keyed by locale +const additionalMessages: Record[]> = {} + +/** + * Register additional i18n messages for a specific locale. + * This allows other packages to extend the translations of the common package. + * + * @param locale The locale code to extend (e.g., 'en', 'fr', etc.) + * @param messages The additional messages to merge with existing translations + */ +export const registerAdditionalMessages = ( + locale: string, + messages: Record +): void => { + if (!additionalMessages[locale]) { + additionalMessages[locale] = [] + } + + additionalMessages[locale].push(messages) + + // If i18n is already initialized, merge the messages immediately + if (i18nInstance && i18nInstance.global.availableLocales.includes(locale)) { + mergeAdditionalMessages(locale) + } +} + +/** + * Merge all registered additional messages for a locale with the base messages + * + * @param locale The locale code to merge messages for + */ +const mergeAdditionalMessages = (locale: string): void => { + if ( + !i18nInstance || + !additionalMessages[locale] || + additionalMessages[locale].length === 0 + ) { + return + } + + // Get current messages for the locale + const currentMessages = i18nInstance.global.getLocaleMessage(locale) + + // Deep merge additional messages with current messages + const newMessages = additionalMessages[locale].reduce( + (acc, messages) => merge(acc, messages), + { ...currentMessages } + ) + + // Update the locale messages + i18nInstance.global.setLocaleMessage(locale, newMessages) +} + const resolveCurrentLocale = async () => pipe( // Resolve from locale and make sure it is in languages @@ -122,6 +176,9 @@ export const changeAppLanguage = async (locale: string) => { i18nInstance.global.setLocaleMessage(locale, localeData) + // Apply any additional messages for this locale + mergeAdditionalMessages(locale) + // TODO: Look into the type issues here i18nInstance.global.locale.value = locale