@develia/commons 0.5.0 → 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.
Files changed (60) hide show
  1. package/dist/parse.d.ts +62 -44
  2. package/dist/parse.d.ts.map +1 -1
  3. package/dist/parse.js +95 -59
  4. package/dist/parse.js.map +1 -1
  5. package/dist/range.d.ts +2 -10
  6. package/dist/range.d.ts.map +1 -1
  7. package/dist/range.js +0 -12
  8. package/dist/range.js.map +1 -1
  9. package/dist/stopwatch.d.ts +2 -2
  10. package/dist/stopwatch.d.ts.map +1 -1
  11. package/dist/stopwatch.js +9 -9
  12. package/dist/stopwatch.js.map +1 -1
  13. package/dist/string.d.ts +10 -0
  14. package/dist/string.d.ts.map +1 -1
  15. package/dist/string.js +20 -0
  16. package/dist/string.js.map +1 -1
  17. package/dist/timespan.d.ts +10 -15
  18. package/dist/timespan.d.ts.map +1 -1
  19. package/dist/timespan.js +10 -15
  20. package/dist/timespan.js.map +1 -1
  21. package/dist/triggers.d.ts +6 -15
  22. package/dist/triggers.d.ts.map +1 -1
  23. package/dist/triggers.js +8 -22
  24. package/dist/triggers.js.map +1 -1
  25. package/dist/uuid.d.ts +11 -11
  26. package/dist/uuid.d.ts.map +1 -1
  27. package/dist/uuid.js +18 -18
  28. package/dist/uuid.js.map +1 -1
  29. package/package.json +1 -1
  30. package/src/array.ts +0 -0
  31. package/src/async-pool-executor.ts +0 -0
  32. package/src/browser/form-utilities.ts +0 -0
  33. package/src/browser/geo-location.ts +0 -0
  34. package/src/browser/index.ts +0 -0
  35. package/src/browser/native-bridge.ts +0 -0
  36. package/src/cancellable-promise.ts +0 -0
  37. package/src/clean-url-search-params.ts +0 -0
  38. package/src/collections/cache-dictionary.ts +0 -0
  39. package/src/collections/default-map.ts +0 -0
  40. package/src/collections/default-weak-map.ts +0 -0
  41. package/src/collections/index.ts +0 -0
  42. package/src/draft.ts +0 -0
  43. package/src/event-bus.ts +0 -0
  44. package/src/functions.ts +0 -0
  45. package/src/key-value-pair.ts +0 -0
  46. package/src/lazy.ts +0 -0
  47. package/src/math.ts +0 -0
  48. package/src/order.ts +0 -0
  49. package/src/parse.ts +108 -66
  50. package/src/patch.ts +0 -0
  51. package/src/range.ts +2 -16
  52. package/src/stopwatch.ts +9 -9
  53. package/src/string.ts +24 -0
  54. package/src/timer.ts +0 -0
  55. package/src/timespan.ts +10 -15
  56. package/src/triggers.ts +10 -24
  57. package/src/type-code.ts +0 -0
  58. package/src/type.ts +0 -0
  59. package/src/types.ts +0 -0
  60. package/src/uuid.ts +19 -19
package/dist/parse.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Options for {@link parseBoolean}.
2
+ * Options for {@link tryParseBoolean} and {@link parseBoolean}.
3
3
  */
