locl-js 1.0.0 → 1.0.2

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025 Sztrida Sámuel
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Sztrida Sámuel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.d.mts CHANGED
@@ -49,7 +49,7 @@ declare const defaultFormatters: {
49
49
  * @param {string} [args[1]="..."] - The suffix to append if the string is truncated.
50
50
  * @returns The truncated string.
51
51
  */
52
- truncate: (val: any, args: string[]) => string;
52
+ truncate: (val: any, args?: string[]) => string;
53
53
  /**
54
54
  * Formats a number using `Intl.NumberFormat`.
55
55
  * @param val - The value to format.
@@ -58,7 +58,7 @@ declare const defaultFormatters: {
58
58
  * @param {string} [args[1]] - The style of formatting to use (e.g., "decimal", "percent").
59
59
  * @returns The formatted number.
60
60
  */
61
- number: (val: any, args: string[]) => string;
61
+ number: (val: any, args?: string[]) => string;
62
62
  /**
63
63
  * Formats a number as a currency string using `Intl.NumberFormat`.
64
64
  * @param val - The value to format.
@@ -67,7 +67,7 @@ declare const defaultFormatters: {
67
67
  * @param {string} [args[1]] - The locale to use.
68
68
  * @returns The formatted currency string.
69
69
  */
70
- currency: (val: any, args: string[]) => string;
70
+ currency: (val: any, args?: string[]) => string;
71
71
  /**
72
72
  * Formats a date using `Intl.DateTimeFormat`.
73
73
  * @param val - The value to format.
@@ -76,7 +76,7 @@ declare const defaultFormatters: {
76
76
  * @param {string} [args[1]] - The date style to use (e.g., "short", "long").
77
77
  * @returns The formatted date string.
78
78
  */
79
- date: (val: any, args: string[]) => string;
79
+ date: (val: any, args?: string[]) => string;
80
80
  /**
81
81
  * Formats a date as a relative time string (e.g., "2 hours ago").
82
82
  * @param val - The value to format.
@@ -84,7 +84,7 @@ declare const defaultFormatters: {
84
84
  * @param {string} [args[0]] - The locale to use.
85
85
  * @returns The relative time string.
86
86
  */
87
- relativeDate: (val: any, args: string[]) => string;
87
+ relativeDate: (val: any, args?: string[]) => string;
88
88
  /**
89
89
  * Converts a value to a JSON string.
90
90
  * @param val - The value to format.
@@ -99,7 +99,7 @@ declare const defaultFormatters: {
99
99
  * @param {string} [args[1]="No"] - The string to return for a falsy value.
100
100
  * @returns "Yes" or "No".
101
101
  */
102
- yesNo: (val: any, args?: [string, string]) => string;
102
+ yesNo: (val: any, args?: string[]) => string;
103
103
  /**
104
104
  * Converts a boolean value to a "true" or "false" string.
105
105
  * @param val - The value to format.
@@ -108,7 +108,7 @@ declare const defaultFormatters: {
108
108
  * @param {string} [args[1]="false"] - The string to return for a falsy value.
109
109
  * @returns "true" or "false".
110
110
  */
111
- boolean: (val: any, args?: [string, string]) => string;
111
+ boolean: (val: any, args?: string[]) => string;
112
112
  /**
113
113
  * Pads the start of a string with another string.
114
114
  * @param val - The value to format.
@@ -117,7 +117,7 @@ declare const defaultFormatters: {
117
117
  * @param {string} [args[1]=" "] - The string to pad with.
118
118
  * @returns The padded string.
119
119
  */
120
- padStart: (val: any, args: string[]) => string;
120
+ padStart: (val: any, args?: string[]) => string;
121
121
  /**
122
122
  * Pads the end of a string with another string.
123
123
  * @param val - The value to format.
@@ -126,16 +126,16 @@ declare const defaultFormatters: {
126
126
  * @param {string} [args[1]=" "] - The string to pad with.
127
127
  * @returns The padded string.
128
128
  */
129
- padEnd: (val: any, args: string[]) => string;
129
+ padEnd: (val: any, args?: string[]) => string;
130
130
  };
131
131
 
