@digitaldefiance/i18n-lib 4.1.2 → 4.2.1

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.
@@ -1,6 +1,107 @@
1
+ /**
2
+ * Enum translation registry (v2 - no generics)
3
+ *
4
+ * This module provides the `EnumRegistry` class for managing translations of enum
5
+ * values across multiple languages. It supports both traditional TypeScript enums
6
+ * and branded enums from `@digitaldefiance/branded-enum`.
7
+ *
8
+ * ## Overview
9
+ *
10
+ * The `EnumRegistry` is the v2 implementation of enum translation management,
11
+ * designed to work with the `I18nEngine`. It provides:
12
+ *
13
+ * - Registration of enums with their translations
14
+ * - Translation of enum values to localized strings
15
+ * - Automatic name inference for branded enums
16
+ * - Full backward compatibility with traditional enums
17
+ *
18
+ * ## Branded Enum Support
19
+ *
20
+ * When registering branded enums, the registry can automatically infer the enum
21
+ * name from the branded enum's component ID, eliminating the need to provide
22
+ * an explicit name parameter.
23
+ *
24
+ * @example Traditional enum usage
25
+ * ```typescript
26
+ * enum Status { Active = 'active', Inactive = 'inactive' }
27
+ *
28
+ * const registry = new EnumRegistry();
29
+ * registry.register(Status, {
30
+ * en: { active: 'Active', inactive: 'Inactive' },
31
+ * es: { active: 'Activo', inactive: 'Inactivo' },
32
+ * }, 'Status');
33
+ *
34
+ * registry.translate(Status, Status.Active, 'en'); // 'Active'
35
+ * ```
36
+ *
37
+ * @example Branded enum usage (name inferred)
38
+ * ```typescript
39
+ * import { createBrandedEnum } from '@digitaldefiance/branded-enum';
40
+ *
41
+ * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' });
42
+ *
43
+ * const registry = new EnumRegistry();
44
+ * registry.register(Status, {
45
+ * en: { active: 'Active', inactive: 'Inactive' },
46
+ * }); // Name 'status' is inferred from branded enum
47
+ *
48
+ * registry.translate(Status, Status.Active, 'en'); // 'Active'
49
+ * ```
50
+ *
51
+ * @module core/enum-registry
52
+ * @see {@link EnumTranslationRegistry} - Legacy registry with language validation
53
+ * @see {@link I18nEngine} - Main engine that uses this registry
54
+ */
55
+ import type { AnyBrandedEnum, BrandedEnumValue } from '@digitaldefiance/branded-enum';
1
56
  /**
2
57
  * Registry for managing translations of enum values across multiple languages.
3
- * Provides a centralized way to register and translate enum values.
58
+ *
59
+ * Provides a centralized way to register and translate enum values with support
60
+ * for both traditional TypeScript enums and branded enums from
61
+ * `@digitaldefiance/branded-enum`.
62
+ *
63
+ * ## Key Features
64
+ *
65
+ * - **Dual Enum Support**: Works with both traditional and branded enums
66
+ * - **Automatic Name Inference**: Branded enums can have their name inferred from component ID
67
+ * - **Multi-Language**: Supports translations across any number of languages
68
+ * - **Type Safety**: Full TypeScript support with proper type inference
69
+ *
70
+ * ## Registration
71
+ *
72
+ * Use {@link register} to add an enum with its translations. For branded enums,
73
+ * the `enumName` parameter is optional and will be inferred from the component ID.
74
+ *
75
+ * ## Translation
76
+ *
77
+ * Use {@link translate} to get the localized string for an enum value. The method
78
+ * handles both traditional enum values and branded enum values.
79
+ *
80
+ * @example Complete workflow
81
+ * ```typescript
82
+ * import { createBrandedEnum } from '@digitaldefiance/branded-enum';
83
+ *
84
+ * // Create a branded enum
85
+ * const Priority = createBrandedEnum('priority', {
86
+ * High: 'high',
87
+ * Medium: 'medium',
88
+ * Low: 'low',
89
+ * });
90
+ *
91
+ * // Create registry and register enum
92
+ * const registry = new EnumRegistry();
93
+ * registry.register(Priority, {
94
+ * en: { high: 'High Priority', medium: 'Medium Priority', low: 'Low Priority' },
95
+ * es: { high: 'Alta Prioridad', medium: 'Prioridad Media', low: 'Baja Prioridad' },
96
+ * });
97
+ *
98
+ * // Check if registered
99
+ * registry.has(Priority); // true
100
+ *
101
+ * // Translate values
102
+ * registry.translate(Priority, Priority.High, 'en'); // 'High Priority'
103
+ * registry.translate(Priority, Priority.High, 'es'); // 'Alta Prioridad'
104
+ * ```
4
105
  */
