@develia/commons 0.4.26 → 0.6.1
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/array.d.ts +10 -0
- package/dist/array.d.ts.map +1 -1
- package/dist/array.js +18 -0
- package/dist/array.js.map +1 -1
- package/dist/async-pool-executor.d.ts +3 -5
- package/dist/async-pool-executor.d.ts.map +1 -1
- package/dist/async-pool-executor.js +9 -9
- package/dist/async-pool-executor.js.map +1 -1
- package/dist/browser/form-utilities.d.ts +0 -2
- package/dist/browser/form-utilities.d.ts.map +1 -1
- package/dist/browser/form-utilities.js +3 -23
- package/dist/browser/form-utilities.js.map +1 -1
- package/dist/browser/geo-location.js +3 -3
- package/dist/browser/geo-location.js.map +1 -1
- package/dist/browser/native-bridge.d.ts +1 -1
- package/dist/browser/native-bridge.d.ts.map +1 -1
- package/dist/browser/native-bridge.js +2 -2
- package/dist/browser/native-bridge.js.map +1 -1
- package/dist/cancellable-promise.d.ts +8 -2
- package/dist/cancellable-promise.d.ts.map +1 -1
- package/dist/cancellable-promise.js +9 -3
- package/dist/cancellable-promise.js.map +1 -1
- package/dist/clean-url-search-params.js +3 -3
- package/dist/clean-url-search-params.js.map +1 -1
- package/dist/collections/from.d.ts +16 -5
- package/dist/collections/from.d.ts.map +1 -1
- package/dist/collections/from.js +69 -38
- package/dist/collections/from.js.map +1 -1
- package/dist/draft.d.ts +2 -2
- package/dist/draft.d.ts.map +1 -1
- package/dist/draft.js +2 -2
- package/dist/draft.js.map +1 -1
- package/dist/functions.d.ts +2 -2
- package/dist/functions.d.ts.map +1 -1
- package/dist/functions.js +1 -1
- package/dist/functions.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/math.d.ts +14 -5
- package/dist/math.d.ts.map +1 -1
- package/dist/math.js +16 -5
- package/dist/math.js.map +1 -1
- package/dist/parse.d.ts +62 -44
- package/dist/parse.d.ts.map +1 -1
- package/dist/parse.js +95 -59
- package/dist/parse.js.map +1 -1
- package/dist/range.d.ts +2 -10
- package/dist/range.d.ts.map +1 -1
- package/dist/range.js +0 -12
- package/dist/range.js.map +1 -1
- package/dist/stopwatch.d.ts +2 -2
- package/dist/stopwatch.d.ts.map +1 -1
- package/dist/stopwatch.js +9 -9
- package/dist/stopwatch.js.map +1 -1
- package/dist/string.d.ts +15 -0
- package/dist/string.d.ts.map +1 -1
- package/dist/string.js +28 -3
- package/dist/string.js.map +1 -1
- package/dist/timespan.d.ts +10 -15
- package/dist/timespan.d.ts.map +1 -1
- package/dist/timespan.js +10 -15
- package/dist/timespan.js.map +1 -1
- package/dist/triggers.d.ts +6 -15
- package/dist/triggers.d.ts.map +1 -1
- package/dist/triggers.js +8 -22
- package/dist/triggers.js.map +1 -1
- package/dist/types.d.ts +0 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/utilities.d.ts +7 -6
- package/dist/utilities.d.ts.map +1 -1
- package/dist/utilities.js +19 -20
- package/dist/utilities.js.map +1 -1
- package/dist/uuid.d.ts +73 -0
- package/dist/uuid.d.ts.map +1 -0
- package/dist/uuid.js +129 -0
- package/dist/uuid.js.map +1 -0
- package/package.json +5 -1
- package/src/array.ts +19 -0
- package/src/async-pool-executor.ts +9 -9
- package/src/browser/form-utilities.ts +3 -32
- package/src/browser/geo-location.ts +3 -3
- package/src/browser/index.ts +0 -0
- package/src/browser/native-bridge.ts +2 -2
- package/src/cancellable-promise.ts +9 -3
- package/src/clean-url-search-params.ts +3 -3
- package/src/collections/cache-dictionary.ts +0 -0
- package/src/collections/default-map.ts +0 -0
- package/src/collections/default-weak-map.ts +0 -0
- package/src/collections/from.ts +70 -38
- package/src/collections/index.ts +0 -0
- package/src/draft.ts +3 -3
- package/src/event-bus.ts +0 -0
- package/src/functions.ts +3 -3
- package/src/index.ts +2 -1
- package/src/key-value-pair.ts +0 -0
- package/src/lazy.ts +0 -0
- package/src/math.ts +17 -5
- package/src/order.ts +0 -0
- package/src/parse.ts +108 -66
- package/src/patch.ts +0 -0
- package/src/range.ts +2 -16
- package/src/stopwatch.ts +9 -9
- package/src/string.ts +33 -3
- package/src/timer.ts +0 -0
- package/src/timespan.ts +10 -15
- package/src/triggers.ts +10 -24
- package/src/type-code.ts +0 -0
- package/src/type.ts +0 -0
- package/src/types.ts +0 -1
- package/src/utilities.ts +22 -25
- package/src/uuid.ts +153 -0
package/dist/parse.js
CHANGED
|
@@ -16,55 +16,67 @@ function isValidInteger(value, radix) {
|
|
|
16
16
|
return [...signless.toLowerCase()].every((char) => digits.includes(char));
|
|
17
17
|
}
|
|
18
18
|
// ============================================
|
|
19
|
-
// parseInteger
|
|
19
|
+
// tryParseInteger / parseInteger
|
|
20
20
|
// ============================================
|
|
21
21
|
/**
|
|
22
22
|
* Safely parses a value into an integer.
|
|
23
|
-
* Returns `
|
|
23
|
+
* Returns `undefined` if the value cannot be parsed.
|
|
24
24
|
*
|
|
25
|
-
* - `null` or `undefined` → `
|
|
25
|
+
* - `null` or `undefined` → `undefined`
|
|
26
26
|
* - `number` → returned as-is (floats are truncated)
|
|
27
27
|
* - `string` → parsed with the given options
|
|
28
28
|
*
|
|
29
29
|
* @param value - The value to parse.
|
|
30
30
|
* @param options - Optional parsing configuration.
|
|
31
|
-
* @returns The parsed integer, or `
|
|
31
|
+
* @returns The parsed integer, or `undefined` on failure.
|
|
32
32
|
*
|
|
33
33
|
* @example
|
|
34
34
|
* ```ts
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
35
|
+
* tryParseInteger(42) // 42
|
|
36
|
+
* tryParseInteger(3.7) // 3
|
|
37
|
+
* tryParseInteger(null) // undefined
|
|
38
|
+
* tryParseInteger(undefined) // undefined
|
|
39
|
+
* tryParseInteger("42") // 42
|
|
40
|
+
* tryParseInteger("1.234.567", { thousandsSeparator: "." }) // 1234567
|
|
41
|
+
* tryParseInteger("FF", { radix: 16 }) // 255
|
|
42
|
+
* tryParseInteger("abc") // undefined
|
|
43
43
|
* ```
|
|
44
44
|
*/
|
|
45
|
-
export function
|
|
45
|
+
export function tryParseInteger(value, options = {}) {
|
|
46
46
|
if (value === null || value === undefined)
|
|
47
|
-
return
|
|
47
|
+
return undefined;
|
|
48
48
|
if (typeof value === "number") {
|
|
49
|
-
return Number.isFinite(value) ? Math.trunc(value) :
|
|
49
|
+
return Number.isFinite(value) ? Math.trunc(value) : undefined;
|
|
50
50
|
}
|
|
51
51
|
const { radix = 10, thousandsSeparator } = options;
|
|
52
52
|
const cleaned = stripThousands(value.trim(), thousandsSeparator);
|
|
53
53
|
if (cleaned === "")
|
|
54
|
-
return
|
|
54
|
+
return undefined;
|
|
55
55
|
if (!isValidInteger(cleaned, radix))
|
|
56
|
-
return
|
|
56
|
+
return undefined;
|
|
57
57
|
const parsed = Number.parseInt(cleaned, radix);
|
|
58
|
-
return Number.isNaN(parsed) ?
|
|
58
|
+
return Number.isNaN(parsed) ? undefined : parsed;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Parses a value into an integer as {@link tryParseInteger} does.
|
|
62
|
+
*
|
|
63
|
+
* @throws {SyntaxError} If the value cannot be parsed.
|
|
64
|
+
*/
|
|
65
|
+
export function parseInteger(value, options = {}) {
|
|
66
|
+
const parsed = tryParseInteger(value, options);
|
|
67
|
+
if (parsed === undefined) {
|
|
68
|
+
throw new SyntaxError(`Invalid integer "${value}".`);
|
|
69
|
+
}
|
|
70
|
+
return parsed;
|
|
59
71
|
}
|
|
60
72
|
// ============================================
|
|
61
|
-
// parseDecimal
|
|
73
|
+
// tryParseDecimal / parseDecimal
|
|
62
74
|
// ============================================
|
|
63
75
|
/**
|
|
64
76
|
* Safely parses a value into a floating-point number.
|
|
65
|
-
* Returns `
|
|
77
|
+
* Returns `undefined` if the value cannot be parsed.
|
|
66
78
|
*
|
|
67
|
-
* - `null` or `undefined` → `
|
|
79
|
+
* - `null` or `undefined` → `undefined`
|
|
68
80
|
* - `number` → returned as-is (if finite)
|
|
69
81
|
* - `string` → parsed with the given options
|
|
70
82
|
*
|
|
@@ -73,50 +85,62 @@ export function parseInteger(value, options = {}) {
|
|
|
73
85
|
*
|
|
74
86
|
* @param value - The value to parse.
|
|
75
87
|
* @param options - Optional parsing configuration.
|
|
76
|
-
* @returns The parsed float, or `
|
|
88
|
+
* @returns The parsed float, or `undefined` on failure.
|
|
77
89
|
*
|
|
78
90
|
* @example
|
|
79
91
|
* ```ts
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
92
|
+
* tryParseDecimal(3.14) // 3.14
|
|
93
|
+
* tryParseDecimal(null) // undefined
|
|
94
|
+
* tryParseDecimal(undefined) // undefined
|
|
95
|
+
* tryParseDecimal("3.14") // 3.14
|
|
96
|
+
* tryParseDecimal("3,14", { decimalSeparator: "," }) // 3.14
|
|
97
|
+
* tryParseDecimal("1.234,56", { decimalSeparator: ",", thousandsSeparator: "." }) // 1234.56
|
|
98
|
+
* tryParseDecimal("abc") // undefined
|
|
87
99
|
* ```
|
|
88
100
|
*/
|
|
89
|
-
export function
|
|
101
|
+
export function tryParseDecimal(value, options = {}) {
|
|
90
102
|
if (value === null || value === undefined)
|
|
91
|
-
return
|
|
103
|
+
return undefined;
|
|
92
104
|
if (typeof value === "number") {
|
|
93
|
-
return Number.isFinite(value) ? value :
|
|
105
|
+
return Number.isFinite(value) ? value : undefined;
|
|
94
106
|
}
|
|
95
107
|
const { decimalSeparator = ".", thousandsSeparator } = options;
|
|
96
108
|
let cleaned = stripThousands(value.trim(), thousandsSeparator);
|
|
97
109
|
if (cleaned === "")
|
|
98
|
-
return
|
|
110
|
+
return undefined;
|
|
99
111
|
if (decimalSeparator === ",") {
|
|
100
112
|
const commaCount = (cleaned.match(/,/g) || []).length;
|
|
101
113
|
if (commaCount > 1)
|
|
102
|
-
return
|
|
114
|
+
return undefined;
|
|
103
115
|
cleaned = cleaned.replace(",", ".");
|
|
104
116
|
}
|
|
105
117
|
if (!/^[+-]?\d+(\.\d+)?$/.test(cleaned))
|
|
106
|
-
return
|
|
118
|
+
return undefined;
|
|
107
119
|
const parsed = Number.parseFloat(cleaned);
|
|
108
|
-
return Number.isNaN(parsed) || !Number.isFinite(parsed) ?
|
|
120
|
+
return Number.isNaN(parsed) || !Number.isFinite(parsed) ? undefined : parsed;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Parses a value into a decimal number as {@link tryParseDecimal} does.
|
|
124
|
+
*
|
|
125
|
+
* @throws {SyntaxError} If the value cannot be parsed.
|
|
126
|
+
*/
|
|
127
|
+
export function parseDecimal(value, options = {}) {
|
|
128
|
+
const parsed = tryParseDecimal(value, options);
|
|
129
|
+
if (parsed === undefined) {
|
|
130
|
+
throw new SyntaxError(`Invalid decimal number "${value}".`);
|
|
131
|
+
}
|
|
132
|
+
return parsed;
|
|
109
133
|
}
|
|
110
134
|
// ============================================
|
|
111
|
-
// parseBoolean
|
|
135
|
+
// tryParseBoolean / parseBoolean
|
|
112
136
|
// ============================================
|
|
113
137
|
const DEFAULT_TRUTHY = ["true", "1", "yes", "si", "sí", "on"];
|
|
114
138
|
const DEFAULT_FALSY = ["false", "0", "no", "off"];
|
|
115
139
|
/**
|
|
116
140
|
* Safely parses a value into a boolean.
|
|
117
|
-
* Returns `
|
|
141
|
+
* Returns `undefined` if the value cannot be interpreted as boolean.
|
|
118
142
|
*
|
|
119
|
-
* - `null` or `undefined` → `
|
|
143
|
+
* - `null` or `undefined` → `undefined`
|
|
120
144
|
* - `boolean` → returned as-is
|
|
121
145
|
* - `number` → `0` is `false`, any other finite number is `true`
|
|
122
146
|
* - `string` → matched case-insensitively against known truthy/falsy values
|
|
@@ -126,44 +150,56 @@ const DEFAULT_FALSY = ["false", "0", "no", "off"];
|
|
|
126
150
|
*
|
|
127
151
|
* @param value - The value to parse.
|
|
128
152
|
* @param options - Optional parsing configuration.
|
|
129
|
-
* @returns The parsed boolean, or `
|
|
153
|
+
* @returns The parsed boolean, or `undefined` on failure.
|
|
130
154
|
*
|
|
131
155
|
* @example
|
|
132
156
|
* ```ts
|
|
133
|
-
*
|
|
134
|
-
*
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
*
|
|
157
|
+
* tryParseBoolean(true) // true
|
|
158
|
+
* tryParseBoolean(false) // false
|
|
159
|
+
* tryParseBoolean(1) // true
|
|
160
|
+
* tryParseBoolean(0) // false
|
|
161
|
+
* tryParseBoolean(null) // undefined
|
|
162
|
+
* tryParseBoolean(undefined) // undefined
|
|
163
|
+
* tryParseBoolean("yes") // true
|
|
164
|
+
* tryParseBoolean("no") // false
|
|
165
|
+
* tryParseBoolean("sí") // true
|
|
166
|
+
* tryParseBoolean("TRUE") // true
|
|
167
|
+
* tryParseBoolean("oui") // undefined
|
|
168
|
+
* tryParseBoolean("oui", { extraTruthy: ["oui"] }) // true
|
|
169
|
+
* tryParseBoolean("nein", { extraFalsy: ["nein"] }) // false
|
|
170
|
+
* tryParseBoolean("whatever") // undefined
|
|
147
171
|
* ```
|
|
148
172
|
*/
|
|
149
|
-
export function
|
|
173
|
+
export function tryParseBoolean(value, options = {}) {
|
|
150
174
|
if (value === null || value === undefined)
|
|
151
|
-
return
|
|
175
|
+
return undefined;
|
|
152
176
|
if (typeof value === "boolean")
|
|
153
177
|
return value;
|
|
154
178
|
if (typeof value === "number") {
|
|
155
|
-
return Number.isFinite(value) ? value !== 0 :
|
|
179
|
+
return Number.isFinite(value) ? value !== 0 : undefined;
|
|
156
180
|
}
|
|
157
181
|
const { extraTruthy = [], extraFalsy = [] } = options;
|
|
158
182
|
const normalized = value.trim().toLowerCase();
|
|
159
183
|
if (normalized === "")
|
|
160
|
-
return
|
|
184
|
+
return undefined;
|
|
161
185
|
const truthy = [...DEFAULT_TRUTHY, ...extraTruthy.map((s) => s.toLowerCase())];
|
|
162
186
|
const falsy = [...DEFAULT_FALSY, ...extraFalsy.map((s) => s.toLowerCase())];
|
|
163
187
|
if (truthy.includes(normalized))
|
|
164
188
|
return true;
|
|
165
189
|
if (falsy.includes(normalized))
|
|
166
190
|
return false;
|
|
167
|
-
return
|
|
191
|
+
return undefined;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Parses a value into a boolean as {@link tryParseBoolean} does.
|
|
195
|
+
*
|
|
196
|
+
* @throws {SyntaxError} If the value cannot be parsed.
|
|
197
|
+
*/
|
|
198
|
+
export function parseBoolean(value, options = {}) {
|
|
199
|
+
const parsed = tryParseBoolean(value, options);
|
|
200
|
+
if (parsed === undefined) {
|
|
201
|
+
throw new SyntaxError(`Invalid boolean "${value}".`);
|
|
202
|
+
}
|
|
203
|
+
return parsed;
|
|
168
204
|
}
|
|
169
205
|
//# sourceMappingURL=parse.js.map
|
package/dist/parse.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAwDA,+CAA+C;AAC/C,UAAU;AACV,+CAA+C;AAE/C,SAAS,cAAc,CAAC,KAAa,EAAE,SAAkB;IACrD,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7B,OAAO,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,cAAc,CAAC,KAAa,EAAE,KAAa;IAChD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,KAAK,CAAC;IAEtE,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC5C,IAAI,QAAQ,KAAK,EAAE;QAAE,OAAO,KAAK,CAAC;IAElC,MAAM,MAAM,GAAG,sCAAsC,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEtE,OAAO,CAAC,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED,+CAA+C;AAC/C,eAAe;AACf,+CAA+C;AAE/C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,YAAY,CACxB,KAAyC,EACzC,UAA+B,EAAE;IAEjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAEvD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC7D,CAAC;IAED,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC;IAEnD,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC;IAEjE,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEjD,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAE/C,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AAChD,CAAC;AAED,+CAA+C;AAC/C,eAAe;AACf,+CAA+C;AAE/C;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,YAAY,CACxB,KAAyC,EACzC,UAA+B,EAAE;IAEjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAEvD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACjD,CAAC;IAED,MAAM,EAAE,gBAAgB,GAAG,GAAG,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC;IAE/D,IAAI,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC;IAE/D,IAAI,OAAO,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAEhC,IAAI,gBAAgB,KAAK,GAAG,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC;QACtD,IAAI,UAAU,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAChC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAErD,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAE1C,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AAC5E,CAAC;AAED,+CAA+C;AAC/C,eAAe;AACf,+CAA+C;AAE/C,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9D,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,YAAY,CACxB,KAAmD,EACnD,UAA+B,EAAE;IAEjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAEvD,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAE7C,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACvD,CAAC;IAED,MAAM,EAAE,WAAW,GAAG,EAAE,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAEtD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE9C,IAAI,UAAU,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IAEnC,MAAM,MAAM,GAAG,CAAC,GAAG,cAAc,EAAE,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAC/E,MAAM,KAAK,GAAG,CAAC,GAAG,aAAa,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAE5E,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7C,IAAI,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IAE7C,OAAO,IAAI,CAAC;AAChB,CAAC","sourcesContent":["// parse.ts\n/**\n * Options for {@link parseBoolean}.\n */\nexport interface ParseBooleanOptions {\n /**\n * Additional strings to consider as `true`.\n * These are matched case-insensitively.\n * @example [\"oui\", \"ja\"]\n */\n extraTruthy?: string[];\n\n /**\n * Additional strings to consider as `false`.\n * These are matched case-insensitively.\n * @example [\"non\", \"nein\"]\n */\n extraFalsy?: string[];\n}\n\n/**\n * Options for {@link parseInteger}.\n */\nexport interface ParseIntegerOptions {\n /**\n * Numeric base for conversion.\n * @default 10\n */\n radix?: number;\n\n /**\n * Thousands separator to strip before parsing.\n * @example \".\" for \"1.234.567\" → 1234567\n * @example \",\" for \"1,234,567\" → 1234567\n */\n thousandsSeparator?: string;\n}\n\n/**\n * Options for {@link parseDecimal}.\n */\nexport interface ParseDecimalOptions {\n /**\n * Character used as decimal point.\n * @default \".\"\n */\n decimalSeparator?: \".\" | \",\";\n\n /**\n * Thousands separator to strip before parsing.\n * @example \".\" for \"1.234,56\" (EU format)\n * @example \",\" for \"1,234.56\" (US format)\n */\n thousandsSeparator?: string;\n}\n\n// ============================================\n// HELPERS\n// ============================================\n\nfunction stripThousands(value: string, separator?: string): string {\n if (!separator) return value;\n return value.split(separator).join(\"\");\n}\n\nfunction isValidInteger(value: string, radix: number): boolean {\n if (!Number.isInteger(radix) || radix < 2 || radix > 36) return false;\n\n const signless = value.replace(/^[+-]/, \"\");\n if (signless === \"\") return false;\n\n const digits = \"0123456789abcdefghijklmnopqrstuvwxyz\".slice(0, radix);\n\n return [...signless.toLowerCase()].every((char) => digits.includes(char));\n}\n\n// ============================================\n// parseInteger\n// ============================================\n\n/**\n * Safely parses a value into an integer.\n * Returns `null` if the value cannot be parsed.\n *\n * - `null` or `undefined` → `null`\n * - `number` → returned as-is (floats are truncated)\n * - `string` → parsed with the given options\n *\n * @param value - The value to parse.\n * @param options - Optional parsing configuration.\n * @returns The parsed integer, or `null` on failure.\n *\n * @example\n * ```ts\n * parseInteger(42) // 42\n * parseInteger(3.7) // 3\n * parseInteger(null) // null\n * parseInteger(undefined) // null\n * parseInteger(\"42\") // 42\n * parseInteger(\"1.234.567\", { thousandsSeparator: \".\" }) // 1234567\n * parseInteger(\"FF\", { radix: 16 }) // 255\n * parseInteger(\"abc\") // null\n * ```\n */\nexport function parseInteger(\n value: string | number | null | undefined,\n options: ParseIntegerOptions = {}\n): number | null {\n if (value === null || value === undefined) return null;\n\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? Math.trunc(value) : null;\n }\n\n const { radix = 10, thousandsSeparator } = options;\n\n const cleaned = stripThousands(value.trim(), thousandsSeparator);\n\n if (cleaned === \"\") return null;\n if (!isValidInteger(cleaned, radix)) return null;\n\n const parsed = Number.parseInt(cleaned, radix);\n\n return Number.isNaN(parsed) ? null : parsed;\n}\n\n// ============================================\n// parseDecimal\n// ============================================\n\n/**\n * Safely parses a value into a floating-point number.\n * Returns `null` if the value cannot be parsed.\n *\n * - `null` or `undefined` → `null`\n * - `number` → returned as-is (if finite)\n * - `string` → parsed with the given options\n *\n * Supports custom decimal and thousands separators, making it suitable\n * for both US (`1,234.56`) and EU (`1.234,56`) number formats.\n *\n * @param value - The value to parse.\n * @param options - Optional parsing configuration.\n * @returns The parsed float, or `null` on failure.\n *\n * @example\n * ```ts\n * parseDecimal(3.14) // 3.14\n * parseDecimal(null) // null\n * parseDecimal(undefined) // null\n * parseDecimal(\"3.14\") // 3.14\n * parseDecimal(\"3,14\", { decimalSeparator: \",\" }) // 3.14\n * parseDecimal(\"1.234,56\", { decimalSeparator: \",\", thousandsSeparator: \".\" }) // 1234.56\n * parseDecimal(\"abc\") // null\n * ```\n */\nexport function parseDecimal(\n value: string | number | null | undefined,\n options: ParseDecimalOptions = {}\n): number | null {\n if (value === null || value === undefined) return null;\n\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : null;\n }\n\n const { decimalSeparator = \".\", thousandsSeparator } = options;\n\n let cleaned = stripThousands(value.trim(), thousandsSeparator);\n\n if (cleaned === \"\") return null;\n\n if (decimalSeparator === \",\") {\n const commaCount = (cleaned.match(/,/g) || []).length;\n if (commaCount > 1) return null;\n cleaned = cleaned.replace(\",\", \".\");\n }\n\n if (!/^[+-]?\\d+(\\.\\d+)?$/.test(cleaned)) return null;\n\n const parsed = Number.parseFloat(cleaned);\n\n return Number.isNaN(parsed) || !Number.isFinite(parsed) ? null : parsed;\n}\n\n// ============================================\n// parseBoolean\n// ============================================\n\nconst DEFAULT_TRUTHY = [\"true\", \"1\", \"yes\", \"si\", \"sí\", \"on\"];\nconst DEFAULT_FALSY = [\"false\", \"0\", \"no\", \"off\"];\n\n/**\n * Safely parses a value into a boolean.\n * Returns `null` if the value cannot be interpreted as boolean.\n *\n * - `null` or `undefined` → `null`\n * - `boolean` → returned as-is\n * - `number` → `0` is `false`, any other finite number is `true`\n * - `string` → matched case-insensitively against known truthy/falsy values\n *\n * Default truthy: `\"true\"`, `\"1\"`, `\"yes\"`, `\"si\"`, `\"sí\"`, `\"on\"`\n * Default falsy: `\"false\"`, `\"0\"`, `\"no\"`, `\"off\"`\n *\n * @param value - The value to parse.\n * @param options - Optional parsing configuration.\n * @returns The parsed boolean, or `null` on failure.\n *\n * @example\n * ```ts\n * parseBoolean(true) // true\n * parseBoolean(false) // false\n * parseBoolean(1) // true\n * parseBoolean(0) // false\n * parseBoolean(null) // null\n * parseBoolean(undefined) // null\n * parseBoolean(\"yes\") // true\n * parseBoolean(\"no\") // false\n * parseBoolean(\"sí\") // true\n * parseBoolean(\"TRUE\") // true\n * parseBoolean(\"oui\") // null\n * parseBoolean(\"oui\", { extraTruthy: [\"oui\"] }) // true\n * parseBoolean(\"nein\", { extraFalsy: [\"nein\"] }) // false\n * parseBoolean(\"whatever\") // null\n * ```\n */\nexport function parseBoolean(\n value: string | number | boolean | null | undefined,\n options: ParseBooleanOptions = {}\n): boolean | null {\n if (value === null || value === undefined) return null;\n\n if (typeof value === \"boolean\") return value;\n\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value !== 0 : null;\n }\n\n const { extraTruthy = [], extraFalsy = [] } = options;\n\n const normalized = value.trim().toLowerCase();\n\n if (normalized === \"\") return null;\n\n const truthy = [...DEFAULT_TRUTHY, ...extraTruthy.map((s) => s.toLowerCase())];\n const falsy = [...DEFAULT_FALSY, ...extraFalsy.map((s) => s.toLowerCase())];\n\n if (truthy.includes(normalized)) return true;\n if (falsy.includes(normalized)) return false;\n\n return null;\n}"]}
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"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","sourcesContent":["// parse.ts\n/**\n * Options for {@link tryParseBoolean} and {@link parseBoolean}.\n */\nexport interface ParseBooleanOptions {\n /**\n * Additional strings to consider as `true`.\n * These are matched case-insensitively.\n * @example [\"oui\", \"ja\"]\n */\n extraTruthy?: string[];\n\n /**\n * Additional strings to consider as `false`.\n * These are matched case-insensitively.\n * @example [\"non\", \"nein\"]\n */\n extraFalsy?: string[];\n}\n\n/**\n * Options for {@link tryParseInteger} and {@link parseInteger}.\n */\nexport interface ParseIntegerOptions {\n /**\n * Numeric base for conversion.\n * @default 10\n */\n radix?: number;\n\n /**\n * Thousands separator to strip before parsing.\n * @example \".\" for \"1.234.567\" → 1234567\n * @example \",\" for \"1,234,567\" → 1234567\n */\n thousandsSeparator?: string;\n}\n\n/**\n * Options for {@link tryParseDecimal} and {@link parseDecimal}.\n */\nexport interface ParseDecimalOptions {\n /**\n * Character used as decimal point.\n * @default \".\"\n */\n decimalSeparator?: \".\" | \",\";\n\n /**\n * Thousands separator to strip before parsing.\n * @example \".\" for \"1.234,56\" (EU format)\n * @example \",\" for \"1,234.56\" (US format)\n */\n thousandsSeparator?: string;\n}\n\n// ============================================\n// HELPERS\n// ============================================\n\nfunction stripThousands(value: string, separator?: string): string {\n if (!separator) return value;\n return value.split(separator).join(\"\");\n}\n\nfunction isValidInteger(value: string, radix: number): boolean {\n if (!Number.isInteger(radix) || radix < 2 || radix > 36) return false;\n\n const signless = value.replace(/^[+-]/, \"\");\n if (signless === \"\") return false;\n\n const digits = \"0123456789abcdefghijklmnopqrstuvwxyz\".slice(0, radix);\n\n return [...signless.toLowerCase()].every((char) => digits.includes(char));\n}\n\n// ============================================\n// tryParseInteger / parseInteger\n// ============================================\n\n/**\n * Safely parses a value into an integer.\n * Returns `undefined` if the value cannot be parsed.\n *\n * - `null` or `undefined` → `undefined`\n * - `number` → returned as-is (floats are truncated)\n * - `string` → parsed with the given options\n *\n * @param value - The value to parse.\n * @param options - Optional parsing configuration.\n * @returns The parsed integer, or `undefined` on failure.\n *\n * @example\n * ```ts\n * tryParseInteger(42) // 42\n * tryParseInteger(3.7) // 3\n * tryParseInteger(null) // undefined\n * tryParseInteger(undefined) // undefined\n * tryParseInteger(\"42\") // 42\n * tryParseInteger(\"1.234.567\", { thousandsSeparator: \".\" }) // 1234567\n * tryParseInteger(\"FF\", { radix: 16 }) // 255\n * tryParseInteger(\"abc\") // undefined\n * ```\n */\nexport function tryParseInteger(\n value: string | number | null | undefined,\n options: ParseIntegerOptions = {}\n): number | undefined {\n if (value === null || value === undefined) return undefined;\n\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? Math.trunc(value) : undefined;\n }\n\n const { radix = 10, thousandsSeparator } = options;\n\n const cleaned = stripThousands(value.trim(), thousandsSeparator);\n\n if (cleaned === \"\") return undefined;\n if (!isValidInteger(cleaned, radix)) return undefined;\n\n const parsed = Number.parseInt(cleaned, radix);\n\n return Number.isNaN(parsed) ? undefined : parsed;\n}\n\n/**\n * Parses a value into an integer as {@link tryParseInteger} does.\n *\n * @throws {SyntaxError} If the value cannot be parsed.\n */\nexport function parseInteger(value: string | number, options: ParseIntegerOptions = {}): number {\n const parsed = tryParseInteger(value, options);\n if (parsed === undefined) {\n throw new SyntaxError(`Invalid integer \"${value}\".`);\n }\n\n return parsed;\n}\n\n// ============================================\n// tryParseDecimal / parseDecimal\n// ============================================\n\n/**\n * Safely parses a value into a floating-point number.\n * Returns `undefined` if the value cannot be parsed.\n *\n * - `null` or `undefined` → `undefined`\n * - `number` → returned as-is (if finite)\n * - `string` → parsed with the given options\n *\n * Supports custom decimal and thousands separators, making it suitable\n * for both US (`1,234.56`) and EU (`1.234,56`) number formats.\n *\n * @param value - The value to parse.\n * @param options - Optional parsing configuration.\n * @returns The parsed float, or `undefined` on failure.\n *\n * @example\n * ```ts\n * tryParseDecimal(3.14) // 3.14\n * tryParseDecimal(null) // undefined\n * tryParseDecimal(undefined) // undefined\n * tryParseDecimal(\"3.14\") // 3.14\n * tryParseDecimal(\"3,14\", { decimalSeparator: \",\" }) // 3.14\n * tryParseDecimal(\"1.234,56\", { decimalSeparator: \",\", thousandsSeparator: \".\" }) // 1234.56\n * tryParseDecimal(\"abc\") // undefined\n * ```\n */\nexport function tryParseDecimal(\n value: string | number | null | undefined,\n options: ParseDecimalOptions = {}\n): number | undefined {\n if (value === null || value === undefined) return undefined;\n\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value : undefined;\n }\n\n const { decimalSeparator = \".\", thousandsSeparator } = options;\n\n let cleaned = stripThousands(value.trim(), thousandsSeparator);\n\n if (cleaned === \"\") return undefined;\n\n if (decimalSeparator === \",\") {\n const commaCount = (cleaned.match(/,/g) || []).length;\n if (commaCount > 1) return undefined;\n cleaned = cleaned.replace(\",\", \".\");\n }\n\n if (!/^[+-]?\\d+(\\.\\d+)?$/.test(cleaned)) return undefined;\n\n const parsed = Number.parseFloat(cleaned);\n\n return Number.isNaN(parsed) || !Number.isFinite(parsed) ? undefined : parsed;\n}\n\n/**\n * Parses a value into a decimal number as {@link tryParseDecimal} does.\n *\n * @throws {SyntaxError} If the value cannot be parsed.\n */\nexport function parseDecimal(value: string | number, options: ParseDecimalOptions = {}): number {\n const parsed = tryParseDecimal(value, options);\n if (parsed === undefined) {\n throw new SyntaxError(`Invalid decimal number \"${value}\".`);\n }\n\n return parsed;\n}\n\n// ============================================\n// tryParseBoolean / parseBoolean\n// ============================================\n\nconst DEFAULT_TRUTHY = [\"true\", \"1\", \"yes\", \"si\", \"sí\", \"on\"];\nconst DEFAULT_FALSY = [\"false\", \"0\", \"no\", \"off\"];\n\n/**\n * Safely parses a value into a boolean.\n * Returns `undefined` if the value cannot be interpreted as boolean.\n *\n * - `null` or `undefined` → `undefined`\n * - `boolean` → returned as-is\n * - `number` → `0` is `false`, any other finite number is `true`\n * - `string` → matched case-insensitively against known truthy/falsy values\n *\n * Default truthy: `\"true\"`, `\"1\"`, `\"yes\"`, `\"si\"`, `\"sí\"`, `\"on\"`\n * Default falsy: `\"false\"`, `\"0\"`, `\"no\"`, `\"off\"`\n *\n * @param value - The value to parse.\n * @param options - Optional parsing configuration.\n * @returns The parsed boolean, or `undefined` on failure.\n *\n * @example\n * ```ts\n * tryParseBoolean(true) // true\n * tryParseBoolean(false) // false\n * tryParseBoolean(1) // true\n * tryParseBoolean(0) // false\n * tryParseBoolean(null) // undefined\n * tryParseBoolean(undefined) // undefined\n * tryParseBoolean(\"yes\") // true\n * tryParseBoolean(\"no\") // false\n * tryParseBoolean(\"sí\") // true\n * tryParseBoolean(\"TRUE\") // true\n * tryParseBoolean(\"oui\") // undefined\n * tryParseBoolean(\"oui\", { extraTruthy: [\"oui\"] }) // true\n * tryParseBoolean(\"nein\", { extraFalsy: [\"nein\"] }) // false\n * tryParseBoolean(\"whatever\") // undefined\n * ```\n */\nexport function tryParseBoolean(\n value: string | number | boolean | null | undefined,\n options: ParseBooleanOptions = {}\n): boolean | undefined {\n if (value === null || value === undefined) return undefined;\n\n if (typeof value === \"boolean\") return value;\n\n if (typeof value === \"number\") {\n return Number.isFinite(value) ? value !== 0 : undefined;\n }\n\n const { extraTruthy = [], extraFalsy = [] } = options;\n\n const normalized = value.trim().toLowerCase();\n\n if (normalized === \"\") return undefined;\n\n const truthy = [...DEFAULT_TRUTHY, ...extraTruthy.map((s) => s.toLowerCase())];\n const falsy = [...DEFAULT_FALSY, ...extraFalsy.map((s) => s.toLowerCase())];\n\n if (truthy.includes(normalized)) return true;\n if (falsy.includes(normalized)) return false;\n\n return undefined;\n}\n\n/**\n * Parses a value into a boolean as {@link tryParseBoolean} does.\n *\n * @throws {SyntaxError} If the value cannot be parsed.\n */\nexport function parseBoolean(value: string | number | boolean, options: ParseBooleanOptions = {}): boolean {\n const parsed = tryParseBoolean(value, options);\n if (parsed === undefined) {\n throw new SyntaxError(`Invalid boolean \"${value}\".`);\n }\n\n return parsed;\n}\n"]}
|
package/dist/range.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default class Range<T> {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
readonly start: T;
|
|
3
|
+
readonly end: T;
|
|
4
4
|
/**
|
|
5
5
|
* Range constructor.
|
|
6
6
|
* @param start
|
|
@@ -36,14 +36,6 @@ export default class Range<T> {
|
|
|
36
36
|
* @returns Returns true if the specified value is within the range, false otherwise.
|
|
37
37
|
*/
|
|
38
38
|
contains(obj: T, inclusive?: boolean): boolean;
|
|
39
|
-
/**
|
|
40
|
-
* @returns T
|
|
41
|
-
*/
|
|
42
|
-
getStart(): T;
|
|
43
|
-
/**
|
|
44
|
-
* @returns T
|
|
45
|
-
*/
|
|
46
|
-
getEnd(): T;
|
|
47
39
|
/**
|
|
48
40
|
* Finds the intersection between two sets of ranges.
|
|
49
41
|
*
|
package/dist/range.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"range.d.ts","sourceRoot":"","sources":["../src/range.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,OAAO,KAAK,CAAC,CAAC;IAExB,
|
|
1
|
+
{"version":3,"file":"range.d.ts","sourceRoot":"","sources":["../src/range.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,OAAO,KAAK,CAAC,CAAC;IAExB,SAAgB,KAAK,EAAE,CAAC,CAAC;IACzB,SAAgB,GAAG,EAAE,CAAC,CAAC;IAEvB;;;;OAIG;gBACS,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;IAK5B;;;;;OAKG;IACI,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI;IAWlD;;;;;OAKG;IACI,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE;IAoB5C;;;;;OAKG;IACI,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO;IAWzC;;;;;;OAMG;IACI,QAAQ,CAAC,GAAG,EAAE,CAAC,EAAE,SAAS,GAAE,OAAc,GAAG,OAAO;IAM3D;;;;;;OAMG;WACW,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE;IAatF;;;;;;OAMG;WACW,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO;IAW/E;;;;;;OAMG;WACW,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE;CAiBxF"}
|
package/dist/range.js
CHANGED
|
@@ -75,18 +75,6 @@ export default class Range {
|
|
|
75
75
|
(this.start <= obj && this.end >= obj) :
|
|
76
76
|
(this.start < obj && this.end > obj);
|
|
77
77
|
}
|
|
78
|
-
/**
|
|
79
|
-
* @returns T
|
|
80
|
-
*/
|
|
81
|
-
getStart() {
|
|
82
|
-
return this.start;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* @returns T
|
|
86
|
-
*/
|
|
87
|
-
getEnd() {
|
|
88
|
-
return this.end;
|
|
89
|
-
}
|
|
90
78
|
/**
|
|
91
79
|
* Finds the intersection between two sets of ranges.
|
|
92
80
|
*
|
package/dist/range.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"range.js","sourceRoot":"","sources":["../src/range.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"range.js","sourceRoot":"","sources":["../src/range.ts"],"names":[],"mappings":"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","sourcesContent":["export default class Range<T> {\n\n public readonly start: T;\n public readonly end: T;\n\n /**\n * Range constructor.\n * @param start\n * @param end\n */\n constructor(start: T, end: T) {\n this.start = start;\n this.end = end;\n }\n\n /**\n * Finds the intersection between two ranges.\n *\n * @param other The Range object to intersect with.\n * @returns The intersected Range object, or null if there is no intersection.\n */\n public intersect(other: Range<T>): Range<T> | null {\n const start = (this.start > other.start) ? this.start : other.start;\n const end = (this.end < other.end) ? this.end : other.end;\n\n if (start < end) {\n return new Range(start, end);\n } else {\n return null;\n }\n }\n\n /**\n * Subtract the given range from this range.\n *\n * @param other The range to subtract from this range.\n * @returns An array of Range objects representing the result of the subtraction.\n */\n public subtract(other: Range<T>): Range<T>[] {\n const result: Range<T>[] = [];\n\n if (this.start >= other.end || this.end <= other.start) {\n result.push(new Range(this.start, this.end));\n } else if (other.start <= this.start && other.end >= this.end) {\n return result;\n } else {\n if (this.start < other.start) {\n result.push(new Range(this.start, other.start));\n }\n\n if (this.end > other.end) {\n result.push(new Range(other.end, this.end));\n }\n }\n\n return result;\n }\n\n /**\n * Determines if the given range overlaps with the current range.\n *\n * @param other The range to be checked for overlap.\n * @returns Returns true if there is an overlap between the ranges, false otherwise.\n */\n public overlaps(other: Range<T>): boolean {\n const s1 = this.start;\n const e1 = this.end;\n const s2 = other.start;\n const e2 = other.end;\n\n return (s2 > s1 && s2 < e1 || e2 > s1 && e2 < e1) ||\n (s1 > s2 && s1 < e2 || e1 > s2 && e1 < e2) ||\n (s1 === s2 && e1 === e2);\n }\n\n /**\n * Determines whether the specified value is within the range defined by the start and end values.\n *\n * @param obj The value to check if it is within the range.\n * @param inclusive Optional. If set to true, the range boundaries are considered inclusive.\n * @returns Returns true if the specified value is within the range, false otherwise.\n */\n public contains(obj: T, inclusive: boolean = true): boolean {\n return inclusive ?\n (this.start <= obj && this.end >= obj) :\n (this.start < obj && this.end > obj);\n }\n\n /**\n * Finds the intersection between two sets of ranges.\n *\n * @param ranges1\n * @param ranges2\n * @returns\n */\n public static intersectRanges<T>(ranges1: Range<T>[], ranges2: Range<T>[]): Range<T>[] {\n const result: Range<T>[] = [];\n for (const r1 of ranges1) {\n for (const r2 of ranges2) {\n const intersection = r1.intersect(r2);\n if (intersection !== null) {\n result.push(intersection);\n }\n }\n }\n return result;\n }\n\n /**\n * Determines if any range in the first set overlaps with any range in the second set.\n *\n * @param ranges1\n * @param ranges2\n * @returns\n */\n public static overlapsAny<T>(ranges1: Range<T>[], ranges2: Range<T>[]): boolean {\n for (const r1 of ranges1) {\n for (const r2 of ranges2) {\n if (r1.overlaps(r2)) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * Subtracts the second set of ranges from the first set of ranges.\n *\n * @param ranges1\n * @param ranges2\n * @returns\n */\n public static subtractRanges<T>(ranges1: Range<T>[], ranges2: Range<T>[]): Range<T>[] {\n let currentRanges = ranges1;\n for (const r2 of ranges2) {\n const nextRanges: Range<T>[] = [];\n for (const r1 of currentRanges) {\n const subtracted = r1.subtract(r2);\n for (const s of subtracted) {\n nextRanges.push(s);\n }\n }\n currentRanges = nextRanges;\n if (currentRanges.length === 0) {\n break;\n }\n }\n return currentRanges;\n }\n}\n"]}
|
package/dist/stopwatch.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import TimeSpan from "./timespan.js";
|
|
2
2
|
export default class Stopwatch {
|
|
3
3
|
private startTime;
|
|
4
|
-
private
|
|
4
|
+
private elapsedMilliseconds;
|
|
5
5
|
start(): void;
|
|
6
6
|
stop(): void;
|
|
7
7
|
resume(): void;
|
|
8
|
-
|
|
8
|
+
get elapsedTime(): TimeSpan;
|
|
9
9
|
}
|
|
10
10
|
//# sourceMappingURL=stopwatch.d.ts.map
|
package/dist/stopwatch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stopwatch.d.ts","sourceRoot":"","sources":["../src/stopwatch.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,OAAO,OAAO,SAAS;IAC1B,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"stopwatch.d.ts","sourceRoot":"","sources":["../src/stopwatch.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,OAAO,OAAO,SAAS;IAC1B,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,mBAAmB,CAAuB;IAalD,KAAK,IAAI,IAAI;IAKb,IAAI,IAAI,IAAI;IAOZ,MAAM,IAAI,IAAI;IAOd,IAAI,WAAW,IAAI,QAAQ,CAK1B;CACJ"}
|
package/dist/stopwatch.js
CHANGED
|
@@ -2,7 +2,7 @@ import TimeSpan from "./timespan.js";
|
|
|
2
2
|
export default class Stopwatch {
|
|
3
3
|
constructor() {
|
|
4
4
|
this.startTime = null;
|
|
5
|
-
this.
|
|
5
|
+
this.elapsedMilliseconds = null;
|
|
6
6
|
}
|
|
7
7
|
/*static measure<T>(callback: () => T, measure: { value: TimeSpan | null }): T {
|
|
8
8
|
const stopwatch = new Stopwatch();
|
|
@@ -11,30 +11,30 @@ export default class Stopwatch {
|
|
|
11
11
|
return callback();
|
|
12
12
|
} finally {
|
|
13
13
|
stopwatch.stop();
|
|
14
|
-
measure.value = stopwatch.
|
|
14
|
+
measure.value = stopwatch.elapsedTime;
|
|
15
15
|
}
|
|
16
16
|
}*/
|
|
17
17
|
start() {
|
|
18
18
|
this.startTime = performance.now();
|
|
19
|
-
this.
|
|
19
|
+
this.elapsedMilliseconds = null;
|
|
20
20
|
}
|
|
21
21
|
stop() {
|
|
22
22
|
if (this.startTime !== null) {
|
|
23
|
-
this.
|
|
23
|
+
this.elapsedMilliseconds = performance.now() - this.startTime;
|
|
24
24
|
this.startTime = null;
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
resume() {
|
|
28
|
-
if (this.
|
|
29
|
-
this.startTime = performance.now() - this.
|
|
30
|
-
this.
|
|
28
|
+
if (this.elapsedMilliseconds !== null) {
|
|
29
|
+
this.startTime = performance.now() - this.elapsedMilliseconds;
|
|
30
|
+
this.elapsedMilliseconds = null;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
|
|
33
|
+
get elapsedTime() {
|
|
34
34
|
if (this.startTime !== null) {
|
|
35
35
|
return TimeSpan.fromMilliseconds(performance.now() - this.startTime);
|
|
36
36
|
}
|
|
37
|
-
return TimeSpan.fromMilliseconds(this.
|
|
37
|
+
return TimeSpan.fromMilliseconds(this.elapsedMilliseconds ?? 0.0);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
//# sourceMappingURL=stopwatch.js.map
|
package/dist/stopwatch.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stopwatch.js","sourceRoot":"","sources":["../src/stopwatch.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,OAAO,OAAO,SAAS;IAA9B;QACY,cAAS,GAAkB,IAAI,CAAC;QAChC,
|
|
1
|
+
{"version":3,"file":"stopwatch.js","sourceRoot":"","sources":["../src/stopwatch.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,OAAO,OAAO,SAAS;IAA9B;QACY,cAAS,GAAkB,IAAI,CAAC;QAChC,wBAAmB,GAAkB,IAAI,CAAC;IAsCtD,CAAC;IApCG;;;;;;;;;OASG;IAEH,KAAK;QACD,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QACnC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;IACpC,CAAC;IAED,IAAI;QACA,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC1B,IAAI,CAAC,mBAAmB,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC;YAC9D,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QAC1B,CAAC;IACL,CAAC;IAED,MAAM;QACF,IAAI,IAAI,CAAC,mBAAmB,KAAK,IAAI,EAAE,CAAC;YACpC,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,mBAAmB,CAAC;YAC9D,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QACpC,CAAC;IACL,CAAC;IAED,IAAI,WAAW;QACX,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,QAAQ,CAAC,gBAAgB,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,mBAAmB,IAAI,GAAG,CAAC,CAAC;IACtE,CAAC;CACJ","sourcesContent":["import TimeSpan from \"./timespan.js\";\n\nexport default class Stopwatch {\n private startTime: number | null = null;\n private elapsedMilliseconds: number | null = null;\n\n /*static measure<T>(callback: () => T, measure: { value: TimeSpan | null }): T {\n const stopwatch = new Stopwatch();\n stopwatch.start();\n try {\n return callback();\n } finally {\n stopwatch.stop();\n measure.value = stopwatch.elapsedTime;\n }\n }*/\n\n start(): void {\n this.startTime = performance.now();\n this.elapsedMilliseconds = null;\n }\n\n stop(): void {\n if (this.startTime !== null) {\n this.elapsedMilliseconds = performance.now() - this.startTime;\n this.startTime = null;\n }\n }\n\n resume(): void {\n if (this.elapsedMilliseconds !== null) {\n this.startTime = performance.now() - this.elapsedMilliseconds;\n this.elapsedMilliseconds = null;\n }\n }\n\n get elapsedTime(): TimeSpan {\n if (this.startTime !== null) {\n return TimeSpan.fromMilliseconds(performance.now() - this.startTime);\n }\n return TimeSpan.fromMilliseconds(this.elapsedMilliseconds ?? 0.0);\n }\n}\n"]}
|
package/dist/string.d.ts
CHANGED
|
@@ -14,6 +14,11 @@ export declare function ensurePrefix(str: string, prefix: string): string;
|
|
|
14
14
|
* @return {string} - The modified string with the suffix added if it was not already present.
|
|
15
15
|
*/
|
|
16
16
|
export declare function ensureSuffix(str: string, suffix: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Null for an empty string, as `Str::nullIfEmpty()` of develia/commons for PHP; any other string as it is. Compose it
|
|
19
|
+
* with `trim()` to turn a blank string into null: `nullIfEmpty(value.trim())`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function nullIfEmpty(str: string | null | undefined): string | null;
|
|
17
22
|
/**
|
|
18
23
|
* Normalizes Unicode whitespaces into single ASCII spaces and removes leading
|
|
19
24
|
* and trailing whitespace.
|
|
@@ -68,4 +73,14 @@ export declare function toPascalCase(str: string): string;
|
|
|
68
73
|
* @return {string} - The string converted to CONSTANT_CASE.
|
|
69
74
|
*/
|
|
70
75
|
export declare function toConstantCase(str: string): string;
|
|
76
|
+
/**
|
|
77
|
+
* Formats a size in bytes with the largest unit it fills, in powers of 1024: `340 B`, `1.2 MB`.
|
|
78
|
+
*
|
|
79
|
+
* Bytes are written whole and the larger units with at most one decimal, with the separators of the locale.
|
|
80
|
+
*
|
|
81
|
+
* @param {number} bytes - The size in bytes; a negative or non-finite size is formatted as zero.
|
|
82
|
+
* @param {string} [locale] - The locale of the number, such as `es-ES`; the one of the runtime when omitted.
|
|
83
|
+
* @return {string} The number, a space and the unit.
|
|
84
|
+
*/
|
|
85
|
+
export declare function formatFileSize(bytes: number, locale?: string): string;
|
|
71
86
|
//# sourceMappingURL=string.d.ts.map
|
package/dist/string.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../src/string.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIhE;AAGD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIhE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../src/string.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIhE;AAGD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIhE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAEzE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,MAAM,CAgB/D;AA0BD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIhD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAID;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAWrE"}
|
package/dist/string.js
CHANGED
|
@@ -22,14 +22,19 @@ export function ensureSuffix(str, suffix) {
|
|
|
22
22
|
return str + suffix;
|
|
23
23
|
return str;
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Null for an empty string, as `Str::nullIfEmpty()` of develia/commons for PHP; any other string as it is. Compose it
|
|
27
|
+
* with `trim()` to turn a blank string into null: `nullIfEmpty(value.trim())`.
|
|
28
|
+
*/
|
|
29
|
+
export function nullIfEmpty(str) {
|
|
30
|
+
return str === undefined || str === null || str === '' ? null : str;
|
|
31
|
+
}
|
|
25
32
|
/**
|
|
26
33
|
* Normalizes Unicode whitespaces into single ASCII spaces and removes leading
|
|
27
34
|
* and trailing whitespace.
|
|
28
35
|
*/
|
|
29
36
|
export function normalizeWhitespaces(str) {
|
|
30
|
-
return str.
|
|
31
|
-
.replace(/[\s\u200B\uFEFF]+/gu, ' ')
|
|
32
|
-
.trim();
|
|
37
|
+
return str.replace(/[\s\u200B\uFEFF]+/gu, ' ').trim();
|
|
33
38
|
}
|
|
34
39
|
/**
|
|
35
40
|
* Removes Unicode diacritics while preserving the original letter casing.
|
|
@@ -139,4 +144,24 @@ export function toPascalCase(str) {
|
|
|
139
144
|
export function toConstantCase(str) {
|
|
140
145
|
return toWords(str).join('_').toUpperCase();
|
|
141
146
|
}
|
|
147
|
+
const FILE_SIZE_UNITS = Object.freeze(['B', 'KB', 'MB', 'GB', 'TB', 'PB']);
|
|
148
|
+
/**
|
|
149
|
+
* Formats a size in bytes with the largest unit it fills, in powers of 1024: `340 B`, `1.2 MB`.
|
|
150
|
+
*
|
|
151
|
+
* Bytes are written whole and the larger units with at most one decimal, with the separators of the locale.
|
|
152
|
+
*
|
|
153
|
+
* @param {number} bytes - The size in bytes; a negative or non-finite size is formatted as zero.
|
|
154
|
+
* @param {string} [locale] - The locale of the number, such as `es-ES`; the one of the runtime when omitted.
|
|
155
|
+
* @return {string} The number, a space and the unit.
|
|
156
|
+
*/
|
|
157
|
+
export function formatFileSize(bytes, locale) {
|
|
158
|
+
let size = Number.isFinite(bytes) && bytes > 0 ? bytes : 0;
|
|
159
|
+
let unitIndex = 0;
|
|
160
|
+
while (size >= 1024 && unitIndex < FILE_SIZE_UNITS.length - 1) {
|
|
161
|
+
size /= 1024;
|
|
162
|
+
unitIndex++;
|
|
163
|
+
}
|
|
164
|
+
const maximumFractionDigits = unitIndex === 0 ? 0 : 1;
|
|
165
|
+
return `${size.toLocaleString(locale, { maximumFractionDigits })} ${FILE_SIZE_UNITS[unitIndex]}`;
|
|
166
|
+
}
|
|
142
167
|
//# sourceMappingURL=string.js.map
|
package/dist/string.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"string.js","sourceRoot":"","sources":["../src/string.ts"],"names":[],"mappings":"AACA;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,MAAc;IACpD,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;QACvB,OAAO,MAAM,GAAG,GAAG,CAAA;IACvB,OAAO,GAAG,CAAA;AACd,CAAC;AAGD;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,MAAc;IACpD,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC;QACrB,OAAO,GAAG,GAAG,MAAM,CAAA;IACvB,OAAO,GAAG,CAAA;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"string.js","sourceRoot":"","sources":["../src/string.ts"],"names":[],"mappings":"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","sourcesContent":["\n/**\n * Ensures that a given string has a specific prefix.\n *\n * @param {string} str - The string to ensure the prefix on.\n * @param {string} prefix - The prefix to ensure on the string.\n * @return {string} - The resulting string with the ensured prefix.\n */\nexport function ensurePrefix(str: string, prefix: string): string {\n if (!str.startsWith(prefix))\n return prefix + str\n return str\n}\n\n\n/**\n * Ensures that a string ends with a specified suffix.\n *\n * @param {string} str - The original string.\n * @param {string} suffix - The suffix to ensure.\n * @return {string} - The modified string with the suffix added if it was not already present.\n */\nexport function ensureSuffix(str: string, suffix: string): string {\n if (!str.endsWith(suffix))\n return str + suffix\n return str\n}\n\n/**\n * Null for an empty string, as `Str::nullIfEmpty()` of develia/commons for PHP; any other string as it is. Compose it\n * with `trim()` to turn a blank string into null: `nullIfEmpty(value.trim())`.\n */\nexport function nullIfEmpty(str: string | null | undefined): string | null {\n return str === undefined || str === null || str === '' ? null : str;\n}\n\n/**\n * Normalizes Unicode whitespaces into single ASCII spaces and removes leading\n * and trailing whitespace.\n */\nexport function normalizeWhitespaces(str: string): string {\n return str.replace(/[\\s\\u200B\\uFEFF]+/gu, ' ').trim();\n}\n\n/**\n * Removes Unicode diacritics while preserving the original letter casing.\n *\n * @example removeDiacritics('áÁñÑ') // 'aAnN'\n */\nexport function removeDiacritics(str: string): string {\n return str\n .normalize('NFD')\n .replace(/\\p{M}+/gu, '')\n}\n\n/**\n * Formats a string using a template and provided arguments.\n *\n * @param {string} template - The template string containing placeholders.\n * @param {any[]} args - Optional arguments to replace the placeholders in the template.\n * @return {string} The formatted string.\n */\nexport function format(template: string, ...args: any[]): string {\n\n let regex: RegExp;\n const hasNamedPlaceholders = /{(?!\\d+})[^{}]+}/.test(template);\n if (args.length === 1 && args[0] !== null && typeof args[0] === 'object' && hasNamedPlaceholders) {\n args = args[0];\n regex = /{(.+?)}/g;\n } else {\n regex = /{(\\d+?)}/g;\n }\n\n return template.replace(regex, (match, key) => {\n return Object.prototype.hasOwnProperty.call(args, key) && typeof args[key] !== 'undefined'\n ? args[key]\n : \"\";\n });\n}\n\n/**\n * Splits a string into its constituent words, regardless of the original case\n * style (camelCase, PascalCase, snake_case, kebab-case, CONSTANT_CASE,\n * space-separated, etc.).\n *\n * @param {string} str - The string to split into words.\n * @return {string[]} - The list of lowercase words extracted from the input.\n */\nfunction toWords(str: string): string[] {\n if (!str) return [];\n\n return str\n // Insert a space between a lowercase/digit and an uppercase letter (camelCase -> camel Case)\n .replace(/([\\p{Ll}\\p{N}])(\\p{Lu})/gu, '$1 $2')\n // Insert a space between consecutive uppercase letters followed by a lowercase letter (XMLParser -> XML Parser)\n .replace(/(\\p{Lu}+)(\\p{Lu}\\p{Ll})/gu, '$1 $2')\n // Replace any non-alphanumeric character with a space\n .replace(/[^\\p{L}\\p{N}]+/gu, ' ')\n .trim()\n .toLowerCase()\n .split(/\\s+/)\n .filter(Boolean);\n}\n\n/**\n * Converts a string to snake_case.\n *\n * @param {string} str - The string to convert.\n * @return {string} - The string converted to snake_case.\n */\nexport function toSnakeCase(str: string): string {\n return toWords(str).join('_');\n}\n\n/**\n * Converts a string to kebab-case.\n *\n * @param {string} str - The string to convert.\n * @return {string} - The string converted to kebab-case.\n */\nexport function toKebabCase(str: string): string {\n return toWords(str).join('-');\n}\n\n/**\n * Converts a string to camelCase.\n *\n * @param {string} str - The string to convert.\n * @return {string} - The string converted to camelCase.\n */\nexport function toCamelCase(str: string): string {\n const words = toWords(str);\n if (words.length === 0) return '';\n return words\n .map((word, i) => i === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1))\n .join('');\n}\n\n/**\n * Converts a string to PascalCase.\n *\n * @param {string} str - The string to convert.\n * @return {string} - The string converted to PascalCase.\n */\nexport function toPascalCase(str: string): string {\n return toWords(str)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join('');\n}\n\n/**\n * Converts a string to CONSTANT_CASE (a.k.a. SCREAMING_SNAKE_CASE).\n *\n * @param {string} str - The string to convert.\n * @return {string} - The string converted to CONSTANT_CASE.\n */\nexport function toConstantCase(str: string): string {\n return toWords(str).join('_').toUpperCase();\n}\n\nconst FILE_SIZE_UNITS: readonly string[] = Object.freeze(['B', 'KB', 'MB', 'GB', 'TB', 'PB']);\n\n/**\n * Formats a size in bytes with the largest unit it fills, in powers of 1024: `340 B`, `1.2 MB`.\n *\n * Bytes are written whole and the larger units with at most one decimal, with the separators of the locale.\n *\n * @param {number} bytes - The size in bytes; a negative or non-finite size is formatted as zero.\n * @param {string} [locale] - The locale of the number, such as `es-ES`; the one of the runtime when omitted.\n * @return {string} The number, a space and the unit.\n */\nexport function formatFileSize(bytes: number, locale?: string): string {\n let size = Number.isFinite(bytes) && bytes > 0 ? bytes : 0;\n let unitIndex = 0;\n while (size >= 1024 && unitIndex < FILE_SIZE_UNITS.length - 1) {\n size /= 1024;\n unitIndex++;\n }\n\n const maximumFractionDigits = unitIndex === 0 ? 0 : 1;\n\n return `${size.toLocaleString(locale, {maximumFractionDigits})} ${FILE_SIZE_UNITS[unitIndex]}`;\n}\n"]}
|