@digitaldefiance/i18n-lib 1.0.32 → 1.1.0
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 +440 -4
- package/dist/component-definition.d.ts +11 -0
- package/dist/component-definition.js +2 -0
- package/dist/component-registration.d.ts +9 -0
- package/dist/component-registration.js +2 -0
- package/dist/component-registry.d.ts +64 -0
- package/dist/component-registry.js +238 -0
- package/dist/context.d.ts +2 -1
- package/dist/core-i18n.d.ts +330 -0
- package/dist/core-i18n.js +435 -0
- package/dist/core-language.d.ts +13 -0
- package/dist/core-language.js +17 -0
- package/dist/core-string-key.d.ts +39 -0
- package/dist/core-string-key.js +47 -0
- package/dist/default-config.d.ts +2 -1
- package/dist/default-config.js +24 -24
- package/dist/enum-registry.d.ts +10 -1
- package/dist/enum-registry.js +31 -4
- package/dist/i18n-config.d.ts +20 -0
- package/dist/i18n-config.js +2 -0
- package/dist/i18n-context.d.ts +14 -0
- package/dist/i18n-context.js +2 -0
- package/dist/i18n-engine.d.ts +9 -2
- package/dist/i18n-engine.js +16 -13
- package/dist/index.d.ts +21 -1
- package/dist/index.js +25 -2
- package/dist/language-definition.d.ts +13 -0
- package/dist/language-definition.js +2 -0
- package/dist/language-registry.d.ts +106 -0
- package/dist/language-registry.js +194 -0
- package/dist/plugin-i18n-engine.d.ts +126 -0
- package/dist/plugin-i18n-engine.js +266 -0
- package/dist/registry-config.d.ts +14 -0
- package/dist/registry-config.js +2 -0
- package/dist/registry-context.d.ts +12 -0
- package/dist/registry-context.js +2 -0
- package/dist/registry-error-type.d.ts +12 -0
- package/dist/registry-error-type.js +16 -0
- package/dist/registry-error.d.ts +19 -0
- package/dist/registry-error.js +44 -0
- package/dist/translation-request.d.ts +9 -0
- package/dist/translation-request.js +2 -0
- package/dist/translation-response.d.ts +8 -0
- package/dist/translation-response.js +2 -0
- package/dist/typed-error.d.ts +63 -3
- package/dist/typed-error.js +230 -2
- package/dist/types.d.ts +42 -29
- package/dist/validation-config.d.ts +11 -0
- package/dist/validation-config.js +2 -0
- package/dist/validation-result.d.ts +12 -0
- package/dist/validation-result.js +2 -0
- package/package.json +2 -1
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RegistryError = void 0;
|
|
4
|
+
const core_string_key_1 = require("./core-string-key");
|
|
5
|
+
const registry_error_type_1 = require("./registry-error-type");
|
|
6
|
+
const typed_error_1 = require("./typed-error");
|
|
7
|
+
/**
|
|
8
|
+
* Reason map for registry errors
|
|
9
|
+
*/
|
|
10
|
+
const REGISTRY_ERROR_REASON_MAP = {
|
|
11
|
+
[registry_error_type_1.RegistryErrorType.ComponentNotFound]: core_string_key_1.CoreStringKey.Error_ComponentNotFoundTemplate,
|
|
12
|
+
[registry_error_type_1.RegistryErrorType.DuplicateComponent]: core_string_key_1.CoreStringKey.Error_DuplicateComponentTemplate,
|
|
13
|
+
[registry_error_type_1.RegistryErrorType.DuplicateLanguage]: core_string_key_1.CoreStringKey.Error_DuplicateLanguageTemplate,
|
|
14
|
+
[registry_error_type_1.RegistryErrorType.IncompleteRegistration]: core_string_key_1.CoreStringKey.Error_IncompleteRegistrationTemplate,
|
|
15
|
+
[registry_error_type_1.RegistryErrorType.LanguageNotFound]: core_string_key_1.CoreStringKey.Error_LanguageNotFoundTemplate,
|
|
16
|
+
[registry_error_type_1.RegistryErrorType.StringKeyNotFound]: core_string_key_1.CoreStringKey.Error_StringKeyNotFoundTemplate,
|
|
17
|
+
[registry_error_type_1.RegistryErrorType.ValidationFailed]: core_string_key_1.CoreStringKey.Error_ValidationFailedTemplate,
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Registry error class that can work with plugin engines
|
|
21
|
+
*/
|
|
22
|
+
class RegistryError extends Error {
|
|
23
|
+
constructor(type, message, metadata) {
|
|
24
|
+
super(message);
|
|
25
|
+
this.type = type;
|
|
26
|
+
this.metadata = metadata;
|
|
27
|
+
this.name = 'RegistryError';
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Create a registry error with translation support
|
|
31
|
+
*/
|
|
32
|
+
static createWithEngine(engine, type, variables, language, metadata) {
|
|
33
|
+
const error = (0, typed_error_1.createTranslatedError)(engine, 'core', type, REGISTRY_ERROR_REASON_MAP, variables, language, metadata, 'RegistryError');
|
|
34
|
+
// Convert to RegistryError instance
|
|
35
|
+
return new RegistryError(type, error.message, metadata);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Create a simple RegistryError without engine dependency
|
|
39
|
+
*/
|
|
40
|
+
static createSimple(type, message, metadata) {
|
|
41
|
+
return new RegistryError(type, message, metadata);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.RegistryError = RegistryError;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translation request interface
|
|
3
|
+
*/
|
|
4
|
+
export interface TranslationRequest<TStringKeys extends string, TLanguages extends string> {
|
|
5
|
+
readonly componentId: string;
|
|
6
|
+
readonly stringKey: TStringKeys;
|
|
7
|
+
readonly language?: TLanguages;
|
|
8
|
+
readonly variables?: Record<string, string | number>;
|
|
9
|
+
}
|
package/dist/typed-error.d.ts
CHANGED
|
@@ -1,11 +1,36 @@
|
|
|
1
1
|
import { Language, StringKey } from './default-config';
|
|
2
2
|
import { I18nEngine } from './i18n-engine';
|
|
3
|
+
import { CoreLanguage } from './core-language';
|
|
4
|
+
import { CoreStringKey } from './core-string-key';
|
|
5
|
+
import { PluginI18nEngine } from './plugin-i18n-engine';
|
|
6
|
+
/**
|
|
7
|
+
* Interface for engines that can translate strings (unified interface)
|
|
8
|
+
*/
|
|
9
|
+
export interface TranslationEngine {
|
|
10
|
+
safeTranslate(componentId: string, stringKey: string, variables?: Record<string, string | number>, language?: string): string;
|
|
11
|
+
}
|
|
3
12
|
/**
|
|
4
13
|
* Type constraint to ensure reasonMap has entries for all enum values
|
|
5
14
|
*/
|
|
6
|
-
type CompleteReasonMap<TEnum extends Record<string, string | number>, TStringKey extends string> = Record<TEnum[keyof TEnum], TStringKey>;
|
|
15
|
+
export type CompleteReasonMap<TEnum extends Record<string, string | number>, TStringKey extends string> = Record<TEnum[keyof TEnum], TStringKey>;
|
|
16
|
+
/**
|
|
17
|
+
* Base typed error class with common patterns
|
|
18
|
+
*/
|
|
19
|
+
export declare abstract class BaseTypedError<TEnum extends Record<string, string>, TStringKey extends string> extends Error {
|
|
20
|
+
readonly type: TEnum[keyof TEnum];
|
|
21
|
+
readonly metadata?: Record<string, any> | undefined;
|
|
22
|
+
constructor(type: TEnum[keyof TEnum], message: string, metadata?: Record<string, any> | undefined);
|
|
23
|
+
/**
|
|
24
|
+
* Create a simple typed error without engine dependency
|
|
25
|
+
*/
|
|
26
|
+
static createSimple<TEnum extends Record<string, string>, TStringKey extends string, TError extends BaseTypedError<TEnum, TStringKey>>(this: new (type: TEnum[keyof TEnum], message: string, metadata?: Record<string, any>) => TError, type: TEnum[keyof TEnum], message: string, metadata?: Record<string, any>): TError;
|
|
27
|
+
/**
|
|
28
|
+
* Create a typed error with translation support
|
|
29
|
+
*/
|
|
30
|
+
static createTranslated<TEnum extends Record<string, string>, TStringKey extends string, TError extends BaseTypedError<TEnum, TStringKey>>(this: new (type: TEnum[keyof TEnum], message: string, metadata?: Record<string, any>) => TError, engine: TranslationEngine, componentId: string, type: TEnum[keyof TEnum], reasonMap: CompleteReasonMap<TEnum, TStringKey>, variables?: Record<string, string | number>, language?: string, metadata?: Record<string, any>): TError;
|
|
31
|
+
}
|
|
7
32
|
/**
|
|
8
|
-
*
|
|
33
|
+
* Legacy TypedError that ensures complete enum coverage (for backward compatibility)
|
|
9
34
|
*/
|
|
10
35
|
export declare abstract class TypedError<TEnum extends Record<string, string>, TStringKey extends string = StringKey> extends Error {
|
|
11
36
|
readonly type: TEnum[keyof TEnum];
|
|
@@ -14,4 +39,39 @@ export declare abstract class TypedError<TEnum extends Record<string, string>, T
|
|
|
14
39
|
readonly otherVars?: Record<string, string | number> | undefined;
|
|
15
40
|
constructor(engine: I18nEngine<TStringKey, Language, Record<string, any>, string>, type: TEnum[keyof TEnum], reasonMap: CompleteReasonMap<TEnum, TStringKey>, language?: Language | undefined, otherVars?: Record<string, string | number> | undefined);
|
|
16
41
|
}
|
|
17
|
-
|
|
42
|
+
/**
|
|
43
|
+
* Plugin-based TypedError that works with the new component registration system
|
|
44
|
+
*/
|
|
45
|
+
export declare abstract class PluginTypedError<TEnum extends Record<string, string>, TStringKey extends string, TLanguages extends string = CoreLanguage> extends Error {
|
|
46
|
+
readonly componentId: string;
|
|
47
|
+
readonly type: TEnum[keyof TEnum];
|
|
48
|
+
readonly reasonMap: CompleteReasonMap<TEnum, TStringKey>;
|
|
49
|
+
readonly language?: TLanguages | undefined;
|
|
50
|
+
readonly otherVars?: Record<string, string | number> | undefined;
|
|
51
|
+
constructor(engine: PluginI18nEngine<TLanguages>, componentId: string, type: TEnum[keyof TEnum], reasonMap: CompleteReasonMap<TEnum, TStringKey>, language?: TLanguages | undefined, otherVars?: Record<string, string | number> | undefined);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Core system TypedError using the core component strings
|
|
55
|
+
*/
|
|
56
|
+
export declare abstract class CoreTypedError<TEnum extends Record<string, string>> extends Error {
|
|
57
|
+
readonly type: TEnum[keyof TEnum];
|
|
58
|
+
readonly reasonMap: CompleteReasonMap<TEnum, CoreStringKey>;
|
|
59
|
+
readonly language?: CoreLanguage | undefined;
|
|
60
|
+
readonly otherVars?: Record<string, string | number> | undefined;
|
|
61
|
+
constructor(engine: PluginI18nEngine<CoreLanguage>, type: TEnum[keyof TEnum], reasonMap: CompleteReasonMap<TEnum, CoreStringKey>, language?: CoreLanguage | undefined, otherVars?: Record<string, string | number> | undefined);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Helper function to create a plugin-based TypedError with automatic engine detection
|
|
65
|
+
*/
|
|
66
|
+
export declare function createPluginTypedError<TEnum extends Record<string, string>, TStringKey extends string, TLanguages extends string = CoreLanguage>(componentId: string, type: TEnum[keyof TEnum], reasonMap: CompleteReasonMap<TEnum, TStringKey>, otherVars?: Record<string, string | number>, language?: TLanguages, instanceKey?: string): Error;
|
|
67
|
+
/**
|
|
68
|
+
* Helper function to create a core system TypedError with automatic engine detection
|
|
69
|
+
*/
|
|
70
|
+
export declare function createCoreTypedError<TEnum extends Record<string, string>>(type: TEnum[keyof TEnum], reasonMap: CompleteReasonMap<TEnum, CoreStringKey>, otherVars?: Record<string, string | number>, language?: CoreLanguage, instanceKey?: string): Error;
|
|
71
|
+
/**
|
|
72
|
+
* Create a simple error with translation support (generalized pattern from RegistryError)
|
|
73
|
+
*/
|
|
74
|
+
export declare function createTranslatedError<TEnum extends Record<string, string>, TStringKey extends string>(engine: TranslationEngine, componentId: string, type: TEnum[keyof TEnum], reasonMap: Record<TEnum[keyof TEnum], TStringKey>, variables?: Record<string, string | number>, language?: string, metadata?: Record<string, any>, errorName?: string): Error;
|
|
75
|
+
/**
|
|
76
|
+
* Example usage of the new plugin-based TypedError system
|
|
77
|
+
*/
|
package/dist/typed-error.js
CHANGED
|
@@ -1,9 +1,49 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.TypedError = void 0;
|
|
3
|
+
exports.CoreTypedError = exports.PluginTypedError = exports.TypedError = exports.BaseTypedError = void 0;
|
|
4
|
+
exports.createPluginTypedError = createPluginTypedError;
|
|
5
|
+
exports.createCoreTypedError = createCoreTypedError;
|
|
6
|
+
exports.createTranslatedError = createTranslatedError;
|
|
7
|
+
// Legacy imports (for backward compatibility)
|
|
4
8
|
const default_config_1 = require("./default-config");
|
|
9
|
+
const core_string_key_1 = require("./core-string-key");
|
|
10
|
+
const plugin_i18n_engine_1 = require("./plugin-i18n-engine");
|
|
5
11
|
/**
|
|
6
|
-
*
|
|
12
|
+
* Base typed error class with common patterns
|
|
13
|
+
*/
|
|
14
|
+
class BaseTypedError extends Error {
|
|
15
|
+
constructor(type, message, metadata) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.type = type;
|
|
18
|
+
this.metadata = metadata;
|
|
19
|
+
this.name = this.constructor.name;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Create a simple typed error without engine dependency
|
|
23
|
+
*/
|
|
24
|
+
static createSimple(type, message, metadata) {
|
|
25
|
+
return new this(type, message, metadata);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create a typed error with translation support
|
|
29
|
+
*/
|
|
30
|
+
static createTranslated(engine, componentId, type, reasonMap, variables, language, metadata) {
|
|
31
|
+
const key = reasonMap[type];
|
|
32
|
+
let message;
|
|
33
|
+
if (key && engine) {
|
|
34
|
+
// Try to translate the error message using the engine
|
|
35
|
+
message = engine.safeTranslate(componentId, key, variables, language);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// Fallback to a basic English message
|
|
39
|
+
message = `Error: ${type}${metadata ? ` - ${JSON.stringify(metadata)}` : ''}`;
|
|
40
|
+
}
|
|
41
|
+
return new this(type, message, metadata);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.BaseTypedError = BaseTypedError;
|
|
45
|
+
/**
|
|
46
|
+
* Legacy TypedError that ensures complete enum coverage (for backward compatibility)
|
|
7
47
|
*/
|
|
8
48
|
class TypedError extends Error {
|
|
9
49
|
constructor(engine, type, reasonMap, language, otherVars) {
|
|
@@ -19,3 +59,191 @@ class TypedError extends Error {
|
|
|
19
59
|
}
|
|
20
60
|
}
|
|
21
61
|
exports.TypedError = TypedError;
|
|
62
|
+
/**
|
|
63
|
+
* Plugin-based TypedError that works with the new component registration system
|
|
64
|
+
*/
|
|
65
|
+
class PluginTypedError extends Error {
|
|
66
|
+
constructor(engine, componentId, type, reasonMap, language, otherVars) {
|
|
67
|
+
const key = reasonMap[type];
|
|
68
|
+
// If key is not found in the reason map, use core error message
|
|
69
|
+
if (!key) {
|
|
70
|
+
const errorMsg = engine.safeTranslate('core', core_string_key_1.CoreStringKey.Error_StringKeyNotFoundTemplate, {
|
|
71
|
+
stringKey: String(type),
|
|
72
|
+
componentId: componentId,
|
|
73
|
+
}, language);
|
|
74
|
+
throw new Error(errorMsg);
|
|
75
|
+
}
|
|
76
|
+
// Translate the error message using the component and string key
|
|
77
|
+
const translatedMessage = engine.safeTranslate(componentId, key, otherVars, language);
|
|
78
|
+
super(translatedMessage);
|
|
79
|
+
this.componentId = componentId;
|
|
80
|
+
this.type = type;
|
|
81
|
+
this.reasonMap = reasonMap;
|
|
82
|
+
this.language = language;
|
|
83
|
+
this.otherVars = otherVars;
|
|
84
|
+
this.name = this.constructor.name;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.PluginTypedError = PluginTypedError;
|
|
88
|
+
/**
|
|
89
|
+
* Core system TypedError using the core component strings
|
|
90
|
+
*/
|
|
91
|
+
class CoreTypedError extends Error {
|
|
92
|
+
constructor(engine, type, reasonMap, language, otherVars) {
|
|
93
|
+
const key = reasonMap[type];
|
|
94
|
+
// If key is not found in the reason map, use a fallback error
|
|
95
|
+
if (!key) {
|
|
96
|
+
const errorMsg = engine.safeTranslate('core', core_string_key_1.CoreStringKey.Error_StringKeyNotFoundTemplate, {
|
|
97
|
+
stringKey: String(type),
|
|
98
|
+
componentId: 'core',
|
|
99
|
+
}, language);
|
|
100
|
+
throw new Error(errorMsg);
|
|
101
|
+
}
|
|
102
|
+
// Translate the error message using the core component
|
|
103
|
+
const translatedMessage = engine.safeTranslate('core', key, otherVars, language);
|
|
104
|
+
super(translatedMessage);
|
|
105
|
+
this.type = type;
|
|
106
|
+
this.reasonMap = reasonMap;
|
|
107
|
+
this.language = language;
|
|
108
|
+
this.otherVars = otherVars;
|
|
109
|
+
this.name = this.constructor.name;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
exports.CoreTypedError = CoreTypedError;
|
|
113
|
+
/**
|
|
114
|
+
* Helper function to create a plugin-based TypedError with automatic engine detection
|
|
115
|
+
*/
|
|
116
|
+
function createPluginTypedError(componentId, type, reasonMap, otherVars, language, instanceKey) {
|
|
117
|
+
const engine = plugin_i18n_engine_1.PluginI18nEngine.getInstance(instanceKey);
|
|
118
|
+
return new (class extends PluginTypedError {
|
|
119
|
+
constructor() {
|
|
120
|
+
super(engine, componentId, type, reasonMap, language, otherVars);
|
|
121
|
+
}
|
|
122
|
+
})();
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Helper function to create a core system TypedError with automatic engine detection
|
|
126
|
+
*/
|
|
127
|
+
function createCoreTypedError(type, reasonMap, otherVars, language, instanceKey) {
|
|
128
|
+
const engine = plugin_i18n_engine_1.PluginI18nEngine.getInstance(instanceKey);
|
|
129
|
+
return new (class extends CoreTypedError {
|
|
130
|
+
constructor() {
|
|
131
|
+
super(engine, type, reasonMap, language, otherVars);
|
|
132
|
+
}
|
|
133
|
+
})();
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Create a simple error with translation support (generalized pattern from RegistryError)
|
|
137
|
+
*/
|
|
138
|
+
function createTranslatedError(engine, componentId, type, reasonMap, variables, language, metadata, errorName) {
|
|
139
|
+
const key = reasonMap[type];
|
|
140
|
+
let message;
|
|
141
|
+
if (key && engine) {
|
|
142
|
+
try {
|
|
143
|
+
// Try to translate the error message using the engine
|
|
144
|
+
message = engine.safeTranslate(componentId, key, variables, language);
|
|
145
|
+
}
|
|
146
|
+
catch (translationError) {
|
|
147
|
+
// Fallback if translation fails
|
|
148
|
+
message = `Error: ${type}${metadata ? ` - ${JSON.stringify(metadata)}` : ''}`;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
// Fallback to a basic English message
|
|
153
|
+
message = `Error: ${type}${metadata ? ` - ${JSON.stringify(metadata)}` : ''}`;
|
|
154
|
+
}
|
|
155
|
+
const error = new Error(message);
|
|
156
|
+
error.name = errorName || 'TranslatedError';
|
|
157
|
+
error.type = type;
|
|
158
|
+
error.metadata = metadata;
|
|
159
|
+
return error;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Example usage of the new plugin-based TypedError system
|
|
163
|
+
*/
|
|
164
|
+
// Example 1: Core system error using CoreStringKey
|
|
165
|
+
/*
|
|
166
|
+
enum DatabaseErrorType {
|
|
167
|
+
ConnectionFailed = 'connectionFailed',
|
|
168
|
+
QueryTimeout = 'queryTimeout',
|
|
169
|
+
AccessDenied = 'accessDenied'
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const coreErrorReasonMap: CompleteReasonMap<typeof DatabaseErrorType, CoreStringKey> = {
|
|
173
|
+
[DatabaseErrorType.ConnectionFailed]: CoreStringKey.Error_NetworkError,
|
|
174
|
+
[DatabaseErrorType.QueryTimeout]: CoreStringKey.Error_InternalServer,
|
|
175
|
+
[DatabaseErrorType.AccessDenied]: CoreStringKey.Error_AccessDenied
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
class DatabaseError extends CoreTypedError<typeof DatabaseErrorType> {
|
|
179
|
+
constructor(
|
|
180
|
+
engine: PluginI18nEngine<CoreLanguage>,
|
|
181
|
+
type: DatabaseErrorType,
|
|
182
|
+
otherVars?: Record<string, string | number>,
|
|
183
|
+
language?: CoreLanguage
|
|
184
|
+
) {
|
|
185
|
+
super(engine, type, coreErrorReasonMap, language, otherVars);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Usage:
|
|
190
|
+
// const engine = PluginI18nEngine.getInstance<CoreLanguage>();
|
|
191
|
+
// throw new DatabaseError(engine, DatabaseErrorType.ConnectionFailed);
|
|
192
|
+
*/
|
|
193
|
+
// Example 2: Custom component error with custom strings
|
|
194
|
+
/*
|
|
195
|
+
enum UserErrorType {
|
|
196
|
+
UserNotFound = 'userNotFound',
|
|
197
|
+
InvalidCredentials = 'invalidCredentials',
|
|
198
|
+
AccountLocked = 'accountLocked'
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
enum UserErrorStringKey {
|
|
202
|
+
UserNotFoundMessage = 'userNotFoundMessage',
|
|
203
|
+
InvalidCredentialsMessage = 'invalidCredentialsMessage',
|
|
204
|
+
AccountLockedMessage = 'accountLockedMessage'
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const userErrorReasonMap: CompleteReasonMap<typeof UserErrorType, UserErrorStringKey> = {
|
|
208
|
+
[UserErrorType.UserNotFound]: UserErrorStringKey.UserNotFoundMessage,
|
|
209
|
+
[UserErrorType.InvalidCredentials]: UserErrorStringKey.InvalidCredentialsMessage,
|
|
210
|
+
[UserErrorType.AccountLocked]: UserErrorStringKey.AccountLockedMessage
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
class UserError extends PluginTypedError<typeof UserErrorType, UserErrorStringKey, CoreLanguage> {
|
|
214
|
+
constructor(
|
|
215
|
+
engine: PluginI18nEngine<CoreLanguage>,
|
|
216
|
+
type: UserErrorType,
|
|
217
|
+
otherVars?: Record<string, string | number>,
|
|
218
|
+
language?: CoreLanguage
|
|
219
|
+
) {
|
|
220
|
+
super(engine, 'user-system', type, userErrorReasonMap, language, otherVars);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Usage:
|
|
225
|
+
// const engine = PluginI18nEngine.getInstance<CoreLanguage>();
|
|
226
|
+
// throw new UserError(engine, UserErrorType.UserNotFound, { username: 'john_doe' });
|
|
227
|
+
*/
|
|
228
|
+
// Example 3: Using helper functions for simpler error creation
|
|
229
|
+
/*
|
|
230
|
+
// Define your error types and mappings
|
|
231
|
+
enum ApiErrorType {
|
|
232
|
+
Timeout = 'timeout',
|
|
233
|
+
NotFound = 'notFound'
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
const apiErrorMap: CompleteReasonMap<typeof ApiErrorType, CoreStringKey> = {
|
|
237
|
+
[ApiErrorType.Timeout]: CoreStringKey.Error_NetworkError,
|
|
238
|
+
[ApiErrorType.NotFound]: CoreStringKey.Error_NotFound
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
// Create errors using helper functions
|
|
242
|
+
function throwApiError(type: ApiErrorType, vars?: Record<string, string | number>) {
|
|
243
|
+
throw createCoreTypedError(type, apiErrorMap, vars);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// Usage:
|
|
247
|
+
// throwApiError(ApiErrorType.NotFound, { resource: 'user' });
|
|
248
|
+
*/
|
|
249
|
+
// Export the type for external use (already exported above)
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ComponentDefinition } from './component-definition';
|
|
2
|
+
import { ComponentRegistration } from './component-registration';
|
|
3
|
+
import { LanguageDefinition } from './language-definition';
|
|
3
4
|
/**
|
|
4
5
|
* Standard language contexts
|
|
5
6
|
*/
|
|
@@ -33,33 +34,29 @@ export type LanguageCodeCollection<TLanguage extends string> = Partial<Record<TL
|
|
|
33
34
|
*/
|
|
34
35
|
export type EnumTranslationMap<TEnum extends string | number, TLanguage extends string> = Partial<Record<TLanguage, Partial<Record<TEnum, string>>>>;
|
|
35
36
|
/**
|
|
36
|
-
*
|
|
37
|
-
*/
|
|
38
|
-
export
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
currentContext: TTranslationContext;
|
|
60
|
-
timezone: Timezone;
|
|
61
|
-
adminTimezone: Timezone;
|
|
62
|
-
}
|
|
37
|
+
* String collection for a specific language and component
|
|
38
|
+
*/
|
|
39
|
+
export type ComponentStrings<TStringKeys extends string> = {
|
|
40
|
+
[K in TStringKeys]: string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Partial string collection (used during registration before validation)
|
|
44
|
+
*/
|
|
45
|
+
export type PartialComponentStrings<TStringKeys extends string> = {
|
|
46
|
+
[K in TStringKeys]?: string;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Language strings for a component across all registered languages
|
|
50
|
+
*/
|
|
51
|
+
export type ComponentLanguageStrings<TStringKeys extends string, TLanguages extends string> = {
|
|
52
|
+
[L in TLanguages]: ComponentStrings<TStringKeys>;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Partial language strings (used during registration before validation)
|
|
56
|
+
*/
|
|
57
|
+
export type PartialComponentLanguageStrings<TStringKeys extends string, TLanguages extends string> = {
|
|
58
|
+
[L in TLanguages]?: PartialComponentStrings<TStringKeys>;
|
|
59
|
+
};
|
|
63
60
|
/**
|
|
64
61
|
* Generic translation type for any enumeration
|
|
65
62
|
*/
|
|
@@ -72,6 +69,22 @@ export type EnumTranslation<T extends string | number> = {
|
|
|
72
69
|
export type EnumLanguageTranslation<T extends string | number, TLanguage extends string = string> = Partial<{
|
|
73
70
|
[L in TLanguage]: EnumTranslation<T>;
|
|
74
71
|
}>;
|
|
72
|
+
/**
|
|
73
|
+
* Type utility to extract string keys from a component definition
|
|
74
|
+
*/
|
|
75
|
+
export type ExtractStringKeys<T> = T extends ComponentDefinition<infer K> ? K : never;
|
|
76
|
+
/**
|
|
77
|
+
* Type utility to extract languages from registry
|
|
78
|
+
*/
|
|
79
|
+
export type ExtractLanguages<T> = T extends LanguageDefinition ? T['id'] : never;
|
|
80
|
+
/**
|
|
81
|
+
* Type utility to create a strongly typed component registration
|
|
82
|
+
*/
|
|
83
|
+
export type CreateComponentRegistration<TComponent extends ComponentDefinition<any>, TLanguages extends string> = ComponentRegistration<ExtractStringKeys<TComponent>, TLanguages>;
|
|
84
|
+
/**
|
|
85
|
+
* Utility type to ensure all string keys are provided for all languages
|
|
86
|
+
*/
|
|
87
|
+
export type CompleteComponentStrings<TStringKeys extends string, TLanguages extends string> = ComponentLanguageStrings<TStringKeys, TLanguages>;
|
|
75
88
|
/**
|
|
76
89
|
* Helper function to create typed translations for an enumeration
|
|
77
90
|
*/
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for component registration validation
|
|
3
|
+
*/
|
|
4
|
+
export interface ValidationConfig {
|
|
5
|
+
/** Whether to require all languages to have all strings */
|
|
6
|
+
readonly requireCompleteStrings: boolean;
|
|
7
|
+
/** Whether to allow registration with missing strings (will use fallbacks) */
|
|
8
|
+
readonly allowPartialRegistration: boolean;
|
|
9
|
+
/** Default language to fall back to for missing strings */
|
|
10
|
+
readonly fallbackLanguageId: string;
|
|
11
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation result for component registration
|
|
3
|
+
*/
|
|
4
|
+
export interface ValidationResult {
|
|
5
|
+
readonly isValid: boolean;
|
|
6
|
+
readonly missingKeys: ReadonlyArray<{
|
|
7
|
+
readonly languageId: string;
|
|
8
|
+
readonly componentId: string;
|
|
9
|
+
readonly stringKey: string;
|
|
10
|
+
}>;
|
|
11
|
+
readonly errors: readonly string[];
|
|
12
|
+
}
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitaldefiance/i18n-lib",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Generic i18n library with enum translation support",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "yarn tsc",
|
|
9
9
|
"test": "yarn jest --detectOpenHandles",
|
|
10
|
+
"test:stream": "yarn jest --detectOpenHandles --runInBand --outputStyle=stream",
|
|
10
11
|
"lint": "eslint src/**/*.ts tests/**/*.ts",
|
|
11
12
|
"lint:fix": "eslint src/**/*.ts tests/**/*.ts --fix",
|
|
12
13
|
"prettier:check": "prettier --check 'src/**/*.{ts,tsx}' 'tests/**/*.{ts,tsx}'",
|