4
4
  export interface ParseBooleanOptions {
5
5
  /**
@@ -16,7 +16,7 @@ export interface ParseBooleanOptions {
16
16
  extraFalsy?: string[];
17
17
  }
18
18
  /**
19
- * Options for {@link parseInteger}.
19
+ * Options for {@link tryParseInteger} and {@link parseInteger}.
20
20
  */
21
21
  export interface ParseIntegerOptions {
22
22
  /**
@@ -32,7 +32,7 @@ export interface ParseIntegerOptions {
32
32
  thousandsSeparator?: string;
33
33
  }
34
34
  /**
35
- * Options for {@link parseDecimal}.
35
+ * Options for {@link tryParseDecimal} and {@link parseDecimal}.
36
36
  */
37
37
  export interface ParseDecimalOptions {
38
38
  /**
@@ -49,34 +49,40 @@ export interface ParseDecimalOptions {
49
49
  }
50
50
  /**
51
51
  * Safely parses a value into an integer.
52
- * Returns `null` if the value cannot be parsed.
52
+ * Returns `undefined` if the value cannot be parsed.
53
53
  *
54
- * - `null` or `undefined` → `null`
54
+ * - `null` or `undefined` → `undefined`
55
55
  * - `number` → returned as-is (floats are truncated)
56
56
  * - `string` → parsed with the given options
57
57
  *
58
58
  * @param value - The value to parse.
59
59
  * @param options - Optional parsing configuration.
60
- * @returns The parsed integer, or `null` on failure.
60
+ * @returns The parsed integer, or `undefined` on failure.
61
61
  *
62
62
  * @example
63
63
  * ```ts
64
- * parseInteger(42) // 42
65
- * parseInteger(3.7) // 3
66
- * parseInteger(null) // null
67
- * parseInteger(undefined) // null
68
- * parseInteger("42") // 42
69
- * parseInteger("1.234.567", { thousandsSeparator: "." }) // 1234567
70
- * parseInteger("FF", { radix: 16 }) // 255
71
- * parseInteger("abc") // null
64
+ * tryParseInteger(42) // 42
65
+ * tryParseInteger(3.7) // 3
66
+ * tryParseInteger(null) // undefined
67
+ * tryParseInteger(undefined) // undefined
68
+ * tryParseInteger("42") // 42
69
+ * tryParseInteger("1.234.567", { thousandsSeparator: "." }) // 1234567
70
+ * tryParseInteger("FF", { radix: 16 }) // 255
71
+ * tryParseInteger("abc") // undefined
72
72
  * ```
73
73
  */
74
- export declare function parseInteger(value: string | number | null | undefined, options?: ParseIntegerOptions): number | null;
74
+ export declare function tryParseInteger(value: string | number | null | undefined, options?: ParseIntegerOptions): number | undefined;
75
+ /**
76
+ * Parses a value into an integer as {@link tryParseInteger} does.
77
+ *
78
+ * @throws {SyntaxError} If the value cannot be parsed.
79
+ */
80
+ export declare function parseInteger(value: string | number, options?: ParseIntegerOptions): number;
75
81
  /**
76
82
  * Safely parses a value into a floating-point number.
77
- * Returns `null` if the value cannot be parsed.
83
+ * Returns `undefined` if the value cannot be parsed.
78
84
  *
79
- * - `null` or `undefined` → `null`
85
+ * - `null` or `undefined` → `undefined`
80
86
  * - `number` → returned as-is (if finite)
81
87
  * - `string` → parsed with the given options
82
88
  *
@@ -85,25 +91,31 @@ export declare function parseInteger(value: string | number | null | undefined,
85
91
  *
86
92
  * @param value - The value to parse.
87
93
  * @param options - Optional parsing configuration.
88
- * @returns The parsed float, or `null` on failure.
94
+ * @returns The parsed float, or `undefined` on failure.
89
95
  *
90
96
  * @example
91
97
  * ```ts
92
- * parseDecimal(3.14) // 3.14
93
- * parseDecimal(null) // null
94
- * parseDecimal(undefined) // null
95
- * parseDecimal("3.14") // 3.14
96
- * parseDecimal("3,14", { decimalSeparator: "," }) // 3.14
97
- * parseDecimal("1.234,56", { decimalSeparator: ",", thousandsSeparator: "." }) // 1234.56
98
- * parseDecimal("abc") // null
98
+ * tryParseDecimal(3.14) // 3.14
99
+ * tryParseDecimal(null) // undefined
100
+ * tryParseDecimal(undefined) // undefined
101
+ * tryParseDecimal("3.14") // 3.14
102
+ * tryParseDecimal("3,14", { decimalSeparator: "," }) // 3.14
103
+ * tryParseDecimal("1.234,56", { decimalSeparator: ",", thousandsSeparator: "." }) // 1234.56
104
+ * tryParseDecimal("abc") // undefined
99
105
  * ```
100
106
  */
101
- export declare function parseDecimal(value: string | number | null | undefined, options?: ParseDecimalOptions): number | null;
107
+ export declare function tryParseDecimal(value: string | number | null | undefined, options?: ParseDecimalOptions): number | undefined;
108
+ /**
109
+ * Parses a value into a decimal number as {@link tryParseDecimal} does.
110
+ *
111
+ * @throws {SyntaxError} If the value cannot be parsed.
112
+ */
113
+ export declare function parseDecimal(value: string | number, options?: ParseDecimalOptions): number;
102
114
  /**
103
115
  * Safely parses a value into a boolean.
104
- * Returns `null` if the value cannot be interpreted as boolean.
116
+ * Returns `undefined` if the value cannot be interpreted as boolean.
105
117
  *
106
- * - `null` or `undefined` → `null`
118
+ * - `null` or `undefined` → `undefined`
107
119
  * - `boolean` → returned as-is
108
120
  * - `number` → `0` is `false`, any other finite number is `true`
109
121
  * - `string` → matched case-insensitively against known truthy/falsy values
@@ -113,25 +125,31 @@ export declare function parseDecimal(value: string | number | null | undefined,
113
125
  *
114
126
  * @param value - The value to parse.
115
127
  * @param options - Optional parsing configuration.
116
- * @returns The parsed boolean, or `null` on failure.
128
+ * @returns The parsed boolean, or `undefined` on failure.
117
129
  *
118
130
  * @example
119
131
  * ```ts
120
- * parseBoolean(true) // true
121
- * parseBoolean(false) // false
122
- * parseBoolean(1) // true
123
- * parseBoolean(0) // false
124
- * parseBoolean(null) // null
125
- * parseBoolean(undefined) // null
126
- * parseBoolean("yes") // true
127
- * parseBoolean("no") // false
128
- * parseBoolean("sí") // true
129
- * parseBoolean("TRUE") // true
130
- * parseBoolean("oui") // null
131
- * parseBoolean("oui", { extraTruthy: ["oui"] }) // true
132
- * parseBoolean("nein", { extraFalsy: ["nein"] }) // false
133
- * parseBoolean("whatever") // null
132
+ * tryParseBoolean(true) // true
133
+ * tryParseBoolean(false) // false
134
+ * tryParseBoolean(1) // true
135
+ * tryParseBoolean(0) // false
136
+ * tryParseBoolean(null) // undefined
137
+ * tryParseBoolean(undefined) // undefined
138
+ * tryParseBoolean("yes") // true
139
+ * tryParseBoolean("no") // false
140
+ * tryParseBoolean("sí") // true
141
+ * tryParseBoolean("TRUE") // true
142
+ * tryParseBoolean("oui") // undefined
143
+ * tryParseBoolean("oui", { extraTruthy: ["oui"] }) // true
144
+ * tryParseBoolean("nein", { extraFalsy: ["nein"] }) // false
145
+ * tryParseBoolean("whatever") // undefined
134
146
  * ```
135
147
  */
136
- export declare function parseBoolean(value: string | number | boolean | null | undefined, options?: ParseBooleanOptions): boolean | null;
148
+ export declare function tryParseBoolean(value: string | number | boolean | null | undefined, options?: ParseBooleanOptions): boolean | undefined;
149
+ /**
150
+ * Parses a value into a boolean as {@link tryParseBoolean} does.
151
+ *
152
+ * @throws {SyntaxError} If the value cannot be parsed.
153
+ */
154
+ export declare function parseBoolean(value: string | number | boolean, options?: ParseBooleanOptions): boolean;
137
155
  //# sourceMappingURL=parse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAEvB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;IAE7B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B;AA0BD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CACxB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,OAAO,GAAE,mBAAwB,GAClC,MAAM,GAAG,IAAI,CAiBf;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,YAAY,CACxB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,OAAO,GAAE,mBAAwB,GAClC,MAAM,GAAG,IAAI,CAwBf;AASD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,YAAY,CACxB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,EACnD,OAAO,GAAE,mBAAwB,GAClC,OAAO,GAAG,IAAI,CAsBhB"}
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AACA;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAEvB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAChC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;IAE7B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC/B;AA0BD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,eAAe,CAC3B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,OAAO,GAAE,mBAAwB,GAClC,MAAM,GAAG,SAAS,CAiBpB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAO9F;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,eAAe,CAC3B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,EACzC,OAAO,GAAE,mBAAwB,GAClC,MAAM,GAAG,SAAS,CAwBpB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAO9F;AASD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,eAAe,CAC3B,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,EACnD,OAAO,GAAE,mBAAwB,GAClC,OAAO,GAAG,SAAS,CAsBrB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAOzG"}
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 `null` if the value cannot be parsed.
23
+ * Returns `undefined` if the value cannot be parsed.
24
24
  *
25
- * - `null` or `undefined` → `null`
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 `null` on failure.
31
+ * @returns The parsed integer, or `undefined` on failure.
32
32
  *
33
33
  * @example
34
34
  * ```ts
35
- * parseInteger(42) // 42
36
- * parseInteger(3.7) // 3
37
- * parseInteger(null) // null
38
- * parseInteger(undefined) // null
39
- * parseInteger("42") // 42
40
- * parseInteger("1.234.567", { thousandsSeparator: "." }) // 1234567
41
- * parseInteger("FF", { radix: 16 }) // 255
42
- * parseInteger("abc") // null
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 parseInteger(value, options = {}) {
45
+ export function tryParseInteger(value, options = {}) {
46
46
  if (value === null || value === undefined)
47
- return null;
47
+ return undefined;
48
48
  if (typeof value === "number") {
49
- return Number.isFinite(value) ? Math.trunc(value) : null;
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 null;
54
+ return undefined;
55
55
  if (!isValidInteger(cleaned, radix))
56
- return null;
56
+ return undefined;
57
57
  const parsed = Number.parseInt(cleaned, radix);
58
- return Number.isNaN(parsed) ? null : 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 `null` if the value cannot be parsed.
77
+ * Returns `undefined` if the value cannot be parsed.
66
78
  *
67
- * - `null` or `undefined` → `null`
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 `null` on failure.
88
+ * @returns The parsed float, or `undefined` on failure.
77
89
  *
78
90
  * @example
79
91
  * ```ts
80
- * parseDecimal(3.14) // 3.14
81
- * parseDecimal(null) // null
82
- * parseDecimal(undefined) // null
83
- * parseDecimal("3.14") // 3.14
84
- * parseDecimal("3,14", { decimalSeparator: "," }) // 3.14
85
- * parseDecimal("1.234,56", { decimalSeparator: ",", thousandsSeparator: "." }) // 1234.56
86
- * parseDecimal("abc") // null
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 parseDecimal(value, options = {}) {
101
+ export function tryParseDecimal(value, options = {}) {
90
102
  if (value === null || value === undefined)
91
- return null;
103
+ return undefined;
92
104
  if (typeof value === "number") {
93
- return Number.isFinite(value) ? value : null;
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 null;
110
+ return undefined;
99
111
  if (decimalSeparator === ",") {
100
112
  const commaCount = (cleaned.match(/,/g) || []).length;
101
113
  if (commaCount > 1)
102
- return null;
114
+ return undefined;
103
115
  cleaned = cleaned.replace(",", ".");
104
116
  }
105
117
  if (!/^[+-]?\d+(\.\d+)?$/.test(cleaned))
106
- return null;
118
+ return undefined;
107
119
  const parsed = Number.parseFloat(cleaned);
108
- return Number.isNaN(parsed) || !Number.isFinite(parsed) ? null : 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 `null` if the value cannot be interpreted as boolean.
141
+ * Returns `undefined` if the value cannot be interpreted as boolean.
118
142
  *
119
- * - `null` or `undefined` → `null`
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 `null` on failure.
153
+ * @returns The parsed boolean, or `undefined` on failure.
130
154
  *
131
155
  * @example
132
156
  * ```ts
133
- * parseBoolean(true) // true
134
- * parseBoolean(false) // false
135
- * parseBoolean(1) // true
136
- * parseBoolean(0) // false
137
- * parseBoolean(null) // null
138
- * parseBoolean(undefined) // null
139
- * parseBoolean("yes") // true
140
- * parseBoolean("no") // false
141
- * parseBoolean("sí") // true
142
- * parseBoolean("TRUE") // true
143
- * parseBoolean("oui") // null
144
- * parseBoolean("oui", { extraTruthy: ["oui"] }) // true
145
- * parseBoolean("nein", { extraFalsy: ["nein"] }) // false
146
- * parseBoolean("whatever") // null
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 parseBoolean(value, options = {}) {
173
+ export function tryParseBoolean(value, options = {}) {
150
174
  if (value === null || value === undefined)
151
- return null;
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 : null;
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 null;
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 null;
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
- private readonly start;
3
- private readonly end;
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
  *
@@ -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,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAI;IAC1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAI;IAExB;;;;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;;OAEG;IACI,QAAQ,IAAI,CAAC;IAIpB;;OAEG;IACI,MAAM,IAAI,CAAC;IAIlB;;;;;;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"}
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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","sourcesContent":["export default class Range<T> {\n\n private readonly start: T;\n private 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 * @returns T\n */\n public getStart(): T {\n return this.start;\n }\n\n /**\n * @returns T\n */\n public getEnd(): T {\n return this.end;\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"]}
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"]}
@@ -1,10 +1,10 @@
1
1
  import TimeSpan from "./timespan.js";
2
2
  export default class Stopwatch {
3
3
  private startTime;
4
- private elapsedTime;
4
+ private elapsedMilliseconds;
5
5
  start(): void;
6
6
  stop(): void;
7
7
  resume(): void;
8
- getElapsedTime(): TimeSpan;
8
+ get elapsedTime(): TimeSpan;
9
9
  }
10
10
  //# sourceMappingURL=stopwatch.d.ts.map
@@ -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,WAAW,CAAuB;IAa1C,KAAK,IAAI,IAAI;IAKb,IAAI,IAAI,IAAI;IAOZ,MAAM,IAAI,IAAI;IAOd,cAAc,IAAI,QAAQ;CAM7B"}
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"}