@digitaldefiance/i18n-lib 1.3.1 → 1.3.2

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 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,10 @@ For issues, questions, or contributions:
2215
2274
 
2216
2275
  ## ChangeLog
2217
2276
 
2277
+ ### Version 1.3.2
2278
+
2279
+ - Add functionality to Language Registry for getMatchingLanguageCode
2280
+
2218
2281
  ### Version 1.3.1
2219
2282
 
2220
2283
  - **Changed**: `CoreLanguageCode` is now `string` - Language Registry is single source of truth
@@ -54,6 +54,13 @@ export declare class LanguageRegistry<TLanguages extends string> {
54
54
  * Get the default language ID
55
55
  */
56
56
  getDefaultLanguageId(): TLanguages | 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
+ getMatchingLanguageCode(requestedCode?: string, userDefaultCode?: string): string;
57
64
  /**
58
65
  * Set the default language
59
66
  */
@@ -105,6 +105,28 @@ class LanguageRegistry {
105
105
  getDefaultLanguageId() {
106
106
  return this.defaultLanguageId;
107
107
  }
108
+ /**
109
+ * Get matching language code with fallback logic:
110
+ * 1. Try requested code
111
+ * 2. Fall back to user default
112
+ * 3. Fall back to site default
113
+ */
114
+ getMatchingLanguageCode(requestedCode, userDefaultCode) {
115
+ // Try requested code first
116
+ if (requestedCode && this.hasLanguageCode(requestedCode)) {
117
+ return requestedCode;
118
+ }
119
+ // Try user default
120
+ if (userDefaultCode && this.hasLanguageCode(userDefaultCode)) {
121
+ return userDefaultCode;
122
+ }
123
+ // Fall back to site default
124
+ const defaultLanguage = this.getDefaultLanguage();
125
+ if (!defaultLanguage) {
126
+ throw registry_error_1.RegistryError.createSimple(registry_error_type_1.RegistryErrorType.LanguageNotFound, 'No default language configured', {});
127
+ }
128
+ return defaultLanguage.code;
129
+ }
108
130
  /**
109
131
  * Set the default language
110
132
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitaldefiance/i18n-lib",
3
- "version": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "description": "Generic i18n library with enum translation support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",