@digitaldefiance/i18n-lib 1.0.33 β†’ 1.1.1

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 (51) hide show
  1. package/README.md +477 -4
  2. package/dist/component-definition.d.ts +11 -0
  3. package/dist/component-definition.js +2 -0
  4. package/dist/component-registration.d.ts +9 -0
  5. package/dist/component-registration.js +2 -0
  6. package/dist/component-registry.d.ts +64 -0
  7. package/dist/component-registry.js +238 -0
  8. package/dist/context.d.ts +2 -1
  9. package/dist/core-i18n.d.ts +41 -0
  10. package/dist/core-i18n.js +436 -0
  11. package/dist/core-language.d.ts +13 -0
  12. package/dist/core-language.js +17 -0
  13. package/dist/core-string-key.d.ts +39 -0
  14. package/dist/core-string-key.js +47 -0
  15. package/dist/default-config.d.ts +2 -1
  16. package/dist/default-config.js +24 -24
  17. package/dist/i18n-config.d.ts +20 -0
  18. package/dist/i18n-config.js +2 -0
  19. package/dist/i18n-context.d.ts +14 -0
  20. package/dist/i18n-context.js +2 -0
  21. package/dist/i18n-engine.d.ts +3 -1
  22. package/dist/index.d.ts +21 -1
  23. package/dist/index.js +25 -2
  24. package/dist/language-definition.d.ts +13 -0
  25. package/dist/language-definition.js +2 -0
  26. package/dist/language-registry.d.ts +106 -0
  27. package/dist/language-registry.js +194 -0
  28. package/dist/plugin-i18n-engine.d.ts +126 -0
  29. package/dist/plugin-i18n-engine.js +266 -0
  30. package/dist/registry-config.d.ts +14 -0
  31. package/dist/registry-config.js +2 -0
  32. package/dist/registry-context.d.ts +12 -0
  33. package/dist/registry-context.js +2 -0
  34. package/dist/registry-error-type.d.ts +12 -0
  35. package/dist/registry-error-type.js +16 -0
  36. package/dist/registry-error.d.ts +19 -0
  37. package/dist/registry-error.js +44 -0
  38. package/dist/strict-types.d.ts +18 -0
  39. package/dist/strict-types.js +17 -0
  40. package/dist/translation-request.d.ts +9 -0
  41. package/dist/translation-request.js +2 -0
  42. package/dist/translation-response.d.ts +8 -0
  43. package/dist/translation-response.js +2 -0
  44. package/dist/typed-error.d.ts +63 -3
  45. package/dist/typed-error.js +230 -2
  46. package/dist/types.d.ts +42 -29
  47. package/dist/validation-config.d.ts +11 -0
  48. package/dist/validation-config.js +2 -0
  49. package/dist/validation-result.d.ts +12 -0
  50. package/dist/validation-result.js +2 -0
  51. package/package.json +2 -1
package/README.md CHANGED
@@ -1,10 +1,24 @@
1
1
  # @digitaldefiance/i18n-lib
2
2
 
3
- A comprehensive TypeScript internationalization library with enum translation support, template processing, and context management.
3
+ A comprehensive TypeScript internationalization library with plugin-based component registration, enum translation support, template processing, and context management.
4
+
5
+ ## πŸš€ New Plugin-Based Architecture
6
+
7
+ **Version 1.1.0** introduces a revolutionary plugin-based architecture with component registration and rigid compile-time type safety:
8
+
9
+ - **Component Registration System**: Register translation components with their own string keys
10
+ - **Language Plugin Support**: Add new languages dynamically with validation
11
+ - **Compile-Time Type Safety**: TypeScript ensures all strings are complete for all languages
12
+ - **Automatic Validation**: Comprehensive validation with detailed error reporting
13
+ - **Fallback System**: Intelligent fallback to default languages with missing translation detection
14
+ - **Multi-Instance Support**: Named instances for different application contexts
4
15
 
5
16
  ## Features
6
17
 
18
+ ### Core Features
19
+
7
20
  - **Type-Safe Translations**: Full TypeScript support with generic types for strings and languages
