@digitaldefiance/i18n-lib 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -0
- package/dist/language-registry.d.ts +32 -25
- package/dist/language-registry.js +75 -53
- package/dist/plugin-i18n-engine.d.ts +5 -11
- package/dist/plugin-i18n-engine.js +20 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -234,6 +234,17 @@ const displayNames = registry.getLanguageDisplayNames();
|
|
|
234
234
|
// Get language codes for Mongoose enum
|
|
235
235
|
const languageCodes = registry.getLanguageIds(); // ['en-US', 'fr', 'es']
|
|
236
236
|
const isoCodes = registry.getLanguageCodes(); // ['en-US', 'fr', 'es']
|
|
237
|
+
|
|
238
|
+
// Get matching language code with fallback logic
|
|
239
|
+
const matchedCode = registry.getMatchingLanguageCode(
|
|
240
|
+
'de-DE', // Requested code (not registered)
|
|
241
|
+
'fr', // User default (registered)
|
|
242
|
+
// Falls back to site default if neither match
|
|
243
|
+
);
|
|
244
|
+
// Returns: 'fr' (user default)
|
|
245
|
+
|
|
246
|
+
const defaultCode = registry.getMatchingLanguageCode();
|
|
247
|
+
// Returns: 'en-US' (site default)
|
|
237
248
|
```
|
|
238
249
|
|
|
239
250
|
**Key Features:**
|
|
@@ -243,6 +254,53 @@ const isoCodes = registry.getLanguageCodes(); // ['en-US', 'fr', 'es']
|
|
|
243
254
|
- Default language management
|
|
244
255
|
- Duplicate detection and validation
|
|
245
256
|
- Extract language codes for schema definitions
|
|
257
|
+
- Intelligent language code matching with fallback chain
|
|
258
|
+
|
|
259
|
+
### Language Code Resolution
|
|
260
|
+
|
|
261
|
+
The Language Registry provides intelligent language code matching with a fallback chain for handling user preferences and browser language headers:
|
|
262
|
+
|
|
263
|
+
```typescript
|
|
264
|
+
import { LanguageRegistry } from '@digitaldefiance/i18n-lib';
|
|
265
|
+
|
|
266
|
+
const registry = new LanguageRegistry<'en-US' | 'fr' | 'es'>();
|
|
267
|
+
registry.registerLanguages([
|
|
268
|
+
createLanguageDefinition('en-US', 'English (US)', 'en-US', true),
|
|
269
|
+
createLanguageDefinition('fr', 'Français', 'fr'),
|
|
270
|
+
createLanguageDefinition('es', 'Español', 'es'),
|
|
271
|
+
]);
|
|
272
|
+
|
|
273
|
+
// Fallback chain: requested → user default → site default
|
|
274
|
+
const languageCode = registry.getMatchingLanguageCode(
|
|
275
|
+
req.headers['accept-language'], // 1. Try requested code first
|
|
276
|
+
req.user?.siteLanguage, // 2. Fall back to user default
|
|
277
|
+
// 3. Falls back to site default if neither match
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
// Example scenarios:
|
|
281
|
+
registry.getMatchingLanguageCode('fr', 'es'); // Returns: 'fr' (requested exists)
|
|
282
|
+
registry.getMatchingLanguageCode('de', 'es'); // Returns: 'es' (user default exists)
|
|
283
|
+
registry.getMatchingLanguageCode('de', 'it'); // Returns: 'en-US' (site default)
|
|
284
|
+
registry.getMatchingLanguageCode(); // Returns: 'en-US' (site default)
|
|
285
|
+
registry.getMatchingLanguageCode('', ''); // Returns: 'en-US' (empty strings ignored)
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Use Cases:**
|
|
289
|
+
- HTTP Accept-Language header processing
|
|
290
|
+
- User preference resolution
|
|
291
|
+
- Browser language detection with fallback
|
|
292
|
+
- Multi-tenant applications with per-user defaults
|
|
293
|
+
|
|
294
|
+
**Error Handling:**
|
|
295
|
+
```typescript
|
|
296
|
+
try {
|
|
297
|
+
const emptyRegistry = new LanguageRegistry();
|
|
298
|
+
emptyRegistry.getMatchingLanguageCode('en-US');
|
|
299
|
+
} catch (error) {
|
|
300
|
+
// Throws RegistryError if no default language configured
|
|
301
|
+
console.error('No default language configured');
|
|
302
|
+
}
|
|
303
|
+
```
|
|
246
304
|
|
|
247
305
|
### Enum Translation Registry
|
|
248
306
|
|
|
@@ -1391,6 +1449,7 @@ The core component provides 40+ system strings organized by category:
|
|
|
1391
1449
|
- `hasLanguage(language)` - Check if language exists
|
|
1392
1450
|
- `setLanguage(language)` - Set current language
|
|
1393
1451
|
- `getLanguageByCode(code)` - Get language by ISO code
|
|
1452
|
+
- `getMatchingLanguageCode(requestedCode?, userDefaultCode?)` - Get matching language code with fallback logic
|
|
1394
1453
|
|
|
1395
1454
|
**Validation**
|
|
1396
1455
|
|
|
@@ -2215,6 +2274,14 @@ For issues, questions, or contributions:
|
|
|
2215
2274
|
|
|
2216
2275
|
## ChangeLog
|
|
2217
2276
|
|
|
2277
|
+
### Version 1.3.3
|
|
2278
|
+
|
|
2279
|
+
- Make LanguageRegistry static
|
|
2280
|
+
|
|
2281
|
+
### Version 1.3.2
|
|
2282
|
+
|
|
2283
|
+
- Add functionality to Language Registry for getMatchingLanguageCode
|
|
2284
|
+
|
|
2218
2285
|
### Version 1.3.1
|
|
2219
2286
|
|
|
2220
2287
|
- **Changed**: `CoreLanguageCode` is now `string` - Language Registry is single source of truth
|
|
@@ -3,85 +3,92 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { LanguageDefinition } from './language-definition';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
6
|
+
* Static singleton registry for managing supported languages globally
|
|
7
7
|
*/
|
|
8
|
-
export declare class LanguageRegistry
|
|
9
|
-
private
|
|
10
|
-
private
|
|
11
|
-
private defaultLanguageId;
|
|
12
|
-
constructor();
|
|
8
|
+
export declare class LanguageRegistry {
|
|
9
|
+
private static languages;
|
|
10
|
+
private static languagesByCodes;
|
|
11
|
+
private static defaultLanguageId;
|
|
12
|
+
private constructor();
|
|
13
13
|
/**
|
|
14
14
|
* Register a new language
|
|
15
15
|
*/
|
|
16
|
-
registerLanguage(language: LanguageDefinition): void;
|
|
16
|
+
static registerLanguage(language: LanguageDefinition): void;
|
|
17
17
|
/**
|
|
18
18
|
* Register multiple languages at once
|
|
19
19
|
*/
|
|
20
|
-
registerLanguages(languages: readonly LanguageDefinition[]): void;
|
|
20
|
+
static registerLanguages(languages: readonly LanguageDefinition[]): void;
|
|
21
21
|
/**
|
|
22
22
|
* Get a language by its ID
|
|
23
23
|
*/
|
|
24
|
-
getLanguage(languageId:
|
|
24
|
+
static getLanguage(languageId: string): LanguageDefinition | undefined;
|
|
25
25
|
/**
|
|
26
26
|
* Get a language by its code
|
|
27
27
|
*/
|
|
28
|
-
getLanguageByCode(code: string): LanguageDefinition | undefined;
|
|
28
|
+
static getLanguageByCode(code: string): LanguageDefinition | undefined;
|
|
29
29
|
/**
|
|
30
30
|
* Get all registered languages
|
|
31
31
|
*/
|
|
32
|
-
getAllLanguages(): ReadonlyArray<LanguageDefinition>;
|
|
32
|
+
static getAllLanguages(): ReadonlyArray<LanguageDefinition>;
|
|
33
33
|
/**
|
|
34
34
|
* Get all language IDs
|
|
35
35
|
*/
|
|
36
|
-
getLanguageIds(): readonly
|
|
36
|
+
static getLanguageIds(): readonly string[];
|
|
37
37
|
/**
|
|
38
38
|
* Get all language codes
|
|
39
39
|
*/
|
|
40
|
-
getLanguageCodes(): readonly string[];
|
|
40
|
+
static getLanguageCodes(): readonly string[];
|
|
41
41
|
/**
|
|
42
42
|
* Check if a language is registered
|
|
43
43
|
*/
|
|
44
|
-
hasLanguage(languageId:
|
|
44
|
+
static hasLanguage(languageId: string): boolean;
|
|
45
45
|
/**
|
|
46
46
|
* Check if a language code is registered
|
|
47
47
|
*/
|
|
48
|
-
hasLanguageCode(code: string): boolean;
|
|
48
|
+
static hasLanguageCode(code: string): boolean;
|
|
49
49
|
/**
|
|
50
50
|
* Get the default language
|
|
51
51
|
*/
|
|
52
|
-
getDefaultLanguage(): LanguageDefinition | null;
|
|
52
|
+
static getDefaultLanguage(): LanguageDefinition | null;
|
|
53
53
|
/**
|
|
54
54
|
* Get the default language ID
|
|
55
55
|
*/
|
|
56
|
-
getDefaultLanguageId():
|
|
56
|
+
static getDefaultLanguageId(): string | null;
|
|
57
|
+
/**
|
|
58
|
+
* Get matching language code with fallback logic:
|
|
59
|
+
* 1. Try requested code
|
|
60
|
+
* 2. Fall back to user default
|
|
61
|
+
* 3. Fall back to site default
|
|
62
|
+
*/
|
|
63
|
+
static getMatchingLanguageCode(requestedCode?: string, userDefaultCode?: string): string;
|
|
57
64
|
/**
|
|
58
65
|
* Set the default language
|
|
59
66
|
*/
|
|
60
|
-
setDefaultLanguage(languageId:
|
|
67
|
+
static setDefaultLanguage(languageId: string): void;
|
|
61
68
|
/**
|
|
62
69
|
* Get the number of registered languages
|
|
63
70
|
*/
|
|
64
|
-
getLanguageCount(): number;
|
|
71
|
+
static getLanguageCount(): number;
|
|
65
72
|
/**
|
|
66
73
|
* Validate that all required languages are present
|
|
67
74
|
*/
|
|
68
|
-
validateRequiredLanguages(requiredLanguages: readonly
|
|
75
|
+
static validateRequiredLanguages(requiredLanguages: readonly string[]): LanguageValidationResult;
|
|
69
76
|
/**
|
|
70
77
|
* Create a mapping of language IDs to their display names
|
|
71
78
|
*/
|
|
72
|
-
getLanguageDisplayNames(): Record<
|
|
79
|
+
static getLanguageDisplayNames(): Record<string, string>;
|
|
73
80
|
/**
|
|
74
81
|
* Create a mapping of language IDs to their codes
|
|
75
82
|
*/
|
|
76
|
-
getLanguageCodeMapping(): Record<
|
|
83
|
+
static getLanguageCodeMapping(): Record<string, string>;
|
|
77
84
|
/**
|
|
78
85
|
* Find languages by partial name match (case-insensitive)
|
|
79
86
|
*/
|
|
80
|
-
findLanguagesByName(partialName: string): readonly LanguageDefinition[];
|
|
87
|
+
static findLanguagesByName(partialName: string): readonly LanguageDefinition[];
|
|
81
88
|
/**
|
|
82
|
-
* Clear all registered languages
|
|
89
|
+
* Clear all registered languages (useful for testing)
|
|
83
90
|
*/
|
|
84
|
-
clear(): void;
|
|
91
|
+
static clear(): void;
|
|
85
92
|
}
|
|
86
93
|
/**
|
|
87
94
|
* Validation result for language operations
|
|
@@ -9,125 +9,144 @@ exports.createLanguageDefinitions = createLanguageDefinitions;
|
|
|
9
9
|
const registry_error_1 = require("./registry-error");
|
|
10
10
|
const registry_error_type_1 = require("./registry-error-type");
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
12
|
+
* Static singleton registry for managing supported languages globally
|
|
13
13
|
*/
|
|
14
14
|
class LanguageRegistry {
|
|
15
15
|
constructor() {
|
|
16
|
-
|
|
17
|
-
this.languagesByCodes = new Map();
|
|
18
|
-
this.defaultLanguageId = null;
|
|
19
|
-
// Empty constructor - languages are registered via registerLanguage method
|
|
16
|
+
// Private constructor - use static methods
|
|
20
17
|
}
|
|
21
18
|
/**
|
|
22
19
|
* Register a new language
|
|
23
20
|
*/
|
|
24
|
-
registerLanguage(language) {
|
|
21
|
+
static registerLanguage(language) {
|
|
25
22
|
const languageId = language.id;
|
|
26
23
|
// Check for duplicate language ID
|
|
27
|
-
if (
|
|
24
|
+
if (LanguageRegistry.languages.has(languageId)) {
|
|
28
25
|
throw registry_error_1.RegistryError.createSimple(registry_error_type_1.RegistryErrorType.DuplicateLanguage, `Language '${languageId}' is already registered`, { languageId });
|
|
29
26
|
}
|
|
30
27
|
// Check for duplicate language code
|
|
31
|
-
if (
|
|
32
|
-
const existingLanguageId =
|
|
28
|
+
if (LanguageRegistry.languagesByCodes.has(language.code)) {
|
|
29
|
+
const existingLanguageId = LanguageRegistry.languagesByCodes.get(language.code);
|
|
33
30
|
throw registry_error_1.RegistryError.createSimple(registry_error_type_1.RegistryErrorType.DuplicateLanguage, `Language code '${language.code}' is already used by language '${existingLanguageId}'`, { languageId, code: language.code, existingLanguageId });
|
|
34
31
|
}
|
|
35
32
|
// Register the language
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
LanguageRegistry.languages.set(languageId, language);
|
|
34
|
+
LanguageRegistry.languagesByCodes.set(language.code, languageId);
|
|
38
35
|
// Set as default if specified or if it's the first language
|
|
39
|
-
if (language.isDefault ||
|
|
40
|
-
|
|
36
|
+
if (language.isDefault || LanguageRegistry.defaultLanguageId === null) {
|
|
37
|
+
LanguageRegistry.defaultLanguageId = languageId;
|
|
41
38
|
}
|
|
42
39
|
}
|
|
43
40
|
/**
|
|
44
41
|
* Register multiple languages at once
|
|
45
42
|
*/
|
|
46
|
-
registerLanguages(languages) {
|
|
43
|
+
static registerLanguages(languages) {
|
|
47
44
|
for (const language of languages) {
|
|
48
|
-
|
|
45
|
+
LanguageRegistry.registerLanguage(language);
|
|
49
46
|
}
|
|
50
47
|
}
|
|
51
48
|
/**
|
|
52
49
|
* Get a language by its ID
|
|
53
50
|
*/
|
|
54
|
-
getLanguage(languageId) {
|
|
55
|
-
return
|
|
51
|
+
static getLanguage(languageId) {
|
|
52
|
+
return LanguageRegistry.languages.get(languageId);
|
|
56
53
|
}
|
|
57
54
|
/**
|
|
58
55
|
* Get a language by its code
|
|
59
56
|
*/
|
|
60
|
-
getLanguageByCode(code) {
|
|
61
|
-
const languageId =
|
|
62
|
-
return languageId ?
|
|
57
|
+
static getLanguageByCode(code) {
|
|
58
|
+
const languageId = LanguageRegistry.languagesByCodes.get(code);
|
|
59
|
+
return languageId ? LanguageRegistry.languages.get(languageId) : undefined;
|
|
63
60
|
}
|
|
64
61
|
/**
|
|
65
62
|
* Get all registered languages
|
|
66
63
|
*/
|
|
67
|
-
getAllLanguages() {
|
|
68
|
-
return Array.from(
|
|
64
|
+
static getAllLanguages() {
|
|
65
|
+
return Array.from(LanguageRegistry.languages.values());
|
|
69
66
|
}
|
|
70
67
|
/**
|
|
71
68
|
* Get all language IDs
|
|
72
69
|
*/
|
|
73
|
-
getLanguageIds() {
|
|
74
|
-
return Array.from(
|
|
70
|
+
static getLanguageIds() {
|
|
71
|
+
return Array.from(LanguageRegistry.languages.keys());
|
|
75
72
|
}
|
|
76
73
|
/**
|
|
77
74
|
* Get all language codes
|
|
78
75
|
*/
|
|
79
|
-
getLanguageCodes() {
|
|
80
|
-
return Array.from(
|
|
76
|
+
static getLanguageCodes() {
|
|
77
|
+
return Array.from(LanguageRegistry.languagesByCodes.keys());
|
|
81
78
|
}
|
|
82
79
|
/**
|
|
83
80
|
* Check if a language is registered
|
|
84
81
|
*/
|
|
85
|
-
hasLanguage(languageId) {
|
|
86
|
-
return
|
|
82
|
+
static hasLanguage(languageId) {
|
|
83
|
+
return LanguageRegistry.languages.has(languageId);
|
|
87
84
|
}
|
|
88
85
|
/**
|
|
89
86
|
* Check if a language code is registered
|
|
90
87
|
*/
|
|
91
|
-
hasLanguageCode(code) {
|
|
92
|
-
return
|
|
88
|
+
static hasLanguageCode(code) {
|
|
89
|
+
return LanguageRegistry.languagesByCodes.has(code);
|
|
93
90
|
}
|
|
94
91
|
/**
|
|
95
92
|
* Get the default language
|
|
96
93
|
*/
|
|
97
|
-
getDefaultLanguage() {
|
|
98
|
-
return
|
|
99
|
-
?
|
|
94
|
+
static getDefaultLanguage() {
|
|
95
|
+
return LanguageRegistry.defaultLanguageId
|
|
96
|
+
? LanguageRegistry.languages.get(LanguageRegistry.defaultLanguageId) || null
|
|
100
97
|
: null;
|
|
101
98
|
}
|
|
102
99
|
/**
|
|
103
100
|
* Get the default language ID
|
|
104
101
|
*/
|
|
105
|
-
getDefaultLanguageId() {
|
|
106
|
-
return
|
|
102
|
+
static getDefaultLanguageId() {
|
|
103
|
+
return LanguageRegistry.defaultLanguageId;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get matching language code with fallback logic:
|
|
107
|
+
* 1. Try requested code
|
|
108
|
+
* 2. Fall back to user default
|
|
109
|
+
* 3. Fall back to site default
|
|
110
|
+
*/
|
|
111
|
+
static getMatchingLanguageCode(requestedCode, userDefaultCode) {
|
|
112
|
+
// Try requested code first
|
|
113
|
+
if (requestedCode && LanguageRegistry.hasLanguageCode(requestedCode)) {
|
|
114
|
+
return requestedCode;
|
|
115
|
+
}
|
|
116
|
+
// Try user default
|
|
117
|
+
if (userDefaultCode && LanguageRegistry.hasLanguageCode(userDefaultCode)) {
|
|
118
|
+
return userDefaultCode;
|
|
119
|
+
}
|
|
120
|
+
// Fall back to site default
|
|
121
|
+
const defaultLanguage = LanguageRegistry.getDefaultLanguage();
|
|
122
|
+
if (!defaultLanguage) {
|
|
123
|
+
throw registry_error_1.RegistryError.createSimple(registry_error_type_1.RegistryErrorType.LanguageNotFound, 'No default language configured', {});
|
|
124
|
+
}
|
|
125
|
+
return defaultLanguage.code;
|
|
107
126
|
}
|
|
108
127
|
/**
|
|
109
128
|
* Set the default language
|
|
110
129
|
*/
|
|
111
|
-
setDefaultLanguage(languageId) {
|
|
112
|
-
if (!
|
|
130
|
+
static setDefaultLanguage(languageId) {
|
|
131
|
+
if (!LanguageRegistry.languages.has(languageId)) {
|
|
113
132
|
throw registry_error_1.RegistryError.createSimple(registry_error_type_1.RegistryErrorType.LanguageNotFound, `Language '${languageId}' not found`, { languageId });
|
|
114
133
|
}
|
|
115
|
-
|
|
134
|
+
LanguageRegistry.defaultLanguageId = languageId;
|
|
116
135
|
}
|
|
117
136
|
/**
|
|
118
137
|
* Get the number of registered languages
|
|
119
138
|
*/
|
|
120
|
-
getLanguageCount() {
|
|
121
|
-
return
|
|
139
|
+
static getLanguageCount() {
|
|
140
|
+
return LanguageRegistry.languages.size;
|
|
122
141
|
}
|
|
123
142
|
/**
|
|
124
143
|
* Validate that all required languages are present
|
|
125
144
|
*/
|
|
126
|
-
validateRequiredLanguages(requiredLanguages) {
|
|
145
|
+
static validateRequiredLanguages(requiredLanguages) {
|
|
127
146
|
const missingLanguages = [];
|
|
128
147
|
const errors = [];
|
|
129
148
|
for (const languageId of requiredLanguages) {
|
|
130
|
-
if (!
|
|
149
|
+
if (!LanguageRegistry.languages.has(languageId)) {
|
|
131
150
|
missingLanguages.push(languageId);
|
|
132
151
|
errors.push(`Required language '${languageId}' is not registered`);
|
|
133
152
|
}
|
|
@@ -141,9 +160,9 @@ class LanguageRegistry {
|
|
|
141
160
|
/**
|
|
142
161
|
* Create a mapping of language IDs to their display names
|
|
143
162
|
*/
|
|
144
|
-
getLanguageDisplayNames() {
|
|
163
|
+
static getLanguageDisplayNames() {
|
|
145
164
|
const result = {};
|
|
146
|
-
for (const [languageId, language] of
|
|
165
|
+
for (const [languageId, language] of LanguageRegistry.languages) {
|
|
147
166
|
result[languageId] = language.name;
|
|
148
167
|
}
|
|
149
168
|
return result;
|
|
@@ -151,9 +170,9 @@ class LanguageRegistry {
|
|
|
151
170
|
/**
|
|
152
171
|
* Create a mapping of language IDs to their codes
|
|
153
172
|
*/
|
|
154
|
-
getLanguageCodeMapping() {
|
|
173
|
+
static getLanguageCodeMapping() {
|
|
155
174
|
const result = {};
|
|
156
|
-
for (const [languageId, language] of
|
|
175
|
+
for (const [languageId, language] of LanguageRegistry.languages) {
|
|
157
176
|
result[languageId] = language.code;
|
|
158
177
|
}
|
|
159
178
|
return result;
|
|
@@ -161,20 +180,23 @@ class LanguageRegistry {
|
|
|
161
180
|
/**
|
|
162
181
|
* Find languages by partial name match (case-insensitive)
|
|
163
182
|
*/
|
|
164
|
-
findLanguagesByName(partialName) {
|
|
183
|
+
static findLanguagesByName(partialName) {
|
|
165
184
|
const searchTerm = partialName.toLowerCase();
|
|
166
|
-
return Array.from(
|
|
185
|
+
return Array.from(LanguageRegistry.languages.values()).filter((language) => language.name.toLowerCase().includes(searchTerm));
|
|
167
186
|
}
|
|
168
187
|
/**
|
|
169
|
-
* Clear all registered languages
|
|
188
|
+
* Clear all registered languages (useful for testing)
|
|
170
189
|
*/
|
|
171
|
-
clear() {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
190
|
+
static clear() {
|
|
191
|
+
LanguageRegistry.languages.clear();
|
|
192
|
+
LanguageRegistry.languagesByCodes.clear();
|
|
193
|
+
LanguageRegistry.defaultLanguageId = null;
|
|
175
194
|
}
|
|
176
195
|
}
|
|
177
196
|
exports.LanguageRegistry = LanguageRegistry;
|
|
197
|
+
LanguageRegistry.languages = new Map();
|
|
198
|
+
LanguageRegistry.languagesByCodes = new Map();
|
|
199
|
+
LanguageRegistry.defaultLanguageId = null;
|
|
178
200
|
/**
|
|
179
201
|
* Helper function to create language definitions with type safety
|
|
180
202
|
*/
|
|
@@ -7,7 +7,6 @@ import { ComponentRegistry } from './component-registry';
|
|
|
7
7
|
import { EnumTranslationRegistry } from './enum-registry';
|
|
8
8
|
import { IActiveContext } from './active-context';
|
|
9
9
|
import { LanguageDefinition } from './language-definition';
|
|
10
|
-
import { LanguageRegistry } from './language-registry';
|
|
11
10
|
import { RegistryConfig } from './registry-config';
|
|
12
11
|
import { TranslationResponse } from './translation-response';
|
|
13
12
|
import { EnumLanguageTranslation } from './types';
|
|
@@ -15,7 +14,6 @@ import { EnumLanguageTranslation } from './types';
|
|
|
15
14
|
* Plugin-based I18n Engine with registration capabilities
|
|
16
15
|
*/
|
|
17
16
|
export declare class PluginI18nEngine<TLanguages extends string> {
|
|
18
|
-
private readonly languageRegistry;
|
|
19
17
|
private readonly componentRegistry;
|
|
20
18
|
private readonly enumRegistry;
|
|
21
19
|
private readonly config;
|
|
@@ -40,11 +38,11 @@ export declare class PluginI18nEngine<TLanguages extends string> {
|
|
|
40
38
|
*/
|
|
41
39
|
static getInstance<TLangs extends string>(key?: string): PluginI18nEngine<TLangs>;
|
|
42
40
|
/**
|
|
43
|
-
* Register a new language
|
|
41
|
+
* Register a new language (updates static registry)
|
|
44
42
|
*/
|
|
45
43
|
registerLanguage(language: LanguageDefinition): void;
|
|
46
44
|
/**
|
|
47
|
-
* Register multiple languages
|
|
45
|
+
* Register multiple languages (updates static registry)
|
|
48
46
|
*/
|
|
49
47
|
registerLanguages(languages: readonly LanguageDefinition[]): void;
|
|
50
48
|
/**
|
|
@@ -92,7 +90,7 @@ export declare class PluginI18nEngine<TLanguages extends string> {
|
|
|
92
90
|
*/
|
|
93
91
|
setLanguage(language: TLanguages): void;
|
|
94
92
|
/**
|
|
95
|
-
* Get available languages
|
|
93
|
+
* Get available languages from static registry
|
|
96
94
|
*/
|
|
97
95
|
getLanguages(): readonly LanguageDefinition[];
|
|
98
96
|
/**
|
|
@@ -104,17 +102,13 @@ export declare class PluginI18nEngine<TLanguages extends string> {
|
|
|
104
102
|
*/
|
|
105
103
|
hasComponent(componentId: string): boolean;
|
|
106
104
|
/**
|
|
107
|
-
* Check if a language is registered
|
|
105
|
+
* Check if a language is registered in static registry
|
|
108
106
|
*/
|
|
109
107
|
hasLanguage(language: TLanguages): boolean;
|
|
110
108
|
/**
|
|
111
|
-
* Get language by code
|
|
109
|
+
* Get language by code from static registry
|
|
112
110
|
*/
|
|
113
111
|
getLanguageByCode(code: string): LanguageDefinition | undefined;
|
|
114
|
-
/**
|
|
115
|
-
* Get language registry for direct access
|
|
116
|
-
*/
|
|
117
|
-
getLanguageRegistry(): LanguageRegistry<TLanguages>;
|
|
118
112
|
/**
|
|
119
113
|
* Get component registry for direct access
|
|
120
114
|
*/
|
|
@@ -36,12 +36,15 @@ class PluginI18nEngine {
|
|
|
36
36
|
},
|
|
37
37
|
...config,
|
|
38
38
|
};
|
|
39
|
-
//
|
|
40
|
-
|
|
39
|
+
// Register initial languages in static registry (skip if already registered)
|
|
40
|
+
for (const lang of initialLanguages) {
|
|
41
|
+
if (!language_registry_1.LanguageRegistry.hasLanguage(lang.id)) {
|
|
42
|
+
language_registry_1.LanguageRegistry.registerLanguage(lang);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// Initialize component registry (per-instance)
|
|
41
46
|
this.componentRegistry = new component_registry_1.ComponentRegistry(initialLanguages.map((l) => l.id), this.config.validation);
|
|
42
47
|
this.enumRegistry = new enum_registry_1.EnumTranslationRegistry(initialLanguages.map((l) => l.id), (key, vars) => this.safeTranslate('core', key, vars));
|
|
43
|
-
// Register initial languages
|
|
44
|
-
this.languageRegistry.registerLanguages(initialLanguages);
|
|
45
48
|
// Initialize context key for this engine instance
|
|
46
49
|
this.contextKey = PluginI18nEngine.DefaultInstanceKey;
|
|
47
50
|
// Create or get the global context for this engine
|
|
@@ -113,16 +116,16 @@ class PluginI18nEngine {
|
|
|
113
116
|
return instance;
|
|
114
117
|
}
|
|
115
118
|
/**
|
|
116
|
-
* Register a new language
|
|
119
|
+
* Register a new language (updates static registry)
|
|
117
120
|
*/
|
|
118
121
|
registerLanguage(language) {
|
|
119
|
-
|
|
122
|
+
language_registry_1.LanguageRegistry.registerLanguage(language);
|
|
120
123
|
// Update component registry with new language
|
|
121
|
-
const newLanguages =
|
|
124
|
+
const newLanguages = language_registry_1.LanguageRegistry.getLanguageIds();
|
|
122
125
|
this.componentRegistry.updateRegisteredLanguages(newLanguages);
|
|
123
126
|
}
|
|
124
127
|
/**
|
|
125
|
-
* Register multiple languages
|
|
128
|
+
* Register multiple languages (updates static registry)
|
|
126
129
|
*/
|
|
127
130
|
registerLanguages(languages) {
|
|
128
131
|
for (const language of languages) {
|
|
@@ -226,17 +229,17 @@ class PluginI18nEngine {
|
|
|
226
229
|
* Set current language
|
|
227
230
|
*/
|
|
228
231
|
setLanguage(language) {
|
|
229
|
-
if (!
|
|
232
|
+
if (!language_registry_1.LanguageRegistry.hasLanguage(language)) {
|
|
230
233
|
throw registry_error_1.RegistryError.createSimple(registry_error_type_1.RegistryErrorType.LanguageNotFound, `Language '${language}' is not registered`, { language });
|
|
231
234
|
}
|
|
232
235
|
const globalContext = global_active_context_1.GlobalActiveContext.getInstance();
|
|
233
236
|
globalContext.setUserLanguage(language, this.contextKey);
|
|
234
237
|
}
|
|
235
238
|
/**
|
|
236
|
-
* Get available languages
|
|
239
|
+
* Get available languages from static registry
|
|
237
240
|
*/
|
|
238
241
|
getLanguages() {
|
|
239
|
-
return
|
|
242
|
+
return language_registry_1.LanguageRegistry.getAllLanguages();
|
|
240
243
|
}
|
|
241
244
|
/**
|
|
242
245
|
* Get registered components
|
|
@@ -251,22 +254,16 @@ class PluginI18nEngine {
|
|
|
251
254
|
return this.componentRegistry.hasComponent(componentId);
|
|
252
255
|
}
|
|
253
256
|
/**
|
|
254
|
-
* Check if a language is registered
|
|
257
|
+
* Check if a language is registered in static registry
|
|
255
258
|
*/
|
|
256
259
|
hasLanguage(language) {
|
|
257
|
-
return
|
|
260
|
+
return language_registry_1.LanguageRegistry.hasLanguage(language);
|
|
258
261
|
}
|
|
259
262
|
/**
|
|
260
|
-
* Get language by code
|
|
263
|
+
* Get language by code from static registry
|
|
261
264
|
*/
|
|
262
265
|
getLanguageByCode(code) {
|
|
263
|
-
return
|
|
264
|
-
}
|
|
265
|
-
/**
|
|
266
|
-
* Get language registry for direct access
|
|
267
|
-
*/
|
|
268
|
-
getLanguageRegistry() {
|
|
269
|
-
return this.languageRegistry;
|
|
266
|
+
return language_registry_1.LanguageRegistry.getLanguageByCode(code);
|
|
270
267
|
}
|
|
271
268
|
/**
|
|
272
269
|
* Get component registry for direct access
|
|
@@ -288,7 +285,7 @@ class PluginI18nEngine {
|
|
|
288
285
|
const warnings = [];
|
|
289
286
|
let isValid = true;
|
|
290
287
|
const components = this.getComponents();
|
|
291
|
-
const languages =
|
|
288
|
+
const languages = language_registry_1.LanguageRegistry.getLanguageIds();
|
|
292
289
|
for (const component of components) {
|
|
293
290
|
const componentStrings = this.componentRegistry.getComponentStrings(component.id);
|
|
294
291
|
if (!componentStrings) {
|
|
@@ -355,6 +352,7 @@ class PluginI18nEngine {
|
|
|
355
352
|
}
|
|
356
353
|
PluginI18nEngine._instances.clear();
|
|
357
354
|
PluginI18nEngine._defaultKey = null;
|
|
355
|
+
language_registry_1.LanguageRegistry.clear();
|
|
358
356
|
}
|
|
359
357
|
}
|
|
360
358
|
exports.PluginI18nEngine = PluginI18nEngine;
|