@digitaldefiance/i18n-lib 1.0.32 → 1.0.33

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.
@@ -2,9 +2,12 @@ import { EnumLanguageTranslation } from './types';
2
2
  /**
3
3
  * Registry for managing enum translations across multiple languages.
4
4
  */
5
- export declare class EnumTranslationRegistry<TLanguage extends string> {
5
+ export declare class EnumTranslationRegistry<TStringKey extends string, TLanguage extends string> {
6
6
  protected translations: Map<any, Partial<{ [L in TLanguage]: import("./types").EnumTranslation<any>; }>>;
7
7
  protected enumNames: WeakMap<any, string>;
8
+ protected availableLanguages: Set<TLanguage>;
9
+ protected translateFn?: (key: TStringKey, vars?: Record<string, any>) => string;
10
+ constructor(availableLanguages: TLanguage[], translateFn?: (key: TStringKey, vars?: Record<string, any>) => string);
8
11
  /**
9
12
  * Registers an enumeration with its translations and a name.
10
13
  * @param enumObj The enumeration object
@@ -32,4 +35,10 @@ export declare class EnumTranslationRegistry<TLanguage extends string> {
32
35
  * @returns True if translations exist, false otherwise
33
36
  */
34
37
  has(enumObj: any): boolean;
38
+ /**
39
+ * Validates that enum translations only contain available languages.
40
+ * @param translations The translations to validate
41
+ * @param enumName The name of the enumeration for error messages
42
+ */
43
+ private validateTranslations;
35
44
  }
@@ -5,9 +5,11 @@ exports.EnumTranslationRegistry = void 0;
5
5
  * Registry for managing enum translations across multiple languages.
6
6
  */
7
7
  class EnumTranslationRegistry {
8
- constructor() {
8
+ constructor(availableLanguages, translateFn) {
9
9
  this.translations = new Map();
10
10
  this.enumNames = new WeakMap();
11
+ this.availableLanguages = new Set(availableLanguages);
12
+ this.translateFn = translateFn;
11
13
  }
12
14
  /**
13
15
  * Registers an enumeration with its translations and a name.
@@ -16,6 +18,7 @@ class EnumTranslationRegistry {
16
18
  * @param enumName The name of the enumeration
17
19
  */
18
20
  register(enumObj, translations, enumName) {
21
+ this.validateTranslations(translations, enumName);
19
22
  this.translations.set(enumObj, translations);
20
23
  this.enumNames.set(enumObj, enumName);
21
24
  }
@@ -29,11 +32,17 @@ class EnumTranslationRegistry {
29
32
  translate(enumObj, value, language) {
30
33
  const translations = this.translations.get(enumObj);
31
34
  if (!translations) {
32
- throw new Error(`No translations found for enum: ${this.getEnumName(enumObj)}`);
35
+ const message = this.translateFn
36
+ ? this.translateFn('Error_EnumNotFoundTemplate', { enumName: this.getEnumName(enumObj) })
37
+ : `No translations found for enum: ${this.getEnumName(enumObj)}`;
38
+ throw new Error(message);
33
39
  }
34
40
  const langTranslations = translations[language];
35
41
  if (!langTranslations) {
36
- throw new Error(`No translations found for language: ${language}`);
42
+ const message = this.translateFn
43
+ ? this.translateFn('Error_EnumLanguageNotFoundTemplate', { language })
44
+ : `No translations found for language: ${language}`;
45
+ throw new Error(message);
37
46
  }
38
47
  let result = langTranslations[value];
39
48
  if (!result && typeof value === 'number') {
@@ -43,7 +52,10 @@ class EnumTranslationRegistry {
43
52
  }
44
53
  }
45
54
  if (!result) {
46
- throw new Error(`No translation found for value: ${String(value)}`);
55
+ const message = this.translateFn
56
+ ? this.translateFn('Error_EnumValueNotFoundTemplate', { value: String(value) })
57
+ : `No translation found for value: ${String(value)}`;
58
+ throw new Error(message);
47
59
  }
48
60
  return result;
49
61
  }
@@ -63,5 +75,20 @@ class EnumTranslationRegistry {
63
75
  has(enumObj) {
64
76
  return this.translations.has(enumObj);
65
77
  }
78
+ /**
79
+ * Validates that enum translations only contain available languages.
80
+ * @param translations The translations to validate
81
+ * @param enumName The name of the enumeration for error messages
82
+ */
83
+ validateTranslations(translations, enumName) {
84
+ for (const language of Object.keys(translations)) {
85
+ if (!this.availableLanguages.has(language)) {
86
+ const message = this.translateFn
87
+ ? this.translateFn('Error_EnumLanguageNotAvailableTemplate', { language, enumName })
88
+ : `Language '${language}' in enum '${enumName}' is not available in this engine instance`;
89
+ throw new Error(message);
90
+ }
91
+ }
92
+ }
66
93
  }
67
94
  exports.EnumTranslationRegistry = EnumTranslationRegistry;
@@ -7,7 +7,7 @@ export declare class I18nEngine<TStringKey extends string, TLanguage extends str
7
7
  /**
8
8
  * Registry for enum translations
9
9
  */
10
- protected enumRegistry: EnumTranslationRegistry<TLanguage>;
10
+ protected _enumRegistry: EnumTranslationRegistry<TStringKey, TLanguage>;
11
11
  /**
12
12
  * Configuration for the i18n engine
13
13
  */
@@ -74,6 +74,11 @@ export declare class I18nEngine<TStringKey extends string, TLanguage extends str
74
74
  * @param context The context to set
75
75
  */
76
76
  set context(context: Partial<TContext>);
77
+ /**
78
+ * Gets the enum translation registry for this engine instance
79
+ * @returns The enum translation registry
80
+ */
81
+ get enumRegistry(): EnumTranslationRegistry<TStringKey, TLanguage>;
77
82
  /**
78
83
  * Translates a string key into the specified language, replacing any variables as needed.
79
84
  * @param key The string key to translate
@@ -18,7 +18,7 @@ class I18nEngine {
18
18
  constructor(config, key, newContext = () => (0, context_1.createContext)(config.defaultLanguage, config.defaultTranslationContext, config.defaultCurrencyCode, config.timezone, config.adminTimezone)) {
19
19
  this.validateConfig(config);
20
20
  this.config = config;
21
- this.enumRegistry = new enum_registry_1.EnumTranslationRegistry();
21
+ this._enumRegistry = new enum_registry_1.EnumTranslationRegistry(Object.keys(config.strings), (key, vars) => this.safeTranslate(key, vars));
22
22
  this._context = newContext();
23
23
  const instanceKey = key || I18nEngine.DefaultInstanceKey;
24
24
  if (I18nEngine._instances.has(instanceKey)) {
@@ -91,6 +91,13 @@ class I18nEngine {
91
91
  set context(context) {
92
92
  this._context = { ...this._context, ...context };
93
93
  }
94
+ /**
95
+ * Gets the enum translation registry for this engine instance
96
+ * @returns The enum translation registry
97
+ */
98
+ get enumRegistry() {
99
+ return this._enumRegistry;
100
+ }
94
101
  /**
95
102
  * Translates a string key into the specified language, replacing any variables as needed.
96
103
  * @param key The string key to translate
@@ -144,7 +151,7 @@ class I18nEngine {
144
151
  * @returns The translated enumeration value
145
152
  */
146
153
  translateEnum(enumObj, value, language) {
147
- return this.enumRegistry.translate(enumObj, value, language);
154
+ return this._enumRegistry.translate(enumObj, value, language);
148
155
  }
149
156
  /**
150
157
  * Registers an enumeration and its translations with the engine.
@@ -153,7 +160,7 @@ class I18nEngine {
153
160
  * @param enumName The name of the enumeration (for error messages)
154
161
  */
155
162
  registerEnum(enumObj, translations, enumName) {
156
- this.enumRegistry.register(enumObj, translations, enumName);
163
+ this._enumRegistry.register(enumObj, translations, enumName);
157
164
  }
158
165
  /**
159
166
  * Safe translation that prevents infinite recursion for error messages
@@ -274,12 +281,12 @@ class I18nEngine {
274
281
  * @throws Error if validation fails
275
282
  */
276
283
  validateConfig(config) {
277
- // Check that all languages in languageCodes have string collections
278
- for (const language of Object.keys(config.languageCodes)) {
279
- if (!config.strings[language]) {
280
- throw new Error(this.getValidationError('Error_MissingStringCollectionTemplate', { language }, config));
281
- }
282
- // Check that all string keys are provided for this language
284
+ // Check that default language exists
285
+ if (!config.strings[config.defaultLanguage]) {
286
+ throw new Error(this.getValidationError('Error_DefaultLanguageNoCollectionTemplate', { language: config.defaultLanguage }, config));
287
+ }
288
+ // Check that all string keys are provided for each language that has strings
289
+ for (const language of Object.keys(config.strings)) {
283
290
  const strings = config.strings[language];
284
291
  for (const stringKey of config.stringNames) {
285
292
  if (!strings[stringKey]) {
@@ -287,10 +294,6 @@ class I18nEngine {
287
294
  }
288
295
  }
289
296
  }
290
- // Check that default language exists
291
- if (!config.strings[config.defaultLanguage]) {
292
- throw new Error(this.getValidationError('Error_DefaultLanguageNoCollectionTemplate', { language: config.defaultLanguage }, config));
293
- }
294
297
  }
295
298
  /**
296
299
  * Gets validation error message, trying translation first, falling back to template
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitaldefiance/i18n-lib",
3
- "version": "1.0.32",
3
+ "version": "1.0.33",
4
4
  "description": "Generic i18n library with enum translation support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",