132
- type NestedKeyOf<ObjectType extends object> = {
133
- [Key in keyof ObjectType & string]: ObjectType[Key] extends any[] ? `${Key}` : ObjectType[Key] extends object ? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key]>}` : `${Key}`;
132
+ type NestedKeyOf<ObjectType extends object, Depth extends number = 8, UsedDepth extends any[] = []> = UsedDepth['length'] extends Depth ? never : {
133
+ [Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends any[] ? `${Key}` : ObjectType[Key] extends object ? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key], Depth, [...UsedDepth, any]>}` : `${Key}`;
134
+ }[keyof ObjectType & (string | number)];
135
+ type NestedKeyOfObj<ObjectType extends object, SkipArrays extends boolean = false, Depth extends number = 8, UsedDepth extends any[] = []> = UsedDepth['length'] extends Depth ? never : {
136
+ [Key in keyof ObjectType & string]: ObjectType[Key] extends Array<any> ? SkipArrays extends true ? never : `${Key}` | `${Key}.${number}` : ObjectType[Key] extends object ? `${Key}` | `${Key}.${NestedKeyOfObj<ObjectType[Key], SkipArrays, Depth, [...UsedDepth, any]>}` : never;
134
137
  }[keyof ObjectType & string];
135
- type NestedKeyOfObj<ObjectType extends object, SkipArrays extends boolean = false> = {
136
- [Key in keyof ObjectType & string]: ObjectType[Key] extends Array<any> ? SkipArrays extends true ? never : `${Key}` | `${Key}.${number}` : ObjectType[Key] extends object ? `${Key}` | `${Key}.${NestedKeyOfObj<ObjectType[Key], SkipArrays>}` : never;
137
- }[keyof ObjectType & string];
138
- type PathValue<T, P extends string> = P extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? Rest extends string ? PathValue<T[Key], Rest> : never : never : P extends keyof T ? T[P] : never;
138
+ type PathValue<T, P extends string> = P extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? PathValue<T[Key], Rest> : Key extends `${infer N extends number}` ? N extends keyof T ? PathValue<T[N], Rest> : never : never : P extends keyof T ? T[P] : P extends `${infer N extends number}` ? N extends keyof T ? T[N] : never : never;
139
139
  type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
