多语言调整
This commit is contained in:
1 parent
04de5e5a8e
commit
8bd9154414
23 files changed
+395
-155
No files matched your search
+51
-2
@@ -1,4 +1,4 @@
|
||||
import { readFile } from 'node:fs/promises'
|
||||
import { readFile, stat } from 'node:fs/promises'
|
||||
import { build } from 'esbuild'
|
||||
|
||||
const localeCodes = ['zh-CN', 'zh-TW', 'en', 'ja', 'ko', 'fr', 'de', 'pt-BR', 'es']
|
||||
@@ -7,6 +7,7 @@ const localeMessages = Object.fromEntries(await Promise.all(localeCodes.map(asyn
|
||||
JSON.parse(await readFile(`src/i18n/locales/${code}.json`, 'utf8')),
|
||||
])))
|
||||
const zh = localeMessages['zh-CN']
|
||||
const presetIndex = JSON.parse(await readFile('public/Preset/index.json', 'utf8'))
|
||||
|
||||
function flattenKeys(value, prefix = '') {
|
||||
const keys = []
|
||||
@@ -59,6 +60,22 @@ for (const code of localeCodes.slice(1)) {
|
||||
}
|
||||
}
|
||||
|
||||
for (const preset of presetIndex) {
|
||||
const file = typeof preset === 'string' ? preset : preset?.file
|
||||
if (typeof file !== 'string' || !file.trim()) throw new Error('Preset index entry is missing a file')
|
||||
await stat(`public/Preset/${file}`)
|
||||
if (typeof preset === 'string' || preset.name == null) continue
|
||||
if (typeof preset.name === 'string') continue
|
||||
if (typeof preset.name !== 'object' || Array.isArray(preset.name)) {
|
||||
throw new Error(`Preset ${file} has an invalid name`)
|
||||
}
|
||||
for (const [code, name] of Object.entries(preset.name)) {
|
||||
if (!localeCodes.includes(code) || typeof name !== 'string' || !name.trim()) {
|
||||
throw new Error(`Preset ${file} has an invalid ${code} display name`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bundled = await build({
|
||||
entryPoints: ['src/i18n/index.ts'],
|
||||
bundle: true,
|
||||
@@ -71,6 +88,38 @@ const i18nModule = await import(
|
||||
`data:text/javascript;base64,${Buffer.from(bundled.outputFiles[0].contents).toString('base64')}`
|
||||
)
|
||||
|
||||
const presetNamesBundle = await build({
|
||||
entryPoints: ['src/views/particle-panel/presetNames.ts'],
|
||||
bundle: true,
|
||||
format: 'esm',
|
||||
platform: 'node',
|
||||
write: false,
|
||||
logLevel: 'silent',
|
||||
})
|
||||
const presetNames = await import(
|
||||
`data:text/javascript;base64,${Buffer.from(presetNamesBundle.outputFiles[0].contents).toString('base64')}`
|
||||
)
|
||||
const parsedPresets = presetNames.parsePresetIndex([
|
||||
{ file: '8.test.json' },
|
||||
'9.raw.json',
|
||||
{ file: 'old.json', name: 'Old Preset' },
|
||||
{ file: 'partial.json', name: { ja: '日本語プリセット' } },
|
||||
])
|
||||
if (parsedPresets.length !== 4) throw new Error('Preset compatibility parser rejected legacy entries')
|
||||
const presetCases = [
|
||||
[parsedPresets[0], 'zh-CN', '8.test'],
|
||||
[parsedPresets[1], 'en', '9.raw'],
|
||||
[parsedPresets[2], 'fr', 'Old Preset'],
|
||||
[parsedPresets[3], 'ja', '日本語プリセット'],
|
||||
[parsedPresets[3], 'fr', 'partial'],
|
||||
]
|
||||
for (const [preset, locale, expected] of presetCases) {
|
||||
const actual = presetNames.resolvePresetDisplayName(preset, locale)
|
||||
if (actual !== expected) {
|
||||
throw new Error(`Preset fallback failed: expected ${expected}, got ${actual}`)
|
||||
}
|
||||
}
|
||||
|
||||
const cases = [
|
||||
[null, ['zh-CN'], 'zh-CN'],
|
||||
[null, ['zh-Hant-TW'], 'zh-TW'],
|
||||
@@ -95,4 +144,4 @@ for (const [saved, browserLanguages, expected] of cases) {
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`i18n 校验通过:${localeCodes.length} 种语言、${zhKeys.length} 个消息键,键与占位符一致,自动语言与缓存优先级正确`)
|
||||
console.log(`i18n 校验通过:${localeCodes.length} 种语言、${zhKeys.length} 个消息键,预设索引兼容,自动语言与缓存优先级正确`)
|
||||
Reference in new issue
Block a user