21
+ - **Plugin Architecture**: Register components and languages dynamically with full type safety
8
22
  - **Configuration Validation**: Automatic validation ensures all languages have complete string collections
9
23
  - **Localized Error Messages**: Error messages can be translated using the engine's own translation system
10
24
  - **Enum Translation Registry**: Translate enum values with complete type safety
@@ -14,7 +28,15 @@ A comprehensive TypeScript internationalization library with enum translation su
14
28
  - **Currency Formatting**: Built-in currency formatting utilities with locale support
15
29
  - **Fallback System**: Graceful degradation when translations are missing
16
30
  - **Extensible Configuration**: Module augmentation support for layered library extension
17
- - **Zero Dependencies**: Lightweight with no external dependencies
31
+ - **Backward Compatibility**: Legacy I18nEngine remains fully supported
32
+
33
+ ### New Plugin Features
34
+
35
+ - **Component Registry**: Manage translation components with validation
36
+ - **Language Registry**: Dynamic language registration with metadata
37
+ - **Type-Safe Registration**: Compile-time guarantees for translation completeness
38
+ - **Validation Reporting**: Detailed missing translation reports
39
+ - **Plugin System**: Modular component architecture
18
40
 
19
41
  ## Installation
20
42
 
@@ -79,6 +101,326 @@ const spanishGreeting = i18n.translate(MyStrings.UserGreetingTemplate, { name: '
79
101
  // "Β‘Hola, Juan!"
80
102
  ```
81
103
 
104
+ ## πŸ†• Plugin-Based Architecture (New in v1.1.0)
105
+
106
+ The new plugin-based architecture provides a component registration system with rigid compile-time type safety.
107
+
108
+ ### Quick Start with Plugin Architecture
109
+
110
+ ```typescript
111
+ import {
112
+ createCoreI18nEngine,
113
+ CoreStringKey,
114
+ CoreLanguage,
115
+ ComponentDefinition,
116
+ ComponentRegistration
117
+ } from '@digitaldefiance/i18n-lib';
118
+
119
+ // Create engine with default languages and core strings
120
+ const i18n = createCoreI18nEngine('myapp');
121
+
122
+ // Use core translations
123
+ const welcomeMessage = i18n.translate('core', CoreStringKey.System_Welcome);
124
+ const errorMessage = i18n.translate('core', CoreStringKey.Error_ValidationFailed);
125
+
126
+ // Define your own component with type safety
127
+ enum MyComponentStringKey {
128
+ Welcome = 'welcome',
129
+ Goodbye = 'goodbye',
130
+ UserGreetingTemplate = 'userGreetingTemplate'
131
+ }
132
+
133
+ const MyComponent: ComponentDefinition<MyComponentStringKey> = {
134
+ id: 'my-component',
135
+ name: 'My Custom Component',
136
+ stringKeys: Object.values(MyComponentStringKey)
137
+ };
138
+
139
+ // Define translations for all supported languages
140
+ const myComponentStrings = {
141
+ [CoreLanguage.EnglishUS]: {
142
+ [MyComponentStringKey.Welcome]: 'Welcome to my component!',
143
+ [MyComponentStringKey.Goodbye]: 'Goodbye from my component!',
144
+ [MyComponentStringKey.UserGreetingTemplate]: 'Hello, {name}!'
145
+ },
146
+ [CoreLanguage.French]: {
147
+ [MyComponentStringKey.Welcome]: 'Bienvenue dans mon composant !',
148
+ [MyComponentStringKey.Goodbye]: 'Au revoir de mon composant !',
149
+ [MyComponentStringKey.UserGreetingTemplate]: 'Bonjour, {name} !'
150
+ },
151
+ [CoreLanguage.Spanish]: {
152
+ [MyComponentStringKey.Welcome]: 'Β‘Bienvenido a mi componente!',
153
+ [MyComponentStringKey.Goodbye]: 'Β‘AdiΓ³s desde mi componente!',
154
+ [MyComponentStringKey.UserGreetingTemplate]: 'Β‘Hola, {name}!'
155
+ }
156
+ // TypeScript ensures all CoreLanguages are handled
157
+ };
158
+
159
+ // Register component (with validation)
160
+ const registration: ComponentRegistration<MyComponentStringKey, CoreLanguage> = {
161
+ component: MyComponent,
162
+ strings: myComponentStrings
163
+ };
164
+
165
+ const validationResult = i18n.registerComponent(registration);
166
+ if (!validationResult.isValid) {
167
+ console.warn('Missing translations:', validationResult.missingKeys);
168
+ }
169
+
170
+ // Use your component's translations
171
+ const welcome = i18n.translate('my-component', MyComponentStringKey.Welcome);
172
+ const greeting = i18n.translate('my-component', MyComponentStringKey.UserGreetingTemplate, {
173
+ name: 'John'
174
+ });
175
+
176
+ // Change language - affects all components
177
+ i18n.setLanguage(CoreLanguage.French);
178
+ const frenchWelcome = i18n.translate('my-component', MyComponentStringKey.Welcome);
179
+ // "Bienvenue dans mon composant !"
180
+ ```
181
+
182
+ ### Key Plugin Architecture Benefits
183
+
184
+ 1. **Compile-Time Type Safety**: TypeScript ensures all string keys exist for all languages
185
+ 2. **Component Isolation**: Each component manages its own strings independently
186
+ 3. **Flexible Language Support**: Components can support different subsets of system languages
187
+ 4. **Comprehensive Validation**: Automatic detection of missing translations with detailed reporting
188
+ 5. **Fallback System**: Intelligent fallback to default language when translations are missing
189
+ 6. **Dynamic Language Addition**: Add new languages at runtime with automatic validation updates
190
+ 7. **Extensibility**: Easy to add new languages and components dynamically
191
+
192
+ ### Pre-built Components
193
+
194
+ The library includes several pre-built components:
195
+
196
+ #### Core I18n Component
197
+
198
+ Provides essential system strings in 8 languages:
199
+
200
+ - English (US/UK), French, Spanish, German, Chinese (Simplified), Japanese, Ukrainian
201
+
202
+ ```typescript
203
+ import { createCoreI18nEngine, CoreStringKey } from '@digitaldefiance/i18n-lib';
204
+
205
+ const i18n = createCoreI18nEngine();
206
+ const saveText = i18n.translate('core', CoreStringKey.Common_Save);
207
+ const errorMsg = i18n.translate('core', CoreStringKey.Error_ValidationFailed);
208
+ ```
209
+
210
+ #### User System Component (Example)
211
+
212
+ Demonstrates user management strings:
213
+
214
+ ```typescript
215
+ import {
216
+ registerUserSystemComponent,
217
+ getUserTranslation,
218
+ UserStringKey
219
+ } from '@digitaldefiance/i18n-lib';
220
+
221
+ // Register user system with existing engine
222
+ registerUserSystemComponent(i18n);
223
+
224
+ // Use user system translations
225
+ const loginText = getUserTranslation(UserStringKey.Auth_Login);
226
+ const userNotFound = getUserTranslation(
227
+ UserStringKey.Error_UserNotFoundTemplate,
228
+ { username: 'john_doe' }
229
+ );
230
+ ```
231
+
232
+ ### Advanced Plugin Usage
233
+
234
+ #### Compile-Time Completeness Enforcement (Strict Mode)
235
+
236
+ By default the plugin engine performs runtime validation and provides fallbacks. If you want **compile-time** enforcement that every language mapping contains every string key, use the helper in `strict-types`:
237
+
238
+ ```typescript
239
+ import { createCompleteComponentStrings } from '@digitaldefiance/i18n-lib';
240
+
241
+ enum MyStrings {
242
+ Welcome = 'welcome',
243
+ Farewell = 'farewell'
244
+ }
245
+
246
+ type AppLang = 'en' | 'fr';
247
+
248
+ // This will only compile if BOTH languages contain BOTH keys.
249
+ const myStrictStrings = createCompleteComponentStrings<MyStrings, AppLang>({
250
+ en: {
251
+ [MyStrings.Welcome]: 'Welcome',
252
+ [MyStrings.Farewell]: 'Goodbye'
253
+ },
254
+ fr: {
255
+ [MyStrings.Welcome]: 'Bienvenue',
256
+ [MyStrings.Farewell]: 'Au revoir'
257
+ }
258
+ });
259
+
260
+ // If any key is missing, TypeScript reports an error before runtime.
261
+ ```
262
+
263
+ The core library itself uses this helper for the core component (`createCoreComponentStrings`) to guarantee internal completeness. For partial / iterative authoring you can still start with normal objects and later switch to the strict helper when translations stabilize.
264
+
265
+ #### Adding New Languages
266
+
267
+ ```typescript
268
+ import { createLanguageDefinition } from '@digitaldefiance/i18n-lib';
269
+
270
+ // Add Italian support
271
+ const italian = createLanguageDefinition('it', 'Italiano', 'it');
272
+ i18n.registerLanguage(italian);
273
+
274
+ // Update existing components with Italian translations
275
+ i18n.updateComponentStrings('my-component', {
276
+ it: {
277
+ [MyComponentStringKey.Welcome]: 'Benvenuto nel mio componente!',
278
+ [MyComponentStringKey.Goodbye]: 'Arrivederci dal mio componente!',
279
+ [MyComponentStringKey.UserGreetingTemplate]: 'Ciao, {name}!'
280
+ }
281
+ });
282
+ ```
283
+
284
+ #### Component Registration Validation
285
+
286
+ The plugin engine provides comprehensive validation to ensure translation completeness:
287
+
288
+ ```typescript
289
+ // Each component is validated against ALL system languages
290
+ enum MyStrings {
291
+ Welcome = 'welcome',
292
+ Goodbye = 'goodbye'
293
+ }
294
+
295
+ const myComponent: ComponentDefinition<MyStrings> = {
296
+ id: 'my-component',
297
+ name: 'My Component',
298
+ stringKeys: Object.values(MyStrings)
299
+ };
300
+
301
+ // System has EN, FR, ES languages - component must provide translations for all three
302
+ const registration: ComponentRegistration<MyStrings, CoreLanguage> = {
303
+ component: myComponent,
304
+ strings: {
305
+ [CoreLanguage.EnglishUS]: {
306
+ [MyStrings.Welcome]: 'Welcome',
307
+ [MyStrings.Goodbye]: 'Goodbye'
308
+ },
309
+ [CoreLanguage.French]: {
310
+ [MyStrings.Welcome]: 'Bienvenue',
311
+ [MyStrings.Goodbye]: 'Au revoir'
312
+ },
313
+ [CoreLanguage.Spanish]: {
314
+ [MyStrings.Welcome]: 'Bienvenido',
315
+ [MyStrings.Goodbye]: 'AdiΓ³s'
316
+ }
317
+ }
318
+ };
319
+
320
+ const result = i18n.registerComponent(registration);
321
+ if (!result.isValid) {
322
+ console.log('Missing translations:', result.missingKeys);
323
+ // Shows exactly which string keys are missing for which languages
324
+ }
325
+ ```
326
+
327
+ #### Flexible Language Support
328
+
329
+ Components can support different subsets of system languages:
330
+
331
+ ```typescript
332
+ // Component A supports EN, FR, ES
333
+ const componentA = {
334
+ component: { id: 'comp-a', name: 'Component A', stringKeys: ['hello'] },
335
+ strings: {
336
+ en: { hello: 'Hello' },
337
+ fr: { hello: 'Bonjour' },
338
+ es: { hello: 'Hola' }
339
+ }
340
+ };
341
+
342
+ // Component B only supports EN and DE (added later)
343
+ const componentB = {
344
+ component: { id: 'comp-b', name: 'Component B', stringKeys: ['save'] },
345
+ strings: {
346
+ en: { save: 'Save' },
347
+ de: { save: 'Speichern' }
348
+ }
349
+ };
350
+
351
+ // Both components can coexist - missing translations use fallback
352
+ i18n.registerComponent(componentA); // βœ“ Complete
353
+ i18n.registerComponent(componentB); // ⚠ Missing FR, ES - uses fallback
354
+
355
+ // Usage automatically handles fallbacks
356
+ i18n.translate('comp-b', 'save', {}, 'fr'); // Returns 'Save' (EN fallback)
357
+ ```
358
+
359
+ #### Dynamic Language Addition
360
+
361
+ ```typescript
362
+ // Add new language to system
363
+ const germanLang = { id: 'de', name: 'German', code: 'de' };
364
+ i18n.registerLanguage(germanLang);
365
+
366
+ // New component registrations now require German translations
367
+ const newRegistration = {
368
+ component: { id: 'new-comp', name: 'New Component', stringKeys: ['test'] },
369
+ strings: {
370
+ en: { test: 'Test' },
371
+ fr: { test: 'Test' },
372
+ es: { test: 'Prueba' }
373
+ // Missing 'de' - validation will flag this
374
+ }
375
+ };
376
+
377
+ const result = i18n.registerComponent(newRegistration);
378
+ console.log(result.missingKeys); // Shows missing German translations
379
+ ```
380
+
381
+ #### Validation and Error Handling
382
+
383
+ ```typescript
384
+ // Comprehensive validation
385
+ const globalValidation = i18n.validateAllComponents();
386
+ if (!globalValidation.isValid) {
387
+ console.error('Validation errors:', globalValidation.errors);
388
+ console.warn('Warnings:', globalValidation.warnings);
389
+ }
390
+
391
+ // Handle registration errors
392
+ try {
393
+ i18n.registerComponent(incompleteRegistration);
394
+ } catch (error) {
395
+ if (error instanceof RegistryError) {
396
+ console.error(`Registry error: ${error.type}`, error.metadata);
397
+ }
398
+ }
399
+
400
+ // Strict validation mode (rejects incomplete registrations)
401
+ const strictEngine = new PluginI18nEngine(languages, {
402
+ validation: {
403
+ requireCompleteStrings: true,
404
+ allowPartialRegistration: false,
405
+ fallbackLanguageId: 'en'
406
+ }
407
+ });
408
+ ```
409
+
410
+ #### Multi-Instance Support
411
+
412
+ ```typescript
413
+ // Create separate instances for different contexts
414
+ const adminI18n = PluginI18nEngine.createInstance('admin', languages);
415
+ const userI18n = PluginI18nEngine.createInstance('user', languages);
416
+
417
+ // Register different components for each
418
+ adminI18n.registerComponent(adminComponentRegistration);
419
+ userI18n.registerComponent(userComponentRegistration);
420
+ ```
421
+
422
+ For complete documentation on the plugin architecture, see [PLUGIN_ARCHITECTURE.md](./PLUGIN_ARCHITECTURE.md).
423
+
82
424
  ## Advanced Features
83
425
 
84
426
  ### Enum Translation Registry
@@ -214,20 +556,90 @@ I18nEngine.removeInstance('main');
214
556
 
215
557
  ## API Reference
216
558
 
217
- ### I18nEngine
559
+ ### Plugin Architecture API
560
+
561
+ #### PluginI18nEngine
562
+
563
+ **Constructor**
564
+
565
+ - `new PluginI18nEngine<TLanguages>(languages, config?)` - Create new plugin engine
566
+ - `PluginI18nEngine.createInstance<TLanguages>(key, languages, config?)` - Create named instance
567
+ - `PluginI18nEngine.getInstance<TLanguages>(key?)` - Get existing instance
568
+
569
+ **Component Management**
570
+
571
+ - `registerComponent<TStringKeys>(registration)` - Register component with translations
572
+ - `updateComponentStrings<TStringKeys>(componentId, strings)` - Update existing component strings
573
+ - `getComponents()` - Get all registered components
574
+ - `hasComponent(componentId)` - Check if component exists
575
+
576
+ **Translation Methods**
577
+
578
+ - `translate<TStringKeys>(componentId, stringKey, variables?, language?)` - Translate component string
579
+ - `safeTranslate(componentId, stringKey, variables?, language?)` - Safe translate with fallback
580
+ - `getTranslationDetails<TStringKeys>(componentId, stringKey, variables?, language?)` - Get detailed translation response
581
+
582
+ **Language Management**
583
+
584
+ - `registerLanguage(language)` - Register new language
585
+ - `registerLanguages(languages)` - Register multiple languages
586
+ - `getLanguages()` - Get all registered languages
587
+ - `hasLanguage(language)` - Check if language exists
588
+ - `setLanguage(language)` - Set current language
589
+ - `getLanguageByCode(code)` - Get language by ISO code
590
+
591
+ **Validation**
592
+
593
+ - `validateAllComponents()` - Validate all registered components
594
+ - `getLanguageRegistry()` - Access language registry directly
595
+ - `getComponentRegistry()` - Access component registry directly
596
+
597
+ #### Core I18n Functions
598
+
599
+ - `createCoreI18nEngine(instanceKey?)` - Create engine with core components
600
+ - `getCoreTranslation(stringKey, variables?, language?, instanceKey?)` - Get core translation
601
+ - `safeCoreTranslation(stringKey, variables?, language?, instanceKey?)` - Safe core translation
602
+
603
+ #### Component Registration Types
604
+
605
+ ```typescript
606
+ interface ComponentDefinition<TStringKeys extends string> {
607
+ readonly id: string;
608
+ readonly name: string;
609
+ readonly stringKeys: readonly TStringKeys[];
610
+ }
611
+
612
+ interface ComponentRegistration<TStringKeys extends string, TLanguages extends string> {
613
+ readonly component: ComponentDefinition<TStringKeys>;
614
+ readonly strings: PartialComponentLanguageStrings<TStringKeys, TLanguages>;
615
+ }
616
+
617
+ interface LanguageDefinition {
618
+ readonly id: string;
619
+ readonly name: string;
620
+ readonly code: string;
621
+ readonly isDefault?: boolean;
622
+ }
623
+ ```
624
+
625
+ ### Legacy I18nEngine (Still Supported)
218
626
 
219
627
  #### Constructor
628
+
220
629
  - `new I18nEngine<TStringKey, TLanguage>(config, key?)` - Create new engine instance
221
630
 
222
631
  #### Translation Methods
632
+
223
633
  - `translate(key, vars?, language?, fallbackLanguage?)` - Translate string with optional variables
224
634
  - `translateEnum(enumObj, value, language)` - Translate enum value
225
635
  - `t(templateString, language?, ...vars)` - Process template string with `{{EnumName.EnumKey}}` patterns
226
636
 
227
637
  #### Registration
638
+
228
639
  - `registerEnum(enumObj, translations, enumName)` - Register enum translations
229
640
 
230
641
  #### Language Management
642
+
231
643
  - `getLanguageCode(language)` - Get language code for language
232
644
  - `getLanguageFromCode(code)` - Get language from code
233
645
  - `getAllLanguageCodes()` - Get all language codes
@@ -235,34 +647,41 @@ I18nEngine.removeInstance('main');
235
647
  - `isLanguageAvailable(language)` - Check if language is available
236
648
 
237
649
  #### Context Management
650
+
238
651
  - `get context()` - Get current context
239
652
  - `set context(context)` - Set context properties
240
653
 
241
654
  #### Static Methods
655
+
242
656
  - `getInstance(key?)` - Get instance by key
243
657
  - `clearInstances()` - Clear all instances
244
658
  - `removeInstance(key?)` - Remove specific instance
245
659
 
246
660
  ### Context Utilities
661
+
247
662
  - `createContext(defaultLanguage, defaultContext)` - Create new context
248
663
  - `setLanguage(context, language)` - Set user language
249
664
  - `setAdminLanguage(context, language)` - Set admin language
250
665
  - `setContext(context, contextType)` - Set context type
251
666
 
252
667
  ### ContextManager
668
+
253
669
  - `addListener(listener)` - Add change listener
254
670
  - `removeListener(listener)` - Remove change listener
255
671
  - `createProxy(context)` - Create reactive context proxy
256
672
 
257
673
  ### Currency Utilities
674
+
258
675
  - `getCurrencyFormat(locale, currencyCode)` - Get currency formatting info
259
676
 
260
677
  ### Type Utilities
678
+
261
679
  - `createTranslations(translations)` - Helper for creating typed translations
262
680
 
263
681
  ## Type Definitions
264
682
 
265
683
  ### Core Types
684
+
266
685
  ```typescript
267
686
  type EnumTranslation<T extends string | number> = {
268
687
  [K in T]: string;
@@ -422,6 +841,20 @@ If localized error messages aren't provided, the engine falls back to English te
422
841
 
423
842
  ## Best Practices
424
843
 
844
+ ### Plugin Architecture (Recommended for New Projects)
845
+
846
+ 1. **Use Component Registration**: Organize translations into logical components with `PluginI18nEngine`
847
+ 2. **Define String Key Enums**: Always use TypeScript enums for string keys to ensure compile-time type safety
848
+ 3. **Complete Component Translations**: Provide translations for all supported languages in each component
849
+ 4. **Validate Registrations**: Check validation results and handle missing translations appropriately
850
+ 5. **Use Core Components**: Start with `createCoreI18nEngine()` for built-in system strings
851
+ 6. **Fallback Strategy**: Configure appropriate fallback languages for missing translations
852
+ 7. **Component Isolation**: Keep related strings together in the same component
853
+ 8. **Template Variables**: Use template strings with variables for dynamic content
854
+ 9. **Multi-Instance Architecture**: Use named instances for different application contexts (admin, user, etc.)
855
+
856
+ ### Legacy System (Still Supported)
857
+
425
858
  1. **Complete Translations**: EnumTranslation requires all enum values to be translated
426
859
  2. **Type Safety**: Use TypeScript enums for string keys and languages
427
860
  3. **Context Separation**: Use different contexts for admin and user interfaces
@@ -430,10 +863,50 @@ If localized error messages aren't provided, the engine falls back to English te
430
863
  6. **Layered Extension**: Use union types when extending configurations across libraries
431
864
  7. **Default Configuration**: Use `getDefaultI18nEngine()` for standard setups
432
865
 
866
+ ### Migration Strategy
867
+
868
+ When migrating from legacy to plugin architecture:
869
+
870
+ ```typescript
871
+ // Legacy approach
872
+ const legacy = new I18nEngine(config);
873
+ const text = legacy.translate(MyStrings.Welcome);
874
+
875
+ // New plugin approach
876
+ const modern = createCoreI18nEngine();
877
+ modern.registerComponent(myComponentRegistration);
878
+ const text = modern.translate('my-component', MyStrings.Welcome);
879
+ ```
880
+
881
+ Both systems can coexist in the same application during migration.
882
+
433
883
  ## License
434
884
 
435
885
  MIT
436
886
 
437
887
  ## Repository
438
888
 
439
- Part of the DigitalBurnbag project - a secure file sharing and automated protocol system.
889
+ Part of the DigitalBurnbag project - a secure file sharing and automated protocol system.
890
+
891
+ ## ChangeLog
892
+
893
+ ### Version 1.1.1
894
+
895
+ - Sat Oct 11 2025 17:47:00 GMT-0700 (Pacific Daylight Time)
896
+ - Improved type checking for completeness of component translations during registration
897
+ - Updated README/Migration guide for clarity.
898
+
899
+ ### Version 1.1.0
900
+
901
+ - Sat Oct 11 2025 16:49:00 GMT-0700 (Pacific Daylight Time)
902
+ - Introduced plugin-based architecture with component registration and compile-time type safety
903
+ - Added `PluginI18nEngine` with comprehensive validation and fallback system
904
+ - Maintained full support for legacy `I18nEngine`
905
+ - Added pre-built core and user system components
906
+ - Enhanced template processing and context management features
907
+ - Improved documentation and examples for both architectures
908
+
909
+ ### Version 1.0.33
910
+
911
+ - Wed Sep 24 2025 15:20:07 GMT-0700 (Pacific Daylight Time)
912
+ - Initial release of the TypeScript internationalization library with enum translation, template processing, context management, and currency formatting.
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Component definition with its string keys
3
+ */
4
+ export interface ComponentDefinition<TStringKeys extends string> {
5
+ /** Unique identifier for the component */
6
+ readonly id: string;
7
+ /** Human-readable name for the component */
8
+ readonly name: string;
9
+ /** Array of all string keys this component requires */
10
+ readonly stringKeys: readonly TStringKeys[];
11
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,9 @@
1
+ import { ComponentDefinition } from './component-definition';
2
+ import { PartialComponentLanguageStrings } from './types';
3
+ /**
4
+ * Registration payload for a component with its strings
5
+ */
6
+ export interface ComponentRegistration<TStringKeys extends string, TLanguages extends string> {
7
+ readonly component: ComponentDefinition<TStringKeys>;
8
+ readonly strings: PartialComponentLanguageStrings<TStringKeys, TLanguages>;
9
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Component registry for managing internationalization components and their string translations
3
+ */
4
+ import { ComponentDefinition } from './component-definition';
5
+ import { ComponentRegistration } from './component-registration';
6
+ import { TranslationRequest } from './translation-request';
7
+ import { TranslationResponse } from './translation-response';
8
+ import { ComponentLanguageStrings, PartialComponentLanguageStrings } from './types';
9
+ import { ValidationConfig } from './validation-config';
10
+ import { ValidationResult } from './validation-result';
11
+ /**
12
+ * Registry for managing components and their translations
13
+ */
14
+ export declare class ComponentRegistry<TLanguages extends string> {
15
+ private readonly components;
16
+ private readonly componentStrings;
17
+ private readonly validationConfig;
18
+ private readonly registeredLanguages;
19
+ constructor(languages: readonly TLanguages[], validationConfig: ValidationConfig);
20
+ /**
21
+ * Update the set of registered languages (for dynamic language addition)
22
+ */
23
+ updateRegisteredLanguages(languages: readonly TLanguages[]): void;
24
+ /**
25
+ * Register a new component with its translations
26
+ */
27
+ registerComponent<TStringKeys extends string>(registration: ComponentRegistration<TStringKeys, TLanguages>): ValidationResult;
28
+ /**
29
+ * Update strings for an existing component
30
+ */
31
+ updateComponentStrings<TStringKeys extends string>(componentId: string, strings: PartialComponentLanguageStrings<TStringKeys, TLanguages>): ValidationResult;
32
+ /**
33
+ * Get a translation for a specific component, string key, and language
34
+ */
35
+ getTranslation<TStringKeys extends string>(request: TranslationRequest<TStringKeys, TLanguages>): TranslationResponse;
36
+ /**
37
+ * Get all registered components
38
+ */
39
+ getComponents(): ReadonlyArray<ComponentDefinition<any>>;
40
+ /**
41
+ * Get a specific component by ID
42
+ */
43
+ getComponent<TStringKeys extends string>(componentId: string): ComponentDefinition<TStringKeys> | undefined;
44
+ /**
45
+ * Check if a component is registered
46
+ */
47
+ hasComponent(componentId: string): boolean;
48
+ /**
49
+ * Get all strings for a component in all languages
50
+ */
51
+ getComponentStrings<TStringKeys extends string>(componentId: string): ComponentLanguageStrings<TStringKeys, TLanguages> | undefined;
52
+ /**
53
+ * Validate a component registration
54
+ */
55
+ private validateComponentRegistration;
56
+ /**
57
+ * Complete missing strings with fallbacks
58
+ */
59
+ private completeStringsWithFallbacks;
60
+ /**
61
+ * Merge existing strings with new strings
62
+ */
63
+ private mergeStrings;
64
+ }