@digitaldefiance/i18n-lib 1.0.14 → 1.0.16
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 +222 -28
- package/dist/context.d.ts +5 -4
- package/dist/context.js +5 -2
- package/dist/i18n-engine.d.ts +24 -3
- package/dist/i18n-engine.js +39 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/timezone.d.ts +5 -0
- package/dist/timezone.js +16 -0
- package/dist/types.d.ts +11 -3
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +8 -0
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# @digitaldefiance/i18n-lib
|
|
2
2
|
|
|
3
|
-
A
|
|
3
|
+
A comprehensive TypeScript internationalization library with enum translation support, template processing, and context management.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **Context
|
|
11
|
-
- **
|
|
7
|
+
- **Type-Safe Translations**: Full TypeScript support with generic types for strings and languages
|
|
8
|
+
- **Enum Translation Registry**: Translate enum values with complete type safety
|
|
9
|
+
- **Template Processing**: Advanced template system with `{{EnumName.EnumKey}}` patterns and variable replacement
|
|
10
|
+
- **Context Management**: Admin vs user translation contexts with automatic language switching
|
|
11
|
+
- **Singleton Pattern**: Efficient instance management with named instances
|
|
12
|
+
- **Currency Formatting**: Built-in currency formatting utilities with locale support
|
|
13
|
+
- **Fallback System**: Graceful degradation when translations are missing
|
|
12
14
|
- **Zero Dependencies**: Lightweight with no external dependencies
|
|
13
15
|
|
|
14
16
|
## Installation
|
|
@@ -30,11 +32,12 @@ enum MyStrings {
|
|
|
30
32
|
|
|
31
33
|
enum MyLanguages {
|
|
32
34
|
English = 'English',
|
|
33
|
-
Spanish = '
|
|
35
|
+
Spanish = 'Spanish'
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
// Configure the engine
|
|
37
39
|
const config: I18nConfig<MyStrings, MyLanguages> = {
|
|
40
|
+
stringNames: Object.values(MyStrings),
|
|
38
41
|
strings: {
|
|
39
42
|
[MyLanguages.English]: {
|
|
40
43
|
[MyStrings.Welcome]: 'Welcome!',
|
|
@@ -46,40 +49,52 @@ const config: I18nConfig<MyStrings, MyLanguages> = {
|
|
|
46
49
|
}
|
|
47
50
|
},
|
|
48
51
|
defaultLanguage: MyLanguages.English,
|
|
52
|
+
defaultContext: 'user',
|
|
49
53
|
languageCodes: {
|
|
50
54
|
[MyLanguages.English]: 'en',
|
|
51
55
|
[MyLanguages.Spanish]: 'es'
|
|
52
|
-
}
|
|
56
|
+
},
|
|
57
|
+
languages: Object.values(MyLanguages)
|
|
53
58
|
};
|
|
54
59
|
|
|
55
|
-
// Create engine
|
|
60
|
+
// Create engine
|
|
56
61
|
const i18n = new I18nEngine(config);
|
|
57
|
-
const context = createContext(MyLanguages.English);
|
|
58
62
|
|
|
59
63
|
// Translate strings
|
|
60
|
-
const welcome = i18n.translate(MyStrings.Welcome
|
|
64
|
+
const welcome = i18n.translate(MyStrings.Welcome);
|
|
61
65
|
// "Welcome!"
|
|
62
66
|
|
|
63
|
-
const greeting = i18n.translate(MyStrings.UserGreetingTemplate,
|
|
67
|
+
const greeting = i18n.translate(MyStrings.UserGreetingTemplate, { name: 'John' });
|
|
64
68
|
// "Hello, John!"
|
|
69
|
+
|
|
70
|
+
// Change language
|
|
71
|
+
i18n.context = { language: MyLanguages.Spanish };
|
|
72
|
+
const spanishGreeting = i18n.translate(MyStrings.UserGreetingTemplate, { name: 'Juan' });
|
|
73
|
+
// "¡Hola, Juan!"
|
|
65
74
|
```
|
|
66
75
|
|
|
67
|
-
##
|
|
76
|
+
## Advanced Features
|
|
77
|
+
|
|
78
|
+
### Enum Translation Registry
|
|
79
|
+
|
|
68
80
|
```typescript
|
|
69
81
|
enum Status {
|
|
70
82
|
Active = 'active',
|
|
71
|
-
Inactive = 'inactive'
|
|
83
|
+
Inactive = 'inactive',
|
|
84
|
+
Pending = 'pending'
|
|
72
85
|
}
|
|
73
86
|
|
|
74
|
-
// Register enum translations
|
|
87
|
+
// Register enum translations (requires complete translations)
|
|
75
88
|
i18n.registerEnum(Status, {
|
|
76
89
|
[MyLanguages.English]: {
|
|
77
90
|
[Status.Active]: 'Active',
|
|
78
|
-
[Status.Inactive]: 'Inactive'
|
|
91
|
+
[Status.Inactive]: 'Inactive',
|
|
92
|
+
[Status.Pending]: 'Pending'
|
|
79
93
|
},
|
|
80
94
|
[MyLanguages.Spanish]: {
|
|
81
95
|
[Status.Active]: 'Activo',
|
|
82
|
-
[Status.Inactive]: 'Inactivo'
|
|
96
|
+
[Status.Inactive]: 'Inactivo',
|
|
97
|
+
[Status.Pending]: 'Pendiente'
|
|
83
98
|
}
|
|
84
99
|
}, 'Status');
|
|
85
100
|
|
|
@@ -88,24 +103,203 @@ const statusText = i18n.translateEnum(Status, Status.Active, MyLanguages.Spanish
|
|
|
88
103
|
// "Activo"
|
|
89
104
|
```
|
|
90
105
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
106
|
+
### Template Processing
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
enum AppStrings {
|
|
110
|
+
WelcomeMessage = 'welcomeMessage',
|
|
111
|
+
UserGreetingTemplate = 'userGreetingTemplate'
|
|
112
|
+
}
|
|
94
113
|
|
|
95
|
-
|
|
114
|
+
const config: I18nConfig<AppStrings, MyLanguages> = {
|
|
115
|
+
// ... other config
|
|
116
|
+
enumName: 'AppStrings',
|
|
117
|
+
enumObj: AppStrings,
|
|
118
|
+
strings: {
|
|
119
|
+
[MyLanguages.English]: {
|
|
120
|
+
[AppStrings.WelcomeMessage]: 'Welcome to our app!',
|
|
121
|
+
[AppStrings.UserGreetingTemplate]: 'Hello, {name}!'
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
};
|
|
96
125
|
|
|
97
|
-
|
|
126
|
+
const i18n = new I18nEngine(config);
|
|
98
127
|
|
|
99
|
-
|
|
128
|
+
// Use template processor
|
|
129
|
+
const message = i18n.t('{{AppStrings.WelcomeMessage}} {{AppStrings.UserGreetingTemplate}}',
|
|
130
|
+
MyLanguages.English,
|
|
131
|
+
{ name: 'John' }
|
|
132
|
+
);
|
|
133
|
+
// "Welcome to our app! Hello, John!"
|
|
134
|
+
```
|
|
100
135
|
|
|
101
136
|
### Context Management
|
|
102
|
-
- createContext(defaultLanguage) - Create new context
|
|
103
137
|
|
|
104
|
-
|
|
138
|
+
```typescript
|
|
139
|
+
import { createContext, setLanguage, setAdminLanguage, setContext } from '@digitaldefiance/i18n-lib';
|
|
140
|
+
|
|
141
|
+
// Create and manage context
|
|
142
|
+
const context = createContext(MyLanguages.English, 'user');
|
|
143
|
+
|
|
144
|
+
// Set different languages for user and admin contexts
|
|
145
|
+
setLanguage(context, MyLanguages.Spanish);
|
|
146
|
+
setAdminLanguage(context, MyLanguages.English);
|
|
147
|
+
|
|
148
|
+
// Switch between contexts
|
|
149
|
+
setContext(context, 'admin'); // Uses admin language
|
|
150
|
+
setContext(context, 'user'); // Uses user language
|
|
151
|
+
|
|
152
|
+
// Apply context to engine
|
|
153
|
+
i18n.context = context;
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Context Change Monitoring
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
import { ContextManager } from '@digitaldefiance/i18n-lib';
|
|
160
|
+
|
|
161
|
+
interface AppContext {
|
|
162
|
+
language: string;
|
|
163
|
+
theme: string;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const manager = new ContextManager<AppContext>();
|
|
167
|
+
|
|
168
|
+
// Add listeners for context changes
|
|
169
|
+
manager.addListener((property, oldValue, newValue) => {
|
|
170
|
+
console.log(`${property} changed from ${oldValue} to ${newValue}`);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
// Create reactive context
|
|
174
|
+
const context = { language: 'en', theme: 'dark' };
|
|
175
|
+
const reactiveContext = manager.createProxy(context);
|
|
176
|
+
|
|
177
|
+
// Changes are automatically detected
|
|
178
|
+
reactiveContext.language = 'es'; // Triggers listener
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Currency Formatting
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import { getCurrencyFormat } from '@digitaldefiance/i18n-lib';
|
|
185
|
+
|
|
186
|
+
// Get currency formatting information
|
|
187
|
+
const usdFormat = getCurrencyFormat('en-US', 'USD');
|
|
188
|
+
// { symbol: '$', position: 'prefix', groupSeparator: ',', decimalSeparator: '.' }
|
|
189
|
+
|
|
190
|
+
const eurFormat = getCurrencyFormat('de-DE', 'EUR');
|
|
191
|
+
// { symbol: '€', position: 'postfix', groupSeparator: '.', decimalSeparator: ',' }
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Instance Management
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
// Create named instances
|
|
198
|
+
const mainI18n = new I18nEngine(config, 'main');
|
|
199
|
+
const adminI18n = new I18nEngine(adminConfig, 'admin');
|
|
200
|
+
|
|
201
|
+
// Get instances by key
|
|
202
|
+
const instance = I18nEngine.getInstance('main');
|
|
203
|
+
|
|
204
|
+
// Clean up instances (useful for testing)
|
|
205
|
+
I18nEngine.clearInstances();
|
|
206
|
+
I18nEngine.removeInstance('main');
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
## API Reference
|
|
210
|
+
|
|
211
|
+
### I18nEngine
|
|
212
|
+
|
|
213
|
+
#### Constructor
|
|
214
|
+
- `new I18nEngine<TStringKey, TLanguage>(config, key?)` - Create new engine instance
|
|
215
|
+
|
|
216
|
+
#### Translation Methods
|
|
217
|
+
- `translate(key, vars?, language?, fallbackLanguage?)` - Translate string with optional variables
|
|
218
|
+
- `translateEnum(enumObj, value, language)` - Translate enum value
|
|
219
|
+
- `t(templateString, language?, ...vars)` - Process template with enum patterns
|
|
220
|
+
|
|
221
|
+
#### Registration
|
|
222
|
+
- `registerEnum(enumObj, translations, enumName)` - Register enum translations
|
|
223
|
+
|
|
224
|
+
#### Language Management
|
|
225
|
+
- `getLanguageCode(language)` - Get language code for language
|
|
226
|
+
- `getLanguageFromCode(code)` - Get language from code
|
|
227
|
+
- `getAllLanguageCodes()` - Get all language codes
|
|
228
|
+
- `getAvailableLanguages()` - Get available languages
|
|
229
|
+
- `isLanguageAvailable(language)` - Check if language is available
|
|
230
|
+
|
|
231
|
+
#### Context Management
|
|
232
|
+
- `get context()` - Get current context
|
|
233
|
+
- `set context(context)` - Set context properties
|
|
234
|
+
|
|
235
|
+
#### Static Methods
|
|
236
|
+
- `getInstance(key?)` - Get instance by key
|
|
237
|
+
- `clearInstances()` - Clear all instances
|
|
238
|
+
- `removeInstance(key?)` - Remove specific instance
|
|
239
|
+
|
|
240
|
+
### Context Utilities
|
|
241
|
+
- `createContext(defaultLanguage, defaultContext)` - Create new context
|
|
242
|
+
- `setLanguage(context, language)` - Set user language
|
|
243
|
+
- `setAdminLanguage(context, language)` - Set admin language
|
|
244
|
+
- `setContext(context, contextType)` - Set context type
|
|
245
|
+
|
|
246
|
+
### ContextManager
|
|
247
|
+
- `addListener(listener)` - Add change listener
|
|
248
|
+
- `removeListener(listener)` - Remove change listener
|
|
249
|
+
- `createProxy(context)` - Create reactive context proxy
|
|
250
|
+
|
|
251
|
+
### Currency Utilities
|
|
252
|
+
- `getCurrencyFormat(locale, currencyCode)` - Get currency formatting info
|
|
253
|
+
|
|
254
|
+
### Type Utilities
|
|
255
|
+
- `createTranslations(translations)` - Helper for creating typed translations
|
|
256
|
+
|
|
257
|
+
## Type Definitions
|
|
258
|
+
|
|
259
|
+
### Core Types
|
|
260
|
+
```typescript
|
|
261
|
+
type EnumTranslation<T extends string | number> = {
|
|
262
|
+
[K in T]: string;
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
type EnumLanguageTranslation<T extends string | number, TLanguage extends string> = Partial<{
|
|
266
|
+
[L in TLanguage]: EnumTranslation<T>;
|
|
267
|
+
}>;
|
|
268
|
+
|
|
269
|
+
interface I18nConfig<TStringKey, TLanguage, TConstants?, TContext?> {
|
|
270
|
+
stringNames: TStringKey[];
|
|
271
|
+
strings: MasterStringsCollection<TStringKey, TLanguage>;
|
|
272
|
+
defaultLanguage: TLanguage;
|
|
273
|
+
defaultContext: TContext;
|
|
274
|
+
languageCodes: LanguageCodeCollection<TLanguage>;
|
|
275
|
+
languages: TLanguage[];
|
|
276
|
+
constants?: TConstants;
|
|
277
|
+
enumName?: string;
|
|
278
|
+
enumObj?: Record<string, TStringKey>;
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## Testing
|
|
283
|
+
|
|
284
|
+
The library includes comprehensive test coverage:
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Run tests
|
|
288
|
+
yarn test
|
|
289
|
+
|
|
290
|
+
# Run specific test suites
|
|
291
|
+
yarn test context-manager.spec.ts
|
|
292
|
+
yarn test enum-registry.spec.ts
|
|
293
|
+
yarn test i18n-engine.spec.ts
|
|
294
|
+
```
|
|
105
295
|
|
|
106
|
-
|
|
296
|
+
## Best Practices
|
|
107
297
|
|
|
108
|
-
|
|
298
|
+
1. **Complete Translations**: EnumTranslation requires all enum values to be translated
|
|
299
|
+
2. **Type Safety**: Use TypeScript enums for string keys and languages
|
|
300
|
+
3. **Context Separation**: Use different contexts for admin and user interfaces
|
|
301
|
+
4. **Instance Management**: Use named instances for different parts of your application
|
|
302
|
+
5. **Error Handling**: Handle missing translations gracefully with fallback languages
|
|
109
303
|
|
|
110
304
|
## License
|
|
111
305
|
|
|
@@ -113,4 +307,4 @@ MIT
|
|
|
113
307
|
|
|
114
308
|
## Repository
|
|
115
309
|
|
|
116
|
-
|
|
310
|
+
Part of the DigitalBurnbag project - a secure file sharing and automated protocol system.
|
package/dist/context.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { Timezone } from './timezone';
|
|
1
2
|
import { I18nContext, LanguageContext } from './types';
|
|
2
|
-
export declare function createContext<TLanguage extends string>(defaultLanguage: TLanguage): I18nContext<TLanguage>;
|
|
3
|
-
export declare function setLanguage<TLanguage extends string>(context: I18nContext<TLanguage>, language: TLanguage): void;
|
|
4
|
-
export declare function setAdminLanguage<TLanguage extends string>(context: I18nContext<TLanguage>, language: TLanguage): void;
|
|
5
|
-
export declare function setContext<TLanguage extends string>(context: I18nContext<TLanguage>, languageContext:
|
|
3
|
+
export declare function createContext<TLanguage extends string, TContext extends string = LanguageContext>(defaultLanguage: TLanguage, defaultContext: TContext, defaultTimezone?: Timezone, defaultAdminTimezone?: Timezone): I18nContext<TLanguage, TContext>;
|
|
4
|
+
export declare function setLanguage<TLanguage extends string, TContext extends string = LanguageContext>(context: I18nContext<TLanguage, TContext>, language: TLanguage): void;
|
|
5
|
+
export declare function setAdminLanguage<TLanguage extends string, TContext extends string = LanguageContext>(context: I18nContext<TLanguage, TContext>, language: TLanguage): void;
|
|
6
|
+
export declare function setContext<TLanguage extends string, TContext extends string = LanguageContext>(context: I18nContext<TLanguage, TContext>, languageContext: TContext): void;
|
package/dist/context.js
CHANGED
|
@@ -4,11 +4,14 @@ exports.createContext = createContext;
|
|
|
4
4
|
exports.setLanguage = setLanguage;
|
|
5
5
|
exports.setAdminLanguage = setAdminLanguage;
|
|
6
6
|
exports.setContext = setContext;
|
|
7
|
-
|
|
7
|
+
const timezone_1 = require("./timezone");
|
|
8
|
+
function createContext(defaultLanguage, defaultContext, defaultTimezone = new timezone_1.Timezone('UTC'), defaultAdminTimezone = new timezone_1.Timezone('UTC')) {
|
|
8
9
|
return {
|
|
9
10
|
language: defaultLanguage,
|
|
10
11
|
adminLanguage: defaultLanguage,
|
|
11
|
-
currentContext:
|
|
12
|
+
currentContext: defaultContext,
|
|
13
|
+
timezone: defaultTimezone,
|
|
14
|
+
adminTimezone: defaultAdminTimezone,
|
|
12
15
|
};
|
|
13
16
|
}
|
|
14
17
|
function setLanguage(context, language) {
|
package/dist/i18n-engine.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export declare class I18nEngine<TStringKey extends string, TLanguage extends str
|
|
|
8
8
|
/**
|
|
9
9
|
* Configuration for the i18n engine
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
readonly config: I18nConfig<TStringKey, TLanguage, TConstants, TContext>;
|
|
12
12
|
/**
|
|
13
13
|
* Static instances for semi-singleton pattern
|
|
14
14
|
*/
|
|
@@ -32,11 +32,10 @@ export declare class I18nEngine<TStringKey extends string, TLanguage extends str
|
|
|
32
32
|
/**
|
|
33
33
|
* Creates a new I18nEngine instance
|
|
34
34
|
* @param config The i18n configuration
|
|
35
|
-
* @param defaultContext The default context for translations
|
|
36
35
|
* @param key Optional instance key for the semi-singleton pattern
|
|
37
36
|
* @throws Error if an instance with the same key already exists
|
|
38
37
|
*/
|
|
39
|
-
constructor(config: I18nConfig<TStringKey, TLanguage, TConstants
|
|
38
|
+
constructor(config: I18nConfig<TStringKey, TLanguage, TConstants, TContext>, key?: string);
|
|
40
39
|
/**
|
|
41
40
|
* Gets an instance of the I18nEngine by key. If no key is provided, the default instance is returned.
|
|
42
41
|
* @param key The key of the instance to retrieve
|
|
@@ -129,4 +128,26 @@ export declare class I18nEngine<TStringKey extends string, TLanguage extends str
|
|
|
129
128
|
* @returns A record of all language codes
|
|
130
129
|
*/
|
|
131
130
|
getAllLanguageCodes(): Record<TLanguage, string>;
|
|
131
|
+
/**
|
|
132
|
+
* Gets all available languages.
|
|
133
|
+
* @returns An array of all available languages
|
|
134
|
+
*/
|
|
135
|
+
getAvailableLanguages(): TLanguage[];
|
|
136
|
+
/**
|
|
137
|
+
* Checks if a language is available.
|
|
138
|
+
* @param language The language to check
|
|
139
|
+
* @returns True if the language is available, false otherwise
|
|
140
|
+
*/
|
|
141
|
+
isLanguageAvailable(language: string): language is TLanguage;
|
|
142
|
+
/**
|
|
143
|
+
* Clears all instances (for testing purposes)
|
|
144
|
+
* @internal
|
|
145
|
+
*/
|
|
146
|
+
static clearInstances(): void;
|
|
147
|
+
/**
|
|
148
|
+
* Removes a specific instance by key
|
|
149
|
+
* @param key The key of the instance to remove
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
static removeInstance(key?: string): void;
|
|
132
153
|
}
|
package/dist/i18n-engine.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.I18nEngine = void 0;
|
|
4
|
+
const context_1 = require("./context");
|
|
4
5
|
const enum_registry_1 = require("./enum-registry");
|
|
5
6
|
const template_1 = require("./template");
|
|
6
7
|
const utils_1 = require("./utils");
|
|
@@ -8,18 +9,13 @@ class I18nEngine {
|
|
|
8
9
|
/**
|
|
9
10
|
* Creates a new I18nEngine instance
|
|
10
11
|
* @param config The i18n configuration
|
|
11
|
-
* @param defaultContext The default context for translations
|
|
12
12
|
* @param key Optional instance key for the semi-singleton pattern
|
|
13
13
|
* @throws Error if an instance with the same key already exists
|
|
14
14
|
*/
|
|
15
|
-
constructor(config,
|
|
15
|
+
constructor(config, key) {
|
|
16
16
|
this.config = config;
|
|
17
17
|
this.enumRegistry = new enum_registry_1.EnumTranslationRegistry();
|
|
18
|
-
this._context =
|
|
19
|
-
language: config.defaultLanguage,
|
|
20
|
-
adminLanguage: config.defaultLanguage,
|
|
21
|
-
currentContext: defaultContext,
|
|
22
|
-
};
|
|
18
|
+
this._context = (0, context_1.createContext)(config.defaultLanguage, config.defaultContext, config.timezone, config.adminTimezone);
|
|
23
19
|
const instanceKey = key || I18nEngine.DefaultInstanceKey;
|
|
24
20
|
if (I18nEngine._instances.has(instanceKey)) {
|
|
25
21
|
const existing = I18nEngine._instances.get(instanceKey);
|
|
@@ -215,6 +211,42 @@ class I18nEngine {
|
|
|
215
211
|
getAllLanguageCodes() {
|
|
216
212
|
return this.config.languageCodes;
|
|
217
213
|
}
|
|
214
|
+
/**
|
|
215
|
+
* Gets all available languages.
|
|
216
|
+
* @returns An array of all available languages
|
|
217
|
+
*/
|
|
218
|
+
getAvailableLanguages() {
|
|
219
|
+
return Object.keys(this.config.strings);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Checks if a language is available.
|
|
223
|
+
* @param language The language to check
|
|
224
|
+
* @returns True if the language is available, false otherwise
|
|
225
|
+
*/
|
|
226
|
+
isLanguageAvailable(language) {
|
|
227
|
+
return Object.keys(this.config.strings).includes(language);
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Clears all instances (for testing purposes)
|
|
231
|
+
* @internal
|
|
232
|
+
*/
|
|
233
|
+
static clearInstances() {
|
|
234
|
+
I18nEngine._instances.clear();
|
|
235
|
+
I18nEngine._defaultKey = null;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Removes a specific instance by key
|
|
239
|
+
* @param key The key of the instance to remove
|
|
240
|
+
* @internal
|
|
241
|
+
*/
|
|
242
|
+
static removeInstance(key) {
|
|
243
|
+
const instanceKey = key || I18nEngine.DefaultInstanceKey;
|
|
244
|
+
I18nEngine._instances.delete(instanceKey);
|
|
245
|
+
if (I18nEngine._defaultKey === instanceKey) {
|
|
246
|
+
const nextKey = I18nEngine._instances.keys().next().value;
|
|
247
|
+
I18nEngine._defaultKey = I18nEngine._instances.size > 0 && nextKey ? nextKey : null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
218
250
|
}
|
|
219
251
|
exports.I18nEngine = I18nEngine;
|
|
220
252
|
/**
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -21,6 +21,7 @@ __exportStar(require("./currency"), exports);
|
|
|
21
21
|
__exportStar(require("./enum-registry"), exports);
|
|
22
22
|
__exportStar(require("./i18n-engine"), exports);
|
|
23
23
|
__exportStar(require("./template"), exports);
|
|
24
|
+
__exportStar(require("./timezone"), exports);
|
|
24
25
|
__exportStar(require("./types"), exports);
|
|
25
26
|
__exportStar(require("./utils"), exports);
|
|
26
27
|
// Re-export for convenience
|
package/dist/timezone.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Timezone = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
class Timezone {
|
|
6
|
+
constructor(timezone) {
|
|
7
|
+
if (!(0, utils_1.isValidTimezone)(timezone)) {
|
|
8
|
+
throw new Error(`Invalid timezone: ${timezone}`);
|
|
9
|
+
}
|
|
10
|
+
this._timezone = timezone;
|
|
11
|
+
}
|
|
12
|
+
get value() {
|
|
13
|
+
return this._timezone;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
exports.Timezone = Timezone;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,21 +1,29 @@
|
|
|
1
|
+
import { Timezone } from './timezone';
|
|
1
2
|
export type LanguageContext = 'admin' | 'user';
|
|
2
3
|
export type CustomLanguageContext<T extends string = LanguageContext> = T;
|
|
3
4
|
export type StringsCollection<TStringKey extends string> = Partial<Record<TStringKey, string>>;
|
|
4
5
|
export type MasterStringsCollection<TStringKey extends string, TLanguage extends string> = Partial<Record<TLanguage, StringsCollection<TStringKey>>>;
|
|
5
6
|
export type LanguageCodeCollection<TLanguage extends string> = Partial<Record<TLanguage, string>>;
|
|
6
7
|
export type EnumTranslationMap<TEnum extends string | number, TLanguage extends string> = Partial<Record<TLanguage, Partial<Record<TEnum, string>>>>;
|
|
7
|
-
export interface I18nConfig<TStringKey extends string, TLanguage extends string, TConstants extends Record<string, any> = Record<string, any
|
|
8
|
+
export interface I18nConfig<TStringKey extends string, TLanguage extends string, TConstants extends Record<string, any> = Record<string, any>, TContext extends string = LanguageContext> {
|
|
9
|
+
stringNames: TStringKey[];
|
|
8
10
|
strings: MasterStringsCollection<TStringKey, TLanguage>;
|
|
9
11
|
defaultLanguage: TLanguage;
|
|
12
|
+
defaultContext: TContext;
|
|
10
13
|
languageCodes: LanguageCodeCollection<TLanguage>;
|
|
14
|
+
languages: TLanguage[];
|
|
11
15
|
constants?: TConstants;
|
|
12
16
|
enumName?: string;
|
|
13
17
|
enumObj?: Record<string, TStringKey>;
|
|
18
|
+
timezone: Timezone;
|
|
19
|
+
adminTimezone: Timezone;
|
|
14
20
|
}
|
|
15
21
|
export interface I18nContext<TLanguage extends string, TContext extends string = LanguageContext> {
|
|
16
22
|
language: TLanguage;
|
|
17
23
|
adminLanguage: TLanguage;
|
|
18
24
|
currentContext: TContext;
|
|
25
|
+
timezone: Timezone;
|
|
26
|
+
adminTimezone: Timezone;
|
|
19
27
|
}
|
|
20
28
|
/**
|
|
21
29
|
* Generic translation type for any enumeration
|
|
@@ -26,9 +34,9 @@ export type EnumTranslation<T extends string | number> = {
|
|
|
26
34
|
/**
|
|
27
35
|
* Generic language translation type for any enumeration
|
|
28
36
|
*/
|
|
29
|
-
export type EnumLanguageTranslation<T extends string | number, TLanguage extends string = string> = {
|
|
37
|
+
export type EnumLanguageTranslation<T extends string | number, TLanguage extends string = string> = Partial<{
|
|
30
38
|
[L in TLanguage]: EnumTranslation<T>;
|
|
31
|
-
}
|
|
39
|
+
}>;
|
|
32
40
|
/**
|
|
33
41
|
* Helper function to create typed translations for an enumeration
|
|
34
42
|
*/
|
package/dist/utils.d.ts
CHANGED
package/dist/utils.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.replaceVariables = replaceVariables;
|
|
4
7
|
exports.isTemplate = isTemplate;
|
|
8
|
+
exports.isValidTimezone = isValidTimezone;
|
|
9
|
+
const moment_timezone_1 = __importDefault(require("moment-timezone"));
|
|
5
10
|
function replaceVariables(str, vars, constants) {
|
|
6
11
|
const variables = str.match(/\{(.+?)\}/g);
|
|
7
12
|
if (!variables)
|
|
@@ -25,3 +30,6 @@ function replaceVariables(str, vars, constants) {
|
|
|
25
30
|
function isTemplate(key) {
|
|
26
31
|
return key.toLowerCase().endsWith('template');
|
|
27
32
|
}
|
|
33
|
+
function isValidTimezone(timezone) {
|
|
34
|
+
return moment_timezone_1.default.tz.zone(timezone) !== null;
|
|
35
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitaldefiance/i18n-lib",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.16",
|
|
4
4
|
"description": "Generic i18n library with enum translation support",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"@typescript-eslint/parser": "^8.31.1",
|
|
22
22
|
"eslint": "^9.8.0",
|
|
23
23
|
"eslint-config-prettier": "^10.1.2",
|
|
24
|
+
"eslint-plugin-import": "^2.32.0",
|
|
24
25
|
"eslint-plugin-prettier": "^5.3.1",
|
|
25
26
|
"jest": "^29.0.0",
|
|
26
27
|
"jest-util": "^30.0.5",
|
|
@@ -42,5 +43,9 @@
|
|
|
42
43
|
],
|
|
43
44
|
"author": "Digital Defiance",
|
|
44
45
|
"license": "MIT",
|
|
45
|
-
"packageManager": "yarn@4.10.3"
|
|
46
|
+
"packageManager": "yarn@4.10.3",
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"moment": "^2.30.1",
|
|
49
|
+
"moment-timezone": "^0.6.0"
|
|
50
|
+
}
|
|
46
51
|
}
|