- Extend AppLanguage to 7 locales: zh-CN, zh-TW, en, ja, ko, vi, ru - Auto-detect system language via navigator.languages; fallback to English - Add BCP47 locale mapping for date formatting and sorting - Create 50 translation JSON files (5 languages × 10 namespaces, 1137 keys each) - Update language selector with native language names - Extend locale key parity test to cover all 7 languages (70 assertions) - Add VNC/RDP desktop, serial terminal, AI agent, port forwarding, and SFTP features - Add credential encryption, host metrics, session backup crypto, and zmodem bridge - Update Rust backend: desktop services, host metrics, SSH/SFTP enhancements
45 lines
1.5 KiB
TypeScript
45 lines
1.5 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import { I18N_NAMESPACES } from '../../src/i18n'
|
|
import { APP_LANGUAGES, type AppLanguage } from '../../src/i18n/detectLocale'
|
|
|
|
function flattenKeys(value: unknown, prefix = ''): string[] {
|
|
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
return prefix ? [prefix] : []
|
|
}
|
|
|
|
const entries = Object.entries(value as Record<string, unknown>)
|
|
if (entries.length === 0) return prefix ? [prefix] : []
|
|
|
|
return entries.flatMap(([key, nested]) => {
|
|
const next = prefix ? `${prefix}.${key}` : key
|
|
if (nested !== null && typeof nested === 'object' && !Array.isArray(nested)) {
|
|
const childKeys = flattenKeys(nested, next)
|
|
return childKeys.length > 0 ? childKeys : [next]
|
|
}
|
|
return [next]
|
|
})
|
|
}
|
|
|
|
async function loadLocale(namespace: string, language: AppLanguage) {
|
|
const mod = await import(`../../src/i18n/locales/${language}/${namespace}.json`)
|
|
return mod.default as Record<string, unknown>
|
|
}
|
|
|
|
describe('i18n locale key parity', () => {
|
|
for (const namespace of I18N_NAMESPACES) {
|
|
for (const language of APP_LANGUAGES) {
|
|
it(`${language} keys match en for ${namespace}`, async () => {
|
|
const [locale, en] = await Promise.all([
|
|
loadLocale(namespace, language),
|
|
loadLocale(namespace, 'en'),
|
|
])
|
|
|
|
const localeKeys = flattenKeys(locale).sort()
|
|
const enKeys = flattenKeys(en).sort()
|
|
|
|
expect(localeKeys).toEqual(enKeys)
|
|
})
|
|
}
|
|
}
|
|
})
|