@digitaldefiance/i18n-lib 1.3.11 → 1.3.13

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 (148) hide show
  1. package/README.md +8 -0
  2. package/package.json +12 -27
  3. package/src/active-context.ts +30 -0
  4. package/src/component-definition.ts +11 -0
  5. package/src/component-registration.ts +13 -0
  6. package/src/component-registry.ts +392 -0
  7. package/src/context-error-type.ts +3 -0
  8. package/src/context-error.ts +16 -0
  9. package/src/context-manager.ts +71 -0
  10. package/src/context.ts +90 -0
  11. package/src/core-i18n.ts +609 -0
  12. package/src/core-string-key.ts +49 -0
  13. package/src/create-translation-adapter.ts +47 -0
  14. package/src/currency-code.ts +35 -0
  15. package/{dist/currency-format.d.ts → src/currency-format.ts} +5 -4
  16. package/src/currency.ts +52 -0
  17. package/src/default-config.ts +199 -0
  18. package/src/enum-registry.ts +138 -0
  19. package/src/global-active-context.ts +255 -0
  20. package/src/handleable.ts +79 -0
  21. package/src/i-global-active-context.ts +59 -0
  22. package/src/i-handleable-error-options.ts +6 -0
  23. package/src/i-handleable.ts +5 -0
  24. package/src/i18n-config.ts +29 -0
  25. package/{dist/i18n-context.d.ts → src/i18n-context.ts} +7 -6
  26. package/src/i18n-engine.ts +491 -0
  27. package/{dist/index.d.ts → src/index.ts} +10 -1
  28. package/{dist/language-codes.d.ts → src/language-codes.ts} +23 -11
  29. package/src/language-definition.ts +13 -0
  30. package/src/language-registry.ts +292 -0
  31. package/src/plugin-i18n-engine.ts +520 -0
  32. package/src/plugin-translatable-generic-error.ts +106 -0
  33. package/src/plugin-translatable-handleable-generic.ts +60 -0
  34. package/src/plugin-typed-handleable.ts +77 -0
  35. package/src/registry-config.ts +15 -0
  36. package/src/registry-error-type.ts +12 -0
  37. package/src/registry-error.ts +74 -0
  38. package/src/strict-types.ts +35 -0
  39. package/src/template.ts +63 -0
  40. package/src/timezone.ts +20 -0
  41. package/src/translatable.ts +15 -0
  42. package/src/translation-engine.ts +8 -0
  43. package/src/translation-request.ts +12 -0
  44. package/src/translation-response.ts +8 -0
  45. package/src/typed-error.ts +384 -0
  46. package/src/typed-handleable.ts +70 -0
  47. package/{dist/types.d.ts → src/types.ts} +75 -20
  48. package/src/unified-translator.ts +96 -0
  49. package/src/utils.ts +213 -0
  50. package/src/validation-config.ts +11 -0
  51. package/src/validation-result.ts +12 -0
  52. package/dist/active-context.d.ts +0 -29
  53. package/dist/active-context.js +0 -2
  54. package/dist/component-definition.d.ts +0 -11
  55. package/dist/component-definition.js +0 -2
  56. package/dist/component-registration.d.ts +0 -9
  57. package/dist/component-registration.js +0 -2
  58. package/dist/component-registry.d.ts +0 -68
  59. package/dist/component-registry.js +0 -245
  60. package/dist/context-error-type.d.ts +0 -3
  61. package/dist/context-error-type.js +0 -7
  62. package/dist/context-error.d.ts +0 -6
  63. package/dist/context-error.js +0 -15
  64. package/dist/context-manager.d.ts +0 -33
  65. package/dist/context-manager.js +0 -61
  66. package/dist/context.d.ts +0 -44
  67. package/dist/context.js +0 -69
  68. package/dist/core-i18n.d.ts +0 -62
  69. package/dist/core-i18n.js +0 -477
  70. package/dist/core-string-key.d.ts +0 -42
  71. package/dist/core-string-key.js +0 -50
  72. package/dist/create-translation-adapter.d.ts +0 -20
  73. package/dist/create-translation-adapter.js +0 -36
  74. package/dist/currency-code.d.ts +0 -19
  75. package/dist/currency-code.js +0 -36
  76. package/dist/currency-format.js +0 -2
  77. package/dist/currency.d.ts +0 -11
  78. package/dist/currency.js +0 -48
  79. package/dist/default-config.d.ts +0 -32
  80. package/dist/default-config.js +0 -101
  81. package/dist/enum-registry.d.ts +0 -44
  82. package/dist/enum-registry.js +0 -100
  83. package/dist/global-active-context.d.ts +0 -50
  84. package/dist/global-active-context.js +0 -177
  85. package/dist/handleable.d.ts +0 -13
  86. package/dist/handleable.js +0 -56
  87. package/dist/i-global-active-context.d.ts +0 -22
  88. package/dist/i-global-active-context.js +0 -2
  89. package/dist/i-handleable-error-options.d.ts +0 -6
  90. package/dist/i-handleable-error-options.js +0 -2
  91. package/dist/i-handleable.d.ts +0 -5
  92. package/dist/i-handleable.js +0 -2
  93. package/dist/i18n-config.d.ts +0 -20
  94. package/dist/i18n-config.js +0 -2
  95. package/dist/i18n-context.js +0 -2
  96. package/dist/i18n-engine.d.ts +0 -178
  97. package/dist/i18n-engine.js +0 -338
  98. package/dist/index.js +0 -83
  99. package/dist/language-codes.js +0 -31
  100. package/dist/language-definition.d.ts +0 -13
  101. package/dist/language-definition.js +0 -2
  102. package/dist/language-registry.d.ts +0 -113
  103. package/dist/language-registry.js +0 -216
  104. package/dist/plugin-i18n-engine.d.ts +0 -146
  105. package/dist/plugin-i18n-engine.js +0 -360
  106. package/dist/plugin-translatable-generic-error.d.ts +0 -29
  107. package/dist/plugin-translatable-generic-error.js +0 -66
  108. package/dist/plugin-translatable-handleable-generic.d.ts +0 -28
  109. package/dist/plugin-translatable-handleable-generic.js +0 -40
  110. package/dist/plugin-typed-handleable.d.ts +0 -14
  111. package/dist/plugin-typed-handleable.js +0 -45
  112. package/dist/registry-config.d.ts +0 -14
  113. package/dist/registry-config.js +0 -2
  114. package/dist/registry-error-type.d.ts +0 -12
  115. package/dist/registry-error-type.js +0 -16
  116. package/dist/registry-error.d.ts +0 -18
  117. package/dist/registry-error.js +0 -45
  118. package/dist/strict-types.d.ts +0 -18
  119. package/dist/strict-types.js +0 -17
  120. package/dist/template.d.ts +0 -12
  121. package/dist/template.js +0 -30
  122. package/dist/timezone.d.ts +0 -11
  123. package/dist/timezone.js +0 -22
  124. package/dist/translatable-generic-error.d.ts +0 -29
  125. package/dist/translatable-generic-error.js +0 -66
  126. package/dist/translatable-handleable-generic.d.ts +0 -28
  127. package/dist/translatable-handleable-generic.js +0 -40
  128. package/dist/translatable.d.ts +0 -5
  129. package/dist/translatable.js +0 -11
  130. package/dist/translation-engine.d.ts +0 -8
  131. package/dist/translation-engine.js +0 -2
  132. package/dist/translation-request.d.ts +0 -9
  133. package/dist/translation-request.js +0 -2
  134. package/dist/translation-response.d.ts +0 -8
  135. package/dist/translation-response.js +0 -2
  136. package/dist/typed-error.d.ts +0 -72
  137. package/dist/typed-error.js +0 -251
  138. package/dist/typed-handleable.d.ts +0 -14
  139. package/dist/typed-handleable.js +0 -40
  140. package/dist/types.js +0 -18
  141. package/dist/unified-translator.d.ts +0 -30
  142. package/dist/unified-translator.js +0 -68
  143. package/dist/utils.d.ts +0 -64
  144. package/dist/utils.js +0 -130
  145. package/dist/validation-config.d.ts +0 -11
  146. package/dist/validation-config.js +0 -2
  147. package/dist/validation-result.d.ts +0 -12
  148. package/dist/validation-result.js +0 -2
