diff --git a/gui/src/i18n/interpolate.ts b/gui/src/i18n/interpolate.ts new file mode 100644 index 000000000..ccb979b61 --- /dev/null +++ b/gui/src/i18n/interpolate.ts @@ -0,0 +1,11 @@ +import type { TKey } from "./en"; + +export type Vars = Record; +export type TFn = (key: TKey, vars?: Vars) => string; + +export function interpolate(s: string, vars?: Vars): string { + if (!vars) return s; + let out = s; + for (const k of Object.keys(vars)) out = out.split(`{${k}}`).join(String(vars[k])); + return out; +} diff --git a/gui/src/i18n/shared.ts b/gui/src/i18n/shared.ts index 982dd9f9d..ec53d1ab7 100644 --- a/gui/src/i18n/shared.ts +++ b/gui/src/i18n/shared.ts @@ -5,6 +5,9 @@ import { ko } from "./ko"; import { zh } from "./zh"; import { ru } from "./ru"; import { ja } from "./ja"; +import type { TFn } from "./interpolate"; + +export { interpolate, type TFn, type Vars } from "./interpolate"; export type Locale = "en" | "de" | "ko" | "zh" | "ru" | "ja"; export type { TKey }; @@ -47,20 +50,10 @@ export function setActiveLocale(locale: Locale): void { activeLocale = locale; } -export type Vars = Record; -export type TFn = (key: TKey, vars?: Vars) => string; - export interface I18nContextValue { locale: Locale; setLocale: (l: Locale) => void; t: TFn } export const I18nContext = createContext(null); -export function interpolate(s: string, vars?: Vars): string { - if (!vars) return s; - let out = s; - for (const k of Object.keys(vars)) out = out.split(`{${k}}`).join(String(vars[k])); - return out; -} - export function useI18n(): I18nContextValue { const ctx = useContext(I18nContext); if (!ctx) throw new Error("useI18n must be used within LanguageProvider"); diff --git a/tests/provider-workspace-data.test.ts b/tests/provider-workspace-data.test.ts index a17b6e872..8cc979e19 100644 --- a/tests/provider-workspace-data.test.ts +++ b/tests/provider-workspace-data.test.ts @@ -29,7 +29,7 @@ import { providerIconSrc, } from "../gui/src/provider-icons"; import { en } from "../gui/src/i18n/en"; -import { interpolate, type TFn } from "../gui/src/i18n/shared"; +import { interpolate, type TFn } from "../gui/src/i18n/interpolate"; import { bucketPresets, filterPresets, diff --git a/tests/tencent-siliconflow-providers.test.ts b/tests/tencent-siliconflow-providers.test.ts index 966918073..7a3242aa5 100644 --- a/tests/tencent-siliconflow-providers.test.ts +++ b/tests/tencent-siliconflow-providers.test.ts @@ -5,7 +5,7 @@ import { PROVIDER_REGISTRY } from "../src/providers/registry"; import { routeModel } from "../src/router"; import type { OcxConfig } from "../src/types"; import { en } from "../gui/src/i18n/en"; -import { interpolate, type TFn } from "../gui/src/i18n/shared"; +import { interpolate, type TFn } from "../gui/src/i18n/interpolate"; import { formatProviderDisplayName, isCatalogProviderId } from "../gui/src/provider-icons"; const englishT: TFn = (key, vars) => interpolate(en[key], vars); diff --git a/tests/volcengine-providers.test.ts b/tests/volcengine-providers.test.ts index 93c7bf415..f2e4526d6 100644 --- a/tests/volcengine-providers.test.ts +++ b/tests/volcengine-providers.test.ts @@ -10,7 +10,7 @@ import { routeModel } from "../src/router"; import type { OcxConfig } from "../src/types"; import { buildProviderPostBody } from "../gui/src/provider-payload"; import { en } from "../gui/src/i18n/en"; -import { interpolate, type TFn } from "../gui/src/i18n/shared"; +import { interpolate, type TFn } from "../gui/src/i18n/interpolate"; import { formatProviderDisplayName, isCatalogProviderId } from "../gui/src/provider-icons"; import { withTestTranslatorBudget } from "./helpers/translator-budget";