@digitaldefiance/i18n-lib 4.3.0 → 4.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.
Files changed (2) hide show
  1. package/README.md +299 -43
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -8,6 +8,8 @@ Part of [Express Suite](https://github.com/Digital-Defiance/express-suite)
8
8
 
9
9
  ✨ **String Key Enum Registration** - Register branded string key enums for direct translation without specifying component IDs.
10
10
 
11
+ **Prerequisites**: Requires branded enums from v4.0.4+ (see [Branded Enums](#branded-enums) section)
12
+
11
13
  **New Features:**
12
14
  - **`registerStringKeyEnum()`**: Register branded enums for automatic component routing
13
15
  - **`translateStringKey()`**: Translate keys directly - component ID resolved from branded enum
@@ -15,6 +17,15 @@ Part of [Express Suite](https://github.com/Digital-Defiance/express-suite)
15
17
  - **`hasStringKeyEnum()` / `getStringKeyEnums()`**: Query registered enums
16
18
 
17
19
  ```typescript
20
+ import { createI18nStringKeysFromEnum, PluginI18nEngine, LanguageCodes } from '@digitaldefiance/i18n-lib';
21
+
22
+ // First, create a branded enum from your string keys
23
+ enum MyStringKeys {
24
+ Welcome = 'welcome',
25
+ Goodbye = 'goodbye',
26
+ }
27
+ const MyBrandedKeys = createI18nStringKeysFromEnum('my-component', MyStringKeys);
28
+
18
29
  // Register your branded enum
19
30
  engine.registerStringKeyEnum(MyBrandedKeys);
20
31
 
@@ -51,8 +62,8 @@ const text = engine.translateStringKey(MyBrandedKeys.Welcome, { name: 'Alice' })
51
62
  - **Type Safety**: Full TypeScript support with generic types
52
63
  - **Branded Enums**: Runtime-identifiable string keys with collision detection and component routing
53
64
  - **Error Handling**: Comprehensive error classes with translation support and ICU formatting
54
- - **93.22% Test Coverage**: 1,738 tests covering all features
55
- - **Security Hardened**: See [SECURITY.md](SECURITY.md) for details
65
+ - **93.22% Test Coverage**: 2,007 tests covering all features
66
+ - **Security Hardened**: Comprehensive protection against prototype pollution, ReDoS, and XSS attacks
56
67
 
57
68
  ## Installation
58
69
 
@@ -102,8 +113,12 @@ console.log(engine.translate('app', 'welcome', { appName: 'MyApp' }));
102
113
  // Output: "Bienvenue sur MyApp!"
103
114
 
104
115
  // Pluralization (automatic form selection)
105
- engine.register({
106
- id: 'cart',
116
+ engine.registerComponent({
117
+ component: {
118
+ id: 'cart',
119
+ name: 'Cart',
120
+ stringKeys: ['items']
121
+ },
107
122
  strings: {
108
123
  'en-US': {
109
124
  items: {
@@ -122,7 +137,18 @@ console.log(engine.translate('cart', 'items', { count: 5 }));
122
137
 
123
138
  ## ICU MessageFormat
124
139
 
125
- Industry-standard message formatting with powerful features. See [@docs/ICU_MESSAGEFORMAT.md](../../docs/ICU_MESSAGEFORMAT.md) for complete guide.
140
+ Industry-standard message formatting with powerful features. See [docs/ICU_MESSAGEFORMAT.md](docs/ICU_MESSAGEFORMAT.md) for complete guide.
141
+
142
+ **When to use ICU MessageFormat:**
143
+ - Complex pluralization with multiple forms
144
+ - Gender-specific translations
145
+ - Number/date/time formatting with locale awareness
146
+ - Nested conditional logic (select within plural)
147
+
148
+ **When to use simple templates:**
149
+ - Basic variable substitution
150
+ - Component references ({{Component.key}})
151
+ - Simple string interpolation
126
152
 
127
153
  ### Quick Example
128
154
 
@@ -164,9 +190,9 @@ formatICUMessage(
164
190
 
165
191
  ### Documentation
166
192
 
167
- - **[@docs/ICU_MESSAGEFORMAT.md](../../docs/ICU_MESSAGEFORMAT.md)** - Complete guide with syntax reference and examples
168
- - **[@docs/ICU_COMPREHENSIVE_VALIDATION.md](../../docs/ICU_COMPREHENSIVE_VALIDATION.md)** - Validation report with test coverage
169
- - **[@docs/ICU_PROJECT_COMPLETE.md](../../docs/ICU_PROJECT_COMPLETE.md)** - Implementation summary
193
+ - **[docs/ICU_MESSAGEFORMAT.md](docs/ICU_MESSAGEFORMAT.md)** - Complete guide with syntax reference and examples
194
+ - **[docs/ICU_COMPREHENSIVE_VALIDATION.md](docs/ICU_COMPREHENSIVE_VALIDATION.md)** - Validation report with test coverage
195
+ - **[docs/ICU_PROJECT_COMPLETE.md](docs/ICU_PROJECT_COMPLETE.md)** - Implementation summary
170
196
 
171
197
  ### API
172
198
 
@@ -190,11 +216,19 @@ import {
190
216
  Automatic plural form selection based on count with CLDR-compliant rules for 37 languages:
191
217
 
192
218
  ```typescript
193
- import { createPluralString } from '@digitaldefiance/i18n-lib';
219
+ import { createPluralString, PluginI18nEngine, LanguageCodes } from '@digitaldefiance/i18n-lib';
220
+
221
+ const engine = PluginI18nEngine.createInstance('app', [
222
+ { id: LanguageCodes.EN_US, name: 'English', code: 'en-US', isDefault: true }
223
+ ]);
194
224
 
195
225
  // English (one/other)
196
- engine.register({
197
- id: 'shop',
226
+ engine.registerComponent({
227
+ component: {
228
+ id: 'shop',
229
+ name: 'Shop',
230
+ stringKeys: ['items']
231
+ },
198
232
  strings: {
199
233
  'en-US': {
200
234
  items: createPluralString({
@@ -206,8 +240,12 @@ engine.register({
206
240
  });
207
241
 
208
242
  // Russian (one/few/many)
209
- engine.register({
210
- id: 'shop',
243
+ engine.registerComponent({
244
+ component: {
245
+ id: 'shop',
246
+ name: 'Shop',
247
+ stringKeys: ['items']
248
+ },
211
249
  strings: {
212
250
  'ru': {
213
251
  items: createPluralString({
@@ -220,8 +258,12 @@ engine.register({
220
258
  });
221
259
 
222
260
  // Arabic (zero/one/two/few/many/other)
223
- engine.register({
224
- id: 'shop',
261
+ engine.registerComponent({
262
+ component: {
263
+ id: 'shop',
264
+ name: 'Shop',
265
+ stringKeys: ['items']
266
+ },
225
267
  strings: {
226
268
  'ar': {
227
269
  items: createPluralString({
@@ -258,10 +300,18 @@ See [PLURALIZATION_SUPPORT.md](docs/PLURALIZATION_SUPPORT.md) for complete langu
258
300
  Gender-aware translations with intelligent fallback:
259
301
 
260
302
  ```typescript
261
- import { createGenderedString } from '@digitaldefiance/i18n-lib';
303
+ import { createGenderedString, PluginI18nEngine, LanguageCodes } from '@digitaldefiance/i18n-lib';
262
304
 
263
- engine.register({
264
- id: 'profile',
305
+ const engine = PluginI18nEngine.createInstance('app', [
306
+ { id: LanguageCodes.EN_US, name: 'English', code: 'en-US', isDefault: true }
307
+ ]);
308
+
309
+ engine.registerComponent({
310
+ component: {
311
+ id: 'profile',
312
+ name: 'Profile',
313
+ stringKeys: ['greeting']
314
+ },
265
315
  strings: {
266
316
  'en-US': {
267
317
  greeting: createGenderedString({
@@ -364,10 +414,10 @@ The main engine class that manages translations, languages, and components.
364
414
  ```typescript
365
415
  import { PluginI18nEngine, LanguageCodes } from '@digitaldefiance/i18n-lib';
366
416
 
367
- // Create instance
417
+ // Recommended: Create named instance (supports multiple engines)
368
418
  const engine = PluginI18nEngine.createInstance('myapp', languages);
369
419
 
370
- // Or use constructor
420
+ // Alternative: Direct constructor (for single engine use cases)
371
421
  const engine = new PluginI18nEngine(languages, config);
372
422
  ```
373
423
 
@@ -511,8 +561,16 @@ engine.translateStringKey(BrandedKeys.Welcome);
511
561
 
512
562
  ### Context Integration
513
563
 
564
+ Automatic injection of currency, timezone, and language from GlobalActiveContext:
565
+
514
566
  ```typescript
515
- import { GlobalActiveContext, CurrencyCode, Timezone } from '@digitaldefiance/i18n-lib';
567
+ import {
568
+ GlobalActiveContext,
569
+ CurrencyCode,
570
+ Timezone,
571
+ PluginI18nEngine,
572
+ LanguageCodes
573
+ } from '@digitaldefiance/i18n-lib';
516
574
 
517
575
  // Set context variables
518
576
  const context = GlobalActiveContext.getInstance();
@@ -531,16 +589,23 @@ engine.t('Price in {currency}', { currency: 'USD' }); // "Price in USD"
531
589
 
532
590
  ### Constants Management
533
591
 
592
+ Manage application-wide constants for use in translations:
593
+
534
594
  ```typescript
535
- // Merge constants (adds/overwrites specific keys)
595
+ // Merge constants (adds/updates specific keys, preserves others)
536
596
  engine.mergeConstants({ Version: '2.0', NewKey: 'value' });
537
597
  // Existing constants preserved, specified ones added/updated
538
598
 
539
- // Update all constants (replaces everything)
599
+ // Update all constants (replaces entire constants object)
540
600
  engine.updateConstants({ Site: 'NewSite', Version: '2.0' });
541
601
  // All previous constants removed, only these remain
542
602
  ```
543
603
 
604
+ **When to use:**
605
+ - **Constants**: Application-wide values that rarely change (AppName, Version)
606
+ - **Variables**: Request-specific or dynamic values passed to translate()
607
+ - **Context**: User-specific values (currency, timezone, language)
608
+
544
609
  ### Language Management
545
610
 
546
611
  ```typescript
@@ -550,9 +615,11 @@ engine.setLanguage(LanguageCodes.FR);
550
615
  // Get current language
551
616
  const lang = engine.getCurrentLanguage();
552
617
 
553
- // Check if language exists
618
+ // Check if language exists (recommended before setLanguage)
554
619
  if (engine.hasLanguage(LanguageCodes.ES)) {
555
620
  engine.setLanguage(LanguageCodes.ES);
621
+ } else {
622
+ console.warn('Spanish not available, using default');
556
623
  }
557
624
 
558
625
  // Get all languages
@@ -561,22 +628,29 @@ const languages = engine.getLanguages();
561
628
 
562
629
  ### Admin Context
563
630
 
564
- Separate language for admin interfaces:
631
+ Separate language for admin interfaces (useful for multi-tenant applications where admins need consistent UI language regardless of user's language):
565
632
 
566
633
  ```typescript
567
- // Set admin language
634
+ // Set admin language (e.g., always English for admin panel)
568
635
  engine.setAdminLanguage(LanguageCodes.EN_US);
569
636
 
570
- // Switch to admin context
637
+ // Switch to admin context (uses admin language)
571
638
  engine.switchToAdmin();
639
+ const adminText = engine.translate('app', 'dashboard'); // Uses EN_US
572
640
 
573
- // Switch back to user context
641
+ // Switch back to user context (uses user's language)
574
642
  engine.switchToUser();
643
+ const userText = engine.translate('app', 'dashboard'); // Uses user's language
575
644
  ```
576
645
 
646
+ **Use cases:**
647
+ - Admin panels in multi-language applications
648
+ - Support interfaces that need consistent language
649
+ - Internal tools accessed by multilingual teams
650
+
577
651
  ## Core System Strings
578
652
 
579
- Pre-built translations for common UI elements:
653
+ Pre-built translations for common UI elements in 8 languages:
580
654
 
581
655
  ```typescript
582
656
  import { getCoreI18nEngine, CoreStringKey, CoreI18nComponentId } from '@digitaldefiance/i18n-lib';
@@ -588,21 +662,23 @@ const yes = coreEngine.translate(CoreI18nComponentId, CoreStringKey.Common_Yes);
588
662
  const error = coreEngine.translate(CoreI18nComponentId, CoreStringKey.Error_NotFound);
589
663
  ```
590
664
 
591
- Available core string categories:
665
+ **Available core string categories:**
666
+
667
+ - **Common** (30+ strings): Yes, No, Cancel, OK, Save, Delete, Edit, Create, Update, Loading, Search, Filter, Sort, Export, Import, Settings, Help, About, Contact, Terms, Privacy, Logout, Profile, Dashboard, Home, Back, Next, Previous, Submit, Reset
668
+ - **Errors** (25+ strings): InvalidInput, NetworkError, NotFound, AccessDenied, ValidationFailed, Unauthorized, Forbidden, ServerError, Timeout, BadRequest, Conflict, Gone, TooManyRequests, ServiceUnavailable
669
+ - **System** (20+ strings): Welcome, Goodbye, PleaseWait, ProcessingRequest, OperationComplete, OperationFailed, Success, Warning, Info, Confirm, AreYouSure, UnsavedChanges, SessionExpired, MaintenanceMode
592
670
 
593
- - **Common**: Yes, No, Cancel, OK, Save, Delete, Edit, Create, Update, Loading, etc.
594
- - **Errors**: InvalidInput, NetworkError, NotFound, AccessDenied, ValidationFailed, etc.
595
- - **System**: Welcome, Goodbye, PleaseWait, ProcessingRequest, OperationComplete, etc.
671
+ See `CoreStringKey` enum for complete list of available strings.
596
672
 
597
673
  ## Multiple Instances
598
674
 
599
- Create isolated engines for different parts of your application:
675
+ Create isolated engines for different parts of your application (useful for micro-frontends, plugins, or multi-tenant systems):
600
676
 
601
677
  ```typescript
602
- // Admin engine
678
+ // Admin engine with admin-specific languages
603
679
  const adminEngine = PluginI18nEngine.createInstance('admin', adminLanguages);
604
680
 
605
- // User engine
681
+ // User engine with user-facing languages
606
682
  const userEngine = PluginI18nEngine.createInstance('user', userLanguages);
607
683
 
608
684
  // Get instance by key
@@ -613,13 +689,19 @@ if (PluginI18nEngine.hasInstance('admin')) {
613
689
  // ...
614
690
  }
615
691
 
616
- // Remove instance
692
+ // Remove instance (cleanup)
617
693
  PluginI18nEngine.removeInstance('admin');
618
694
 
619
- // Reset all instances
620
- PluginI18nEngine.resetAll();
695
+ // Reset all instances (useful in tests)
696
+ PluginI18nEngine.resetAll(); // ⚠️ Removes ALL instances globally
621
697
  ```
622
698
 
699
+ **Use cases:**
700
+ - Micro-frontends with independent i18n
701
+ - Plugin systems with isolated translations
702
+ - Multi-tenant applications with tenant-specific languages
703
+ - Testing (create/destroy engines per test)
704
+
623
705
  ## Error Handling
624
706
 
625
707
  ### RegistryError
@@ -663,7 +745,7 @@ throw new MyError(LanguageCodes.FR); // Throws with French error message
663
745
 
664
746
  ## Translation Adapter
665
747
 
666
- Adapt PluginI18nEngine to simpler TranslationEngine interface:
748
+ Adapt PluginI18nEngine to simpler TranslationEngine interface (useful when integrating with error classes or other components expecting a simplified translation interface):
667
749
 
668
750
  ```typescript
669
751
  import { createTranslationAdapter } from '@digitaldefiance/i18n-lib';
@@ -671,6 +753,7 @@ import { createTranslationAdapter } from '@digitaldefiance/i18n-lib';
671
753
  const adapter = createTranslationAdapter(engine, 'componentId');
672
754
 
673
755
  // Use adapter where TranslationEngine is expected
756
+ // (e.g., error classes, third-party libraries)
674
757
  const message = adapter.translate('key', { var: 'value' });
675
758
  ```
676
759
 
@@ -691,6 +774,23 @@ LanguageCodes.JA // 'ja'
691
774
  LanguageCodes.UK // 'uk'
692
775
  ```
693
776
 
777
+ **Adding custom language codes:**
778
+
779
+ ```typescript
780
+ // Define your custom language type
781
+ type MyLanguages = CoreLanguageCode | 'pt-BR' | 'it' | 'nl';
782
+
783
+ // Create engine with custom languages
784
+ const engine = PluginI18nEngine.createInstance<MyLanguages>('app', [
785
+ { id: LanguageCodes.EN_US, name: 'English', code: 'en-US', isDefault: true },
786
+ { id: 'pt-BR', name: 'Portuguese (Brazil)', code: 'pt-BR' },
787
+ { id: 'it', name: 'Italian', code: 'it' },
788
+ { id: 'nl', name: 'Dutch', code: 'nl' },
789
+ ]);
790
+ ```
791
+
792
+ **Note**: The 8 built-in codes have pre-translated core strings. Custom languages require you to provide all translations.
793
+
694
794
  ## API Reference
695
795
 
696
796
  ### PluginI18nEngine
@@ -1217,11 +1317,167 @@ function translateAnyValue<T extends string | number>(
1217
1317
 
1218
1318
  ## Browser Support
1219
1319
 
1220
- - Chrome/Edge: Latest 2 versions
1221
- - Firefox: Latest 2 versions
1222
- - Safari: Latest 2 versions
1320
+ - Chrome/Edge: Latest 2 versions (minimum: Chrome 90, Edge 90)
1321
+ - Firefox: Latest 2 versions (minimum: Firefox 88)
1322
+ - Safari: Latest 2 versions (minimum: Safari 14)
1223
1323
  - Node.js: 18+
1224
1324
 
1325
+ **Polyfills**: Not required for supported versions. For older browsers, you may need:
1326
+ - `Intl.PluralRules` polyfill
1327
+ - `Intl.NumberFormat` polyfill
1328
+
1329
+ ## Troubleshooting
1330
+
1331
+ ### Component Not Found Error
1332
+
1333
+ **Problem**: `RegistryError: Component 'xyz' not found`
1334
+
1335
+ **Solutions**:
1336
+ 1. Ensure component is registered before use: `engine.registerComponent({...})`
1337
+ 2. Check component ID spelling matches exactly
1338
+ 3. Verify registration completed successfully (no errors thrown)
1339
+
1340
+ ### Translation Returns `[componentId.key]`
1341
+
1342
+ **Problem**: Translation returns placeholder instead of translated text
1343
+
1344
+ **Solutions**:
1345
+ 1. Check string key exists in component registration
1346
+ 2. Verify current language has translation for this key
1347
+ 3. Use `engine.validate()` to find missing translations
1348
+ 4. Check if using `safeTranslate()` (returns placeholder on error)
1349
+
1350
+ ### Plural Forms Not Working
1351
+
1352
+ **Problem**: Always shows same plural form regardless of count
1353
+
1354
+ **Solutions**:
1355
+ 1. Ensure passing `count` variable: `engine.translate('id', 'key', { count: 5 })`
1356
+ 2. Use `createPluralString()` helper to create plural object
1357
+ 3. Verify language has correct plural rules (see PLURALIZATION_SUPPORT.md)
1358
+ 4. Check required plural forms for language: `getRequiredPluralForms('ru')`
1359
+
1360
+ ### ICU MessageFormat Not Parsing
1361
+
1362
+ **Problem**: ICU syntax appears as literal text
1363
+
1364
+ **Solutions**:
1365
+ 1. Use `formatICUMessage()` function, not `translate()`
1366
+ 2. Check ICU syntax is valid: `validateICUMessage(message)`
1367
+ 3. Ensure variables are provided: `formatICUMessage(msg, { count: 1 })`
1368
+ 4. See [docs/ICU_MESSAGEFORMAT.md](docs/ICU_MESSAGEFORMAT.md) for syntax
1369
+
1370
+ ### Memory Leak with Multiple Instances
1371
+
1372
+ **Problem**: Memory usage grows over time
1373
+
1374
+ **Solutions**:
1375
+ 1. Call `PluginI18nEngine.removeInstance(key)` when done
1376
+ 2. Use `resetAll()` in test cleanup
1377
+ 3. Reuse instances instead of creating new ones
1378
+ 4. Check for circular references in custom code
1379
+
1380
+ ### TypeScript Type Errors
1381
+
1382
+ **Problem**: Type errors with language codes or string keys
1383
+
1384
+ **Solutions**:
1385
+ 1. Use generic types: `PluginI18nEngine.createInstance<MyLanguages>(...)`
1386
+ 2. Ensure `as const` on string key objects
1387
+ 3. Import types: `import type { ComponentRegistration } from '@digitaldefiance/i18n-lib'`
1388
+ 4. Check TypeScript version (4.5+ recommended)
1389
+
1390
+ ## FAQ
1391
+
1392
+ ### When should I use ICU MessageFormat vs simple templates?
1393
+
1394
+ **Use ICU MessageFormat when:**
1395
+ - You need complex pluralization (multiple forms)
1396
+ - You need gender-specific translations
1397
+ - You need number/date/time formatting
1398
+ - You need nested conditional logic
1399
+
1400
+ **Use simple templates when:**
1401
+ - You only need variable substitution
1402
+ - You're referencing other components ({{Component.key}})
1403
+ - You want simpler, more readable strings
1404
+
1405
+ ### How do I handle missing translations?
1406
+
1407
+ **Options:**
1408
+ 1. Use `safeTranslate()` - returns `[componentId.key]` placeholder
1409
+ 2. Set fallback language in config
1410
+ 3. Use `engine.validate()` to find missing translations during development
1411
+ 4. Implement custom error handling with try/catch
1412
+
1413
+ ### Can I use this library without TypeScript?
1414
+
1415
+ **Yes**, but you lose type safety benefits:
1416
+ ```javascript
1417
+ const { PluginI18nEngine, LanguageCodes } = require('@digitaldefiance/i18n-lib');
1418
+ const engine = PluginI18nEngine.createInstance('app', languages);
1419
+ ```
1420
+
1421
+ ### How do I add a new language?
1422
+
1423
+ **Steps:**
1424
+ 1. Add language definition to engine creation
1425
+ 2. Register components with translations for new language
1426
+ 3. If using plurals, check required forms: `getRequiredPluralForms('pt-BR')`
1427
+ 4. See [docs/ADDING_LANGUAGES.md](docs/ADDING_LANGUAGES.md) for details
1428
+
1429
+ ### What's the difference between branded enums and regular enums?
1430
+
1431
+ **Branded enums** (v4.0.4+):
1432
+ - Runtime identification of component ownership
1433
+ - Collision detection between components
1434
+ - Automatic component routing
1435
+ - Created with `createI18nStringKeys()`
1436
+
1437
+ **Regular enums**:
1438
+ - Compile-time only (erased at runtime)
1439
+ - No collision detection
1440
+ - Must specify component ID in every translate call
1441
+
1442
+ ### How do I migrate from v1.x to v4.x?
1443
+
1444
+ **Key changes:**
1445
+ 1. `CoreLanguage` enum → `LanguageCodes` constants
1446
+ 2. Language IDs now use BCP 47 codes ('en-US' not 'English (US)')
1447
+ 3. `register()` → `registerComponent()` (more explicit)
1448
+ 4. See [docs/MIGRATION_GUIDE.md](docs/MIGRATION_GUIDE.md) for complete guide
1449
+
1450
+ ### Can I use multiple engines in the same application?
1451
+
1452
+ **Yes**, use named instances:
1453
+ ```typescript
1454
+ const adminEngine = PluginI18nEngine.createInstance('admin', adminLangs);
1455
+ const userEngine = PluginI18nEngine.createInstance('user', userLangs);
1456
+ ```
1457
+
1458
+ See [Multiple Instances](#multiple-instances) section for details.
1459
+
1460
+ ### How do I test components that use i18n?
1461
+
1462
+ **Pattern:**
1463
+ ```typescript
1464
+ import { PluginI18nEngine } from '@digitaldefiance/i18n-lib';
1465
+
1466
+ describe('MyComponent', () => {
1467
+ beforeEach(() => {
1468
+ PluginI18nEngine.resetAll();
1469
+ const engine = PluginI18nEngine.createInstance('test', languages);
1470
+ engine.registerComponent(/* ... */);
1471
+ });
1472
+
1473
+ afterEach(() => {
1474
+ PluginI18nEngine.resetAll();
1475
+ });
1476
+ });
1477
+ ```
1478
+
1479
+ See [Testing](#testing) section for more patterns.
1480
+
1225
1481
  ## License
1226
1482
 
1227
1483
  MIT License - See LICENSE file for details
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitaldefiance/i18n-lib",
3
- "version": "4.3.0",
3
+ "version": "4.3.2",
4
4
  "description": "i18n library with enum translation support",
5
5
  "homepage": "https://github.com/Digital-Defiance/i18n-lib",
6
6
  "repository": {