@digitaldefiance/i18n-lib 1.3.13 → 1.3.14
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 +4 -0
- package/package.json +4 -3
- package/src/active-context.d.ts +30 -0
- package/src/active-context.d.ts.map +1 -0
- package/src/active-context.js +3 -0
- package/src/active-context.js.map +1 -0
- package/src/component-definition.d.ts +12 -0
- package/src/component-definition.d.ts.map +1 -0
- package/src/component-definition.js +3 -0
- package/src/component-definition.js.map +1 -0
- package/src/component-registration.d.ts +10 -0
- package/src/component-registration.d.ts.map +1 -0
- package/src/component-registration.js +3 -0
- package/src/component-registration.js.map +1 -0
- package/src/component-registry.d.ts +69 -0
- package/src/component-registry.d.ts.map +1 -0
- package/src/component-registry.js +248 -0
- package/src/component-registry.js.map +1 -0
- package/src/context-error-type.d.ts +4 -0
- package/src/context-error-type.d.ts.map +1 -0
- package/src/context-error-type.js +8 -0
- package/src/context-error-type.js.map +1 -0
- package/src/context-error.d.ts +7 -0
- package/src/context-error.d.ts.map +1 -0
- package/src/context-error.js +18 -0
- package/src/context-error.js.map +1 -0
- package/src/context-manager.d.ts +34 -0
- package/src/context-manager.d.ts.map +1 -0
- package/src/context-manager.js +60 -0
- package/src/context-manager.js.map +1 -0
- package/src/context.d.ts +45 -0
- package/src/context.d.ts.map +1 -0
- package/src/context.js +70 -0
- package/src/context.js.map +1 -0
- package/src/core-i18n.d.ts +63 -0
- package/src/core-i18n.d.ts.map +1 -0
- package/src/core-i18n.js +478 -0
- package/src/core-i18n.js.map +1 -0
- package/src/core-string-key.d.ts +43 -0
- package/src/core-string-key.d.ts.map +1 -0
- package/src/core-string-key.js +51 -0
- package/src/core-string-key.js.map +1 -0
- package/src/create-translation-adapter.d.ts +21 -0
- package/src/create-translation-adapter.d.ts.map +1 -0
- package/src/create-translation-adapter.js +37 -0
- package/src/create-translation-adapter.js.map +1 -0
- package/src/currency-code.d.ts +20 -0
- package/src/currency-code.d.ts.map +1 -0
- package/src/currency-code.js +37 -0
- package/src/currency-code.js.map +1 -0
- package/src/{currency-format.ts → currency-format.d.ts} +5 -5
- package/src/currency-format.d.ts.map +1 -0
- package/src/currency-format.js +3 -0
- package/src/currency-format.js.map +1 -0
- package/src/currency.d.ts +12 -0
- package/src/currency.d.ts.map +1 -0
- package/src/currency.js +49 -0
- package/src/currency.js.map +1 -0
- package/src/default-config.d.ts +33 -0
- package/src/default-config.d.ts.map +1 -0
- package/src/default-config.js +102 -0
- package/src/default-config.js.map +1 -0
- package/src/enum-registry.d.ts +45 -0
- package/src/enum-registry.d.ts.map +1 -0
- package/src/enum-registry.js +103 -0
- package/src/enum-registry.js.map +1 -0
- package/src/global-active-context.d.ts +51 -0
- package/src/global-active-context.d.ts.map +1 -0
- package/src/global-active-context.js +179 -0
- package/src/global-active-context.js.map +1 -0
- package/src/handleable.d.ts +14 -0
- package/src/handleable.d.ts.map +1 -0
- package/src/handleable.js +66 -0
- package/src/handleable.js.map +1 -0
- package/src/i-global-active-context.d.ts +23 -0
- package/src/i-global-active-context.d.ts.map +1 -0
- package/src/i-global-active-context.js +3 -0
- package/src/i-global-active-context.js.map +1 -0
- package/src/i-handleable-error-options.d.ts +7 -0
- package/src/i-handleable-error-options.d.ts.map +1 -0
- package/src/i-handleable-error-options.js +3 -0
- package/src/i-handleable-error-options.js.map +1 -0
- package/src/i-handleable.d.ts +6 -0
- package/src/i-handleable.d.ts.map +1 -0
- package/src/i-handleable.js +3 -0
- package/src/i-handleable.js.map +1 -0
- package/src/i18n-config.d.ts +21 -0
- package/src/i18n-config.d.ts.map +1 -0
- package/src/i18n-config.js +3 -0
- package/src/i18n-config.js.map +1 -0
- package/src/{i18n-context.ts → i18n-context.d.ts} +7 -7
- package/src/i18n-context.d.ts.map +1 -0
- package/src/i18n-context.js +3 -0
- package/src/i18n-context.js.map +1 -0
- package/src/i18n-engine.d.ts +179 -0
- package/src/i18n-engine.d.ts.map +1 -0
- package/src/i18n-engine.js +355 -0
- package/src/i18n-engine.js.map +1 -0
- package/src/{index.ts → index.d.ts} +2 -10
- package/src/index.d.ts.map +1 -0
- package/src/index.js +71 -0
- package/src/index.js.map +1 -0
- package/src/{language-codes.ts → language-codes.d.ts} +12 -23
- package/src/language-codes.d.ts.map +1 -0
- package/src/language-codes.js +32 -0
- package/src/language-codes.js.map +1 -0
- package/src/language-definition.d.ts +14 -0
- package/src/language-definition.d.ts.map +1 -0
- package/src/language-definition.js +3 -0
- package/src/language-definition.js.map +1 -0
- package/src/language-registry.d.ts +114 -0
- package/src/language-registry.d.ts.map +1 -0
- package/src/language-registry.js +217 -0
- package/src/language-registry.js.map +1 -0
- package/src/plugin-i18n-engine.d.ts +147 -0
- package/src/plugin-i18n-engine.d.ts.map +1 -0
- package/src/plugin-i18n-engine.js +369 -0
- package/src/plugin-i18n-engine.js.map +1 -0
- package/src/plugin-translatable-generic-error.d.ts +30 -0
- package/src/plugin-translatable-generic-error.d.ts.map +1 -0
- package/src/plugin-translatable-generic-error.js +72 -0
- package/src/plugin-translatable-generic-error.js.map +1 -0
- package/src/plugin-translatable-handleable-generic.d.ts +29 -0
- package/src/plugin-translatable-handleable-generic.d.ts.map +1 -0
- package/src/plugin-translatable-handleable-generic.js +44 -0
- package/src/plugin-translatable-handleable-generic.js.map +1 -0
- package/src/plugin-typed-handleable.d.ts +15 -0
- package/src/plugin-typed-handleable.d.ts.map +1 -0
- package/src/plugin-typed-handleable.js +51 -0
- package/src/plugin-typed-handleable.js.map +1 -0
- package/src/registry-config.d.ts +15 -0
- package/src/registry-config.d.ts.map +1 -0
- package/src/registry-config.js +3 -0
- package/src/registry-config.js.map +1 -0
- package/src/registry-error-type.d.ts +13 -0
- package/src/registry-error-type.d.ts.map +1 -0
- package/src/registry-error-type.js +17 -0
- package/src/registry-error-type.js.map +1 -0
- package/src/registry-error.d.ts +19 -0
- package/src/registry-error.d.ts.map +1 -0
- package/src/registry-error.js +48 -0
- package/src/registry-error.js.map +1 -0
- package/src/strict-types.d.ts +19 -0
- package/src/strict-types.d.ts.map +1 -0
- package/src/strict-types.js +18 -0
- package/src/strict-types.js.map +1 -0
- package/src/template.d.ts +13 -0
- package/src/template.d.ts.map +1 -0
- package/src/template.js +31 -0
- package/src/template.js.map +1 -0
- package/src/timezone.d.ts +12 -0
- package/src/timezone.d.ts.map +1 -0
- package/src/timezone.js +24 -0
- package/src/timezone.js.map +1 -0
- package/src/translatable.d.ts +6 -0
- package/src/translatable.d.ts.map +1 -0
- package/src/translatable.js +12 -0
- package/src/translatable.js.map +1 -0
- package/src/translation-engine.d.ts +9 -0
- package/src/translation-engine.d.ts.map +1 -0
- package/src/translation-engine.js +3 -0
- package/src/translation-engine.js.map +1 -0
- package/src/translation-request.d.ts +10 -0
- package/src/translation-request.d.ts.map +1 -0
- package/src/translation-request.js +3 -0
- package/src/translation-request.js.map +1 -0
- package/src/translation-response.d.ts +9 -0
- package/src/translation-response.d.ts.map +1 -0
- package/src/translation-response.js +3 -0
- package/src/translation-response.js.map +1 -0
- package/src/typed-error.d.ts +73 -0
- package/src/typed-error.d.ts.map +1 -0
- package/src/typed-error.js +267 -0
- package/src/typed-error.js.map +1 -0
- package/src/typed-handleable.d.ts +15 -0
- package/src/typed-handleable.d.ts.map +1 -0
- package/src/typed-handleable.js +46 -0
- package/src/typed-handleable.js.map +1 -0
- package/src/{types.ts → types.d.ts} +21 -75
- package/src/types.d.ts.map +1 -0
- package/src/types.js +19 -0
- package/src/types.js.map +1 -0
- package/src/unified-translator.d.ts +31 -0
- package/src/unified-translator.d.ts.map +1 -0
- package/src/unified-translator.js +71 -0
- package/src/unified-translator.js.map +1 -0
- package/src/utils.d.ts +65 -0
- package/src/utils.d.ts.map +1 -0
- package/src/utils.js +129 -0
- package/src/utils.js.map +1 -0
- package/src/validation-config.d.ts +12 -0
- package/src/validation-config.d.ts.map +1 -0
- package/src/validation-config.js +3 -0
- package/src/validation-config.js.map +1 -0
- package/src/validation-result.d.ts +13 -0
- package/src/validation-result.d.ts.map +1 -0
- package/src/validation-result.js +3 -0
- package/src/validation-result.js.map +1 -0
- package/LICENSE +0 -21
- package/src/active-context.ts +0 -30
- package/src/component-definition.ts +0 -11
- package/src/component-registration.ts +0 -13
- package/src/component-registry.ts +0 -392
- package/src/context-error-type.ts +0 -3
- package/src/context-error.ts +0 -16
- package/src/context-manager.ts +0 -71
- package/src/context.ts +0 -90
- package/src/core-i18n.ts +0 -609
- package/src/core-string-key.ts +0 -49
- package/src/create-translation-adapter.ts +0 -47
- package/src/currency-code.ts +0 -35
- package/src/currency.ts +0 -52
- package/src/default-config.ts +0 -199
- package/src/enum-registry.ts +0 -138
- package/src/global-active-context.ts +0 -255
- package/src/handleable.ts +0 -79
- package/src/i-global-active-context.ts +0 -59
- package/src/i-handleable-error-options.ts +0 -6
- package/src/i-handleable.ts +0 -5
- package/src/i18n-config.ts +0 -29
- package/src/i18n-engine.ts +0 -491
- package/src/language-definition.ts +0 -13
- package/src/language-registry.ts +0 -292
- package/src/plugin-i18n-engine.ts +0 -520
- package/src/plugin-translatable-generic-error.ts +0 -106
- package/src/plugin-translatable-handleable-generic.ts +0 -60
- package/src/plugin-typed-handleable.ts +0 -77
- package/src/registry-config.ts +0 -15
- package/src/registry-error-type.ts +0 -12
- package/src/registry-error.ts +0 -74
- package/src/strict-types.ts +0 -35
- package/src/template.ts +0 -63
- package/src/timezone.ts +0 -20
- package/src/translatable.ts +0 -15
- package/src/translation-engine.ts +0 -8
- package/src/translation-request.ts +0 -12
- package/src/translation-response.ts +0 -8
- package/src/typed-error.ts +0 -384
- package/src/typed-handleable.ts +0 -70
- package/src/unified-translator.ts +0 -96
- package/src/utils.ts +0 -213
- package/src/validation-config.ts +0 -11
- package/src/validation-result.ts +0 -12
|
@@ -1,392 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Component registry for managing internationalization components and their string translations
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { ComponentDefinition } from './component-definition';
|
|
6
|
-
import { ComponentRegistration } from './component-registration';
|
|
7
|
-
import { RegistryError } from './registry-error';
|
|
8
|
-
import { RegistryErrorType } from './registry-error-type';
|
|
9
|
-
import { TranslationRequest } from './translation-request';
|
|
10
|
-
import { TranslationResponse } from './translation-response';
|
|
11
|
-
import {
|
|
12
|
-
ComponentLanguageStrings,
|
|
13
|
-
ComponentStrings,
|
|
14
|
-
PartialComponentLanguageStrings,
|
|
15
|
-
PartialComponentStrings,
|
|
16
|
-
} from './types';
|
|
17
|
-
import { isTemplate, replaceVariables } from './utils';
|
|
18
|
-
import { ValidationConfig } from './validation-config';
|
|
19
|
-
import { ValidationResult } from './validation-result';
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Registry for managing components and their translations
|
|
23
|
-
*/
|
|
24
|
-
export class ComponentRegistry<TLanguages extends string> {
|
|
25
|
-
private readonly components = new Map<string, ComponentDefinition<any>>();
|
|
26
|
-
private readonly componentStrings = new Map<
|
|
27
|
-
string,
|
|
28
|
-
ComponentLanguageStrings<any, TLanguages>
|
|
29
|
-
>();
|
|
30
|
-
private readonly validationConfig: ValidationConfig;
|
|
31
|
-
private readonly registeredLanguages: Set<TLanguages>;
|
|
32
|
-
|
|
33
|
-
constructor(
|
|
34
|
-
languages: readonly TLanguages[],
|
|
35
|
-
validationConfig: ValidationConfig,
|
|
36
|
-
) {
|
|
37
|
-
this.registeredLanguages = new Set(languages);
|
|
38
|
-
this.validationConfig = validationConfig;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Update the set of registered languages (for dynamic language addition)
|
|
43
|
-
*/
|
|
44
|
-
public updateRegisteredLanguages(languages: readonly TLanguages[]): void {
|
|
45
|
-
this.registeredLanguages.clear();
|
|
46
|
-
languages.forEach((lang) => this.registeredLanguages.add(lang));
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Register a new component with its translations
|
|
51
|
-
*/
|
|
52
|
-
public registerComponent<TStringKeys extends string>(
|
|
53
|
-
registration: ComponentRegistration<TStringKeys, TLanguages>,
|
|
54
|
-
): ValidationResult {
|
|
55
|
-
const { component, strings } = registration;
|
|
56
|
-
|
|
57
|
-
// Check for duplicate component
|
|
58
|
-
if (this.components.has(component.id)) {
|
|
59
|
-
throw RegistryError.createSimple(
|
|
60
|
-
RegistryErrorType.DuplicateComponent,
|
|
61
|
-
`Component '${component.id}' is already registered`,
|
|
62
|
-
{ componentId: component.id },
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Validate the registration
|
|
67
|
-
const validationResult = this.validateComponentRegistration(registration);
|
|
68
|
-
|
|
69
|
-
if (
|
|
70
|
-
!validationResult.isValid &&
|
|
71
|
-
!this.validationConfig.allowPartialRegistration
|
|
72
|
-
) {
|
|
73
|
-
throw RegistryError.createSimple(
|
|
74
|
-
RegistryErrorType.ValidationFailed,
|
|
75
|
-
`Component registration validation failed: ${validationResult.errors.join(
|
|
76
|
-
', ',
|
|
77
|
-
)}`,
|
|
78
|
-
{
|
|
79
|
-
componentId: component.id,
|
|
80
|
-
missingKeys: validationResult.missingKeys,
|
|
81
|
-
errors: validationResult.errors,
|
|
82
|
-
},
|
|
83
|
-
);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// Complete missing strings with fallbacks if partial registration is allowed
|
|
87
|
-
const completeStrings = this.completeStringsWithFallbacks(
|
|
88
|
-
component,
|
|
89
|
-
strings,
|
|
90
|
-
);
|
|
91
|
-
|
|
92
|
-
// Register the component
|
|
93
|
-
this.components.set(component.id, component);
|
|
94
|
-
this.componentStrings.set(component.id, completeStrings);
|
|
95
|
-
|
|
96
|
-
return validationResult;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Update strings for an existing component
|
|
101
|
-
*/
|
|
102
|
-
public updateComponentStrings<TStringKeys extends string>(
|
|
103
|
-
componentId: string,
|
|
104
|
-
strings: PartialComponentLanguageStrings<TStringKeys, TLanguages>,
|
|
105
|
-
): ValidationResult {
|
|
106
|
-
const component = this.components.get(componentId);
|
|
107
|
-
if (!component) {
|
|
108
|
-
throw RegistryError.createSimple(
|
|
109
|
-
RegistryErrorType.ComponentNotFound,
|
|
110
|
-
`Component with ID '${componentId}' not found`,
|
|
111
|
-
{ componentId },
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const registration: ComponentRegistration<TStringKeys, TLanguages> = {
|
|
116
|
-
component: component as ComponentDefinition<TStringKeys>,
|
|
117
|
-
strings,
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
const validationResult = this.validateComponentRegistration(registration);
|
|
121
|
-
|
|
122
|
-
if (
|
|
123
|
-
validationResult.isValid ||
|
|
124
|
-
this.validationConfig.allowPartialRegistration
|
|
125
|
-
) {
|
|
126
|
-
const existingStrings =
|
|
127
|
-
this.componentStrings.get(componentId) ||
|
|
128
|
-
({} as ComponentLanguageStrings<TStringKeys, TLanguages>);
|
|
129
|
-
const updatedStrings = this.mergeStrings(existingStrings, strings);
|
|
130
|
-
const completeStrings = this.completeStringsWithFallbacks(
|
|
131
|
-
component,
|
|
132
|
-
updatedStrings,
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
this.componentStrings.set(componentId, completeStrings);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
return validationResult;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Get a translation for a specific component, string key, and language
|
|
143
|
-
*/
|
|
144
|
-
public getTranslation<TStringKeys extends string>(
|
|
145
|
-
request: TranslationRequest<TStringKeys, TLanguages>,
|
|
146
|
-
): TranslationResponse {
|
|
147
|
-
const { componentId, stringKey, language, variables } = request;
|
|
148
|
-
|
|
149
|
-
// Check if component exists
|
|
150
|
-
if (!this.components.has(componentId)) {
|
|
151
|
-
throw RegistryError.createSimple(
|
|
152
|
-
RegistryErrorType.ComponentNotFound,
|
|
153
|
-
`Component '${componentId}' not found`,
|
|
154
|
-
{ componentId },
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
const componentStrings = this.componentStrings.get(componentId);
|
|
159
|
-
if (!componentStrings) {
|
|
160
|
-
throw RegistryError.createSimple(
|
|
161
|
-
RegistryErrorType.StringKeyNotFound,
|
|
162
|
-
`No strings registered for component '${componentId}'`,
|
|
163
|
-
{ componentId },
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const targetLanguage =
|
|
168
|
-
language || (this.validationConfig.fallbackLanguageId as TLanguages);
|
|
169
|
-
let actualLanguage = targetLanguage;
|
|
170
|
-
let wasFallback = false;
|
|
171
|
-
|
|
172
|
-
// Try to get the string in the requested language
|
|
173
|
-
let languageStrings = componentStrings[targetLanguage];
|
|
174
|
-
|
|
175
|
-
// If not found and different from fallback, try fallback language
|
|
176
|
-
if (
|
|
177
|
-
!languageStrings &&
|
|
178
|
-
targetLanguage !== this.validationConfig.fallbackLanguageId
|
|
179
|
-
) {
|
|
180
|
-
languageStrings =
|
|
181
|
-
componentStrings[
|
|
182
|
-
this.validationConfig.fallbackLanguageId as TLanguages
|
|
183
|
-
];
|
|
184
|
-
actualLanguage = this.validationConfig.fallbackLanguageId as TLanguages;
|
|
185
|
-
wasFallback = true;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (!languageStrings) {
|
|
189
|
-
throw RegistryError.createSimple(
|
|
190
|
-
RegistryErrorType.LanguageNotFound,
|
|
191
|
-
`No strings found for language '${targetLanguage}' in component '${componentId}'`,
|
|
192
|
-
{ componentId, language: targetLanguage },
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
const translation = languageStrings[stringKey];
|
|
197
|
-
if (!translation) {
|
|
198
|
-
throw RegistryError.createSimple(
|
|
199
|
-
RegistryErrorType.StringKeyNotFound,
|
|
200
|
-
`String key '${stringKey}' not found for component '${componentId}' in language '${actualLanguage}'`,
|
|
201
|
-
{ componentId, stringKey, language: actualLanguage },
|
|
202
|
-
);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Process variables if the string key indicates it's a template
|
|
206
|
-
let processedTranslation: string = translation;
|
|
207
|
-
if (variables && isTemplate(stringKey)) {
|
|
208
|
-
processedTranslation = replaceVariables(translation, variables);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
return {
|
|
212
|
-
translation: processedTranslation,
|
|
213
|
-
actualLanguage,
|
|
214
|
-
wasFallback,
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Get all registered components
|
|
220
|
-
*/
|
|
221
|
-
public getComponents(): ReadonlyArray<ComponentDefinition<any>> {
|
|
222
|
-
return Array.from(this.components.values());
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* Get a specific component by ID
|
|
227
|
-
*/
|
|
228
|
-
public getComponent<TStringKeys extends string>(
|
|
229
|
-
componentId: string,
|
|
230
|
-
): ComponentDefinition<TStringKeys> | undefined {
|
|
231
|
-
return this.components.get(componentId) as
|
|
232
|
-
| ComponentDefinition<TStringKeys>
|
|
233
|
-
| undefined;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Check if a component is registered
|
|
238
|
-
*/
|
|
239
|
-
public hasComponent(componentId: string): boolean {
|
|
240
|
-
return this.components.has(componentId);
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/**
|
|
244
|
-
* Get all strings for a component in all languages
|
|
245
|
-
*/
|
|
246
|
-
public getComponentStrings<TStringKeys extends string>(
|
|
247
|
-
componentId: string,
|
|
248
|
-
): ComponentLanguageStrings<TStringKeys, TLanguages> | undefined {
|
|
249
|
-
return this.componentStrings.get(componentId) as
|
|
250
|
-
| ComponentLanguageStrings<TStringKeys, TLanguages>
|
|
251
|
-
| undefined;
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Validate a component registration
|
|
256
|
-
*/
|
|
257
|
-
private validateComponentRegistration<TStringKeys extends string>(
|
|
258
|
-
registration: ComponentRegistration<TStringKeys, TLanguages>,
|
|
259
|
-
): ValidationResult {
|
|
260
|
-
const { component, strings } = registration;
|
|
261
|
-
const missingKeys: Array<{
|
|
262
|
-
languageId: string;
|
|
263
|
-
componentId: string;
|
|
264
|
-
stringKey: string;
|
|
265
|
-
}> = [];
|
|
266
|
-
const errors: string[] = [];
|
|
267
|
-
|
|
268
|
-
// Check if all required string keys are provided for each language
|
|
269
|
-
for (const languageId of this.registeredLanguages) {
|
|
270
|
-
const languageStrings = strings[languageId];
|
|
271
|
-
|
|
272
|
-
if (!languageStrings) {
|
|
273
|
-
if (this.validationConfig.requireCompleteStrings) {
|
|
274
|
-
errors.push(
|
|
275
|
-
`Missing all strings for language '${languageId}' in component '${component.id}'`,
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
// Add all missing keys for this language
|
|
279
|
-
for (const stringKey of component.stringKeys) {
|
|
280
|
-
missingKeys.push({
|
|
281
|
-
languageId,
|
|
282
|
-
componentId: component.id,
|
|
283
|
-
stringKey,
|
|
284
|
-
});
|
|
285
|
-
}
|
|
286
|
-
continue;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
// Check individual string keys
|
|
290
|
-
for (const stringKey of component.stringKeys) {
|
|
291
|
-
if (!languageStrings[stringKey]) {
|
|
292
|
-
missingKeys.push({
|
|
293
|
-
languageId,
|
|
294
|
-
componentId: component.id,
|
|
295
|
-
stringKey,
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
if (this.validationConfig.requireCompleteStrings) {
|
|
299
|
-
errors.push(
|
|
300
|
-
`Missing string key '${stringKey}' for language '${languageId}' in component '${component.id}'`,
|
|
301
|
-
);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
return {
|
|
308
|
-
isValid: missingKeys.length === 0,
|
|
309
|
-
missingKeys,
|
|
310
|
-
errors,
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
/**
|
|
315
|
-
* Complete missing strings with fallbacks
|
|
316
|
-
*/
|
|
317
|
-
private completeStringsWithFallbacks<TStringKeys extends string>(
|
|
318
|
-
component: ComponentDefinition<TStringKeys>,
|
|
319
|
-
strings: PartialComponentLanguageStrings<TStringKeys, TLanguages>,
|
|
320
|
-
): ComponentLanguageStrings<TStringKeys, TLanguages> {
|
|
321
|
-
const result: { [L in TLanguages]: ComponentStrings<TStringKeys> } =
|
|
322
|
-
{} as any;
|
|
323
|
-
const fallbackLanguage = this.validationConfig
|
|
324
|
-
.fallbackLanguageId as TLanguages;
|
|
325
|
-
const fallbackStrings = strings[fallbackLanguage];
|
|
326
|
-
|
|
327
|
-
// Ensure all languages have all required keys
|
|
328
|
-
for (const languageId of this.registeredLanguages) {
|
|
329
|
-
const existingLanguageStrings =
|
|
330
|
-
strings[languageId] || ({} as PartialComponentStrings<TStringKeys>);
|
|
331
|
-
const languageStrings: { [K in TStringKeys]: string } = {} as any;
|
|
332
|
-
|
|
333
|
-
for (const stringKey of component.stringKeys) {
|
|
334
|
-
if (existingLanguageStrings[stringKey]) {
|
|
335
|
-
languageStrings[stringKey] = existingLanguageStrings[stringKey]!;
|
|
336
|
-
} else if (fallbackStrings && fallbackStrings[stringKey]) {
|
|
337
|
-
// Try to use fallback language
|
|
338
|
-
languageStrings[stringKey] = fallbackStrings[stringKey]!;
|
|
339
|
-
} else {
|
|
340
|
-
// Last resort: use a placeholder
|
|
341
|
-
languageStrings[stringKey] = `[${component.id}.${stringKey}]`;
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
result[languageId] = languageStrings;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
return result;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
* Merge existing strings with new strings
|
|
353
|
-
*/
|
|
354
|
-
private mergeStrings<TStringKeys extends string>(
|
|
355
|
-
existing: ComponentLanguageStrings<TStringKeys, TLanguages>,
|
|
356
|
-
updates: PartialComponentLanguageStrings<TStringKeys, TLanguages>,
|
|
357
|
-
): PartialComponentLanguageStrings<TStringKeys, TLanguages> {
|
|
358
|
-
const result: { [L in TLanguages]?: PartialComponentStrings<TStringKeys> } =
|
|
359
|
-
{};
|
|
360
|
-
|
|
361
|
-
// Copy existing strings
|
|
362
|
-
for (const [languageId, languageStrings] of Object.entries(existing) as [
|
|
363
|
-
TLanguages,
|
|
364
|
-
ComponentStrings<TStringKeys>,
|
|
365
|
-
][]) {
|
|
366
|
-
result[languageId] = { ...languageStrings };
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
// Apply updates
|
|
370
|
-
for (const [languageId, languageStrings] of Object.entries(updates) as [
|
|
371
|
-
TLanguages,
|
|
372
|
-
PartialComponentStrings<TStringKeys> | undefined,
|
|
373
|
-
][]) {
|
|
374
|
-
if (languageStrings) {
|
|
375
|
-
result[languageId] = {
|
|
376
|
-
...result[languageId],
|
|
377
|
-
...languageStrings,
|
|
378
|
-
};
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
return result;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Clear all components and their strings (useful for testing)
|
|
387
|
-
*/
|
|
388
|
-
public clearAllComponents(): void {
|
|
389
|
-
this.components.clear();
|
|
390
|
-
this.componentStrings.clear();
|
|
391
|
-
}
|
|
392
|
-
}
|
package/src/context-error.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ContextErrorType } from './context-error-type';
|
|
2
|
-
|
|
3
|
-
export class ContextError extends Error {
|
|
4
|
-
public readonly type: ContextErrorType;
|
|
5
|
-
public readonly contextKey?: string;
|
|
6
|
-
|
|
7
|
-
constructor(type: ContextErrorType, contextKey?: string) {
|
|
8
|
-
const message = contextKey
|
|
9
|
-
? `Invalid context: ${contextKey}`
|
|
10
|
-
: 'Invalid context';
|
|
11
|
-
super(message);
|
|
12
|
-
this.name = 'ContextError';
|
|
13
|
-
this.type = type;
|
|
14
|
-
this.contextKey = contextKey;
|
|
15
|
-
}
|
|
16
|
-
}
|
package/src/context-manager.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Context change management for i18n systems
|
|
3
|
-
*/
|
|
4
|
-
export type ContextChangeListener<T = any> = (
|
|
5
|
-
property: string,
|
|
6
|
-
oldValue: T,
|
|
7
|
-
newValue: T,
|
|
8
|
-
) => void;
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Manages context changes and notifies listeners.
|
|
12
|
-
*/
|
|
13
|
-
export class ContextManager<TContext extends Record<string, any>> {
|
|
14
|
-
protected listeners: ContextChangeListener[] = [];
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Adds a listener to be notified of context changes.
|
|
18
|
-
* @param listener - The listener function to add
|
|
19
|
-
*/
|
|
20
|
-
public addListener(listener: ContextChangeListener): void {
|
|
21
|
-
this.listeners.push(listener);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Removes a listener from the notification list.
|
|
26
|
-
* @param listener - The listener function to remove
|
|
27
|
-
*/
|
|
28
|
-
public removeListener(listener: ContextChangeListener): void {
|
|
29
|
-
const index = this.listeners.indexOf(listener);
|
|
30
|
-
if (index > -1) {
|
|
31
|
-
this.listeners.splice(index, 1);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Notifies all listeners of a context change.
|
|
37
|
-
* @param property - The property that changed
|
|
38
|
-
* @param oldValue - The old value of the property
|
|
39
|
-
* @param newValue - The new value of the property
|
|
40
|
-
*/
|
|
41
|
-
public notifyChange<K extends keyof TContext>(
|
|
42
|
-
property: K,
|
|
43
|
-
oldValue: TContext[K],
|
|
44
|
-
newValue: TContext[K],
|
|
45
|
-
): void {
|
|
46
|
-
this.listeners.forEach((listener) => {
|
|
47
|
-
try {
|
|
48
|
-
listener(property as string, oldValue, newValue);
|
|
49
|
-
} catch (error) {
|
|
50
|
-
console.error('Error in context change listener:', error);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Creates a proxy for the given context to automatically notify listeners on changes.
|
|
57
|
-
* @param context - The context object to proxy
|
|
58
|
-
* @returns A proxied version of the context object
|
|
59
|
-
*/
|
|
60
|
-
public createProxy(context: TContext): TContext {
|
|
61
|
-
const manager = this;
|
|
62
|
-
return new Proxy(context, {
|
|
63
|
-
set(target, property, value) {
|
|
64
|
-
const oldValue = target[property as keyof TContext];
|
|
65
|
-
target[property as keyof TContext] = value;
|
|
66
|
-
manager.notifyChange(property as keyof TContext, oldValue, value);
|
|
67
|
-
return true;
|
|
68
|
-
},
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
}
|
package/src/context.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { CurrencyCode } from './currency-code';
|
|
2
|
-
import { I18nContext } from './i18n-context';
|
|
3
|
-
import { Timezone } from './timezone';
|
|
4
|
-
import { LanguageContextSpace } from './types';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Creates a new I18n context with default values.
|
|
8
|
-
* @param defaultLanguage - The default language for the context
|
|
9
|
-
* @param defaultContext - The default language context
|
|
10
|
-
* @param defaultCurrencyCode - The default currency code (defaults to USD)
|
|
11
|
-
* @param defaultTimezone - The default timezone (defaults to UTC)
|
|
12
|
-
* @param defaultAdminTimezone - The default admin timezone (defaults to UTC)
|
|
13
|
-
* @returns A new I18nContext instance
|
|
14
|
-
*/
|
|
15
|
-
export function createContext<TLanguage extends string>(
|
|
16
|
-
defaultLanguage: TLanguage,
|
|
17
|
-
defaultContext: LanguageContextSpace = 'admin',
|
|
18
|
-
defaultCurrencyCode: CurrencyCode = new CurrencyCode('USD'),
|
|
19
|
-
defaultTimezone: Timezone = new Timezone('UTC'),
|
|
20
|
-
defaultAdminTimezone: Timezone = new Timezone('UTC'),
|
|
21
|
-
): I18nContext<TLanguage> {
|
|
22
|
-
return {
|
|
23
|
-
language: defaultLanguage,
|
|
24
|
-
adminLanguage: defaultLanguage,
|
|
25
|
-
currencyCode: defaultCurrencyCode,
|
|
26
|
-
currentContext: defaultContext,
|
|
27
|
-
timezone: defaultTimezone,
|
|
28
|
-
adminTimezone: defaultAdminTimezone,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Sets the language for the given I18n context.
|
|
34
|
-
* @param context - The I18n context to modify
|
|
35
|
-
* @param language - The language to set
|
|
36
|
-
*/
|
|
37
|
-
export function setLanguage<TLanguage extends string>(
|
|
38
|
-
context: I18nContext<TLanguage>,
|
|
39
|
-
language: TLanguage,
|
|
40
|
-
): void {
|
|
41
|
-
context.language = language;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Sets the admin language for the given I18n context.
|
|
46
|
-
* @param context - The I18n context to modify
|
|
47
|
-
* @param language - The admin language to set
|
|
48
|
-
*/
|
|
49
|
-
export function setAdminLanguage<TLanguage extends string>(
|
|
50
|
-
context: I18nContext<TLanguage>,
|
|
51
|
-
language: TLanguage,
|
|
52
|
-
): void {
|
|
53
|
-
context.adminLanguage = language;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Sets the current context for the given I18n context.
|
|
58
|
-
* @param context - The I18n context to modify
|
|
59
|
-
* @param languageContext - The language context to set
|
|
60
|
-
*/
|
|
61
|
-
export function setContext<TLanguage extends string>(
|
|
62
|
-
context: I18nContext<TLanguage>,
|
|
63
|
-
languageContext: LanguageContextSpace,
|
|
64
|
-
): void {
|
|
65
|
-
context.currentContext = languageContext;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Sets the timezone for the given I18n context.
|
|
70
|
-
* @param context - The I18n context to modify
|
|
71
|
-
* @param timezone - The timezone to set
|
|
72
|
-
*/
|
|
73
|
-
export function setTimezone<TLanguage extends string>(
|
|
74
|
-
context: I18nContext<TLanguage>,
|
|
75
|
-
timezone: Timezone,
|
|
76
|
-
): void {
|
|
77
|
-
context.timezone = timezone;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Sets the admin timezone for the given I18n context.
|
|
82
|
-
* @param context - The I18n context to modify
|
|
83
|
-
* @param timezone - The admin timezone to set
|
|
84
|
-
*/
|
|
85
|
-
export function setAdminTimezone<TLanguage extends string>(
|
|
86
|
-
context: I18nContext<TLanguage>,
|
|
87
|
-
timezone: Timezone,
|
|
88
|
-
): void {
|
|
89
|
-
context.adminTimezone = timezone;
|
|
90
|
-
}
|