diff --git a/scripts/cleanup-unused-i18n.mjs b/scripts/cleanup-unused-i18n.mjs index 1a4dc134..da6f84df 100644 --- a/scripts/cleanup-unused-i18n.mjs +++ b/scripts/cleanup-unused-i18n.mjs @@ -928,9 +928,7 @@ function loadLocales() { try { data[file.namespace] = JSON.parse(raw); } catch (error) { - console.warn( - `Warning: failed to parse ${file.path}: ${error.message}`, - ); + console.warn(`Warning: failed to parse ${file.path}: ${error.message}`); data[file.namespace] = {}; } } @@ -983,9 +981,8 @@ function toModuleIdentifier(namespace, seen) { ]); const base = - namespace - .replace(/[^a-zA-Z0-9_$]/g, "_") - .replace(/^[^a-zA-Z_$]+/, "") || "ns"; + namespace.replace(/[^a-zA-Z0-9_$]/g, "_").replace(/^[^a-zA-Z_$]+/, "") || + "ns"; let candidate = base; let counter = 1; @@ -1142,10 +1139,7 @@ function processLocale( return { locale: locale.name, - file: - locale.format === "single-file" - ? locale.files[0].path - : locale.dir, + file: locale.format === "single-file" ? locale.files[0].path : locale.dir, totalKeys: flattened.size, expectedKeys: expectedTotal, unusedKeys: unused, diff --git a/scripts/split-locales.mjs b/scripts/split-locales.mjs index d1c46f3e..cc5ca7b2 100644 --- a/scripts/split-locales.mjs +++ b/scripts/split-locales.mjs @@ -16,7 +16,14 @@ async function ensureDir(dirPath) { await fs.mkdir(dirPath, { recursive: true }); } -const RESERVED = new Set(["default", "function", "var", "let", "const", "import"]); +const RESERVED = new Set([ + "default", + "function", + "var", + "let", + "const", + "import", +]); function toIdentifier(namespace, taken) { let base = namespace @@ -61,11 +68,7 @@ async function splitLocaleFile(filePath, lang) { const taken = new Set(); for (const [namespace, value] of namespaces) { - if ( - typeof value !== "object" || - value === null || - Array.isArray(value) - ) { + if (typeof value !== "object" || value === null || Array.isArray(value)) { throw new Error( `Locale ${lang} namespace "${namespace}" must be an object`, ); diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 207db6e6..7cb1cf3d 100755 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -245,4 +245,4 @@ iter_on_empty_collections = "deny" # fallible_impl_from = "deny" // 过于激进,暂时不开启 equatable_if_let = "deny" collection_is_never_read = "deny" -branches_sharing_code = "deny" \ No newline at end of file +branches_sharing_code = "deny" diff --git a/src/locales/ar/index.ts b/src/locales/ar/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/ar/index.ts +++ b/src/locales/ar/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/locales/de/index.ts b/src/locales/de/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/de/index.ts +++ b/src/locales/de/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/locales/en/index.ts b/src/locales/en/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/en/index.ts +++ b/src/locales/en/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/locales/es/index.ts b/src/locales/es/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/es/index.ts +++ b/src/locales/es/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/locales/fa/index.ts b/src/locales/fa/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/fa/index.ts +++ b/src/locales/fa/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/locales/id/index.ts b/src/locales/id/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/id/index.ts +++ b/src/locales/id/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/locales/jp/index.ts b/src/locales/jp/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/jp/index.ts +++ b/src/locales/jp/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/locales/ko/index.ts b/src/locales/ko/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/ko/index.ts +++ b/src/locales/ko/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/locales/ru/index.ts b/src/locales/ru/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/ru/index.ts +++ b/src/locales/ru/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/locales/tr/index.ts b/src/locales/tr/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/tr/index.ts +++ b/src/locales/tr/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/locales/tt/index.ts b/src/locales/tt/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/tt/index.ts +++ b/src/locales/tt/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/locales/zh/index.ts b/src/locales/zh/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/zh/index.ts +++ b/src/locales/zh/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/locales/zhtw/index.ts b/src/locales/zhtw/index.ts index 2977171d..6c3e9449 100644 --- a/src/locales/zhtw/index.ts +++ b/src/locales/zhtw/index.ts @@ -1,27 +1,27 @@ -import shared from "./shared.json"; +import connections from "./connections.json"; +import home from "./home.json"; +import layout from "./layout.json"; +import logs from "./logs.json"; import profiles from "./profiles.json"; import proxies from "./proxies.json"; -import connections from "./connections.json"; -import tests from "./tests.json"; -import logs from "./logs.json"; import rules from "./rules.json"; -import home from "./home.json"; -import unlock from "./unlock.json"; import settings from "./settings.json"; -import layout from "./layout.json"; +import shared from "./shared.json"; +import tests from "./tests.json"; +import unlock from "./unlock.json"; const resources = { - "shared": shared, - "profiles": profiles, - "proxies": proxies, - "connections": connections, - "tests": tests, - "logs": logs, - "rules": rules, - "home": home, - "unlock": unlock, - "settings": settings, - "layout": layout, + shared: shared, + profiles: profiles, + proxies: proxies, + connections: connections, + tests: tests, + logs: logs, + rules: rules, + home: home, + unlock: unlock, + settings: settings, + layout: layout, }; export default resources; diff --git a/src/services/i18n.ts b/src/services/i18n.ts index 2cb6c153..710378e7 100644 --- a/src/services/i18n.ts +++ b/src/services/i18n.ts @@ -17,6 +17,24 @@ export const supportedLanguages = [ "zhtw", ]; +const FALLBACK_LANGUAGE = "zh"; + +type LocaleModule = { + default: Record; +}; + +const localeModules = import.meta.glob("@/locales/*/index.ts"); + +const localeLoaders = Object.entries(localeModules).reduce< + Record Promise> +>((acc, [path, loader]) => { + const match = path.match(/[/\\]locales[/\\]([^/\\]+)[/\\]index\.ts$/); + if (match) { + acc[match[1]] = loader; + } + return acc; +}, {}); + export const languages: Record = supportedLanguages.reduce( (acc, lang) => { acc[lang] = {}; @@ -27,14 +45,27 @@ export const languages: Record = supportedLanguages.reduce( export const loadLanguage = async (language: string) => { try { - const module = await import(`@/locales/${language}/index.ts`); + const loader = localeLoaders[language]; + if (!loader) { + throw new Error(`Locale loader not found for language "${language}"`); + } + const module = await loader(); return module.default; } catch (error) { - console.warn( - `Failed to load language ${language}, fallback to zh, ${error}`, - ); - const fallback = await import("@/locales/zh/index.ts"); - return fallback.default; + if (language !== FALLBACK_LANGUAGE) { + console.warn( + `Failed to load language ${language}, fallback to ${FALLBACK_LANGUAGE}, ${error}`, + ); + const fallbackLoader = localeLoaders[FALLBACK_LANGUAGE]; + if (!fallbackLoader) { + throw new Error( + `Fallback language "${FALLBACK_LANGUAGE}" resources are missing.`, + ); + } + const fallback = await fallbackLoader(); + return fallback.default; + } + throw error; } };