140
140
  type DeepPick<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? {
141
141
  [Key in K]: DeepPick<T[K], Rest>;
@@ -150,7 +150,7 @@ type TranslationObjectFor<S extends Scope<T, Fallback> | Scope<T, Fallback>[] |
150
150
  type Translations<S extends ScopeType<T, F>, T extends Record<string, any>, F extends keyof T & string> = TranslationObjectFor<S, T, F>;
151
151
  type PluralForms = "zero" | "one" | "two" | "few" | "many" | "other";
152
152
  type PluralKeys<S extends ScopeType<T, F>, T extends Record<string, any>, F extends keyof T & string> = ExtractPluralKeys<Translations<S, T, F>>;
153
- type ExtractPluralKeys<T, Path extends string = "", Depth extends any[] = []> = Depth['length'] extends 32 ? never : T extends object ? {
153
+ type ExtractPluralKeys<T, Path extends string = "", Depth extends any[] = []> = Depth['length'] extends 16 ? never : T extends object ? {
154
154
  [K in keyof T & string]: T[K] extends Partial<Record<PluralForms, string>> ? Path extends "" ? K : `${Path}.${K}` : K extends `${infer Base}_one` ? `${Base}_other` extends keyof T ? Path extends "" ? Base : `${Path}.${Base}` : never : T[K] extends object ? ExtractPluralKeys<T[K], Path extends "" ? K : `${Path}.${K}`, [...Depth, 1]> : never;
155
155
  }[keyof T & string] : never;
156
156
  interface InterpolationOptions {
@@ -173,7 +173,7 @@ type ObjectPlural = {
173
173
  [K in RequiredPlural]: string;
174
174
  } & Partial<Record<OptionalPlural, string>>;
175
175
  type Primitive = string | number | boolean | null | undefined;
176
- type StrKey<T> = Extract<keyof T, string>;
176
+ type StrKey<T> = Extract<keyof T, string | number>;
177
177
  type PluralObjectKeys<T> = {
178
178
  [K in StrKey<T>]: T[K] extends object ? Extract<keyof T[K], PluralForms> extends never ? never : K : never;
179
179
  }[StrKey<T>];
@@ -249,6 +249,7 @@ declare class LocL<T extends Record<string, any>, Fallback extends keyof T & str
249
249
  fallbackLanguage: Fallback;
250
250
  formatters?: F;
251
251
  useDefaultFormatters?: UseDefaultFormatter;
252
+ scope?: S;
252
253
  });
253
254
  /**
254
255
  * Creates a new proxy translator instance with a different configuration.
@@ -284,7 +285,7 @@ declare class LocL<T extends Record<string, any>, Fallback extends keyof T & str
284
285
  * @returns The translated and formatted string, or the translation object.
285
286
  */
286
287
  t(): TranslationObjectFor<S, T, Fallback>;
287
- t<K extends NestedKeyOf<TranslationObjectFor<S, T, Fallback>>>(key: K, values?: InterpolationOptions, format?: FormatOptions<F, UseDefaultFormatter>): PathValue<TranslationObjectFor<S, T, Fallback>, K> extends string ? string : PathValue<TranslationObjectFor<S, T, Fallback>, K>;
288
+ t<K extends NestedKeyOf<TranslationObjectFor<S, T, Fallback>>>(key: K, values?: InterpolationOptions, format?: FormatOptions<F, UseDefaultFormatter>): PathValue<TranslationObjectFor<S, T, Fallback>, K>;
288
289
  /**
289
290
  * Translates a key without strict type checking.
290
291
  * This is useful for compatibility with other i18n libraries or dynamic keys.
@@ -371,7 +372,7 @@ declare class LocL<T extends Record<string, any>, Fallback extends keyof T & str
371
372
  *
372
373
  * @returns A new `LocL` instance configured with the provided options.
373
374
  */
374
- declare function initLocL<T extends Record<string, any>, Fallback extends keyof T & string, S extends ScopeType<T, Fallback> | undefined = undefined, F extends Record<string, Formatter> = {}, UseDefaultFormatter extends boolean = true>(config: LocLConfig<T, Fallback> & {
375
+ declare function initLocL<T extends Record<string, any>, Fallback extends keyof T & string, S extends ScopeType<T, Fallback> = undefined, F extends Record<string, Formatter> = {}, UseDefaultFormatter extends boolean = true>(config: LocLConfig<T, Fallback> & {
375
376
  scope?: S;
376
377
  formatters?: F;
377
378
  useDefaultFormatters?: UseDefaultFormatter;
package/dist/index.d.ts CHANGED
@@ -49,7 +49,7 @@ declare const defaultFormatters: {
49
49
  * @param {string} [args[1]="..."] - The suffix to append if the string is truncated.
50
50
  * @returns The truncated string.
51
51
  */
52
- truncate: (val: any, args: string[]) => string;
52
+ truncate: (val: any, args?: string[]) => string;
53
53
  /**
54
54
  * Formats a number using `Intl.NumberFormat`.
55
55
  * @param val - The value to format.
@@ -58,7 +58,7 @@ declare const defaultFormatters: {
58
58
  * @param {string} [args[1]] - The style of formatting to use (e.g., "decimal", "percent").
59
59
  * @returns The formatted number.
60
60
  */
61
- number: (val: any, args: string[]) => string;
61
+ number: (val: any, args?: string[]) => string;
62
62
  /**
63
63
  * Formats a number as a currency string using `Intl.NumberFormat`.
64
64
  * @param val - The value to format.
@@ -67,7 +67,7 @@ declare const defaultFormatters: {
67
67
  * @param {string} [args[1]] - The locale to use.
68
68
  * @returns The formatted currency string.
69
69
  */
70
- currency: (val: any, args: string[]) => string;
70
+ currency: (val: any, args?: string[]) => string;
71
71
  /**
72
72
  * Formats a date using `Intl.DateTimeFormat`.
73
73
  * @param val - The value to format.
@@ -76,7 +76,7 @@ declare const defaultFormatters: {
76
76
  * @param {string} [args[1]] - The date style to use (e.g., "short", "long").
77
77
  * @returns The formatted date string.
78
78
  */
79
- date: (val: any, args: string[]) => string;
79
+ date: (val: any, args?: string[]) => string;
80
80
  /**
81
81
  * Formats a date as a relative time string (e.g., "2 hours ago").
82
82
  * @param val - The value to format.
@@ -84,7 +84,7 @@ declare const defaultFormatters: {
84
84
  * @param {string} [args[0]] - The locale to use.
85
85
  * @returns The relative time string.
86
86
  */
87
- relativeDate: (val: any, args: string[]) => string;
87
+ relativeDate: (val: any, args?: string[]) => string;
88
88
  /**
89
89
  * Converts a value to a JSON string.
90
90
  * @param val - The value to format.
@@ -99,7 +99,7 @@ declare const defaultFormatters: {
99
99
  * @param {string} [args[1]="No"] - The string to return for a falsy value.
100
100
  * @returns "Yes" or "No".
101
101
  */
102
- yesNo: (val: any, args?: [string, string]) => string;
102
+ yesNo: (val: any, args?: string[]) => string;
103
103
  /**
104
104
  * Converts a boolean value to a "true" or "false" string.
105
105
  * @param val - The value to format.
@@ -108,7 +108,7 @@ declare const defaultFormatters: {
108
108
  * @param {string} [args[1]="false"] - The string to return for a falsy value.
109
109
  * @returns "true" or "false".
110
110
  */
111
- boolean: (val: any, args?: [string, string]) => string;
111
+ boolean: (val: any, args?: string[]) => string;
112
112
  /**
113
113
  * Pads the start of a string with another string.
114
114
  * @param val - The value to format.
@@ -117,7 +117,7 @@ declare const defaultFormatters: {
117
117
  * @param {string} [args[1]=" "] - The string to pad with.
118
118
  * @returns The padded string.
119
119
  */
120
- padStart: (val: any, args: string[]) => string;
120
+ padStart: (val: any, args?: string[]) => string;
121
121
  /**
122
122
  * Pads the end of a string with another string.
123
123
  * @param val - The value to format.
@@ -126,16 +126,16 @@ declare const defaultFormatters: {
126
126
  * @param {string} [args[1]=" "] - The string to pad with.
127
127
  * @returns The padded string.
128
128
  */
129
- padEnd: (val: any, args: string[]) => string;
129
+ padEnd: (val: any, args?: string[]) => string;
130
130
  };
131
131
 
132
- type NestedKeyOf<ObjectType extends object> = {
133
- [Key in keyof ObjectType & string]: ObjectType[Key] extends any[] ? `${Key}` : ObjectType[Key] extends object ? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key]>}` : `${Key}`;
132
+ type NestedKeyOf<ObjectType extends object, Depth extends number = 8, UsedDepth extends any[] = []> = UsedDepth['length'] extends Depth ? never : {
133
+ [Key in keyof ObjectType & (string | number)]: ObjectType[Key] extends any[] ? `${Key}` : ObjectType[Key] extends object ? `${Key}` | `${Key}.${NestedKeyOf<ObjectType[Key], Depth, [...UsedDepth, any]>}` : `${Key}`;
134
+ }[keyof ObjectType & (string | number)];
135
+ type NestedKeyOfObj<ObjectType extends object, SkipArrays extends boolean = false, Depth extends number = 8, UsedDepth extends any[] = []> = UsedDepth['length'] extends Depth ? never : {
136
+ [Key in keyof ObjectType & string]: ObjectType[Key] extends Array<any> ? SkipArrays extends true ? never : `${Key}` | `${Key}.${number}` : ObjectType[Key] extends object ? `${Key}` | `${Key}.${NestedKeyOfObj<ObjectType[Key], SkipArrays, Depth, [...UsedDepth, any]>}` : never;
134
137
  }[keyof ObjectType & string];
135
- type NestedKeyOfObj<ObjectType extends object, SkipArrays extends boolean = false> = {
136
- [Key in keyof ObjectType & string]: ObjectType[Key] extends Array<any> ? SkipArrays extends true ? never : `${Key}` | `${Key}.${number}` : ObjectType[Key] extends object ? `${Key}` | `${Key}.${NestedKeyOfObj<ObjectType[Key], SkipArrays>}` : never;
137
- }[keyof ObjectType & string];
138
- type PathValue<T, P extends string> = P extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? Rest extends string ? PathValue<T[Key], Rest> : never : never : P extends keyof T ? T[P] : never;
138
+ type PathValue<T, P extends string> = P extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? PathValue<T[Key], Rest> : Key extends `${infer N extends number}` ? N extends keyof T ? PathValue<T[N], Rest> : never : never : P extends keyof T ? T[P] : P extends `${infer N extends number}` ? N extends keyof T ? T[N] : never : never;
139
139
  type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
140
140
  type DeepPick<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? {
141
141
  [Key in K]: DeepPick<T[K], Rest>;
@@ -150,7 +150,7 @@ type TranslationObjectFor<S extends Scope<T, Fallback> | Scope<T, Fallback>[] |
150
150
  type Translations<S extends ScopeType<T, F>, T extends Record<string, any>, F extends keyof T & string> = TranslationObjectFor<S, T, F>;
151
151
  type PluralForms = "zero" | "one" | "two" | "few" | "many" | "other";
152
152
  type PluralKeys<S extends ScopeType<T, F>, T extends Record<string, any>, F extends keyof T & string> = ExtractPluralKeys<Translations<S, T, F>>;
153
- type ExtractPluralKeys<T, Path extends string = "", Depth extends any[] = []> = Depth['length'] extends 32 ? never : T extends object ? {
153
+ type ExtractPluralKeys<T, Path extends string = "", Depth extends any[] = []> = Depth['length'] extends 16 ? never : T extends object ? {
154
154
  [K in keyof T & string]: T[K] extends Partial<Record<PluralForms, string>> ? Path extends "" ? K : `${Path}.${K}` : K extends `${infer Base}_one` ? `${Base}_other` extends keyof T ? Path extends "" ? Base : `${Path}.${Base}` : never : T[K] extends object ? ExtractPluralKeys<T[K], Path extends "" ? K : `${Path}.${K}`, [...Depth, 1]> : never;
155
155
  }[keyof T & string] : never;
156
156
  interface InterpolationOptions {
@@ -173,7 +173,7 @@ type ObjectPlural = {
173
173
  [K in RequiredPlural]: string;
174
174
  } & Partial<Record<OptionalPlural, string>>;
175
175
  type Primitive = string | number | boolean | null | undefined;
176
- type StrKey<T> = Extract<keyof T, string>;
176
+ type StrKey<T> = Extract<keyof T, string | number>;
177
177
  type PluralObjectKeys<T> = {
178
178
  [K in StrKey<T>]: T[K] extends object ? Extract<keyof T[K], PluralForms> extends never ? never : K : never;
179
179
  }[StrKey<T>];
@@ -249,6 +249,7 @@ declare class LocL<T extends Record<string, any>, Fallback extends keyof T & str
249
249
  fallbackLanguage: Fallback;
250
250
  formatters?: F;
251
251
  useDefaultFormatters?: UseDefaultFormatter;
252
+ scope?: S;
252
253
  });
253
254
  /**
254
255
  * Creates a new proxy translator instance with a different configuration.
@@ -284,7 +285,7 @@ declare class LocL<T extends Record<string, any>, Fallback extends keyof T & str
284
285
  * @returns The translated and formatted string, or the translation object.
285
286
  */
286
287
  t(): TranslationObjectFor<S, T, Fallback>;
287
- t<K extends NestedKeyOf<TranslationObjectFor<S, T, Fallback>>>(key: K, values?: InterpolationOptions, format?: FormatOptions<F, UseDefaultFormatter>): PathValue<TranslationObjectFor<S, T, Fallback>, K> extends string ? string : PathValue<TranslationObjectFor<S, T, Fallback>, K>;
288
+ t<K extends NestedKeyOf<TranslationObjectFor<S, T, Fallback>>>(key: K, values?: InterpolationOptions, format?: FormatOptions<F, UseDefaultFormatter>): PathValue<TranslationObjectFor<S, T, Fallback>, K>;
288
289
  /**
289
290
  * Translates a key without strict type checking.
290
291
  * This is useful for compatibility with other i18n libraries or dynamic keys.
@@ -371,7 +372,7 @@ declare class LocL<T extends Record<string, any>, Fallback extends keyof T & str
371
372
  *
372
373
  * @returns A new `LocL` instance configured with the provided options.
373
374
  */
374
- declare function initLocL<T extends Record<string, any>, Fallback extends keyof T & string, S extends ScopeType<T, Fallback> | undefined = undefined, F extends Record<string, Formatter> = {}, UseDefaultFormatter extends boolean = true>(config: LocLConfig<T, Fallback> & {
375
+ declare function initLocL<T extends Record<string, any>, Fallback extends keyof T & string, S extends ScopeType<T, Fallback> = undefined, F extends Record<string, Formatter> = {}, UseDefaultFormatter extends boolean = true>(config: LocLConfig<T, Fallback> & {
375
376
  scope?: S;
376
377
  formatters?: F;
377
378
  useDefaultFormatters?: UseDefaultFormatter;
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ var defaultFormatters = {
58
58
  * @param {string} [args[1]="..."] - The suffix to append if the string is truncated.
59
59
  * @returns The truncated string.
60
60
  */
61
- truncate: (val, args) => {
61
+ truncate: (val, args = []) => {
62
62
  const length = parseInt(args[0]) || 10;
63
63
  const suffix = args[1] || "...";
64
64
  const str = String(val);
@@ -72,7 +72,7 @@ var defaultFormatters = {
72
72
  * @param {string} [args[1]] - The style of formatting to use (e.g., "decimal", "percent").
73
73
  * @returns The formatted number.
74
74
  */
75
- number: (val, args) => {
75
+ number: (val, args = []) => {
76
76
  const locales = args[0] || void 0;
77
77
  const options = {};
78
78
  if (args[1]) options.style = args[1];
@@ -86,7 +86,7 @@ var defaultFormatters = {
86
86
  * @param {string} [args[1]] - The locale to use.
87
87
  * @returns The formatted currency string.
88
88
  */
89
- currency: (val, args) => {
89
+ currency: (val, args = []) => {
90
90
  const currency = args[0] || "USD";
91
91
  const locales = args[1] || void 0;
92
92
  return new Intl.NumberFormat(locales, {
@@ -102,7 +102,7 @@ var defaultFormatters = {
102
102
  * @param {string} [args[1]] - The date style to use (e.g., "short", "long").
103
103
  * @returns The formatted date string.
104
104
  */
105
- date: (val, args) => {
105
+ date: (val, args = []) => {
106
106
  const locales = args[0] || void 0;
107
107
  const options = {};
108
108
  if (args[1]) options.dateStyle = args[1];
@@ -115,7 +115,7 @@ var defaultFormatters = {
115
115
  * @param {string} [args[0]] - The locale to use.
116
116
  * @returns The relative time string.
117
117
  */
118
- relativeDate: (val, args) => {
118
+ relativeDate: (val, args = []) => {
119
119
  const locales = args[0] || void 0;
120
120
  const options = { numeric: "auto" };
121
121
  const rtf = new Intl.RelativeTimeFormat(locales, options);
@@ -139,7 +139,7 @@ var defaultFormatters = {
139
139
  * @param {string} [args[1]="No"] - The string to return for a falsy value.
140
140
  * @returns "Yes" or "No".
141
141
  */
142
- yesNo: (val, args) => {
142
+ yesNo: (val, args = []) => {
143
143
  const [yesVal, noVal] = args || [];
144
144
  return val ? yesVal || "Yes" : noVal || "No";
145
145
  },
@@ -151,7 +151,7 @@ var defaultFormatters = {
151
151
  * @param {string} [args[1]="false"] - The string to return for a falsy value.
152
152
  * @returns "true" or "false".
153
153
  */
154
- boolean: (val, args) => {
154
+ boolean: (val, args = []) => {
155
155
  const [trueVal, falseVal] = args || [];
156
156
  return val ? trueVal || "true" : falseVal || "false";
157
157
  },
@@ -163,7 +163,7 @@ var defaultFormatters = {
163
163
  * @param {string} [args[1]=" "] - The string to pad with.
164
164
  * @returns The padded string.
165
165
  */
166
- padStart: (val, args) => {
166
+ padStart: (val, args = []) => {
167
167
  const length = parseInt(args[0]) || 0;
168
168
  const fill = args[1] || " ";
169
169
  return String(val).padStart(length, fill);
@@ -176,7 +176,7 @@ var defaultFormatters = {
176
176
  * @param {string} [args[1]=" "] - The string to pad with.
177
177
  * @returns The padded string.
178
178
  */
179
- padEnd: (val, args) => {
179
+ padEnd: (val, args = []) => {
180
180
  const length = parseInt(args[0]) || 0;
181
181
  const fill = args[1] || " ";
182
182
  return String(val).padEnd(length, fill);
@@ -226,7 +226,7 @@ var LocL = class _LocL {
226
226
  if (this.cache.has(cacheKey)) {
227
227
  return this.cache.get(cacheKey);
228
228
  }
229
- return new Proxy(this, {
229
+ const result = new Proxy(this, {
230
230
  get(target, prop) {
231
231
  if (prop === "language") {
232
232
  return config.language ?? target.language;
@@ -237,6 +237,8 @@ var LocL = class _LocL {
237
237
  return target[prop];
238
238
  }
239
239
  });
240
+ this.cache.set(cacheKey, result);
241
+ return result;
240
242
  }
241
243
  /**
242
244
  * Creates a new `LocL` instance with a different language or scope.
package/dist/index.mjs CHANGED
@@ -32,7 +32,7 @@ var defaultFormatters = {
32
32
  * @param {string} [args[1]="..."] - The suffix to append if the string is truncated.
33
33
  * @returns The truncated string.
34
34
  */
35
- truncate: (val, args) => {
35
+ truncate: (val, args = []) => {
36
36
  const length = parseInt(args[0]) || 10;
37
37
  const suffix = args[1] || "...";
38
38
  const str = String(val);
@@ -46,7 +46,7 @@ var defaultFormatters = {
46
46
  * @param {string} [args[1]] - The style of formatting to use (e.g., "decimal", "percent").
47
47
  * @returns The formatted number.
48
48
  */
49
- number: (val, args) => {
49
+ number: (val, args = []) => {
50
50
  const locales = args[0] || void 0;
51
51
  const options = {};
52
52
  if (args[1]) options.style = args[1];
@@ -60,7 +60,7 @@ var defaultFormatters = {
60
60
  * @param {string} [args[1]] - The locale to use.
61
61
  * @returns The formatted currency string.
62
62
  */
63
- currency: (val, args) => {
63
+ currency: (val, args = []) => {
64
64
  const currency = args[0] || "USD";
65
65
  const locales = args[1] || void 0;
66
66
  return new Intl.NumberFormat(locales, {
@@ -76,7 +76,7 @@ var defaultFormatters = {
76
76
  * @param {string} [args[1]] - The date style to use (e.g., "short", "long").
77
77
  * @returns The formatted date string.
78
78
  */
79
- date: (val, args) => {
79
+ date: (val, args = []) => {
80
80
  const locales = args[0] || void 0;
81
81
  const options = {};
82
82
  if (args[1]) options.dateStyle = args[1];
@@ -89,7 +89,7 @@ var defaultFormatters = {
89
89
  * @param {string} [args[0]] - The locale to use.
90
90
  * @returns The relative time string.
91
91
  */
92
- relativeDate: (val, args) => {
92
+ relativeDate: (val, args = []) => {
93
93
  const locales = args[0] || void 0;
94
94
  const options = { numeric: "auto" };
95
95
  const rtf = new Intl.RelativeTimeFormat(locales, options);
@@ -113,7 +113,7 @@ var defaultFormatters = {
113
113
  * @param {string} [args[1]="No"] - The string to return for a falsy value.
114
114
  * @returns "Yes" or "No".
115
115
  */
116
- yesNo: (val, args) => {
116
+ yesNo: (val, args = []) => {
117
117
  const [yesVal, noVal] = args || [];
118
118
  return val ? yesVal || "Yes" : noVal || "No";
119
119
  },
@@ -125,7 +125,7 @@ var defaultFormatters = {
125
125
  * @param {string} [args[1]="false"] - The string to return for a falsy value.
126
126
  * @returns "true" or "false".
127
127
  */
128
- boolean: (val, args) => {
128
+ boolean: (val, args = []) => {
129
129
  const [trueVal, falseVal] = args || [];
130
130
  return val ? trueVal || "true" : falseVal || "false";
131
131
  },
@@ -137,7 +137,7 @@ var defaultFormatters = {
137
137
  * @param {string} [args[1]=" "] - The string to pad with.
138
138
  * @returns The padded string.
139
139
  */
140
- padStart: (val, args) => {
140
+ padStart: (val, args = []) => {
141
141
  const length = parseInt(args[0]) || 0;
142
142
  const fill = args[1] || " ";
143
143
  return String(val).padStart(length, fill);
@@ -150,7 +150,7 @@ var defaultFormatters = {
150
150
  * @param {string} [args[1]=" "] - The string to pad with.
151
151
  * @returns The padded string.
152
152
  */
153
- padEnd: (val, args) => {
153
+ padEnd: (val, args = []) => {
154
154
  const length = parseInt(args[0]) || 0;
155
155
  const fill = args[1] || " ";
156
156
  return String(val).padEnd(length, fill);
@@ -200,7 +200,7 @@ var LocL = class _LocL {
200
200
  if (this.cache.has(cacheKey)) {
201
201
  return this.cache.get(cacheKey);
202
202
  }
203
- return new Proxy(this, {
203
+ const result = new Proxy(this, {
204
204
  get(target, prop) {
205
205
  if (prop === "language") {
206
206
  return config.language ?? target.language;
@@ -211,6 +211,8 @@ var LocL = class _LocL {
211
211
  return target[prop];
212
212
  }
213
213
  });
214
+ this.cache.set(cacheKey, result);
215
+ return result;
214
216
  }
215
217
  /**
216
218
  * Creates a new `LocL` instance with a different language or scope.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "locl-js",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Modern TypeScript internationalization (i18n) library with type-safety, performance, and backend usability",
5
5
  "license": "MIT",
6
6
  "author": "Sztrida Sámuel <sztsam@gmail.com>",
@@ -26,11 +26,11 @@
26
26
  "devDependencies": {
27
27
  "@types/jest": "^30.0.0",
28
28
  "@types/node": "^24.5.2",
29
- "jest": "^30.1.3",
30
- "ts-jest": "^29.4.4",
29
+ "jest": "^30.2.0",
30
+ "ts-jest": "^29.4.6",
31
31
  "ts-node": "^10.9.2",
32
- "tsup": "^8.5.0",
33
- "typescript": "^5.9.2"
32
+ "tsup": "^8.5.1",
33
+ "typescript": "^5.9.3"
34
34
  },
35
35
  "files": [
36
36
  "dist"
package/readme.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # LocL.js 🌐
2
2
 
3
+ ![Coverage](https://img.shields.io/badge/coverage-98%25-brightgreen)
4
+
3
5
  **LocL** is a powerful, lightweight, and fully-featured TypeScript internationalization (i18n) library. It is designed to be flexible, easy to use, and highly extensible, providing a seamless experience for adding multiple languages to your projects. With built-in support for plurals, formatting, and modularization, `LocL` is the perfect tool for developers looking for a modern and robust i18n solution.
4
6
 
5
7
  It is inspired by libraries like `i18next` and `react-i18next`, but with a focus on type-safety, simplicity, performance and backend usability like discord bot and other apps.
@@ -231,7 +233,7 @@ translator.t("price", { price: 123 }); // "The price is $123.00"
231
233
  You can also define your own custom formatters:
232
234
 
233
235
  ```typescript
234
- const translator = initTranslator({
236
+ const translator = initLocL({
235
237
  resources,
236
238
  fallbackLanguage: "en",
237
239
  formatters: {