@digitaldefiance/suite-core-lib 3.10.31 → 3.12.5
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 +41 -16
- package/package.json +3 -3
- package/src/i18n-setup.d.ts +7 -1
- package/src/i18n-setup.d.ts.map +1 -1
- package/src/i18n-setup.js +12 -0
- package/src/i18n-setup.js.map +1 -1
package/README.md
CHANGED
|
@@ -60,27 +60,27 @@ import {
|
|
|
60
60
|
safeGetSuiteCoreTranslation,
|
|
61
61
|
SuiteCoreStringKey
|
|
62
62
|
} from '@digitaldefiance/suite-core-lib';
|
|
63
|
+
import { LanguageCodes } from '@digitaldefiance/i18n-lib';
|
|
63
64
|
|
|
64
65
|
// Direct translation using branded string keys (v3.10.0+)
|
|
65
66
|
// Component ID is automatically resolved from the branded enum
|
|
66
|
-
const message = getSuiteCoreTranslation(SuiteCoreStringKey.
|
|
67
|
-
// Output: "
|
|
67
|
+
const message = getSuiteCoreTranslation(SuiteCoreStringKey.Auth_UserNotFound);
|
|
68
|
+
// Output: "User account not found" (or localized equivalent)
|
|
68
69
|
|
|
69
|
-
// With variables
|
|
70
|
-
const
|
|
71
|
-
SuiteCoreStringKey.
|
|
72
|
-
{ name: 'Alice' }
|
|
70
|
+
// With variables (if the string supports them)
|
|
71
|
+
const validation = getSuiteCoreTranslation(
|
|
72
|
+
SuiteCoreStringKey.Validation_InvalidUsername
|
|
73
73
|
);
|
|
74
74
|
|
|
75
75
|
// With specific language
|
|
76
76
|
const french = getSuiteCoreTranslation(
|
|
77
|
-
SuiteCoreStringKey.
|
|
77
|
+
SuiteCoreStringKey.Auth_AccountLocked,
|
|
78
78
|
{},
|
|
79
|
-
|
|
79
|
+
LanguageCodes.FR // or use string directly: 'fr'
|
|
80
80
|
);
|
|
81
81
|
|
|
82
82
|
// Safe version returns placeholder on failure instead of throwing
|
|
83
|
-
const safe = safeGetSuiteCoreTranslation(SuiteCoreStringKey.
|
|
83
|
+
const safe = safeGetSuiteCoreTranslation(SuiteCoreStringKey.Auth_TokenExpired);
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
## 🏗️ Architecture Overview
|
|
@@ -149,13 +149,13 @@ import {
|
|
|
149
149
|
} from '@digitaldefiance/suite-core-lib';
|
|
150
150
|
|
|
151
151
|
// Throw errors with automatic localization support
|
|
152
|
-
throw new UserNotFoundError(
|
|
152
|
+
throw new UserNotFoundError(LanguageCodes.French);
|
|
153
153
|
// Output: "Compte utilisateur introuvable"
|
|
154
154
|
|
|
155
|
-
throw new UsernameInUseError(
|
|
155
|
+
throw new UsernameInUseError(LanguageCodes.Spanish);
|
|
156
156
|
// Output: "El nombre de usuario ya está en uso"
|
|
157
157
|
|
|
158
|
-
throw new AccountLockedError(
|
|
158
|
+
throw new AccountLockedError(LanguageCodes.German);
|
|
159
159
|
// Output: "Konto ist von einem Administrator gesperrt"
|
|
160
160
|
```
|
|
161
161
|
|
|
@@ -384,7 +384,13 @@ import {
|
|
|
384
384
|
isValidEmail,
|
|
385
385
|
isValidPassword,
|
|
386
386
|
createValidators,
|
|
387
|
-
createConstants
|
|
387
|
+
createConstants,
|
|
388
|
+
formatBackupCode,
|
|
389
|
+
normalizeBackupCode,
|
|
390
|
+
isValidBackupCodeFormat,
|
|
391
|
+
hydrateUserSettings,
|
|
392
|
+
dehydrateUserSettings,
|
|
393
|
+
BCP47_TO_FLAG_CDN
|
|
388
394
|
} from '@digitaldefiance/suite-core-lib';
|
|
389
395
|
|
|
390
396
|
// Use default validators with built-in constants
|
|
@@ -403,6 +409,25 @@ const validators = createValidators(myConstants);
|
|
|
403
409
|
if (!validators.isValidUsername('user_name')) {
|
|
404
410
|
throw new Error('Invalid username');
|
|
405
411
|
}
|
|
412
|
+
|
|
413
|
+
// Format backup codes
|
|
414
|
+
const formatted = formatBackupCode('1234567890ABCDEF'); // "1234-5678-90AB-CDEF"
|
|
415
|
+
const normalized = normalizeBackupCode('1234-5678-90AB-CDEF'); // "1234567890ABCDEF"
|
|
416
|
+
const isValid = isValidBackupCodeFormat('1234-5678-90AB-CDEF'); // true
|
|
417
|
+
|
|
418
|
+
// Hydrate/dehydrate user settings
|
|
419
|
+
const settings = hydrateUserSettings({
|
|
420
|
+
email: 'user@example.com',
|
|
421
|
+
timezone: 'America/New_York',
|
|
422
|
+
currency: 'USD',
|
|
423
|
+
siteLanguage: 'en-US',
|
|
424
|
+
darkMode: false,
|
|
425
|
+
directChallenge: true
|
|
426
|
+
});
|
|
427
|
+
const dto = dehydrateUserSettings(settings);
|
|
428
|
+
|
|
429
|
+
// Map language codes to flag codes for UI
|
|
430
|
+
const flagCode = BCP47_TO_FLAG_CDN['en-US']; // 'us'
|
|
406
431
|
```
|
|
407
432
|
|
|
408
433
|
### Improved Architecture
|
|
@@ -561,11 +586,11 @@ describe('Validators', () => {
|
|
|
561
586
|
#### Testing Error Handling
|
|
562
587
|
|
|
563
588
|
```typescript
|
|
564
|
-
import { UserNotFoundError, UsernameInUseError
|
|
589
|
+
import { UserNotFoundError, UsernameInUseError } from '@digitaldefiance/suite-core-lib';
|
|
565
590
|
|
|
566
591
|
describe('Error Handling', () => {
|
|
567
592
|
it('should throw localized errors', () => {
|
|
568
|
-
const error = new UserNotFoundError(
|
|
593
|
+
const error = new UserNotFoundError(LanguageCodes.French);
|
|
569
594
|
expect(error.message).toContain('utilisateur');
|
|
570
595
|
});
|
|
571
596
|
});
|
|
@@ -611,7 +636,7 @@ describe('User Management', () => {
|
|
|
611
636
|
- Added `registerStringKeyEnum(SuiteCoreStringKey)` during engine initialization
|
|
612
637
|
- Updated `getSuiteCoreTranslation()` to use `translateStringKey()` for automatic component ID resolution
|
|
613
638
|
- Updated `safeGetSuiteCoreTranslation()` to use `safeTranslateStringKey()`
|
|
614
|
-
- Changed `SuiteCoreComponentStrings` to use `BrandedMasterStringsCollection<typeof SuiteCoreStringKey
|
|
639
|
+
- Changed `SuiteCoreComponentStrings` to use `BrandedMasterStringsCollection<typeof SuiteCoreStringKey>` for type-safe branded enum support
|
|
615
640
|
- Upgraded `@digitaldefiance/ecies-lib` from 4.15.6 to 4.16.20
|
|
616
641
|
- Upgraded `@digitaldefiance/i18n-lib` from 4.0.5 to 4.2.20
|
|
617
642
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitaldefiance/suite-core-lib",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.12.5",
|
|
4
4
|
"homepage": "https://github.com/Digital-Defiance/suite-core-lib",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
"publish:public": "npm publish --access public"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@digitaldefiance/ecies-lib": "4.
|
|
32
|
-
"@digitaldefiance/i18n-lib": "4.
|
|
31
|
+
"@digitaldefiance/ecies-lib": "4.17.4",
|
|
32
|
+
"@digitaldefiance/i18n-lib": "4.4.0"
|
|
33
33
|
},
|
|
34
34
|
"files": [
|
|
35
35
|
"src",
|
package/src/i18n-setup.d.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Manages i18n engine initialization, component registration, and translation string loading
|
|
4
4
|
* across 8 supported languages (en-US, en-GB, fr, de, es, zh-CN, ja, uk).
|
|
5
5
|
*/
|
|
6
|
-
import { ComponentConfig, ComponentDefinition, CoreLanguageCode, EngineConfig, I18nEngine, type BrandedMasterStringsCollection } from '@digitaldefiance/i18n-lib';
|
|
6
|
+
import { ComponentConfig, ComponentDefinition, CoreLanguageCode, EngineConfig, I18nEngine, type BrandedMasterStringsCollection, type I18nComponentPackage } from '@digitaldefiance/i18n-lib';
|
|
7
7
|
import { SuiteCoreComponentId, SuiteCoreStringKey, type SuiteCoreStringKeyValue } from './enumerations/suite-core-string-key';
|
|
8
8
|
export declare const SuiteCoreI18nEngineKey: "default";
|
|
9
9
|
export { SuiteCoreComponentId };
|
|
@@ -14,6 +14,12 @@ export declare const SuiteCoreComponent: ComponentDefinition<typeof SuiteCoreStr
|
|
|
14
14
|
*/
|
|
15
15
|
export declare const SuiteCoreComponentStrings: BrandedMasterStringsCollection<typeof SuiteCoreStringKey, CoreLanguageCode>;
|
|
16
16
|
export declare function createSuiteCoreComponentConfig(): ComponentConfig;
|
|
17
|
+
/**
|
|
18
|
+
* Creates an I18nComponentPackage bundling the SuiteCore ComponentConfig
|
|
19
|
+
* with its branded string key enum. Use this with createI18nSetup's
|
|
20
|
+
* libraryComponents array.
|
|
21
|
+
*/
|
|
22
|
+
export declare function createSuiteCoreComponentPackage(): I18nComponentPackage;
|
|
17
23
|
export declare function getSuiteCoreI18nEngine(config?: EngineConfig): I18nEngine;
|
|
18
24
|
export declare function getSuiteCoreTranslation(key: SuiteCoreStringKeyValue, variables?: Record<string, unknown>, language?: string, config?: EngineConfig): string;
|
|
19
25
|
export declare function resetSuiteCoreI18nEngine(): void;
|
package/src/i18n-setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n-setup.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-suite-core-lib/src/i18n-setup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAGhB,YAAY,EACZ,UAAU,EAEV,KAAK,8BAA8B,
|
|
1
|
+
{"version":3,"file":"i18n-setup.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-suite-core-lib/src/i18n-setup.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,gBAAgB,EAGhB,YAAY,EACZ,UAAU,EAEV,KAAK,8BAA8B,EACnC,KAAK,oBAAoB,EAC1B,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,KAAK,uBAAuB,EAC7B,MAAM,sCAAsC,CAAC;AAU9C,eAAO,MAAM,sBAAsB,EAAG,SAAkB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAChC,eAAO,MAAM,kBAAkB,EAAE,mBAAmB,CAClD,OAAO,kBAAkB,CAK1B,CAAC;AACF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,EAAE,8BAA8B,CACpE,OAAO,kBAAkB,EACzB,gBAAgB,CAUjB,CAAC;AA8CF,wBAAgB,8BAA8B,IAAI,eAAe,CAOhE;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,IAAI,oBAAoB,CAKtE;AAID,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,UAAU,CAsBxE;AAED,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,uBAAuB,EAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,YAAY,GACpB,MAAM,CAMR;AAED,wBAAgB,wBAAwB,IAAI,IAAI,CAG/C;AAED,wBAAgB,uBAAuB,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,UAAU,CAEzE;AAED,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,uBAAuB,EAC5B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,YAAY,GACpB,MAAM,CAMR"}
|
package/src/i18n-setup.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SuiteCoreComponentStrings = exports.SuiteCoreComponent = exports.SuiteCoreComponentId = exports.SuiteCoreI18nEngineKey = void 0;
|
|
4
4
|
exports.createSuiteCoreComponentConfig = createSuiteCoreComponentConfig;
|
|
5
|
+
exports.createSuiteCoreComponentPackage = createSuiteCoreComponentPackage;
|
|
5
6
|
exports.getSuiteCoreI18nEngine = getSuiteCoreI18nEngine;
|
|
6
7
|
exports.getSuiteCoreTranslation = getSuiteCoreTranslation;
|
|
7
8
|
exports.resetSuiteCoreI18nEngine = resetSuiteCoreI18nEngine;
|
|
@@ -95,6 +96,17 @@ function createSuiteCoreComponentConfig() {
|
|
|
95
96
|
};
|
|
96
97
|
return SuiteCoreComponentConfig;
|
|
97
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Creates an I18nComponentPackage bundling the SuiteCore ComponentConfig
|
|
101
|
+
* with its branded string key enum. Use this with createI18nSetup's
|
|
102
|
+
* libraryComponents array.
|
|
103
|
+
*/
|
|
104
|
+
function createSuiteCoreComponentPackage() {
|
|
105
|
+
return {
|
|
106
|
+
config: createSuiteCoreComponentConfig(),
|
|
107
|
+
stringKeyEnum: suite_core_string_key_1.SuiteCoreStringKey,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
98
110
|
let _engine;
|
|
99
111
|
function getSuiteCoreI18nEngine(config) {
|
|
100
112
|
if (!_engine || !i18n_lib_1.I18nEngine.hasInstance(exports.SuiteCoreI18nEngineKey)) {
|
package/src/i18n-setup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"i18n-setup.js","sourceRoot":"","sources":["../../../../packages/digitaldefiance-suite-core-lib/src/i18n-setup.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"i18n-setup.js","sourceRoot":"","sources":["../../../../packages/digitaldefiance-suite-core-lib/src/i18n-setup.ts"],"names":[],"mappings":"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"}
|