11import { createI18n } from 'vue-i18n'
22
3- // ESLint cannot statically resolve dynamic imports with relative paths in template strings,
4- // but these are valid ES module imports that Vite processes correctly at build time.
3+ import {
4+ localeDefinitions ,
5+ resolveSupportedLocale
6+ } from '@/locales/localeConfig'
7+ import type { SupportedLocale } from '@/locales/localeConfig'
58
69// Import only English locale eagerly as the default/fallback
710import enCommands from './locales/en/commands.json' with { type : 'json' }
811import en from './locales/en/main.json' with { type : 'json' }
912import enNodes from './locales/en/nodeDefs.json' with { type : 'json' }
1013import enSettings from './locales/en/settings.json' with { type : 'json' }
1114
15+ export { resolveSupportedLocale }
16+
1217function buildLocale <
1318 M extends Record < string , unknown > ,
1419 N extends Record < string , unknown > ,
@@ -23,75 +28,6 @@ function buildLocale<
2328 } as M & { nodeDefs : N ; commands : C ; settings : S }
2429}
2530
26- // Locale loader map - dynamically import locales only when needed
27- const localeLoaders : Record <
28- string ,
29- ( ) => Promise < { default : Record < string , unknown > } >
30- > = {
31- ar : ( ) => import ( './locales/ar/main.json' ) ,
32- es : ( ) => import ( './locales/es/main.json' ) ,
33- fa : ( ) => import ( './locales/fa/main.json' ) ,
34- fr : ( ) => import ( './locales/fr/main.json' ) ,
35- ja : ( ) => import ( './locales/ja/main.json' ) ,
36- ko : ( ) => import ( './locales/ko/main.json' ) ,
37- ru : ( ) => import ( './locales/ru/main.json' ) ,
38- tr : ( ) => import ( './locales/tr/main.json' ) ,
39- zh : ( ) => import ( './locales/zh/main.json' ) ,
40- 'zh-TW' : ( ) => import ( './locales/zh-TW/main.json' ) ,
41- 'pt-BR' : ( ) => import ( './locales/pt-BR/main.json' )
42- }
43-
44- const nodeDefsLoaders : Record <
45- string ,
46- ( ) => Promise < { default : Record < string , unknown > } >
47- > = {
48- ar : ( ) => import ( './locales/ar/nodeDefs.json' ) ,
49- es : ( ) => import ( './locales/es/nodeDefs.json' ) ,
50- fa : ( ) => import ( './locales/fa/nodeDefs.json' ) ,
51- fr : ( ) => import ( './locales/fr/nodeDefs.json' ) ,
52- ja : ( ) => import ( './locales/ja/nodeDefs.json' ) ,
53- ko : ( ) => import ( './locales/ko/nodeDefs.json' ) ,
54- ru : ( ) => import ( './locales/ru/nodeDefs.json' ) ,
55- tr : ( ) => import ( './locales/tr/nodeDefs.json' ) ,
56- zh : ( ) => import ( './locales/zh/nodeDefs.json' ) ,
57- 'zh-TW' : ( ) => import ( './locales/zh-TW/nodeDefs.json' ) ,
58- 'pt-BR' : ( ) => import ( './locales/pt-BR/nodeDefs.json' )
59- }
60-
61- const commandsLoaders : Record <
62- string ,
63- ( ) => Promise < { default : Record < string , unknown > } >
64- > = {
65- ar : ( ) => import ( './locales/ar/commands.json' ) ,
66- es : ( ) => import ( './locales/es/commands.json' ) ,
67- fa : ( ) => import ( './locales/fa/commands.json' ) ,
68- fr : ( ) => import ( './locales/fr/commands.json' ) ,
69- ja : ( ) => import ( './locales/ja/commands.json' ) ,
70- ko : ( ) => import ( './locales/ko/commands.json' ) ,
71- ru : ( ) => import ( './locales/ru/commands.json' ) ,
72- tr : ( ) => import ( './locales/tr/commands.json' ) ,
73- zh : ( ) => import ( './locales/zh/commands.json' ) ,
74- 'zh-TW' : ( ) => import ( './locales/zh-TW/commands.json' ) ,
75- 'pt-BR' : ( ) => import ( './locales/pt-BR/commands.json' )
76- }
77-
78- const settingsLoaders : Record <
79- string ,
80- ( ) => Promise < { default : Record < string , unknown > } >
81- > = {
82- ar : ( ) => import ( './locales/ar/settings.json' ) ,
83- es : ( ) => import ( './locales/es/settings.json' ) ,
84- fa : ( ) => import ( './locales/fa/settings.json' ) ,
85- fr : ( ) => import ( './locales/fr/settings.json' ) ,
86- ja : ( ) => import ( './locales/ja/settings.json' ) ,
87- ko : ( ) => import ( './locales/ko/settings.json' ) ,
88- ru : ( ) => import ( './locales/ru/settings.json' ) ,
89- tr : ( ) => import ( './locales/tr/settings.json' ) ,
90- zh : ( ) => import ( './locales/zh/settings.json' ) ,
91- 'zh-TW' : ( ) => import ( './locales/zh-TW/settings.json' ) ,
92- 'pt-BR' : ( ) => import ( './locales/pt-BR/settings.json' )
93- }
94-
9531// Track which locales have been loaded
9632const loadedLocales = new Set < string > ( [ 'en' ] )
9733
@@ -101,48 +37,6 @@ const loadingLocales = new Map<string, Promise<void>>()
10137// Store custom nodes i18n data for merging when locales are lazily loaded
10238const customNodesI18nData : Record < string , unknown > = { }
10339
104- const SUPPORTED_LOCALES = [
105- 'en' ,
106- 'ar' ,
107- 'es' ,
108- 'fa' ,
109- 'fr' ,
110- 'ja' ,
111- 'ko' ,
112- 'ru' ,
113- 'tr' ,
114- 'zh' ,
115- 'zh-TW' ,
116- 'pt-BR'
117- ] as const
118-
119- type SupportedLocale = ( typeof SUPPORTED_LOCALES ) [ number ]
120-
121- // Lowercased lookup map → canonical tag, since BCP-47 matching is
122- // case-insensitive (e.g. `pt-br` from older browsers must match `pt-BR`).
123- const supportedLocaleByLower = new Map < string , SupportedLocale > (
124- SUPPORTED_LOCALES . map ( ( locale ) => [ locale . toLowerCase ( ) , locale ] )
125- )
126-
127- /**
128- * Resolve a BCP-47 language tag to a locale we ship messages for, with
129- * graceful fallback. Tries the full tag (preserves `zh-TW`, `pt-BR`),
130- * then the base tag (`zh`, `pt`), then `'en'`. Matching is case-insensitive
131- * but the returned tag is always in canonical casing.
132- */
133- export function resolveSupportedLocale (
134- input : string | undefined | null
135- ) : SupportedLocale {
136- if ( ! input ) return 'en'
137- const normalized = input . toLowerCase ( )
138- const exact = supportedLocaleByLower . get ( normalized )
139- if ( exact ) return exact
140- const base = normalized . split ( '-' ) [ 0 ]
141- const baseMatch = supportedLocaleByLower . get ( base )
142- if ( baseMatch ) return baseMatch
143- return 'en'
144- }
145-
14640/**
14741 * Dynamically load a locale and its associated files (nodeDefs, commands, settings).
14842 * Unsupported locales are clamped to `'en'`.
@@ -160,19 +54,19 @@ export async function loadLocale(locale: string): Promise<SupportedLocale> {
16054 return resolved
16155 }
16256
163- const loader = localeLoaders [ resolved ]
164- const nodeDefsLoader = nodeDefsLoaders [ resolved ]
165- const commandsLoader = commandsLoaders [ resolved ]
166- const settingsLoader = settingsLoaders [ resolved ]
57+ const loaders = localeDefinitions [ resolved ] . loaders
58+ if ( ! loaders ) {
59+ return resolved
60+ }
16761
16862 // Create and track the loading promise
16963 const loadPromise = ( async ( ) => {
17064 try {
17165 const [ main , nodes , commands , settings ] = await Promise . all ( [
172- loader ( ) ,
173- nodeDefsLoader ( ) ,
174- commandsLoader ( ) ,
175- settingsLoader ( )
66+ loaders . main ( ) ,
67+ loaders . nodeDefs ( ) ,
68+ loaders . commands ( ) ,
69+ loaders . settings ( )
17670 ] )
17771
17872 const messages = buildLocale (
0 commit comments