5
106
  export declare class EnumRegistry {
6
107
  private translations;
@@ -10,29 +111,143 @@ export declare class EnumRegistry {
10
111
  * Creates a new EnumRegistry instance.
11
112
  * @param translateFn - Optional translation function for error messages
12
113
  */
13
- constructor(translateFn?: (key: string, vars?: Record<string, any>) => string);
114
+ constructor(translateFn?: (key: string, vars?: Record<string, unknown>) => string);
14
115
  /**
15
116
  * Registers an enum with its translations for all languages.
117
+ *
118
+ * Supports both traditional TypeScript enums and branded enums from
119
+ * `@digitaldefiance/branded-enum`. For branded enums, the `enumName` parameter
120
+ * is optional and will be automatically inferred from the branded enum's
121
+ * component ID.
122
+ *
123
+ * ## Name Resolution
124
+ *
125
+ * The enum name is resolved in the following order:
126
+ * 1. Explicit `enumName` parameter (if provided)
127
+ * 2. Component ID from branded enum (if branded)
128
+ * 3. `'UnknownEnum'` (fallback for traditional enums without name)
129
+ *
130
+ * ## Translation Structure
131
+ *
132
+ * The `translations` object should map language codes to objects that map
133
+ * enum values to their translated strings:
134
+ *
135
+ * ```typescript
136
+ * {
137
+ * 'en': { 'value1': 'Translation 1', 'value2': 'Translation 2' },
138
+ * 'es': { 'value1': 'Traducción 1', 'value2': 'Traducción 2' },
139
+ * }
140
+ * ```
141
+ *
16
142
  * @template TEnum - The enum value type (string or number)
17
- * @param enumObj - The enum object to register
143
+ * @param enumObj - The enum object to register (traditional or branded)
18
144
  * @param translations - Mapping of language codes to enum value translations
19
- * @param enumName - Human-readable name for the enum (used in error messages)
145
+ * @param enumName - Human-readable name for the enum (optional for branded enums)
146
+ * @returns The registered translations object
147
+ *
148
+ * @example Traditional enum (name required)
149
+ * ```typescript
150
+ * enum Status { Active = 'active', Inactive = 'inactive' }
151
+ *
152
+ * registry.register(Status, {
153
+ * en: { active: 'Active', inactive: 'Inactive' },
154
+ * es: { active: 'Activo', inactive: 'Inactivo' },
155
+ * }, 'Status');
156
+ * ```
157
+ *
158
+ * @example Branded enum (name inferred)
159
+ * ```typescript
160
+ * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' });
161
+ *
162
+ * // Name 'status' is automatically inferred from the branded enum
163
+ * registry.register(Status, {
164
+ * en: { active: 'Active', inactive: 'Inactive' },
165
+ * });
166
+ * ```
167
+ *
168
+ * @example Branded enum with explicit name override
169
+ * ```typescript
170
+ * const Status = createBrandedEnum('status', { Active: 'active' });
171
+ *
172
+ * // Override the inferred name with a custom name
173
+ * registry.register(Status, {
174
+ * en: { active: 'Active' },
175
+ * }, 'UserStatus');
176
+ * ```
177
+ */
178
+ register<TEnum extends string | number>(enumObj: Record<string, TEnum> | AnyBrandedEnum | {
179
+ [key: string]: string | number;
180
+ }, translations: Record<string, Record<string, string>>, enumName?: string): Record<string, Record<string, string>>;
181
+ /**
182
+ * Resolves the enum name from a branded enum's component ID or returns default.
183
+ * @param enumObj - The enum object
184
+ * @returns The resolved enum name
20
185
  */
21
- register<TEnum extends string | number>(enumObj: Record<string, TEnum>, translations: Record<string, Record<string, string>>, enumName: string): void;
186
+ private resolveEnumName;
22
187
  /**
23
188
  * Translates an enum value to a specific language.
189
+ *
190
+ * Supports both traditional enum values and branded enum values. The method
191
+ * performs multiple lookup strategies to find the correct translation:
192
+ *
193
+ * ## Lookup Strategy
194
+ *
195
+ * 1. **Direct value lookup**: Try the string representation of the value
196
+ * 2. **Numeric enum reverse mapping**: For numeric enums, find the string key
197
+ * 3. **Branded enum key lookup**: For branded enums, find the enum key name
198
+ *
199
+ * ## Error Handling
200
+ *
201
+ * The method throws `I18nError` in the following cases:
202
+ * - Enum not registered: `I18nError.invalidConfig`
203
+ * - Language not found: `I18nError.languageNotFound`
204
+ * - Value not found: `I18nError.translationMissing`
205
+ *
24
206
  * @template TEnum - The enum value type
25
- * @param enumObj - The registered enum object
207
+ * @param enumObj - The registered enum object (traditional or branded)
26
208
  * @param value - The enum value to translate
27
209
  * @param language - The target language code
28
210
  * @returns The translated string
29
211
  * @throws {I18nError} If the enum, language, or value is not found
212
+ *
213
+ * @example Basic translation
214
+ * ```typescript
215
+ * const Status = createBrandedEnum('status', { Active: 'active' });
216
+ * registry.register(Status, { en: { active: 'Active' }, es: { active: 'Activo' } });
217
+ *
218
+ * registry.translate(Status, Status.Active, 'en'); // 'Active'
219
+ * registry.translate(Status, Status.Active, 'es'); // 'Activo'
220
+ * ```
221
+ *
222
+ * @example Error handling
223
+ * ```typescript
224
+ * try {
225
+ * registry.translate(UnregisteredEnum, 'value', 'en');
226
+ * } catch (error) {
227
+ * // I18nError: No translations found for enum: UnknownEnum
228
+ * }
229
+ * ```
30
230
  */
31
- translate<TEnum extends string | number>(enumObj: Record<string, TEnum>, value: TEnum, language: string): string;
231
+ translate<TEnum extends string | number>(enumObj: Record<string, TEnum> | AnyBrandedEnum | {
232
+ [key: string]: string | number;
233
+ }, value: TEnum | BrandedEnumValue<AnyBrandedEnum>, language: string): string;
32
234
  /**
33
235
  * Checks if an enum has been registered.
236
+ *
237
+ * Works with both traditional and branded enums. Uses object reference
238
+ * equality to check registration status.
239
+ *
34
240
  * @param enumObj - The enum object to check
35
- * @returns True if the enum is registered, false otherwise
241
+ * @returns `true` if the enum is registered, `false` otherwise
242
+ *
243
+ * @example
244
+ * ```typescript
245
+ * const Status = createBrandedEnum('status', { Active: 'active' });
246
+ *
247
+ * registry.has(Status); // false (not registered yet)
248
+ * registry.register(Status, { en: { active: 'Active' } });
249
+ * registry.has(Status); // true
250
+ * ```
36
251
  */
37
252
  has(enumObj: object): boolean;
38
253
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"enum-registry.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-i18n-lib/src/core/enum-registry.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAGhB;IACJ,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,WAAW,CAAC,CAAsD;IAE1E;;;OAGG;gBAED,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,MAAM;IAKnE;;;;;;OAMG;IACH,QAAQ,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACpD,QAAQ,EAAE,MAAM,GACf,IAAI;IAKP;;;;;;;;OAQG;IACH,SAAS,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EACrC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAC9B,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,GACf,MAAM;IAkCT;;;;OAIG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI7B;;;;OAIG;IACH,OAAO,CAAC,WAAW;CAGpB"}
1
+ {"version":3,"file":"enum-registry.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-i18n-lib/src/core/enum-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EACjB,MAAM,+BAA+B,CAAC;AAOvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAGhB;IACJ,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,WAAW,CAAC,CAA0D;IAE9E;;;OAGG;gBAED,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM;IAKvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8DG;IACH,QAAQ,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EACpC,OAAO,EACH,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GACrB,cAAc,GACd;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;KAAE,EACtC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EACpD,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAOzC;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAQvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2CG;IACH,SAAS,CAAC,KAAK,SAAS,MAAM,GAAG,MAAM,EACrC,OAAO,EACH,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GACrB,cAAc,GACd;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAA;KAAE,EACtC,KAAK,EAAE,KAAK,GAAG,gBAAgB,CAAC,cAAc,CAAC,EAC/C,QAAQ,EAAE,MAAM,GACf,MAAM;IA4CT;;;;;;;;;;;;;;;;;OAiBG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI7B;;;;OAIG;IACH,OAAO,CAAC,WAAW;CAGpB"}
@@ -1,14 +1,111 @@
1
1
  "use strict";
2
- /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-return */
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.EnumRegistry = void 0;
5
2
  /**
6
3
  * Enum translation registry (v2 - no generics)
4
+ *
5
+ * This module provides the `EnumRegistry` class for managing translations of enum
6
+ * values across multiple languages. It supports both traditional TypeScript enums
7
+ * and branded enums from `@digitaldefiance/branded-enum`.
8
+ *
9
+ * ## Overview
10
+ *
11
+ * The `EnumRegistry` is the v2 implementation of enum translation management,
12
+ * designed to work with the `I18nEngine`. It provides:
13
+ *
14
+ * - Registration of enums with their translations
15
+ * - Translation of enum values to localized strings
16
+ * - Automatic name inference for branded enums
17
+ * - Full backward compatibility with traditional enums
18
+ *
19
+ * ## Branded Enum Support
20
+ *
21
+ * When registering branded enums, the registry can automatically infer the enum
22
+ * name from the branded enum's component ID, eliminating the need to provide
23
+ * an explicit name parameter.
24
+ *
25
+ * @example Traditional enum usage
26
+ * ```typescript
27
+ * enum Status { Active = 'active', Inactive = 'inactive' }
28
+ *
29
+ * const registry = new EnumRegistry();
30
+ * registry.register(Status, {
31
+ * en: { active: 'Active', inactive: 'Inactive' },
32
+ * es: { active: 'Activo', inactive: 'Inactivo' },
33
+ * }, 'Status');
34
+ *
35
+ * registry.translate(Status, Status.Active, 'en'); // 'Active'
36
+ * ```
37
+ *
38
+ * @example Branded enum usage (name inferred)
39
+ * ```typescript
40
+ * import { createBrandedEnum } from '@digitaldefiance/branded-enum';
41
+ *
42
+ * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' });
43
+ *
44
+ * const registry = new EnumRegistry();
45
+ * registry.register(Status, {
46
+ * en: { active: 'Active', inactive: 'Inactive' },
47
+ * }); // Name 'status' is inferred from branded enum
48
+ *
49
+ * registry.translate(Status, Status.Active, 'en'); // 'Active'
50
+ * ```
51
+ *
52
+ * @module core/enum-registry
53
+ * @see {@link EnumTranslationRegistry} - Legacy registry with language validation
54
+ * @see {@link I18nEngine} - Main engine that uses this registry
7
55
  */
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ exports.EnumRegistry = void 0;
58
+ const branded_enum_utils_1 = require("../branded-enum-utils");
8
59
  const i18n_error_1 = require("../errors/i18n-error");
9
60
  /**
10
61
  * Registry for managing translations of enum values across multiple languages.
11
- * Provides a centralized way to register and translate enum values.
62
+ *
63
+ * Provides a centralized way to register and translate enum values with support
64
+ * for both traditional TypeScript enums and branded enums from
65
+ * `@digitaldefiance/branded-enum`.
66
+ *
67
+ * ## Key Features
68
+ *
69
+ * - **Dual Enum Support**: Works with both traditional and branded enums
70
+ * - **Automatic Name Inference**: Branded enums can have their name inferred from component ID
71
+ * - **Multi-Language**: Supports translations across any number of languages
72
+ * - **Type Safety**: Full TypeScript support with proper type inference
73
+ *
74
+ * ## Registration
75
+ *
76
+ * Use {@link register} to add an enum with its translations. For branded enums,
77
+ * the `enumName` parameter is optional and will be inferred from the component ID.
78
+ *
79
+ * ## Translation
80
+ *
81
+ * Use {@link translate} to get the localized string for an enum value. The method
82
+ * handles both traditional enum values and branded enum values.
83
+ *
84
+ * @example Complete workflow
85
+ * ```typescript
86
+ * import { createBrandedEnum } from '@digitaldefiance/branded-enum';
87
+ *
88
+ * // Create a branded enum
89
+ * const Priority = createBrandedEnum('priority', {
90
+ * High: 'high',
91
+ * Medium: 'medium',
92
+ * Low: 'low',
93
+ * });
94
+ *
95
+ * // Create registry and register enum
96
+ * const registry = new EnumRegistry();
97
+ * registry.register(Priority, {
98
+ * en: { high: 'High Priority', medium: 'Medium Priority', low: 'Low Priority' },
99
+ * es: { high: 'Alta Prioridad', medium: 'Prioridad Media', low: 'Baja Prioridad' },
100
+ * });
101
+ *
102
+ * // Check if registered
103
+ * registry.has(Priority); // true
104
+ *
105
+ * // Translate values
106
+ * registry.translate(Priority, Priority.High, 'en'); // 'High Priority'
107
+ * registry.translate(Priority, Priority.High, 'es'); // 'Alta Prioridad'
108
+ * ```
12
109
  */
13
110
  class EnumRegistry {
14
111
  translations = new Map();
@@ -23,23 +120,128 @@ class EnumRegistry {
23
120
  }
24
121
  /**
25
122
  * Registers an enum with its translations for all languages.
123
+ *
124
+ * Supports both traditional TypeScript enums and branded enums from
125
+ * `@digitaldefiance/branded-enum`. For branded enums, the `enumName` parameter
126
+ * is optional and will be automatically inferred from the branded enum's
127
+ * component ID.
128
+ *
129
+ * ## Name Resolution
130
+ *
131
+ * The enum name is resolved in the following order:
132
+ * 1. Explicit `enumName` parameter (if provided)
133
+ * 2. Component ID from branded enum (if branded)
134
+ * 3. `'UnknownEnum'` (fallback for traditional enums without name)
135
+ *
136
+ * ## Translation Structure
137
+ *
138
+ * The `translations` object should map language codes to objects that map
139
+ * enum values to their translated strings:
140
+ *
141
+ * ```typescript
142
+ * {
143
+ * 'en': { 'value1': 'Translation 1', 'value2': 'Translation 2' },
144
+ * 'es': { 'value1': 'Traducción 1', 'value2': 'Traducción 2' },
145
+ * }
146
+ * ```
147
+ *
26
148
  * @template TEnum - The enum value type (string or number)
27
- * @param enumObj - The enum object to register
149
+ * @param enumObj - The enum object to register (traditional or branded)
28
150
  * @param translations - Mapping of language codes to enum value translations
29
- * @param enumName - Human-readable name for the enum (used in error messages)
151
+ * @param enumName - Human-readable name for the enum (optional for branded enums)
152
+ * @returns The registered translations object
153
+ *
154
+ * @example Traditional enum (name required)
155
+ * ```typescript
156
+ * enum Status { Active = 'active', Inactive = 'inactive' }
157
+ *
158
+ * registry.register(Status, {
159
+ * en: { active: 'Active', inactive: 'Inactive' },
160
+ * es: { active: 'Activo', inactive: 'Inactivo' },
161
+ * }, 'Status');
162
+ * ```
163
+ *
164
+ * @example Branded enum (name inferred)
165
+ * ```typescript
166
+ * const Status = createBrandedEnum('status', { Active: 'active', Inactive: 'inactive' });
167
+ *
168
+ * // Name 'status' is automatically inferred from the branded enum
169
+ * registry.register(Status, {
170
+ * en: { active: 'Active', inactive: 'Inactive' },
171
+ * });
172
+ * ```
173
+ *
174
+ * @example Branded enum with explicit name override
175
+ * ```typescript
176
+ * const Status = createBrandedEnum('status', { Active: 'active' });
177
+ *
178
+ * // Override the inferred name with a custom name
179
+ * registry.register(Status, {
180
+ * en: { active: 'Active' },
181
+ * }, 'UserStatus');
182
+ * ```
30
183
  */
31
184
  register(enumObj, translations, enumName) {
185
+ const resolvedName = enumName ?? this.resolveEnumName(enumObj);
32
186
  this.translations.set(enumObj, translations);
33
- this.enumNames.set(enumObj, enumName);
187
+ this.enumNames.set(enumObj, resolvedName);
188
+ return translations;
189
+ }
190
+ /**
191
+ * Resolves the enum name from a branded enum's component ID or returns default.
192
+ * @param enumObj - The enum object
193
+ * @returns The resolved enum name
194
+ */
195
+ resolveEnumName(enumObj) {
196
+ if ((0, branded_enum_utils_1.isBrandedEnum)(enumObj)) {
197
+ const componentId = (0, branded_enum_utils_1.getBrandedEnumComponentId)(enumObj);
198
+ return componentId ?? 'UnknownEnum';
199
+ }
200
+ return 'UnknownEnum';
34
201
  }
35
202
  /**
36
203
  * Translates an enum value to a specific language.
204
+ *
205
+ * Supports both traditional enum values and branded enum values. The method
206
+ * performs multiple lookup strategies to find the correct translation:
207
+ *
208
+ * ## Lookup Strategy
209
+ *
210
+ * 1. **Direct value lookup**: Try the string representation of the value
211
+ * 2. **Numeric enum reverse mapping**: For numeric enums, find the string key
212
+ * 3. **Branded enum key lookup**: For branded enums, find the enum key name
213
+ *
214
+ * ## Error Handling
215
+ *
216
+ * The method throws `I18nError` in the following cases:
217
+ * - Enum not registered: `I18nError.invalidConfig`
218
+ * - Language not found: `I18nError.languageNotFound`
219
+ * - Value not found: `I18nError.translationMissing`
220
+ *
37
221
  * @template TEnum - The enum value type
38
- * @param enumObj - The registered enum object
222
+ * @param enumObj - The registered enum object (traditional or branded)
39
223
  * @param value - The enum value to translate
40
224
  * @param language - The target language code
41
225
  * @returns The translated string
42
226
  * @throws {I18nError} If the enum, language, or value is not found
227
+ *
228
+ * @example Basic translation
229
+ * ```typescript
230
+ * const Status = createBrandedEnum('status', { Active: 'active' });
231
+ * registry.register(Status, { en: { active: 'Active' }, es: { active: 'Activo' } });
232
+ *
233
+ * registry.translate(Status, Status.Active, 'en'); // 'Active'
234
+ * registry.translate(Status, Status.Active, 'es'); // 'Activo'
235
+ * ```
236
+ *
237
+ * @example Error handling
238
+ * ```typescript
239
+ * try {
240
+ * registry.translate(UnregisteredEnum, 'value', 'en');
241
+ * } catch (error) {
242
+ * // I18nError: No translations found for enum: UnknownEnum
243
+ * }
244
+ * ```
43
245
  */
44
246
  translate(enumObj, value, language) {
45
247
  const translations = this.translations.get(enumObj);
@@ -60,6 +262,13 @@ class EnumRegistry {
60
262
  result = langTranslations[stringKey];
61
263
  }
62
264
  }
265
+ // For branded enums, try looking up by the enum key name
266
+ if (!result && (0, branded_enum_utils_1.isBrandedEnum)(enumObj)) {
267
+ const enumKey = Object.keys(enumObj).find((key) => enumObj[key] === value);
268
+ if (enumKey) {
269
+ result = langTranslations[enumKey];
270
+ }
271
+ }
63
272
  if (!result) {
64
273
  throw i18n_error_1.I18nError.translationMissing('enum', String(value), language);
65
274
  }
@@ -67,8 +276,21 @@ class EnumRegistry {
67
276
  }
68
277
  /**
69
278
  * Checks if an enum has been registered.
279
+ *
280
+ * Works with both traditional and branded enums. Uses object reference
281
+ * equality to check registration status.
282
+ *
70
283
  * @param enumObj - The enum object to check
71
- * @returns True if the enum is registered, false otherwise
284
+ * @returns `true` if the enum is registered, `false` otherwise
285
+ *
286
+ * @example
287
+ * ```typescript
288
+ * const Status = createBrandedEnum('status', { Active: 'active' });
289
+ *
290
+ * registry.has(Status); // false (not registered yet)
291
+ * registry.register(Status, { en: { active: 'Active' } });
292
+ * registry.has(Status); // true
293
+ * ```
72
294
  */
73
295
  has(enumObj) {
74
296
  return this.translations.has(enumObj);
@@ -1 +1 @@
1
- {"version":3,"file":"enum-registry.js","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-i18n-lib/src/core/enum-registry.ts"],"names":[],"mappings":";AAAA,2PAA2P;;;AAE3P;;GAEG;AAEH,qDAAiD;AAEjD;;;GAGG;AACH,MAAa,YAAY;IACf,YAAY,GAAG,IAAI,GAAG,EAG3B,CAAC;IACI,SAAS,GAAG,IAAI,OAAO,EAAkB,CAAC;IAC1C,WAAW,CAAuD;IAE1E;;;OAGG;IACH,YACE,WAAiE;QAEjE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED;;;;;;OAMG;IACH,QAAQ,CACN,OAA8B,EAC9B,YAAoD,EACpD,QAAgB;QAEhB,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QAC7C,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACxC,CAAC;IAED;;;;;;;;OAQG;IACH,SAAS,CACP,OAA8B,EAC9B,KAAY,EACZ,QAAgB;QAEhB,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,sBAAS,CAAC,aAAa,CAC3B,mCAAmC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAC/D,CAAC;QACJ,CAAC;QAED,MAAM,gBAAgB,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAChD,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,sBAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAC7C,CAAC;QAED,qCAAqC;QACrC,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;QAExC,wEAAwE;QACxE,IAAI,CAAC,MAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACzC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CACzC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAChC,CAAC;YACF,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,sBAAS,CAAC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,GAAG,CAAC,OAAe;QACjB,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAED;;;;OAIG;IACK,WAAW,CAAC,OAAe;QACjC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,aAAa,CAAC;IACtD,CAAC;CACF;AAlGD,oCAkGC"}
1
+ {"version":3,"file":"enum-registry.js","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-i18n-lib/src/core/enum-registry.ts"],"names":[],"mappings":"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"}