@digitaldefiance/i18n-lib 1.0.31 → 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.
- package/dist/enum-registry.d.ts +10 -1
- package/dist/enum-registry.js +31 -4
- package/dist/i18n-engine.d.ts +6 -1
- package/dist/i18n-engine.js +34 -19
- package/dist/utils.js +4 -0
- package/package.json +1 -1
package/dist/enum-registry.d.ts
CHANGED
|
@@ -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
|
}
|
package/dist/enum-registry.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
package/dist/i18n-engine.d.ts
CHANGED
|
@@ -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
|
|
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
|
package/dist/i18n-engine.js
CHANGED
|
@@ -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.
|
|
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
|
|
@@ -107,19 +114,27 @@ class I18nEngine {
|
|
|
107
114
|
const fallback = fallbackLanguage ?? this.config.defaultLanguage;
|
|
108
115
|
try {
|
|
109
116
|
const stringValue = this.getString(lang, key);
|
|
110
|
-
|
|
117
|
+
let result = (0, utils_1.isTemplate)(key)
|
|
111
118
|
? (0, utils_1.replaceVariables)(stringValue, vars, this.config.constants)
|
|
112
119
|
: stringValue;
|
|
113
|
-
|
|
120
|
+
// Ensure result is always a string
|
|
121
|
+
if (typeof result !== 'string') {
|
|
122
|
+
result = String(result);
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
114
125
|
}
|
|
115
126
|
catch {
|
|
116
127
|
if (lang !== fallback) {
|
|
117
128
|
try {
|
|
118
129
|
const stringValue = this.getString(fallback, key);
|
|
119
|
-
|
|
130
|
+
let result = (0, utils_1.isTemplate)(key)
|
|
120
131
|
? (0, utils_1.replaceVariables)(stringValue, vars, this.config.constants)
|
|
121
132
|
: stringValue;
|
|
122
|
-
|
|
133
|
+
// Ensure result is always a string
|
|
134
|
+
if (typeof result !== 'string') {
|
|
135
|
+
result = String(result);
|
|
136
|
+
}
|
|
137
|
+
return result;
|
|
123
138
|
}
|
|
124
139
|
catch {
|
|
125
140
|
return String(key);
|
|
@@ -136,7 +151,7 @@ class I18nEngine {
|
|
|
136
151
|
* @returns The translated enumeration value
|
|
137
152
|
*/
|
|
138
153
|
translateEnum(enumObj, value, language) {
|
|
139
|
-
return this.
|
|
154
|
+
return this._enumRegistry.translate(enumObj, value, language);
|
|
140
155
|
}
|
|
141
156
|
/**
|
|
142
157
|
* Registers an enumeration and its translations with the engine.
|
|
@@ -145,7 +160,7 @@ class I18nEngine {
|
|
|
145
160
|
* @param enumName The name of the enumeration (for error messages)
|
|
146
161
|
*/
|
|
147
162
|
registerEnum(enumObj, translations, enumName) {
|
|
148
|
-
this.
|
|
163
|
+
this._enumRegistry.register(enumObj, translations, enumName);
|
|
149
164
|
}
|
|
150
165
|
/**
|
|
151
166
|
* Safe translation that prevents infinite recursion for error messages
|
|
@@ -161,10 +176,14 @@ class I18nEngine {
|
|
|
161
176
|
if (!strings?.[key])
|
|
162
177
|
return String(key);
|
|
163
178
|
const stringValue = strings[key];
|
|
164
|
-
|
|
179
|
+
let result = (0, utils_1.isTemplate)(key)
|
|
165
180
|
? (0, utils_1.replaceVariables)(stringValue, vars, this.config.constants)
|
|
166
181
|
: stringValue;
|
|
167
|
-
|
|
182
|
+
// Ensure result is always a string
|
|
183
|
+
if (typeof result !== 'string') {
|
|
184
|
+
result = String(result);
|
|
185
|
+
}
|
|
186
|
+
return result;
|
|
168
187
|
}
|
|
169
188
|
catch {
|
|
170
189
|
return String(key);
|
|
@@ -262,12 +281,12 @@ class I18nEngine {
|
|
|
262
281
|
* @throws Error if validation fails
|
|
263
282
|
*/
|
|
264
283
|
validateConfig(config) {
|
|
265
|
-
// Check that
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
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)) {
|
|
271
290
|
const strings = config.strings[language];
|
|
272
291
|
for (const stringKey of config.stringNames) {
|
|
273
292
|
if (!strings[stringKey]) {
|
|
@@ -275,10 +294,6 @@ class I18nEngine {
|
|
|
275
294
|
}
|
|
276
295
|
}
|
|
277
296
|
}
|
|
278
|
-
// Check that default language exists
|
|
279
|
-
if (!config.strings[config.defaultLanguage]) {
|
|
280
|
-
throw new Error(this.getValidationError('Error_DefaultLanguageNoCollectionTemplate', { language: config.defaultLanguage }, config));
|
|
281
|
-
}
|
|
282
297
|
}
|
|
283
298
|
/**
|
|
284
299
|
* Gets validation error message, trying translation first, falling back to template
|
package/dist/utils.js
CHANGED
|
@@ -21,6 +21,10 @@ const moment_timezone_1 = __importDefault(require("moment-timezone"));
|
|
|
21
21
|
* @returns The string with variables replaced
|
|
22
22
|
*/
|
|
23
23
|
function replaceVariables(str, vars, constants) {
|
|
24
|
+
// Ensure input is a string
|
|
25
|
+
if (typeof str !== 'string') {
|
|
26
|
+
str = String(str);
|
|
27
|
+
}
|
|
24
28
|
const variables = str.match(/\{(.+?)\}/g);
|
|
25
29
|
if (!variables)
|
|
26
30
|
return str;
|