hermes-agent/apps/desktop/src/i18n/languages.ts
2026-06-06 07:51:44 -07:00

86 lines
2.3 KiB
TypeScript

import type { Locale } from './types'
export const DEFAULT_LOCALE: Locale = 'en'
export const LOCALE_OPTIONS = [
{
id: 'en',
name: 'English',
englishName: 'English',
configValue: 'en'
},
{
id: 'zh',
name: '简体中文',
englishName: 'Simplified Chinese',
configValue: 'zh'
},
{
id: 'zh-hant',
name: '繁體中文',
englishName: 'Traditional Chinese',
configValue: 'zh-hant'
},
{
id: 'ja',
name: '日本語',
englishName: 'Japanese',
configValue: 'ja'
}
] as const satisfies readonly { configValue: string; englishName: string; id: Locale; name: string }[]
// `name` is the endonym (native name) shown in the picker so users recognize
// their language regardless of the current UI language. No country flags:
// languages are not countries. `englishName` is search-only (not shown) so an
// English speaker can type "japanese"/"traditional" to filter the list.
export const LOCALE_META: Record<Locale, { name: string; englishName: string }> = Object.fromEntries(
LOCALE_OPTIONS.map(locale => [locale.id, { name: locale.name, englishName: locale.englishName }])
) as Record<Locale, { name: string; englishName: string }>
const LOCALE_ALIASES: Record<string, Locale> = {
en: 'en',
'en-us': 'en',
en_us: 'en',
zh: 'zh',
'zh-cn': 'zh',
zh_cn: 'zh',
'zh-hans': 'zh',
zh_hans: 'zh',
'zh-hans-cn': 'zh',
zh_hans_cn: 'zh',
'zh-tw': 'zh-hant',
zh_tw: 'zh-hant',
'zh-hk': 'zh-hant',
zh_hk: 'zh-hant',
'zh-mo': 'zh-hant',
zh_mo: 'zh-hant',
'zh-hant': 'zh-hant',
zh_hant: 'zh-hant',
'zh-hant-tw': 'zh-hant',
zh_hant_tw: 'zh-hant',
'zh-hant-hk': 'zh-hant',
zh_hant_hk: 'zh-hant',
ja: 'ja',
'ja-jp': 'ja',
ja_jp: 'ja'
}
export function isLocale(value: unknown): value is Locale {
return typeof value === 'string' && LOCALE_OPTIONS.some(locale => locale.id === value)
}
export function normalizeLocale(value: unknown): Locale {
if (typeof value !== 'string') {
return DEFAULT_LOCALE
}
return LOCALE_ALIASES[value.trim().toLowerCase()] ?? DEFAULT_LOCALE
}
export function isSupportedLocaleValue(value: unknown): boolean {
return typeof value === 'string' && LOCALE_ALIASES[value.trim().toLowerCase()] != null
}
export function localeConfigValue(locale: Locale): string {
return LOCALE_OPTIONS.find(item => item.id === locale)?.configValue ?? DEFAULT_LOCALE
}