@digitaldefiance/i18n-lib 1.1.2 → 1.1.4

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
@@ -936,6 +936,16 @@ Part of the DigitalBurnbag project - a secure file sharing and automated protoco
936
936
 
937
937
  ## ChangeLog
938
938
 
939
+ ### Version 1.1.4
940
+
941
+ - Tue Oct 14 2025 14:21:00 GMT-0700 (Pacific Daylight Time)
942
+ - Removed duplicate parallel RegistryContext and focused on GlobalActiveContext
943
+
944
+ ### Version 1.1.3
945
+
946
+ - Tue Oct 14 2025 14:00:00 GMT-0700 (Pacific Daylight Time)
947
+ - Added GlobalActiveContext class instead of plain object
948
+
939
949
  ### Version 1.1.2
940
950
 
941
951
  - Sat Oct 11 2025 19:25:00 GMT-0700 (Pacific Daylight Time)
@@ -1,6 +1,6 @@
1
- import { LanguageContext } from './types';
2
- import { Timezone } from './timezone';
3
1
  import { CurrencyCode } from './currency-code';
2
+ import { Timezone } from './timezone';
3
+ import { LanguageContextSpace } from './types';
4
4
  export interface IActiveContext<TLanguage extends string> {
5
5
  /**
6
6
  * The default language for the user facing application
@@ -17,7 +17,7 @@ export interface IActiveContext<TLanguage extends string> {
17
17
  /**
18
18
  * The default language context for the current context
19
19
  */
20
- currentContext: LanguageContext;
20
+ currentContext: LanguageContextSpace;
21
21
  /**
22
22
  * The default timezone for the user facing application
23
23
  */
@@ -0,0 +1,3 @@
1
+ export declare enum ContextErrorType {
2
+ InvalidContext = "InvalidContext"
3
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContextErrorType = void 0;
4
+ var ContextErrorType;
5
+ (function (ContextErrorType) {
6
+ ContextErrorType["InvalidContext"] = "InvalidContext";
7
+ })(ContextErrorType || (exports.ContextErrorType = ContextErrorType = {}));
@@ -0,0 +1,5 @@
1
+ import { ContextErrorType } from './context-error-type';
2
+ import { CoreTypedError } from './typed-error';
3
+ export declare class ContextError extends CoreTypedError<typeof ContextErrorType> {
4
+ constructor(type: ContextErrorType, contextKey?: string);
5
+ }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ContextError = void 0;
4
+ const context_error_type_1 = require("./context-error-type");
5
+ const core_string_key_1 = require("./core-string-key");
6
+ const plugin_i18n_engine_1 = require("./plugin-i18n-engine");
7
+ const typed_error_1 = require("./typed-error");
8
+ class ContextError extends typed_error_1.CoreTypedError {
9
+ constructor(type, contextKey) {
10
+ const engine = plugin_i18n_engine_1.PluginI18nEngine.getInstance();
11
+ super(engine, type, {
12
+ [context_error_type_1.ContextErrorType.InvalidContext]: core_string_key_1.CoreStringKey.Error_InvalidContextTemplate,
13
+ }, undefined, { ...(contextKey && { contextKey }) });
14
+ }
15
+ }
16
+ exports.ContextError = ContextError;
package/dist/context.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { CurrencyCode } from './currency-code';
2
2
  import { I18nContext } from './i18n-context';
3
3
  import { Timezone } from './timezone';
4
- import { LanguageContext } from './types';
4
+ import { LanguageContextSpace } from './types';
5
5
  /**
6
6
  * Creates a new I18n context with default values.
7
7
  * @param defaultLanguage - The default language for the context
@@ -11,34 +11,34 @@ import { LanguageContext } from './types';
11
11
  * @param defaultAdminTimezone - The default admin timezone (defaults to UTC)
12
12
  * @returns A new I18nContext instance
13
13
  */
14
- export declare function createContext<TLanguage extends string, TTranslationContext extends string = LanguageContext, TContext extends I18nContext<TLanguage, TTranslationContext> = I18nContext<TLanguage, TTranslationContext>>(defaultLanguage: TLanguage, defaultContext: TTranslationContext, defaultCurrencyCode?: CurrencyCode, defaultTimezone?: Timezone, defaultAdminTimezone?: Timezone): TContext;
14
+ export declare function createContext<TLanguage extends string, TTranslationContext extends string = LanguageContextSpace, TContext extends I18nContext<TLanguage, TTranslationContext> = I18nContext<TLanguage, TTranslationContext>>(defaultLanguage: TLanguage, defaultContext: TTranslationContext, defaultCurrencyCode?: CurrencyCode, defaultTimezone?: Timezone, defaultAdminTimezone?: Timezone): TContext;
15
15
  /**
16
16
  * Sets the language for the given I18n context.
17
17
  * @param context - The I18n context to modify
18
18
  * @param language - The language to set
19
19
  */
20
- export declare function setLanguage<TLanguage extends string, TContext extends string = LanguageContext>(context: I18nContext<TLanguage, TContext>, language: TLanguage): void;
20
+ export declare function setLanguage<TLanguage extends string, TContext extends string = LanguageContextSpace>(context: I18nContext<TLanguage, TContext>, language: TLanguage): void;
21
21
  /**
22
22
  * Sets the admin language for the given I18n context.
23
23
  * @param context - The I18n context to modify
24
24
  * @param language - The admin language to set
25
25
  */
26
- export declare function setAdminLanguage<TLanguage extends string, TContext extends string = LanguageContext>(context: I18nContext<TLanguage, TContext>, language: TLanguage): void;
26
+ export declare function setAdminLanguage<TLanguage extends string, TContext extends string = LanguageContextSpace>(context: I18nContext<TLanguage, TContext>, language: TLanguage): void;
27
27
  /**
28
28
  * Sets the current context for the given I18n context.
29
29
  * @param context - The I18n context to modify
30
30
  * @param languageContext - The language context to set
31
31
  */
32
- export declare function setContext<TLanguage extends string, TContext extends string = LanguageContext>(context: I18nContext<TLanguage, TContext>, languageContext: TContext): void;
32
+ export declare function setContext<TLanguage extends string, TContext extends string = LanguageContextSpace>(context: I18nContext<TLanguage, TContext>, languageContext: TContext): void;
33
33
  /**
34
34
  * Sets the timezone for the given I18n context.
35
35
  * @param context - The I18n context to modify
36
36
  * @param timezone - The timezone to set
37
37
  */
38
- export declare function setTimezone<TLanguage extends string, TContext extends string = LanguageContext>(context: I18nContext<TLanguage, TContext>, timezone: Timezone): void;
38
+ export declare function setTimezone<TLanguage extends string, TContext extends string = LanguageContextSpace>(context: I18nContext<TLanguage, TContext>, timezone: Timezone): void;
39
39
  /**
40
40
  * Sets the admin timezone for the given I18n context.
41
41
  * @param context - The I18n context to modify
42
42
  * @param timezone - The admin timezone to set
43
43
  */
44
- export declare function setAdminTimezone<TLanguage extends string, TContext extends string = LanguageContext>(context: I18nContext<TLanguage, TContext>, timezone: Timezone): void;
44
+ export declare function setAdminTimezone<TLanguage extends string, TContext extends string = LanguageContextSpace>(context: I18nContext<TLanguage, TContext>, timezone: Timezone): void;
package/dist/core-i18n.js CHANGED
@@ -100,6 +100,7 @@ function createCoreComponentStrings() {
100
100
  [core_string_key_1.CoreStringKey.Error_InternalServer]: 'Internal server error',
101
101
  [core_string_key_1.CoreStringKey.Error_ValidationFailed]: 'Validation failed',
102
102
  [core_string_key_1.CoreStringKey.Error_RequiredField]: 'This field is required',
103
+ [core_string_key_1.CoreStringKey.Error_InvalidContextTemplate]: 'Invalid context: {contextKey}',
103
104
  // Registry Error Templates
104
105
  [core_string_key_1.CoreStringKey.Error_ComponentNotFoundTemplate]: 'Component "{componentId}" not found',
105
106
  [core_string_key_1.CoreStringKey.Error_LanguageNotFoundTemplate]: 'Language "{language}" not found',
@@ -140,6 +141,7 @@ function createCoreComponentStrings() {
140
141
  [core_string_key_1.CoreStringKey.Error_InternalServer]: 'Internal server error',
141
142
  [core_string_key_1.CoreStringKey.Error_ValidationFailed]: 'Validation failed',
142
143
  [core_string_key_1.CoreStringKey.Error_RequiredField]: 'This field is required',
144
+ [core_string_key_1.CoreStringKey.Error_InvalidContextTemplate]: 'Invalid context: {contextKey}',
143
145
  // Registry Error Templates
144
146
  [core_string_key_1.CoreStringKey.Error_ComponentNotFoundTemplate]: 'Component "{componentId}" not found',
145
147
  [core_string_key_1.CoreStringKey.Error_LanguageNotFoundTemplate]: 'Language "{language}" not found',
@@ -180,6 +182,7 @@ function createCoreComponentStrings() {
180
182
  [core_string_key_1.CoreStringKey.Error_InternalServer]: 'Erreur interne du serveur',
181
183
  [core_string_key_1.CoreStringKey.Error_ValidationFailed]: 'Échec de la validation',
182
184
  [core_string_key_1.CoreStringKey.Error_RequiredField]: 'Ce champ est obligatoire',
185
+ [core_string_key_1.CoreStringKey.Error_InvalidContextTemplate]: 'Contexte invalide : {contextKey}',
183
186
  // Registry Error Templates
184
187
  [core_string_key_1.CoreStringKey.Error_ComponentNotFoundTemplate]: 'Composant "{componentId}" non trouvé',
185
188
  [core_string_key_1.CoreStringKey.Error_LanguageNotFoundTemplate]: 'Langue "{language}" non trouvée',
@@ -220,6 +223,7 @@ function createCoreComponentStrings() {
220
223
  [core_string_key_1.CoreStringKey.Error_InternalServer]: 'Error interno del servidor',
221
224
  [core_string_key_1.CoreStringKey.Error_ValidationFailed]: 'Error de validación',
222
225
  [core_string_key_1.CoreStringKey.Error_RequiredField]: 'Este campo es obligatorio',
226
+ [core_string_key_1.CoreStringKey.Error_InvalidContextTemplate]: 'Contexte invalide : {contextKey}',
223
227
  // Registry Error Templates
224
228
  [core_string_key_1.CoreStringKey.Error_ComponentNotFoundTemplate]: 'Componente "{componentId}" no encontrado',
225
229
  [core_string_key_1.CoreStringKey.Error_LanguageNotFoundTemplate]: 'Idioma "{language}" no encontrado',
@@ -260,6 +264,7 @@ function createCoreComponentStrings() {
260
264
  [core_string_key_1.CoreStringKey.Error_InternalServer]: 'Interner Serverfehler',
261
265
  [core_string_key_1.CoreStringKey.Error_ValidationFailed]: 'Validierung fehlgeschlagen',
262
266
  [core_string_key_1.CoreStringKey.Error_RequiredField]: 'Dieses Feld ist erforderlich',
267
+ [core_string_key_1.CoreStringKey.Error_InvalidContextTemplate]: 'Ungültiger Kontext: {contextKey}',
263
268
  // Registry Error Templates
264
269
  [core_string_key_1.CoreStringKey.Error_ComponentNotFoundTemplate]: 'Komponente "{componentId}" nicht gefunden',
265
270
  [core_string_key_1.CoreStringKey.Error_LanguageNotFoundTemplate]: 'Sprache "{language}" nicht gefunden',
@@ -300,6 +305,7 @@ function createCoreComponentStrings() {
300
305
  [core_string_key_1.CoreStringKey.Error_InternalServer]: '内部服务器错误',
301
306
  [core_string_key_1.CoreStringKey.Error_ValidationFailed]: '验证失败',
302
307
  [core_string_key_1.CoreStringKey.Error_RequiredField]: '此字段为必填项',
308
+ [core_string_key_1.CoreStringKey.Error_InvalidContextTemplate]: '无效的上下文:{contextKey}',
303
309
  // Registry Error Templates
304
310
  [core_string_key_1.CoreStringKey.Error_ComponentNotFoundTemplate]: '未找到组件 "{componentId}"',
305
311
  [core_string_key_1.CoreStringKey.Error_LanguageNotFoundTemplate]: '未找到语言 "{language}"',
@@ -340,6 +346,7 @@ function createCoreComponentStrings() {
340
346
  [core_string_key_1.CoreStringKey.Error_InternalServer]: '内部サーバーエラー',
341
347
  [core_string_key_1.CoreStringKey.Error_ValidationFailed]: '検証に失敗しました',
342
348
  [core_string_key_1.CoreStringKey.Error_RequiredField]: 'このフィールドは必須です',
349
+ [core_string_key_1.CoreStringKey.Error_InvalidContextTemplate]: '無効なコンテキスト:{contextKey}',
343
350
  // Registry Error Templates
344
351
  [core_string_key_1.CoreStringKey.Error_ComponentNotFoundTemplate]: 'コンポーネント "{componentId}" が見つかりません',
345
352
  [core_string_key_1.CoreStringKey.Error_LanguageNotFoundTemplate]: '言語 "{language}" が見つかりません',
@@ -380,6 +387,7 @@ function createCoreComponentStrings() {
380
387
  [core_string_key_1.CoreStringKey.Error_InternalServer]: 'Внутрішня помилка сервера',
381
388
  [core_string_key_1.CoreStringKey.Error_ValidationFailed]: 'Перевірка не вдалася',
382
389
  [core_string_key_1.CoreStringKey.Error_RequiredField]: "Це поле є обов'язковим",
390
+ [core_string_key_1.CoreStringKey.Error_InvalidContextTemplate]: 'Неправильний контекст: {contextKey}',
383
391
  // Registry Error Templates
384
392
  [core_string_key_1.CoreStringKey.Error_ComponentNotFoundTemplate]: 'Компонент "{componentId}" не знайдено',
385
393
  [core_string_key_1.CoreStringKey.Error_LanguageNotFoundTemplate]: 'Мову "{language}" не знайдено',
@@ -23,6 +23,7 @@ export declare enum CoreStringKey {
23
23
  Error_InternalServer = "error_internalServer",
24
24
  Error_ValidationFailed = "error_validationFailed",
25
25
  Error_RequiredField = "error_requiredField",
26
+ Error_InvalidContextTemplate = "error_invalidContextTemplate",
26
27
  Error_ComponentNotFoundTemplate = "error_componentNotFoundTemplate",
27
28
  Error_LanguageNotFoundTemplate = "error_languageNotFoundTemplate",
28
29
  Error_StringKeyNotFoundTemplate = "error_stringKeyNotFoundTemplate",
@@ -29,6 +29,7 @@ var CoreStringKey;
29
29
  CoreStringKey["Error_InternalServer"] = "error_internalServer";
30
30
  CoreStringKey["Error_ValidationFailed"] = "error_validationFailed";
31
31
  CoreStringKey["Error_RequiredField"] = "error_requiredField";
32
+ CoreStringKey["Error_InvalidContextTemplate"] = "error_invalidContextTemplate";
32
33
  // Registry Errors (templates support variables)
33
34
  CoreStringKey["Error_ComponentNotFoundTemplate"] = "error_componentNotFoundTemplate";
34
35
  CoreStringKey["Error_LanguageNotFoundTemplate"] = "error_languageNotFoundTemplate";
@@ -33,14 +33,18 @@ class EnumTranslationRegistry {
33
33
  const translations = this.translations.get(enumObj);
34
34
  if (!translations) {
35
35
  const message = this.translateFn
36
- ? this.translateFn('Error_EnumNotFoundTemplate', { enumName: this.getEnumName(enumObj) })
36
+ ? this.translateFn('Error_EnumNotFoundTemplate', {
37
+ enumName: this.getEnumName(enumObj),
38
+ })
37
39
  : `No translations found for enum: ${this.getEnumName(enumObj)}`;
38
40
  throw new Error(message);
39
41
  }
40
42
  const langTranslations = translations[language];
41
43
  if (!langTranslations) {
42
44
  const message = this.translateFn
43
- ? this.translateFn('Error_EnumLanguageNotFoundTemplate', { language })
45
+ ? this.translateFn('Error_EnumLanguageNotFoundTemplate', {
46
+ language,
47
+ })
44
48
  : `No translations found for language: ${language}`;
45
49
  throw new Error(message);
46
50
  }
@@ -53,7 +57,9 @@ class EnumTranslationRegistry {
53
57
  }
54
58
  if (!result) {
55
59
  const message = this.translateFn
56
- ? this.translateFn('Error_EnumValueNotFoundTemplate', { value: String(value) })
60
+ ? this.translateFn('Error_EnumValueNotFoundTemplate', {
61
+ value: String(value),
62
+ })
57
63
  : `No translation found for value: ${String(value)}`;
58
64
  throw new Error(message);
59
65
  }
@@ -0,0 +1,46 @@
1
+ import { IActiveContext } from './active-context';
2
+ import { CurrencyCode } from './currency-code';
3
+ import { DefaultLanguage } from './default-config';
4
+ import { IGlobalActiveContext } from './i-global-active-context';
5
+ import { Timezone } from './timezone';
6
+ import { LanguageContextSpace } from './types';
7
+ export declare class GlobalActiveContext<TLanguage extends string, TActiveContext extends IActiveContext<TLanguage>> implements IGlobalActiveContext<TLanguage, TActiveContext> {
8
+ protected static _contextMap: Map<string, IActiveContext<any>>;
9
+ static readonly defaultContextKey = "default";
10
+ static readonly defaultLanguage: DefaultLanguage;
11
+ private static _instance;
12
+ static get instance(): GlobalActiveContext<any, any>;
13
+ static getInstance<TLanguage extends string, TActiveContext extends IActiveContext<TLanguage>>(): GlobalActiveContext<TLanguage, TActiveContext>;
14
+ static overrideInstance(instance: GlobalActiveContext<any, any>): void;
15
+ createContext(defaultLanguage: TLanguage, defaultAdminLanguage?: TLanguage, key?: string): TActiveContext;
16
+ getContext(key?: string): TActiveContext;
17
+ get context(): TActiveContext;
18
+ set context(ctx: TActiveContext);
19
+ setUserLanguage<StringLanguage extends string>(language: StringLanguage, key?: string): void;
20
+ get userLanguage(): TLanguage;
21
+ set userLanguage(lang: TLanguage);
22
+ setCurrencyCode<StringLanguage extends string>(code: CurrencyCode, key?: string): void;
23
+ get currencyCode(): CurrencyCode;
24
+ set currencyCode(code: CurrencyCode);
25
+ /**
26
+ * Sets the admin language for console operations
27
+ * @param language The language to set for admin operations
28
+ */
29
+ setAdminLanguage<StringLanguage extends string>(language: StringLanguage, key?: string): void;
30
+ get adminLanguage(): TLanguage;
31
+ set adminLanguage(lang: TLanguage);
32
+ /**
33
+ * Sets the language context for the current context
34
+ * @param context The language context to set
35
+ */
36
+ setLanguageContextSpace<StringLanguage extends string>(context: LanguageContextSpace, key?: string): void;
37
+ getLanguageContextSpace<StringLanguage extends string>(key?: string): LanguageContextSpace;
38
+ get languageContextSpace(): LanguageContextSpace;
39
+ set languageContextSpace(context: LanguageContextSpace);
40
+ setUserTimezone<StringLanguage extends string>(tz: Timezone, key?: string): void;
41
+ get userTimezone(): Timezone;
42
+ set userTimezone(tz: Timezone);
43
+ setAdminTimezone<StringLanguage extends string>(tz: Timezone, key?: string): void;
44
+ get adminTimezone(): Timezone;
45
+ set adminTimezone(tz: Timezone);
46
+ }
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GlobalActiveContext = void 0;
4
+ const context_error_1 = require("./context-error");
5
+ const context_error_type_1 = require("./context-error-type");
6
+ const currency_code_1 = require("./currency-code");
7
+ const default_config_1 = require("./default-config");
8
+ const timezone_1 = require("./timezone");
9
+ const types_1 = require("./types");
10
+ class GlobalActiveContext {
11
+ static get instance() {
12
+ if (!this._instance) {
13
+ this._instance = new GlobalActiveContext();
14
+ this._instance.createContext(this.defaultLanguage);
15
+ }
16
+ return this._instance;
17
+ }
18
+ static getInstance() {
19
+ if (!this._instance) {
20
+ this._instance = new GlobalActiveContext();
21
+ this._instance.createContext(this.defaultLanguage);
22
+ }
23
+ return this._instance;
24
+ }
25
+ static overrideInstance(instance) {
26
+ this._instance = instance;
27
+ }
28
+ createContext(defaultLanguage, defaultAdminLanguage = defaultLanguage, key = GlobalActiveContext.defaultContextKey) {
29
+ const newContext = {
30
+ /**
31
+ * The language to use for translations in the user facing ui
32
+ */
33
+ language: defaultLanguage,
34
+ /**
35
+ * The language to use for console/admin logs
36
+ */
37
+ adminLanguage: defaultAdminLanguage,
38
+ currencyCode: new currency_code_1.CurrencyCode(types_1.DefaultCurrencyCode),
39
+ /**
40
+ * The current default context for language translations
41
+ */
42
+ currentContext: 'user',
43
+ /**
44
+ * The timezone for the user facing UI
45
+ */
46
+ timezone: new timezone_1.Timezone(types_1.DefaultTimezone),
47
+ /**
48
+ * The timezone for the admin console
49
+ */
50
+ adminTimezone: new timezone_1.Timezone('UTC'),
51
+ };
52
+ GlobalActiveContext._contextMap.set(key, newContext);
53
+ return newContext;
54
+ }
55
+ getContext(key = GlobalActiveContext.defaultContextKey) {
56
+ const context = GlobalActiveContext._contextMap.get(key);
57
+ if (context) {
58
+ return context;
59
+ }
60
+ throw new context_error_1.ContextError(context_error_type_1.ContextErrorType.InvalidContext, key);
61
+ }
62
+ get context() {
63
+ return this.getContext(GlobalActiveContext.defaultContextKey);
64
+ }
65
+ set context(ctx) {
66
+ GlobalActiveContext._contextMap.set(GlobalActiveContext.defaultContextKey, ctx);
67
+ }
68
+ setUserLanguage(language, key = GlobalActiveContext.defaultContextKey) {
69
+ const context = GlobalActiveContext._contextMap.get(key);
70
+ if (context) {
71
+ context.language = language;
72
+ return;
73
+ }
74
+ throw new context_error_1.ContextError(context_error_type_1.ContextErrorType.InvalidContext, key);
75
+ }
76
+ get userLanguage() {
77
+ return this.context.language;
78
+ }
79
+ set userLanguage(lang) {
80
+ this.context.language = lang;
81
+ }
82
+ setCurrencyCode(code, key = GlobalActiveContext.defaultContextKey) {
83
+ const context = GlobalActiveContext._contextMap.get(key);
84
+ if (context) {
85
+ context.currencyCode = code;
86
+ return;
87
+ }
88
+ throw new context_error_1.ContextError(context_error_type_1.ContextErrorType.InvalidContext, key);
89
+ }
90
+ get currencyCode() {
91
+ return this.context.currencyCode;
92
+ }
93
+ set currencyCode(code) {
94
+ this.context.currencyCode = code;
95
+ }
96
+ /**
97
+ * Sets the admin language for console operations
98
+ * @param language The language to set for admin operations
99
+ */
100
+ setAdminLanguage(language, key = GlobalActiveContext.defaultContextKey) {
101
+ const context = GlobalActiveContext._contextMap.get(key);
102
+ if (context) {
103
+ context.adminLanguage = language;
104
+ return;
105
+ }
106
+ throw new context_error_1.ContextError(context_error_type_1.ContextErrorType.InvalidContext, key);
107
+ }
108
+ get adminLanguage() {
109
+ return this.context.adminLanguage;
110
+ }
111
+ set adminLanguage(lang) {
112
+ this.context.adminLanguage = lang;
113
+ }
114
+ /**
115
+ * Sets the language context for the current context
116
+ * @param context The language context to set
117
+ */
118
+ setLanguageContextSpace(context, key = GlobalActiveContext.defaultContextKey) {
119
+ const ctx = GlobalActiveContext._contextMap.get(key);
120
+ if (ctx) {
121
+ ctx.currentContext = context;
122
+ return;
123
+ }
124
+ throw new context_error_1.ContextError(context_error_type_1.ContextErrorType.InvalidContext, key);
125
+ }
126
+ getLanguageContextSpace(key = GlobalActiveContext.defaultContextKey) {
127
+ const ctx = GlobalActiveContext._contextMap.get(key);
128
+ if (ctx) {
129
+ return ctx.currentContext;
130
+ }
131
+ throw new context_error_1.ContextError(context_error_type_1.ContextErrorType.InvalidContext, key);
132
+ }
133
+ get languageContextSpace() {
134
+ return this.context.currentContext;
135
+ }
136
+ set languageContextSpace(context) {
137
+ this.context.currentContext = context;
138
+ }
139
+ setUserTimezone(tz, key = GlobalActiveContext.defaultContextKey) {
140
+ const ctx = GlobalActiveContext._contextMap.get(key);
141
+ if (ctx) {
142
+ ctx.timezone = tz;
143
+ return;
144
+ }
145
+ throw new context_error_1.ContextError(context_error_type_1.ContextErrorType.InvalidContext, key);
146
+ }
147
+ get userTimezone() {
148
+ return this.context.timezone;
149
+ }
150
+ set userTimezone(tz) {
151
+ this.context.timezone = tz;
152
+ }
153
+ setAdminTimezone(tz, key = GlobalActiveContext.defaultContextKey) {
154
+ const ctx = GlobalActiveContext._contextMap.get(key);
155
+ if (ctx) {
156
+ ctx.adminTimezone = tz;
157
+ return;
158
+ }
159
+ throw new context_error_1.ContextError(context_error_type_1.ContextErrorType.InvalidContext, key);
160
+ }
161
+ get adminTimezone() {
162
+ return this.context.adminTimezone;
163
+ }
164
+ set adminTimezone(tz) {
165
+ this.context.adminTimezone = tz;
166
+ }
167
+ }
168
+ exports.GlobalActiveContext = GlobalActiveContext;
169
+ GlobalActiveContext._contextMap = new Map();
170
+ GlobalActiveContext.defaultContextKey = 'default';
171
+ GlobalActiveContext.defaultLanguage = default_config_1.DefaultLanguage.EnglishUS;
@@ -0,0 +1,22 @@
1
+ import { IActiveContext } from './active-context';
2
+ import { CurrencyCode } from './currency-code';
3
+ import { Timezone } from './timezone';
4
+ import { LanguageContextSpace } from './types';
5
+ export interface IGlobalActiveContext<TLanguage extends string, TActiveContext extends IActiveContext<TLanguage>> {
6
+ context: TActiveContext;
7
+ userLanguage: TLanguage;
8
+ currencyCode: CurrencyCode;
9
+ adminLanguage: TLanguage;
10
+ languageContextSpace: LanguageContextSpace;
11
+ userTimezone: Timezone;
12
+ adminTimezone: Timezone;
13
+ createContext(defaultLanguage: TLanguage, defaultAdminLanguage?: TLanguage, key?: string): TActiveContext;
14
+ getContext(key?: string): TActiveContext;
15
+ setUserLanguage(language: TLanguage, key?: string): void;
16
+ setCurrencyCode(code: CurrencyCode, key?: string): void;
17
+ setAdminLanguage(language: TLanguage, key?: string): void;
18
+ setLanguageContextSpace(context: LanguageContextSpace, key?: string): void;
19
+ getLanguageContextSpace(key?: string): LanguageContextSpace;
20
+ setUserTimezone(tz: Timezone, key?: string): void;
21
+ setAdminTimezone(tz: Timezone, key?: string): void;
22
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,10 +1,10 @@
1
1
  import { CurrencyCode } from './currency-code';
2
2
  import { Timezone } from './timezone';
3
- import { LanguageCodeCollection, LanguageContext, MasterStringsCollection } from './types';
3
+ import { LanguageCodeCollection, LanguageContextSpace, MasterStringsCollection } from './types';
4
4
  /**
5
5
  * I18n configuration interface
6
6
  */
7
- export interface I18nConfig<TStringKey extends string, TLanguage extends string, TConstants extends Record<string, any> = Record<string, any>, TTranslationContext extends string = LanguageContext> {
7
+ export interface I18nConfig<TStringKey extends string, TLanguage extends string, TConstants extends Record<string, any> = Record<string, any>, TTranslationContext extends string = LanguageContextSpace> {
8
8
  stringNames: TStringKey[];
9
9
  strings: MasterStringsCollection<TStringKey, TLanguage>;
10
10
  defaultLanguage: TLanguage;
@@ -1,10 +1,10 @@
1
1
  import { CurrencyCode } from './currency-code';
2
2
  import { Timezone } from './timezone';
3
- import { LanguageContext } from './types';
3
+ import { LanguageContextSpace } from './types';
4
4
  /**
5
5
  * I18n context interface
6
6
  */
7
- export interface I18nContext<TLanguage extends string, TTranslationContext extends string = LanguageContext> {
7
+ export interface I18nContext<TLanguage extends string, TTranslationContext extends string = LanguageContextSpace> {
8
8
  language: TLanguage;
9
9
  adminLanguage: TLanguage;
10
10
  currencyCode: CurrencyCode;
@@ -307,9 +307,11 @@ class I18nEngine {
307
307
  }
308
308
  catch { }
309
309
  // Fallback to static templates
310
- const template = key.includes('MissingStringCollection') ? I18nEngine.ErrorTemplates.MissingStringCollection :
311
- key.includes('MissingTranslation') ? I18nEngine.ErrorTemplates.MissingTranslation :
312
- I18nEngine.ErrorTemplates.DefaultLanguageNoCollection;
310
+ const template = key.includes('MissingStringCollection')
311
+ ? I18nEngine.ErrorTemplates.MissingStringCollection
312
+ : key.includes('MissingTranslation')
313
+ ? I18nEngine.ErrorTemplates.MissingTranslation
314
+ : I18nEngine.ErrorTemplates.DefaultLanguageNoCollection;
313
315
  return (0, utils_1.replaceVariables)(template, vars);
314
316
  }
315
317
  }
@@ -331,6 +333,6 @@ I18nEngine.DefaultInstanceKey = 'default';
331
333
  */
332
334
  I18nEngine.ErrorTemplates = {
333
335
  MissingStringCollection: 'Missing string collection for language: {language}',
334
- MissingTranslation: 'Missing translation for key \'{key}\' in language \'{language}\'',
335
- DefaultLanguageNoCollection: 'Default language \'{language}\' has no string collection'
336
+ MissingTranslation: "Missing translation for key '{key}' in language '{language}'",
337
+ DefaultLanguageNoCollection: "Default language '{language}' has no string collection",
336
338
  };
package/dist/index.d.ts CHANGED
@@ -3,12 +3,16 @@ export * from './component-definition';
3
3
  export * from './component-registration';
4
4
  export * from './component-registry';
5
5
  export * from './context';
6
+ export * from './context-error';
7
+ export * from './context-error-type';
6
8
  export * from './context-manager';
7
9
  export * from './currency';
8
10
  export * from './currency-code';
9
11
  export * from './currency-format';
10
12
  export * from './default-config';
11
13
  export * from './enum-registry';
14
+ export * from './global-active-context';
15
+ export * from './i-global-active-context';
12
16
  export * from './i18n-context';
13
17
  export * from './i18n-engine';
14
18
  export * from './language-definition';
@@ -25,7 +29,6 @@ export * from './core-string-key';
25
29
  export * from './language-registry';
26
30
  export * from './plugin-i18n-engine';
27
31
  export * from './registry-config';
28
- export * from './registry-context';
29
32
  export * from './registry-error';
30
33
  export * from './registry-error-type';
31
34
  export * from './translation-request';
package/dist/index.js CHANGED
@@ -22,12 +22,16 @@ __exportStar(require("./component-definition"), exports);
22
22
  __exportStar(require("./component-registration"), exports);
23
23
  __exportStar(require("./component-registry"), exports);
24
24
  __exportStar(require("./context"), exports);
25
+ __exportStar(require("./context-error"), exports);
26
+ __exportStar(require("./context-error-type"), exports);
25
27
  __exportStar(require("./context-manager"), exports);
26
28
  __exportStar(require("./currency"), exports);
27
29
  __exportStar(require("./currency-code"), exports);
28
30
  __exportStar(require("./currency-format"), exports);
29
31
  __exportStar(require("./default-config"), exports);
30
32
  __exportStar(require("./enum-registry"), exports);
33
+ __exportStar(require("./global-active-context"), exports);
34
+ __exportStar(require("./i-global-active-context"), exports);
31
35
  __exportStar(require("./i18n-context"), exports);
32
36
  __exportStar(require("./i18n-engine"), exports);
33
37
  __exportStar(require("./language-definition"), exports);
@@ -44,7 +48,6 @@ __exportStar(require("./core-string-key"), exports);
44
48
  __exportStar(require("./language-registry"), exports);
45
49
  __exportStar(require("./plugin-i18n-engine"), exports);
46
50
  __exportStar(require("./registry-config"), exports);
47
- __exportStar(require("./registry-context"), exports);
48
51
  __exportStar(require("./registry-error"), exports);
49
52
  __exportStar(require("./registry-error-type"), exports);
50
53
  __exportStar(require("./translation-request"), exports);
@@ -5,10 +5,10 @@ import { ComponentDefinition } from './component-definition';
5
5
  import { ComponentRegistration } from './component-registration';
6
6
  import { ComponentRegistry } from './component-registry';
7
7
  import { EnumTranslationRegistry } from './enum-registry';
8
+ import { IActiveContext } from './active-context';
8
9
  import { LanguageDefinition } from './language-definition';
9
10
  import { LanguageRegistry } from './language-registry';
10
11
  import { RegistryConfig } from './registry-config';
11
- import { RegistryContext } from './registry-context';
12
12
  import { TranslationResponse } from './translation-response';
13
13
  import { EnumLanguageTranslation } from './types';
14
14
  /**
@@ -19,7 +19,7 @@ export declare class PluginI18nEngine<TLanguages extends string> {
19
19
  private readonly componentRegistry;
20
20
  private readonly enumRegistry;
21
21
  private readonly config;
22
- private context;
22
+ private contextKey;
23
23
  /**
24
24
  * Static instances for semi-singleton pattern
25
25
  */
@@ -74,11 +74,15 @@ export declare class PluginI18nEngine<TLanguages extends string> {
74
74
  /**
75
75
  * Get current context
76
76
  */
77
- getContext(): RegistryContext<TLanguages>;
77
+ getContext(): IActiveContext<TLanguages>;
78
78
  /**
79
79
  * Update context
80
80
  */
81
- updateContext(updates: Partial<RegistryContext<TLanguages>>): void;
81
+ updateContext(updates: Partial<IActiveContext<TLanguages>>): void;
82
+ /**
83
+ * Get current language from global context
84
+ */
85
+ private getCurrentLanguage;
82
86
  /**
83
87
  * Set current language
84
88
  */
@@ -7,6 +7,7 @@ exports.PluginI18nEngine = void 0;
7
7
  const component_registry_1 = require("./component-registry");
8
8
  const currency_code_1 = require("./currency-code");
9
9
  const enum_registry_1 = require("./enum-registry");
10
+ const global_active_context_1 = require("./global-active-context");
10
11
  const language_registry_1 = require("./language-registry");
11
12
  const registry_error_1 = require("./registry-error");
12
13
  const registry_error_type_1 = require("./registry-error-type");
@@ -41,14 +42,15 @@ class PluginI18nEngine {
41
42
  this.enumRegistry = new enum_registry_1.EnumTranslationRegistry(initialLanguages.map((l) => l.id), (key, vars) => this.safeTranslate('core', key, vars));
42
43
  // Register initial languages
43
44
  this.languageRegistry.registerLanguages(initialLanguages);
44
- // Initialize context
45
- this.context = {
46
- currentLanguage: this.config.defaultLanguage,
47
- fallbackLanguage: this.config.fallbackLanguage,
48
- currencyCode: this.config.defaultCurrencyCode,
49
- timezone: this.config.timezone,
50
- adminTimezone: this.config.adminTimezone,
51
- };
45
+ // Initialize context key for this engine instance
46
+ this.contextKey = PluginI18nEngine.DefaultInstanceKey;
47
+ // Create or get the global context for this engine
48
+ const globalContext = global_active_context_1.GlobalActiveContext.getInstance();
49
+ // Always create/update the context for this engine
50
+ globalContext.createContext(this.config.defaultLanguage, this.config.defaultLanguage, this.contextKey);
51
+ globalContext.setCurrencyCode(this.config.defaultCurrencyCode, this.contextKey);
52
+ globalContext.setUserTimezone(this.config.timezone, this.contextKey);
53
+ globalContext.setAdminTimezone(this.config.adminTimezone, this.contextKey);
52
54
  // Auto-register as default instance if none exists
53
55
  if (!PluginI18nEngine._defaultKey) {
54
56
  PluginI18nEngine._instances.set(PluginI18nEngine.DefaultInstanceKey, this);
@@ -63,6 +65,13 @@ class PluginI18nEngine {
63
65
  throw registry_error_1.RegistryError.createSimple(registry_error_type_1.RegistryErrorType.DuplicateComponent, `I18n instance with key '${key}' already exists`, { key });
64
66
  }
65
67
  const instance = new PluginI18nEngine(initialLanguages, config);
68
+ instance.contextKey = key;
69
+ // Create context for this specific instance
70
+ const globalContext = global_active_context_1.GlobalActiveContext.getInstance();
71
+ globalContext.createContext(instance.config.defaultLanguage, instance.config.defaultLanguage, key);
72
+ globalContext.setCurrencyCode(instance.config.defaultCurrencyCode, key);
73
+ globalContext.setUserTimezone(instance.config.timezone, key);
74
+ globalContext.setAdminTimezone(instance.config.adminTimezone, key);
66
75
  PluginI18nEngine._instances.set(key, instance);
67
76
  if (!PluginI18nEngine._defaultKey) {
68
77
  PluginI18nEngine._defaultKey = key;
@@ -124,7 +133,7 @@ class PluginI18nEngine {
124
133
  const request = {
125
134
  componentId,
126
135
  stringKey,
127
- language: language || this.context.currentLanguage,
136
+ language: language || this.getCurrentLanguage(),
128
137
  variables,
129
138
  };
130
139
  const response = this.componentRegistry.getTranslation(request);
@@ -146,7 +155,7 @@ class PluginI18nEngine {
146
155
  * Translate an enum value
147
156
  */
148
157
  translateEnum(enumObj, value, language) {
149
- return this.enumRegistry.translate(enumObj, value, language || this.context.currentLanguage);
158
+ return this.enumRegistry.translate(enumObj, value, language || this.getCurrentLanguage());
150
159
  }
151
160
  /**
152
161
  * Get detailed translation response
@@ -155,7 +164,7 @@ class PluginI18nEngine {
155
164
  const request = {
156
165
  componentId,
157
166
  stringKey,
158
- language: language || this.context.currentLanguage,
167
+ language: language || this.getCurrentLanguage(),
159
168
  variables,
160
169
  };
161
170
  return this.componentRegistry.getTranslation(request);
@@ -164,13 +173,33 @@ class PluginI18nEngine {
164
173
  * Get current context
165
174
  */
166
175
  getContext() {
167
- return { ...this.context };
176
+ const globalContext = global_active_context_1.GlobalActiveContext.getInstance();
177
+ return globalContext.getContext(this.contextKey);
168
178
  }
169
179
  /**
170
180
  * Update context
171
181
  */
172
182
  updateContext(updates) {
173
- this.context = { ...this.context, ...updates };
183
+ const globalContext = global_active_context_1.GlobalActiveContext.getInstance();
184
+ if (updates.language)
185
+ globalContext.setUserLanguage(updates.language, this.contextKey);
186
+ if (updates.adminLanguage)
187
+ globalContext.setAdminLanguage(updates.adminLanguage, this.contextKey);
188
+ if (updates.currencyCode)
189
+ globalContext.setCurrencyCode(updates.currencyCode, this.contextKey);
190
+ if (updates.currentContext)
191
+ globalContext.setLanguageContextSpace(updates.currentContext, this.contextKey);
192
+ if (updates.timezone)
193
+ globalContext.setUserTimezone(updates.timezone, this.contextKey);
194
+ if (updates.adminTimezone)
195
+ globalContext.setAdminTimezone(updates.adminTimezone, this.contextKey);
196
+ }
197
+ /**
198
+ * Get current language from global context
199
+ */
200
+ getCurrentLanguage() {
201
+ const globalContext = global_active_context_1.GlobalActiveContext.getInstance();
202
+ return globalContext.getContext(this.contextKey).language;
174
203
  }
175
204
  /**
176
205
  * Set current language
@@ -179,7 +208,8 @@ class PluginI18nEngine {
179
208
  if (!this.languageRegistry.hasLanguage(language)) {
180
209
  throw registry_error_1.RegistryError.createSimple(registry_error_type_1.RegistryErrorType.LanguageNotFound, `Language '${language}' is not registered`, { language });
181
210
  }
182
- this.context.currentLanguage = language;
211
+ const globalContext = global_active_context_1.GlobalActiveContext.getInstance();
212
+ globalContext.setUserLanguage(language, this.contextKey);
183
213
  }
184
214
  /**
185
215
  * Get available languages
package/dist/types.d.ts CHANGED
@@ -2,13 +2,17 @@ import { ComponentDefinition } from './component-definition';
2
2
  import { ComponentRegistration } from './component-registration';
3
3
  import { LanguageDefinition } from './language-definition';
4
4
  /**
5
- * Standard language contexts
5
+ * Standard language context spaces
6
6
  */
7
- export type LanguageContext = 'admin' | 'user' | 'system' | 'api';
7
+ export type LanguageContextSpace = 'admin' | 'user' | 'system' | 'api';
8
8
  /**
9
9
  * Default currency code
10
10
  */
11
11
  export declare const DefaultCurrencyCode: string;
12
+ /**
13
+ * Default timezone
14
+ */
15
+ export declare const DefaultTimezone: string;
12
16
  /**
13
17
  * Currency position type
14
18
  */
@@ -16,7 +20,7 @@ export type CurrencyPosition = 'prefix' | 'postfix' | 'infix';
16
20
  /**
17
21
  * Custom language context type
18
22
  */
19
- export type CustomLanguageContext<T extends string = LanguageContext> = T;
23
+ export type CustomLanguageContext<T extends string = LanguageContextSpace> = T;
20
24
  /**
21
25
  * Collection of localized strings for a specific language
22
26
  */
package/dist/types.js CHANGED
@@ -1,11 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DefaultCurrencyCode = void 0;
3
+ exports.DefaultTimezone = exports.DefaultCurrencyCode = void 0;
4
4
  exports.createTranslations = createTranslations;
5
5
  /**
6
6
  * Default currency code
7
7
  */
8
8
  exports.DefaultCurrencyCode = 'USD';
9
+ /**
10
+ * Default timezone
11
+ */
12
+ exports.DefaultTimezone = 'UTC';
9
13
  /**
10
14
  * Helper function to create typed translations for an enumeration
11
15
  */
package/dist/utils.d.ts CHANGED
@@ -23,7 +23,7 @@ export declare function isValidTimezone(timezone: string): boolean;
23
23
  * @param parts - The parts to join
24
24
  * @returns The joined string key
25
25
  */
26
- export declare function toStringKey<TStringKey extends string>(...parts: (string)[]): TStringKey;
26
+ export declare function toStringKey<TStringKey extends string>(...parts: string[]): TStringKey;
27
27
  /**
28
28
  * Converts an enum value to a string key by joining parts with underscores and appending the enum value.
29
29
  * @param value - The enum value
package/dist/utils.js CHANGED
@@ -87,9 +87,11 @@ function toStringKeyFromEnum(value, ...parts) {
87
87
  */
88
88
  function buildReasonMap(enumObj, prefixes = [], templateKeys) {
89
89
  const map = {};
90
- Object.values(enumObj).forEach(value => {
90
+ Object.values(enumObj).forEach((value) => {
91
91
  const baseKey = [...prefixes, value].join('_');
92
- const finalKey = templateKeys?.has(value) ? baseKey + 'Template' : baseKey;
92
+ const finalKey = templateKeys?.has(value)
93
+ ? baseKey + 'Template'
94
+ : baseKey;
93
95
  map[value] = finalKey;
94
96
  });
95
97
  return map;
@@ -99,9 +101,11 @@ function buildReasonMap(enumObj, prefixes = [], templateKeys) {
99
101
  */
100
102
  function buildTypeSafeReasonMap(enumObj, prefixes, templateKeys) {
101
103
  const map = {};
102
- Object.values(enumObj).forEach(value => {
104
+ Object.values(enumObj).forEach((value) => {
103
105
  const baseKey = [...prefixes, value].join('_');
104
- const finalKey = templateKeys?.has(value) ? baseKey + 'Template' : baseKey;
106
+ const finalKey = templateKeys?.has(value)
107
+ ? baseKey + 'Template'
108
+ : baseKey;
105
109
  map[value] = finalKey;
106
110
  });
107
111
  return map;
@@ -110,7 +114,8 @@ function buildTypeSafeReasonMap(enumObj, prefixes, templateKeys) {
110
114
  * Validates that a reason map has entries for all enum values
111
115
  */
112
116
  function validateReasonMap(enumObj, reasonMap) {
113
- return Object.values(enumObj).every(value => value in reasonMap && reasonMap[value] !== undefined);
117
+ return Object.values(enumObj).every((value) => value in reasonMap &&
118
+ reasonMap[value] !== undefined);
114
119
  }
115
120
  /**
116
121
  * Creates a complete reason map ensuring all enum values are covered
@@ -118,7 +123,7 @@ function validateReasonMap(enumObj, reasonMap) {
118
123
  function createCompleteReasonMap(enumObj, prefixes = [], templateKeys) {
119
124
  const map = buildReasonMap(enumObj, [...prefixes], templateKeys);
120
125
  if (!validateReasonMap(enumObj, map)) {
121
- const missing = Object.values(enumObj).filter(value => !(value in map));
126
+ const missing = Object.values(enumObj).filter((value) => !(value in map));
122
127
  throw new Error(`Missing reason map entries for: ${missing.join(', ')}`);
123
128
  }
124
129
  return map;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitaldefiance/i18n-lib",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "Generic i18n library with enum translation support",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",