@digitaldefiance/i18n-lib 1.1.6 → 1.1.8

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
@@ -423,6 +423,95 @@ For complete documentation on the plugin architecture, see [PLUGIN_ARCHITECTURE.
423
423
 
424
424
  ## Advanced Features
425
425
 
426
+ ### Translatable Errors
427
+
428
+ The `TranslatableGenericError` class provides a simple way to create errors with translated messages that work across any component:
429
+
430
+ ```typescript
431
+ import { TranslatableGenericError, CoreStringKey, CoreLanguage } from '@digitaldefiance/i18n-lib';
432
+
433
+ // Define your error string keys
434
+ enum UserErrorKey {
435
+ UserNotFound = 'userNotFound',
436
+ InvalidCredentials = 'invalidCredentials',
437
+ AccountLocked = 'accountLocked',
438
+ }
439
+
440
+ // Register your component with translations
441
+ const userErrorComponent = {
442
+ id: 'user-errors',
443
+ name: 'User Errors',
444
+ stringKeys: Object.values(UserErrorKey)
445
+ };
446
+
447
+ const registration = {
448
+ component: userErrorComponent,
449
+ strings: {
450
+ en: {
451
+ [UserErrorKey.UserNotFound]: 'User "{username}" not found',
452
+ [UserErrorKey.InvalidCredentials]: 'Invalid credentials provided',
453
+ [UserErrorKey.AccountLocked]: 'Account locked until {unlockTime}'
454
+ },
455
+ fr: {
456
+ [UserErrorKey.UserNotFound]: 'Utilisateur "{username}" introuvable',
457
+ [UserErrorKey.InvalidCredentials]: 'Identifiants invalides fournis',
458
+ [UserErrorKey.AccountLocked]: 'Compte verrouillé jusqu\'à {unlockTime}'
459
+ }
460
+ }
461
+ };
462
+
463
+ i18n.registerComponent(registration);
464
+
465
+ // Throw translatable errors
466
+ throw new TranslatableGenericError(
467
+ 'user-errors',
468
+ UserErrorKey.UserNotFound,
469
+ { username: 'john_doe' },
470
+ 'en',
471
+ { userId: 123 }, // metadata
472
+ 'myapp' // engine instance key
473
+ );
474
+
475
+ // Use with explicit engine instance
476
+ const error = TranslatableGenericError.withEngine(
477
+ i18n,
478
+ 'user-errors',
479
+ UserErrorKey.InvalidCredentials,
480
+ undefined,
481
+ 'fr'
482
+ );
483
+
484
+ // Retranslate errors dynamically
485
+ try {
486
+ // ... code that throws TranslatableGenericError
487
+ } catch (error) {
488
+ if (error instanceof TranslatableGenericError) {
489
+ const localizedMessage = error.retranslate(userLanguage, 'myapp');
490
+ sendToUser(localizedMessage);
491
+ }
492
+ }
493
+
494
+ // Use with core strings
495
+ throw new TranslatableGenericError(
496
+ 'core',
497
+ CoreStringKey.Error_AccessDenied,
498
+ undefined,
499
+ CoreLanguage.EnglishUS,
500
+ { requestId: '12345' },
501
+ 'myapp'
502
+ );
503
+ ```
504
+
505
+ **Key Features:**
506
+ - Works with any registered component and string keys
507
+ - Uses `safeTranslate` for consistent fallback behavior (`[componentId.stringKey]`)
508
+ - Stores error context: stringKey, componentId, language, variables, metadata
509
+ - Supports dynamic retranslation with `retranslate()` method
510
+ - Never throws during construction - always returns a valid error
511
+ - Compatible with both constructor and static factory methods
512
+
513
+ For complete documentation, see [TRANSLATABLE_ERROR_GUIDE.md](./TRANSLATABLE_ERROR_GUIDE.md).
514
+
426
515
  ### Enum Translation Registry
427
516
 
428
517
  ```typescript
@@ -937,6 +1026,33 @@ Part of the DigitalBurnbag project - a secure file sharing and automated protoco
937
1026
 
938
1027
  ## ChangeLog
939
1028
 
1029
+ ### Version 1.1.8
1030
+
1031
+ - Wed Oct 15 2025 16:43:00 GMT-0700 (Pacific Daylight Time)
1032
+ - Fix to translatable prototype inheritance
1033
+
1034
+ ### Version 1.1.7
1035
+
1036
+ - Wed Oct 15 2025 16:13:00 GMT-0700 (Pacific Daylight Time)
1037
+ **Fixed:**
1038
+ - Corrected safeCoreTranslation fallback format to use
1039
+ ```plaintext
1040
+ [CoreStringKey.${stringKey}]
1041
+ ```
1042
+ - Fixed import issues with DefaultInstanceKey
1043
+ **Added:**
1044
+ - New TranslatableGenericError class for generic translatable errors across any component
1045
+ - CoreI18nComponentId constant export
1046
+ - 130+ new tests for comprehensive coverage
1047
+ - Complete usage documentation
1048
+ **Changed:**
1049
+ - Standardized all fallback formats to use square brackets
1050
+ ```plaintext
1051
+ [componentId.stringKey]
1052
+ ```
1053
+ - Refactored to use CoreI18nComponentId constant
1054
+ All tests pass and backward compatibility is maintained.
1055
+
940
1056
  ### Version 1.1.6
941
1057
 
942
1058
  - Tue Oct 14 2025 17:04:00 GMT-0700 (Pacific Daylight Time)
@@ -11,6 +11,7 @@ import { PluginI18nEngine } from './plugin-i18n-engine';
11
11
  * Create default language definitions
12
12
  */
13
13
  export declare function createDefaultLanguages(): LanguageDefinition[];
14
+ export declare const CoreI18nComponentId = "core";
14
15
  /**
15
16
  * Core component definition
16
17
  */
package/dist/core-i18n.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * Core I18n component with default languages and system strings
4
4
  */
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.CoreComponentDefinition = void 0;
6
+ exports.CoreComponentDefinition = exports.CoreI18nComponentId = void 0;
7
7
  exports.createDefaultLanguages = createDefaultLanguages;
8
8
  exports.createCoreComponentStrings = createCoreComponentStrings;
9
9
  exports.createCoreComponentRegistration = createCoreComponentRegistration;
@@ -15,6 +15,7 @@ const core_string_key_1 = require("./core-string-key");
15
15
  const language_registry_1 = require("./language-registry");
16
16
  const plugin_i18n_engine_1 = require("./plugin-i18n-engine");
17
17
  const strict_types_1 = require("./strict-types");
18
+ const DefaultInstanceKey = 'default';
18
19
  /**
19
20
  * Create default language definitions
20
21
  */
@@ -63,11 +64,12 @@ function createDefaultLanguages() {
63
64
  },
64
65
  ]);
65
66
  }
67
+ exports.CoreI18nComponentId = 'core';
66
68
  /**
67
69
  * Core component definition
68
70
  */
69
71
  exports.CoreComponentDefinition = {
70
- id: 'core',
72
+ id: exports.CoreI18nComponentId,
71
73
  name: 'Core I18n System',
72
74
  stringKeys: Object.values(core_string_key_1.CoreStringKey),
73
75
  };
@@ -418,7 +420,7 @@ function createCoreComponentRegistration() {
418
420
  /**
419
421
  * Create a pre-configured I18n engine with core components
420
422
  */
421
- function createCoreI18nEngine(instanceKey = 'default') {
423
+ function createCoreI18nEngine(instanceKey = DefaultInstanceKey) {
422
424
  const languages = createDefaultLanguages();
423
425
  const engine = plugin_i18n_engine_1.PluginI18nEngine.createInstance(instanceKey, languages);
424
426
  engine.registerComponent(createCoreComponentRegistration());
@@ -429,7 +431,7 @@ function createCoreI18nEngine(instanceKey = 'default') {
429
431
  */
430
432
  function getCoreTranslation(stringKey, variables, language, instanceKey) {
431
433
  const engine = plugin_i18n_engine_1.PluginI18nEngine.getInstance(instanceKey);
432
- return engine.translate('core', stringKey, variables, language);
434
+ return engine.translate(exports.CoreI18nComponentId, stringKey, variables, language);
433
435
  }
434
436
  /**
435
437
  * Helper function to safely get core translation with fallback
@@ -439,6 +441,6 @@ function safeCoreTranslation(stringKey, variables, language, instanceKey) {
439
441
  return getCoreTranslation(stringKey, variables, language, instanceKey);
440
442
  }
441
443
  catch {
442
- return `[core.${stringKey}]`;
444
+ return `[CoreStringKey.${stringKey}]`;
443
445
  }
444
446
  }
package/dist/index.d.ts CHANGED
@@ -18,6 +18,7 @@ export * from './i18n-engine';
18
18
  export * from './language-definition';
19
19
  export * from './template';
20
20
  export * from './timezone';
21
+ export * from './translatable-generic-error';
21
22
  export * from './typed-error';
22
23
  export * from './types';
23
24
  export * from './utils';
package/dist/index.js CHANGED
@@ -37,6 +37,7 @@ __exportStar(require("./i18n-engine"), exports);
37
37
  __exportStar(require("./language-definition"), exports);
38
38
  __exportStar(require("./template"), exports);
39
39
  __exportStar(require("./timezone"), exports);
40
+ __exportStar(require("./translatable-generic-error"), exports);
40
41
  __exportStar(require("./typed-error"), exports);
41
42
  __exportStar(require("./types"), exports);
42
43
  __exportStar(require("./utils"), exports);
@@ -0,0 +1,29 @@
1
+ import { PluginI18nEngine } from './plugin-i18n-engine';
2
+ /**
3
+ * Generic translatable error that works with any plugin engine and component
4
+ */
5
+ export declare class TranslatableGenericError<TStringKey extends string = string, TLanguage extends string = string> extends Error {
6
+ readonly stringKey: TStringKey;
7
+ readonly componentId: string;
8
+ readonly language?: TLanguage;
9
+ readonly variables?: Record<string, string | number>;
10
+ readonly metadata?: Record<string, any>;
11
+ /**
12
+ * Create a translatable error
13
+ * @param componentId - The component ID to translate from
14
+ * @param stringKey - The translation key
15
+ * @param variables - Variables for interpolation
16
+ * @param language - Optional language override
17
+ * @param metadata - Additional error metadata
18
+ * @param instanceKey - Optional engine instance key
19
+ */
20
+ constructor(componentId: string, stringKey: TStringKey, variables?: Record<string, string | number>, language?: TLanguage, metadata?: Record<string, any>, instanceKey?: string);
21
+ /**
22
+ * Create error with explicit engine instance
23
+ */
24
+ static withEngine<TStringKey extends string, TLanguage extends string>(engine: PluginI18nEngine<TLanguage>, componentId: string, stringKey: TStringKey, variables?: Record<string, string | number>, language?: TLanguage, metadata?: Record<string, any>): TranslatableGenericError<TStringKey, TLanguage>;
25
+ /**
26
+ * Retranslate the error message in a different language
27
+ */
28
+ retranslate(language: TLanguage, instanceKey?: string): string;
29
+ }
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TranslatableGenericError = void 0;
4
+ const plugin_i18n_engine_1 = require("./plugin-i18n-engine");
5
+ /**
6
+ * Generic translatable error that works with any plugin engine and component
7
+ */
8
+ class TranslatableGenericError extends Error {
9
+ /**
10
+ * Create a translatable error
11
+ * @param componentId - The component ID to translate from
12
+ * @param stringKey - The translation key
13
+ * @param variables - Variables for interpolation
14
+ * @param language - Optional language override
15
+ * @param metadata - Additional error metadata
16
+ * @param instanceKey - Optional engine instance key
17
+ */
18
+ constructor(componentId, stringKey, variables, language, metadata, instanceKey) {
19
+ let translatedMessage;
20
+ try {
21
+ const engine = plugin_i18n_engine_1.PluginI18nEngine.getInstance(instanceKey);
22
+ translatedMessage = engine.safeTranslate(componentId, stringKey, variables, language);
23
+ }
24
+ catch (error) {
25
+ // If engine not found or translation fails, use fallback format
26
+ translatedMessage = `[${componentId}.${stringKey}]`;
27
+ }
28
+ super(translatedMessage);
29
+ this.name = 'TranslatableGenericError';
30
+ this.stringKey = stringKey;
31
+ this.componentId = componentId;
32
+ this.language = language;
33
+ this.variables = variables;
34
+ this.metadata = metadata;
35
+ // Ensure proper prototype chain for instanceof checks across transpiled targets
36
+ Object.setPrototypeOf(this, new.target.prototype);
37
+ }
38
+ /**
39
+ * Create error with explicit engine instance
40
+ */
41
+ static withEngine(engine, componentId, stringKey, variables, language, metadata) {
42
+ const translatedMessage = engine.safeTranslate(componentId, stringKey, variables, language);
43
+ const error = Object.create(TranslatableGenericError.prototype);
44
+ Error.call(error, translatedMessage);
45
+ error.name = 'TranslatableGenericError';
46
+ error.stringKey = stringKey;
47
+ error.componentId = componentId;
48
+ error.language = language;
49
+ error.variables = variables;
50
+ error.metadata = metadata;
51
+ error.message = translatedMessage;
52
+ return error;
53
+ }
54
+ /**
55
+ * Retranslate the error message in a different language
56
+ */
57
+ retranslate(language, instanceKey) {
58
+ try {
59
+ const engine = plugin_i18n_engine_1.PluginI18nEngine.getInstance(instanceKey);
60
+ return engine.safeTranslate(this.componentId, this.stringKey, this.variables, language);
61
+ }
62
+ catch (error) {
63
+ return `[${this.componentId}.${this.stringKey}]`;
64
+ }
65
+ }
66
+ }
67
+ exports.TranslatableGenericError = TranslatableGenericError;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitaldefiance/i18n-lib",
3
- "version": "1.1.6",
3
+ "version": "1.1.8",
4
4
  "description": "Generic i18n library with enum translation support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",