@@ -0,0 +1,255 @@
1
+ import { IActiveContext } from './active-context';
2
+ import { ContextError } from './context-error';
3
+ import { ContextErrorType } from './context-error-type';
4
+ import { CurrencyCode } from './currency-code';
5
+ import { DefaultLanguageCode } from './default-config';
6
+ import { IGlobalActiveContext } from './i-global-active-context';
7
+ import { Timezone } from './timezone';
8
+ import {
9
+ DefaultCurrencyCode,
10
+ DefaultTimezone,
11
+ LanguageContextSpace,
12
+ } from './types';
13
+
14
+ export class GlobalActiveContext<TLanguage extends string, TActiveContext extends IActiveContext<TLanguage>> implements IGlobalActiveContext<TLanguage, TActiveContext> {
15
+ protected static _contextMap: Map<string, IActiveContext<any>> = new Map();
16
+ public static readonly defaultContextKey = 'default';
17
+ public static readonly defaultLanguage: DefaultLanguageCode = 'en-US';
18
+
19
+ private static _instance: GlobalActiveContext<any, any> | undefined;
20
+ public static get instance(): GlobalActiveContext<any, any> {
21
+ if (!this._instance) {
22
+ this._instance = new GlobalActiveContext<any, any>();
23
+ this._instance.createContext(this.defaultLanguage);
24
+ }
25
+ return this._instance;
26
+ }
27
+ public static getInstance<TLanguage extends string, TActiveContext extends IActiveContext<TLanguage>>(): GlobalActiveContext<TLanguage, TActiveContext> {
28
+ if (!this._instance) {
29
+ this._instance = new GlobalActiveContext<TLanguage, TActiveContext>();
30
+ this._instance.createContext(this.defaultLanguage);
31
+ }
32
+ return this._instance as GlobalActiveContext<TLanguage, TActiveContext>;
33
+ }
34
+ public static overrideInstance(instance: GlobalActiveContext<any, any>): void {
35
+ this._instance = instance;
36
+ }
37
+
38
+ public createContext(
39
+ defaultLanguage: TLanguage,
40
+ defaultAdminLanguage: TLanguage = defaultLanguage,
41
+ key: string = GlobalActiveContext.defaultContextKey,
42
+ ): TActiveContext {
43
+ const newContext: IActiveContext<TLanguage> = {
44
+ /**
45
+ * The language to use for translations in the user facing ui
46
+ */
47
+ language: defaultLanguage,
48
+ /**
49
+ * The language to use for console/admin logs
50
+ */
51
+ adminLanguage: defaultAdminLanguage,
52
+ currencyCode: new CurrencyCode(DefaultCurrencyCode),
53
+ /**
54
+ * The current default context for language translations
55
+ */
56
+ currentContext: 'user',
57
+ /**
58
+ * The timezone for the user facing UI
59
+ */
60
+ timezone: new Timezone(DefaultTimezone),
61
+ /**
62
+ * The timezone for the admin console
63
+ */
64
+ adminTimezone: new Timezone('UTC'),
65
+ };
66
+
67
+ GlobalActiveContext._contextMap.set(key, newContext);
68
+ return newContext as TActiveContext;
69
+ }
70
+
71
+ public getContext(
72
+ key: string = GlobalActiveContext.defaultContextKey,
73
+ ): TActiveContext {
74
+ const context = GlobalActiveContext._contextMap.get(
75
+ key,
76
+ ) as TActiveContext;
77
+ if (context) {
78
+ return context;
79
+ }
80
+ throw new ContextError(ContextErrorType.InvalidContext, key);
81
+ }
82
+
83
+ public get context(): TActiveContext {
84
+ return this.getContext(
85
+ GlobalActiveContext.defaultContextKey,
86
+ );
87
+ }
88
+
89
+ public set context(ctx: TActiveContext) {
90
+ GlobalActiveContext._contextMap.set(
91
+ GlobalActiveContext.defaultContextKey,
92
+ ctx,
93
+ );
94
+ }
95
+
96
+ public setUserLanguage(
97
+ language: TLanguage,
98
+ key: string = GlobalActiveContext.defaultContextKey,
99
+ ): void {
100
+ const context = GlobalActiveContext._contextMap.get(
101
+ key,
102
+ ) as IActiveContext<TLanguage>;
103
+ if (context) {
104
+ context.language = language;
105
+ return;
106
+ }
107
+ throw new ContextError(ContextErrorType.InvalidContext, key);
108
+ }
109
+
110
+ public get userLanguage(): TLanguage {
111
+ return this.context.language;
112
+ }
113
+
114
+ public set userLanguage(lang: TLanguage) {
115
+ this.context.language = lang;
116
+ }
117
+
118
+ public setCurrencyCode(
119
+ code: CurrencyCode,
120
+ key: string = GlobalActiveContext.defaultContextKey,
121
+ ): void {
122
+ const context = GlobalActiveContext._contextMap.get(
123
+ key,
124
+ ) as IActiveContext<TLanguage>;
125
+ if (context) {
126
+ context.currencyCode = code;
127
+ return;
128
+ }
129
+ throw new ContextError(ContextErrorType.InvalidContext, key);
130
+ }
131
+
132
+ public get currencyCode(): CurrencyCode {
133
+ return this.context.currencyCode;
134
+ }
135
+
136
+ public set currencyCode(code: CurrencyCode) {
137
+ this.context.currencyCode = code;
138
+ }
139
+
140
+ /**
141
+ * Sets the admin language for console operations
142
+ * @param language The language to set for admin operations
143
+ */
144
+ public setAdminLanguage(
145
+ language: TLanguage,
146
+ key: string = GlobalActiveContext.defaultContextKey,
147
+ ): void {
148
+ const context = GlobalActiveContext._contextMap.get(
149
+ key,
150
+ ) as IActiveContext<TLanguage>;
151
+ if (context) {
152
+ context.adminLanguage = language;
153
+ return;
154
+ }
155
+ throw new ContextError(ContextErrorType.InvalidContext, key);
156
+ }
157
+
158
+ public get adminLanguage(): TLanguage {
159
+ return this.context.adminLanguage;
160
+ }
161
+
162
+ public set adminLanguage(lang: TLanguage) {
163
+ this.context.adminLanguage = lang;
164
+ }
165
+
166
+ /**
167
+ * Sets the language context for the current context
168
+ * @param context The language context to set
169
+ */
170
+ public setLanguageContextSpace(
171
+ context: LanguageContextSpace,
172
+ key: string = GlobalActiveContext.defaultContextKey,
173
+ ): void {
174
+ const ctx = GlobalActiveContext._contextMap.get(
175
+ key,
176
+ ) as IActiveContext<TLanguage>;
177
+ if (ctx) {
178
+ ctx.currentContext = context;
179
+ return;
180
+ }
181
+ throw new ContextError(ContextErrorType.InvalidContext, key);
182
+ }
183
+
184
+ public getLanguageContextSpace(
185
+ key: string = GlobalActiveContext.defaultContextKey,
186
+ ): LanguageContextSpace {
187
+ const ctx = GlobalActiveContext._contextMap.get(
188
+ key,
189
+ ) as IActiveContext<TLanguage>;
190
+ if (ctx) {
191
+ return ctx.currentContext;
192
+ }
193
+ throw new ContextError(ContextErrorType.InvalidContext, key);
194
+ }
195
+
196
+ public get languageContextSpace(): LanguageContextSpace {
197
+ return this.context.currentContext;
198
+ }
199
+
200
+ public set languageContextSpace(context: LanguageContextSpace) {
201
+ this.context.currentContext = context;
202
+ }
203
+
204
+ public setUserTimezone(
205
+ tz: Timezone,
206
+ key: string = GlobalActiveContext.defaultContextKey,
207
+ ): void {
208
+ const ctx = GlobalActiveContext._contextMap.get(
209
+ key,
210
+ ) as IActiveContext<TLanguage>;
211
+ if (ctx) {
212
+ ctx.timezone = tz;
213
+ return;
214
+ }
215
+ throw new ContextError(ContextErrorType.InvalidContext, key);
216
+ }
217
+
218
+ public get userTimezone(): Timezone {
219
+ return this.context.timezone;
220
+ }
221
+
222
+ public set userTimezone(tz: Timezone) {
223
+ this.context.timezone = tz;
224
+ }
225
+
226
+ public setAdminTimezone(
227
+ tz: Timezone,
228
+ key: string = GlobalActiveContext.defaultContextKey,
229
+ ): void {
230
+ const ctx = GlobalActiveContext._contextMap.get(
231
+ key,
232
+ ) as IActiveContext<TLanguage>;
233
+ if (ctx) {
234
+ ctx.adminTimezone = tz;
235
+ return;
236
+ }
237
+ throw new ContextError(ContextErrorType.InvalidContext, key);
238
+ }
239
+
240
+ public get adminTimezone(): Timezone {
241
+ return this.context.adminTimezone;
242
+ }
243
+
244
+ public set adminTimezone(tz: Timezone) {
245
+ this.context.adminTimezone = tz;
246
+ }
247
+
248
+ /**
249
+ * Clear all contexts (useful for testing)
250
+ */
251
+ public static clearAll(): void {
252
+ GlobalActiveContext._contextMap.clear();
253
+ GlobalActiveContext._instance = undefined;
254
+ }
255
+ }
@@ -0,0 +1,79 @@
1
+ import { IHandleable } from './i-handleable';
2
+ import { HandleableErrorOptions } from './i-handleable-error-options';
3
+
4
+ type ErrorConstructorWithStack = ErrorConstructor & {
5
+ captureStackTrace?: (target: Error, constructorOpt?: Function) => void;
6
+ };
7
+
8
+ export class HandleableError extends Error implements IHandleable {
9
+ public override readonly cause?: Error;
10
+ public readonly statusCode: number;
11
+ public readonly sourceData?: unknown;
12
+ private _handled: boolean;
13
+
14
+ constructor(source: Error, options?: HandleableErrorOptions) {
15
+ super(source.message);
16
+ this.name = this.constructor.name;
17
+ this.cause = options?.cause ?? source;
18
+ this.statusCode = options?.statusCode ?? 500;
19
+ this._handled = options?.handled ?? false;
20
+ this.sourceData = options?.sourceData;
21
+
22
+ // Capture stack trace - prioritize source stack, then capture new one
23
+ if (source.stack) {
24
+ this.stack = source.stack;
25
+ } else if ((Error as ErrorConstructorWithStack).captureStackTrace) {
26
+ (Error as ErrorConstructorWithStack).captureStackTrace?.(
27
+ this,
28
+ this.constructor,
29
+ );
30
+ } else {
31
+ this.stack = new Error().stack;
32
+ }
33
+ }
34
+
35
+ public get handled(): boolean {
36
+ return this._handled;
37
+ }
38
+
39
+ public set handled(value: boolean) {
40
+ this._handled = value;
41
+ }
42
+
43
+ private serializeValue(value: unknown): unknown {
44
+ if (
45
+ value &&
46
+ typeof value === 'object' &&
47
+ 'toJSON' in value &&
48
+ typeof value.toJSON === 'function'
49
+ ) {
50
+ return value.toJSON();
51
+ }
52
+ if (value instanceof Error) {
53
+ return value.message;
54
+ }
55
+ if (Array.isArray(value)) {
56
+ return value.map((item) => this.serializeValue(item));
57
+ }
58
+ if (value && typeof value === 'object') {
59
+ return Object.fromEntries(
60
+ Object.entries(value).map(([k, v]) => [k, this.serializeValue(v)]),
61
+ );
62
+ }
63
+ return value;
64
+ }
65
+
66
+ public toJSON(): Record<string, unknown> {
67
+ return {
68
+ name: this.name,
69
+ message: this.message,
70
+ statusCode: this.statusCode,
71
+ handled: this.handled,
72
+ stack: this.stack,
73
+ cause: this.serializeValue(this.cause),
74
+ ...(this.sourceData
75
+ ? { sourceData: this.serializeValue(this.sourceData) }
76
+ : {}),
77
+ };
78
+ }
79
+ }
@@ -0,0 +1,59 @@
1
+ import { IActiveContext } from './active-context';
2
+ import { CurrencyCode } from './currency-code';
3
+ import { DefaultLanguageCode } from './default-config';
4
+ import { Timezone } from './timezone';
5
+ import { LanguageContextSpace } from './types';
6
+
7
+ export interface IGlobalActiveContext<TLanguage extends string, TActiveContext extends IActiveContext<TLanguage>> {
8
+ context: TActiveContext;
9
+ userLanguage: TLanguage;
10
+ currencyCode: CurrencyCode;
11
+ adminLanguage: TLanguage;
12
+ languageContextSpace: LanguageContextSpace;
13
+ userTimezone: Timezone;
14
+ adminTimezone: Timezone;
15
+
16
+ createContext(
17
+ defaultLanguage: TLanguage,
18
+ defaultAdminLanguage?: TLanguage,
19
+ key?: string,
20
+ ): TActiveContext;
21
+
22
+ getContext(
23
+ key?: string,
24
+ ): TActiveContext;
25
+
26
+ setUserLanguage(
27
+ language: TLanguage,
28
+ key?: string,
29
+ ): void;
30
+
31
+ setCurrencyCode(
32
+ code: CurrencyCode,
33
+ key?: string,
34
+ ): void;
35
+
36
+ setAdminLanguage(
37
+ language: TLanguage,
38
+ key?: string,
39
+ ): void;
40
+
41
+ setLanguageContextSpace(
42
+ context: LanguageContextSpace,
43
+ key?: string,
44
+ ): void;
45
+
46
+ getLanguageContextSpace(
47
+ key?: string,
48
+ ): LanguageContextSpace;
49
+
50
+ setUserTimezone(
51
+ tz: Timezone,
52
+ key?: string,
53
+ ): void;
54
+
55
+ setAdminTimezone(
56
+ tz: Timezone,
57
+ key?: string,
58
+ ): void;
59
+ }
@@ -0,0 +1,6 @@
1
+ export interface HandleableErrorOptions {
2
+ cause?: Error;
3
+ handled?: boolean;
4
+ statusCode?: number;
5
+ sourceData?: unknown;
6
+ }
@@ -0,0 +1,5 @@
1
+ export interface IHandleable {
2
+ toJSON(): Record<string, unknown>;
3
+ get handled(): boolean;
4
+ set handled(value: boolean);
5
+ }
@@ -0,0 +1,29 @@
1
+ import { CurrencyCode } from './currency-code';
2
+ import { Timezone } from './timezone';
3
+ import {
4
+ LanguageCodeCollection,
5
+ LanguageContextSpace,
6
+ MasterStringsCollection,
7
+ } from './types';
8
+
9
+ /**
10
+ * I18n configuration interface
11
+ */
12
+ export interface I18nConfig<
13
+ TStringKey extends string,
14
+ TLanguage extends string,
15
+ TConstants extends Record<string, any> = Record<string, any>,
16
+ > {
17
+ stringNames: TStringKey[];
18
+ strings: MasterStringsCollection<TStringKey, TLanguage>;
19
+ defaultLanguage: TLanguage;
20
+ defaultTranslationContext: LanguageContextSpace;
21
+ defaultCurrencyCode: CurrencyCode;
22
+ languageCodes: LanguageCodeCollection<TLanguage>;
23
+ languages: TLanguage[];
24
+ constants?: TConstants;
25
+ enumName?: string;
26
+ enumObj?: Record<string, TStringKey>;
27
+ timezone: Timezone;
28
+ adminTimezone: Timezone;
29
+ }
@@ -1,14 +1,15 @@
1
1
  import { CurrencyCode } from './currency-code';
2
2
  import { Timezone } from './timezone';
3
3
  import { LanguageContextSpace } from './types';
4
+
4
5
  /**
5
6
  * I18n context interface
6
7
  */
7
8
  export interface I18nContext<TLanguage extends string> {
8
- language: TLanguage;
9
- adminLanguage: TLanguage;
10
- currencyCode: CurrencyCode;
11
- currentContext: LanguageContextSpace;
12
- timezone: Timezone;
13
- adminTimezone: Timezone;
9
+ language: TLanguage;
10
+ adminLanguage: TLanguage;
11
+ currencyCode: CurrencyCode;
12
+ currentContext: LanguageContextSpace;
13
+ timezone: Timezone;
14
+ adminTimezone: Timezone;
14
15
  }