@digitaldefiance/i18n-lib 1.0.17 → 1.0.18
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/dist/context-manager.d.ts +23 -1
- package/dist/context-manager.js +22 -3
- package/dist/currency-code.d.ts +12 -0
- package/dist/currency-code.js +12 -0
- package/dist/currency-format.d.ts +3 -0
- package/dist/currency.d.ts +6 -0
- package/dist/currency.js +6 -0
- package/dist/enum-registry.d.ts +28 -2
- package/dist/enum-registry.js +26 -0
- package/dist/i18n-engine.d.ts +3 -0
- package/dist/i18n-engine.js +3 -0
- package/dist/template.d.ts +3 -0
- package/dist/template.js +0 -3
- package/dist/timezone.d.ts +6 -0
- package/dist/timezone.js +6 -0
- package/dist/types.d.ts +30 -0
- package/dist/types.js +3 -0
- package/dist/utils.d.ts +23 -0
- package/dist/utils.js +27 -1
- package/package.json +1 -1
|
@@ -2,10 +2,32 @@
|
|
|
2
2
|
* Context change management for i18n systems
|
|
3
3
|
*/
|
|
4
4
|
export type ContextChangeListener<T = any> = (property: string, oldValue: T, newValue: T) => void;
|
|
5
|
+
/**
|
|
6
|
+
* Manages context changes and notifies listeners.
|
|
7
|
+
*/
|
|
5
8
|
export declare class ContextManager<TContext extends Record<string, any>> {
|
|
6
|
-
|
|
9
|
+
protected listeners: ContextChangeListener[];
|
|
10
|
+
/**
|
|
11
|
+
* Adds a listener to be notified of context changes.
|
|
12
|
+
* @param listener - The listener function to add
|
|
13
|
+
*/
|
|
7
14
|
addListener(listener: ContextChangeListener): void;
|
|
15
|
+
/**
|
|
16
|
+
* Removes a listener from the notification list.
|
|
17
|
+
* @param listener - The listener function to remove
|
|
18
|
+
*/
|
|
8
19
|
removeListener(listener: ContextChangeListener): void;
|
|
20
|
+
/**
|
|
21
|
+
* Notifies all listeners of a context change.
|
|
22
|
+
* @param property - The property that changed
|
|
23
|
+
* @param oldValue - The old value of the property
|
|
24
|
+
* @param newValue - The new value of the property
|
|
25
|
+
*/
|
|
9
26
|
notifyChange<K extends keyof TContext>(property: K, oldValue: TContext[K], newValue: TContext[K]): void;
|
|
27
|
+
/**
|
|
28
|
+
* Creates a proxy for the given context to automatically notify listeners on changes.
|
|
29
|
+
* @param context - The context object to proxy
|
|
30
|
+
* @returns A proxied version of the context object
|
|
31
|
+
*/
|
|
10
32
|
createProxy(context: TContext): TContext;
|
|
11
33
|
}
|
package/dist/context-manager.js
CHANGED
|
@@ -1,22 +1,36 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Context change management for i18n systems
|
|
4
|
-
*/
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
3
|
exports.ContextManager = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Manages context changes and notifies listeners.
|
|
6
|
+
*/
|
|
7
7
|
class ContextManager {
|
|
8
8
|
constructor() {
|
|
9
9
|
this.listeners = [];
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* Adds a listener to be notified of context changes.
|
|
13
|
+
* @param listener - The listener function to add
|
|
14
|
+
*/
|
|
11
15
|
addListener(listener) {
|
|
12
16
|
this.listeners.push(listener);
|
|
13
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Removes a listener from the notification list.
|
|
20
|
+
* @param listener - The listener function to remove
|
|
21
|
+
*/
|
|
14
22
|
removeListener(listener) {
|
|
15
23
|
const index = this.listeners.indexOf(listener);
|
|
16
24
|
if (index > -1) {
|
|
17
25
|
this.listeners.splice(index, 1);
|
|
18
26
|
}
|
|
19
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Notifies all listeners of a context change.
|
|
30
|
+
* @param property - The property that changed
|
|
31
|
+
* @param oldValue - The old value of the property
|
|
32
|
+
* @param newValue - The new value of the property
|
|
33
|
+
*/
|
|
20
34
|
notifyChange(property, oldValue, newValue) {
|
|
21
35
|
this.listeners.forEach((listener) => {
|
|
22
36
|
try {
|
|
@@ -27,6 +41,11 @@ class ContextManager {
|
|
|
27
41
|
}
|
|
28
42
|
});
|
|
29
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Creates a proxy for the given context to automatically notify listeners on changes.
|
|
46
|
+
* @param context - The context object to proxy
|
|
47
|
+
* @returns A proxied version of the context object
|
|
48
|
+
*/
|
|
30
49
|
createProxy(context) {
|
|
31
50
|
const manager = this;
|
|
32
51
|
return new Proxy(context, {
|
package/dist/currency-code.d.ts
CHANGED
|
@@ -1,7 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Class representing a validated currency code.
|
|
3
|
+
*/
|
|
1
4
|
export declare class CurrencyCode {
|
|
2
5
|
private _value;
|
|
6
|
+
/**
|
|
7
|
+
* Gets the currency code value.
|
|
8
|
+
*/
|
|
3
9
|
get value(): string;
|
|
10
|
+
/**
|
|
11
|
+
* Sets the currency code value after validating it.
|
|
12
|
+
*/
|
|
4
13
|
set value(value: string);
|
|
14
|
+
/**
|
|
15
|
+
* Gets the list of all valid currency codes.
|
|
16
|
+
*/
|
|
5
17
|
static get values(): string[];
|
|
6
18
|
constructor(value?: string);
|
|
7
19
|
}
|
package/dist/currency-code.js
CHANGED
|
@@ -3,16 +3,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.CurrencyCode = void 0;
|
|
4
4
|
const currency_codes_1 = require("currency-codes");
|
|
5
5
|
const types_1 = require("./types");
|
|
6
|
+
/**
|
|
7
|
+
* Class representing a validated currency code.
|
|
8
|
+
*/
|
|
6
9
|
class CurrencyCode {
|
|
10
|
+
/**
|
|
11
|
+
* Gets the currency code value.
|
|
12
|
+
*/
|
|
7
13
|
get value() {
|
|
8
14
|
return this._value;
|
|
9
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Sets the currency code value after validating it.
|
|
18
|
+
*/
|
|
10
19
|
set value(value) {
|
|
11
20
|
if (!CurrencyCode.values.includes(value)) {
|
|
12
21
|
throw new Error('Invalid currency code');
|
|
13
22
|
}
|
|
14
23
|
this._value = value;
|
|
15
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Gets the list of all valid currency codes.
|
|
27
|
+
*/
|
|
16
28
|
static get values() {
|
|
17
29
|
return (0, currency_codes_1.codes)();
|
|
18
30
|
}
|
package/dist/currency.d.ts
CHANGED
|
@@ -2,4 +2,10 @@
|
|
|
2
2
|
* Currency formatting utilities
|
|
3
3
|
*/
|
|
4
4
|
import { CurrencyFormat } from './currency-format';
|
|
5
|
+
/**
|
|
6
|
+
* Get currency format details for a given locale and currency code.
|
|
7
|
+
* @param locale The locale string (e.g., 'en-US')
|
|
8
|
+
* @param currencyCode The ISO 4217 currency code (e.g., 'USD')
|
|
9
|
+
* @returns The currency format details
|
|
10
|
+
*/
|
|
5
11
|
export declare function getCurrencyFormat(locale: string, currencyCode: string): CurrencyFormat;
|
package/dist/currency.js
CHANGED
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.getCurrencyFormat = getCurrencyFormat;
|
|
7
|
+
/**
|
|
8
|
+
* Get currency format details for a given locale and currency code.
|
|
9
|
+
* @param locale The locale string (e.g., 'en-US')
|
|
10
|
+
* @param currencyCode The ISO 4217 currency code (e.g., 'USD')
|
|
11
|
+
* @returns The currency format details
|
|
12
|
+
*/
|
|
7
13
|
function getCurrencyFormat(locale, currencyCode) {
|
|
8
14
|
const formatter = new Intl.NumberFormat(locale, {
|
|
9
15
|
style: 'currency',
|
package/dist/enum-registry.d.ts
CHANGED
|
@@ -1,9 +1,35 @@
|
|
|
1
1
|
import { EnumLanguageTranslation } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Registry for managing enum translations across multiple languages.
|
|
4
|
+
*/
|
|
2
5
|
export declare class EnumTranslationRegistry<TLanguage extends string> {
|
|
3
|
-
|
|
4
|
-
|
|
6
|
+
protected translations: Map<any, Partial<{ [L in TLanguage]: import("./types").EnumTranslation<any>; }>>;
|
|
7
|
+
protected enumNames: WeakMap<any, string>;
|
|
8
|
+
/**
|
|
9
|
+
* Registers an enumeration with its translations and a name.
|
|
10
|
+
* @param enumObj The enumeration object
|
|
11
|
+
* @param translations The translations for the enumeration
|
|
12
|
+
* @param enumName The name of the enumeration
|
|
13
|
+
*/
|
|
5
14
|
register<TEnum extends string | number>(enumObj: Record<string, TEnum>, translations: EnumLanguageTranslation<TEnum, TLanguage>, enumName: string): void;
|
|
15
|
+
/**
|
|
16
|
+
* Translates a value from the given enumeration to the specified language.
|
|
17
|
+
* @param enumObj The enumeration object
|
|
18
|
+
* @param value The value to translate
|
|
19
|
+
* @param language The target language for translation
|
|
20
|
+
* @returns The translated string
|
|
21
|
+
*/
|
|
6
22
|
translate<TEnum extends string | number>(enumObj: Record<string, TEnum>, value: TEnum, language: TLanguage): string;
|
|
23
|
+
/**
|
|
24
|
+
* Gets the name of the enumeration.
|
|
25
|
+
* @param enumObj The enumeration object
|
|
26
|
+
* @returns The name of the enumeration
|
|
27
|
+
*/
|
|
7
28
|
private getEnumName;
|
|
29
|
+
/**
|
|
30
|
+
* Checks if the registry has translations for the given enumeration.
|
|
31
|
+
* @param enumObj The enumeration object
|
|
32
|
+
* @returns True if translations exist, false otherwise
|
|
33
|
+
*/
|
|
8
34
|
has(enumObj: any): boolean;
|
|
9
35
|
}
|
package/dist/enum-registry.js
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.EnumTranslationRegistry = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Registry for managing enum translations across multiple languages.
|
|
6
|
+
*/
|
|
4
7
|
class EnumTranslationRegistry {
|
|
5
8
|
constructor() {
|
|
6
9
|
this.translations = new Map();
|
|
7
10
|
this.enumNames = new WeakMap();
|
|
8
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Registers an enumeration with its translations and a name.
|
|
14
|
+
* @param enumObj The enumeration object
|
|
15
|
+
* @param translations The translations for the enumeration
|
|
16
|
+
* @param enumName The name of the enumeration
|
|
17
|
+
*/
|
|
9
18
|
register(enumObj, translations, enumName) {
|
|
10
19
|
this.translations.set(enumObj, translations);
|
|
11
20
|
this.enumNames.set(enumObj, enumName);
|
|
12
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Translates a value from the given enumeration to the specified language.
|
|
24
|
+
* @param enumObj The enumeration object
|
|
25
|
+
* @param value The value to translate
|
|
26
|
+
* @param language The target language for translation
|
|
27
|
+
* @returns The translated string
|
|
28
|
+
*/
|
|
13
29
|
translate(enumObj, value, language) {
|
|
14
30
|
const translations = this.translations.get(enumObj);
|
|
15
31
|
if (!translations) {
|
|
@@ -31,9 +47,19 @@ class EnumTranslationRegistry {
|
|
|
31
47
|
}
|
|
32
48
|
return result;
|
|
33
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Gets the name of the enumeration.
|
|
52
|
+
* @param enumObj The enumeration object
|
|
53
|
+
* @returns The name of the enumeration
|
|
54
|
+
*/
|
|
34
55
|
getEnumName(enumObj) {
|
|
35
56
|
return this.enumNames.get(enumObj) || 'UnknownEnum';
|
|
36
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Checks if the registry has translations for the given enumeration.
|
|
60
|
+
* @param enumObj The enumeration object
|
|
61
|
+
* @returns True if translations exist, false otherwise
|
|
62
|
+
*/
|
|
37
63
|
has(enumObj) {
|
|
38
64
|
return this.translations.has(enumObj);
|
|
39
65
|
}
|
package/dist/i18n-engine.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { EnumTranslationRegistry } from './enum-registry';
|
|
2
2
|
import { EnumLanguageTranslation, I18nConfig, I18nContext } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Internationalization engine class
|
|
5
|
+
*/
|
|
3
6
|
export declare class I18nEngine<TStringKey extends string, TLanguage extends string, TConstants extends Record<string, any> = Record<string, any>, TContext extends string = string> {
|
|
4
7
|
/**
|
|
5
8
|
* Registry for enum translations
|
package/dist/i18n-engine.js
CHANGED
|
@@ -5,6 +5,9 @@ const context_1 = require("./context");
|
|
|
5
5
|
const enum_registry_1 = require("./enum-registry");
|
|
6
6
|
const template_1 = require("./template");
|
|
7
7
|
const utils_1 = require("./utils");
|
|
8
|
+
/**
|
|
9
|
+
* Internationalization engine class
|
|
10
|
+
*/
|
|
8
11
|
class I18nEngine {
|
|
9
12
|
/**
|
|
10
13
|
* Creates a new I18nEngine instance
|
package/dist/template.d.ts
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
* Template processing utilities for i18n
|
|
3
3
|
*/
|
|
4
4
|
export type EnumKeys<T> = keyof T;
|
|
5
|
+
/**
|
|
6
|
+
* Recursive type to validate that all enum keys in the template string exist in the provided enum type
|
|
7
|
+
*/
|
|
5
8
|
export type IsValidEnumTemplate<T extends string, TEnum> = T extends `${string}{{${string}.${infer Key}}}${infer Rest}` ? Key extends EnumKeys<TEnum> ? IsValidEnumTemplate<Rest, TEnum> : false : true;
|
|
6
9
|
/**
|
|
7
10
|
* Template function that processes {{EnumName.EnumKey}} patterns
|
package/dist/template.js
CHANGED
package/dist/timezone.d.ts
CHANGED
package/dist/timezone.js
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Timezone = void 0;
|
|
4
4
|
const utils_1 = require("./utils");
|
|
5
|
+
/**
|
|
6
|
+
* Class representing a validated timezone.
|
|
7
|
+
*/
|
|
5
8
|
class Timezone {
|
|
6
9
|
constructor(timezone) {
|
|
7
10
|
if (!(0, utils_1.isValidTimezone)(timezone)) {
|
|
@@ -9,6 +12,9 @@ class Timezone {
|
|
|
9
12
|
}
|
|
10
13
|
this._timezone = timezone;
|
|
11
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Gets the timezone value.
|
|
17
|
+
*/
|
|
12
18
|
get value() {
|
|
13
19
|
return this._timezone;
|
|
14
20
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,13 +1,40 @@
|
|
|
1
1
|
import { CurrencyCode } from './currency-code';
|
|
2
2
|
import { Timezone } from './timezone';
|
|
3
|
+
/**
|
|
4
|
+
* Standard language contexts
|
|
5
|
+
*/
|
|
3
6
|
export type LanguageContext = 'admin' | 'user' | 'system' | 'api';
|
|
7
|
+
/**
|
|
8
|
+
* Default currency code
|
|
9
|
+
*/
|
|
4
10
|
export declare const DefaultCurrencyCode: string;
|
|
11
|
+
/**
|
|
12
|
+
* Currency position type
|
|
13
|
+
*/
|
|
5
14
|
export type CurrencyPosition = 'prefix' | 'postfix' | 'infix';
|
|
15
|
+
/**
|
|
16
|
+
* Custom language context type
|
|
17
|
+
*/
|
|
6
18
|
export type CustomLanguageContext<T extends string = LanguageContext> = T;
|
|
19
|
+
/**
|
|
20
|
+
* Collection of localized strings for a specific language
|
|
21
|
+
*/
|
|
7
22
|
export type StringsCollection<TStringKey extends string> = Partial<Record<TStringKey, string>>;
|
|
23
|
+
/**
|
|
24
|
+
* Mapping of languages to their respective string collections
|
|
25
|
+
*/
|
|
8
26
|
export type MasterStringsCollection<TStringKey extends string, TLanguage extends string> = Partial<Record<TLanguage, StringsCollection<TStringKey>>>;
|
|
27
|
+
/**
|
|
28
|
+
* Mapping of language codes to their respective languages
|
|
29
|
+
*/
|
|
9
30
|
export type LanguageCodeCollection<TLanguage extends string> = Partial<Record<TLanguage, string>>;
|
|
31
|
+
/**
|
|
32
|
+
* Mapping of enumeration values to their translations in multiple languages
|
|
33
|
+
*/
|
|
10
34
|
export type EnumTranslationMap<TEnum extends string | number, TLanguage extends string> = Partial<Record<TLanguage, Partial<Record<TEnum, string>>>>;
|
|
35
|
+
/**
|
|
36
|
+
* I18n configuration interface
|
|
37
|
+
*/
|
|
11
38
|
export interface I18nConfig<TStringKey extends string, TLanguage extends string, TConstants extends Record<string, any> = Record<string, any>, TTranslationContext extends string = LanguageContext> {
|
|
12
39
|
stringNames: TStringKey[];
|
|
13
40
|
strings: MasterStringsCollection<TStringKey, TLanguage>;
|
|
@@ -22,6 +49,9 @@ export interface I18nConfig<TStringKey extends string, TLanguage extends string,
|
|
|
22
49
|
timezone: Timezone;
|
|
23
50
|
adminTimezone: Timezone;
|
|
24
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* I18n context interface
|
|
54
|
+
*/
|
|
25
55
|
export interface I18nContext<TLanguage extends string, TTranslationContext extends string = LanguageContext> {
|
|
26
56
|
language: TLanguage;
|
|
27
57
|
adminLanguage: TLanguage;
|
package/dist/types.js
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DefaultCurrencyCode = void 0;
|
|
4
4
|
exports.createTranslations = createTranslations;
|
|
5
|
+
/**
|
|
6
|
+
* Default currency code
|
|
7
|
+
*/
|
|
5
8
|
exports.DefaultCurrencyCode = 'USD';
|
|
6
9
|
/**
|
|
7
10
|
* Helper function to create typed translations for an enumeration
|
package/dist/utils.d.ts
CHANGED
|
@@ -1,3 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replaces variables in a string with their corresponding values from vars or constants.
|
|
3
|
+
* @param str - The string containing variables to replace
|
|
4
|
+
* @param vars - An object mapping variable names to their replacement values
|
|
5
|
+
* @param constants - An object containing constant values for replacement
|
|
6
|
+
* @returns The string with variables replaced
|
|
7
|
+
*/
|
|
1
8
|
export declare function replaceVariables(str: string, vars?: Record<string, string | number>, constants?: any): string;
|
|
9
|
+
/**
|
|
10
|
+
* Checks if a given key indicates a template string.
|
|
11
|
+
* @param key - The key to check
|
|
12
|
+
* @returns True if the key indicates a template, false otherwise
|
|
13
|
+
*/
|
|
2
14
|
export declare function isTemplate(key: string): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Checks if a given timezone string is valid.
|
|
17
|
+
* @param timezone - The timezone string to validate
|
|
18
|
+
* @returns
|
|
19
|
+
*/
|
|
3
20
|
export declare function isValidTimezone(timezone: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Converts parts to a single string key, joining with underscores.
|
|
23
|
+
* @param parts - The parts to join
|
|
24
|
+
* @returns The joined string key
|
|
25
|
+
*/
|
|
26
|
+
export declare function toStringKey<TStringKey extends string>(...parts: (string)[]): TStringKey;
|
package/dist/utils.js
CHANGED
|
@@ -6,7 +6,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.replaceVariables = replaceVariables;
|
|
7
7
|
exports.isTemplate = isTemplate;
|
|
8
8
|
exports.isValidTimezone = isValidTimezone;
|
|
9
|
+
exports.toStringKey = toStringKey;
|
|
9
10
|
const moment_timezone_1 = __importDefault(require("moment-timezone"));
|
|
11
|
+
/**
|
|
12
|
+
* Replaces variables in a string with their corresponding values from vars or constants.
|
|
13
|
+
* @param str - The string containing variables to replace
|
|
14
|
+
* @param vars - An object mapping variable names to their replacement values
|
|
15
|
+
* @param constants - An object containing constant values for replacement
|
|
16
|
+
* @returns The string with variables replaced
|
|
17
|
+
*/
|
|
10
18
|
function replaceVariables(str, vars, constants) {
|
|
11
19
|
const variables = str.match(/\{(.+?)\}/g);
|
|
12
20
|
if (!variables)
|
|
@@ -27,9 +35,27 @@ function replaceVariables(str, vars, constants) {
|
|
|
27
35
|
}
|
|
28
36
|
return result;
|
|
29
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Checks if a given key indicates a template string.
|
|
40
|
+
* @param key - The key to check
|
|
41
|
+
* @returns True if the key indicates a template, false otherwise
|
|
42
|
+
*/
|
|
30
43
|
function isTemplate(key) {
|
|
31
|
-
return key.toLowerCase().endsWith('template');
|
|
44
|
+
return key.trim().toLowerCase().endsWith('template');
|
|
32
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Checks if a given timezone string is valid.
|
|
48
|
+
* @param timezone - The timezone string to validate
|
|
49
|
+
* @returns
|
|
50
|
+
*/
|
|
33
51
|
function isValidTimezone(timezone) {
|
|
34
52
|
return moment_timezone_1.default.tz.zone(timezone) !== null;
|
|
35
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Converts parts to a single string key, joining with underscores.
|
|
56
|
+
* @param parts - The parts to join
|
|
57
|
+
* @returns The joined string key
|
|
58
|
+
*/
|
|
59
|
+
function toStringKey(...parts) {
|
|
60
|
+
return parts.join('_');
|
|
61
|
+
}
|