@leaderty/utils 2.1.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -38,13 +38,39 @@ numberToMoney(-1234.5, { decimals: 2 }) // "
38
38
  numberToMoney(undefined, { currency: 'ARS' }) // "-"
39
39
  ```
40
40
 
41
+ ### `moneyToNumber(value)`
42
+
43
+ Lee un monto escrito a la manera argentina: coma para los decimales y sin separador de miles. Es la inversa de lo que un usuario tipea en un campo de plata.
44
+
45
+ **Comportamiento:**
46
+ - Rechaza cualquier punto: `350.5` y `350.000` no se distinguen sin adivinar.
47
+ - Admite un monto a medio escribir (`1234,`) y hasta dos decimales. Con más decimales devuelve `null`: no redondea lo que escribió el usuario.
48
+ - Admite el signo menos y hasta 13 cifras enteras, para que cada centavo sea exacto en un `number`.
49
+ - Ignora los espacios alrededor del monto.
50
+
51
+ **Parámetros:**
52
+ - `value` - `string`
53
+
54
+ **Devuelve:** `number`, o `null` si `value` está vacío o no es un monto válido
55
+
56
+ **Ejemplos:**
57
+ ```typescript
58
+ moneyToNumber('357672,50') // 357672.5
59
+ moneyToNumber('350000') // 350000
60
+ moneyToNumber('1234,') // 1234
61
+ moneyToNumber('450.000') // null
62
+ moneyToNumber('1,2,3') // null
63
+ moneyToNumber('') // null
64
+ ```
65
+
41
66
  ### `dateToShort(value, options?)`
42
67
 
43
68
  Formats a date as `dd/mm/aaaa`, or `dd/mm/aaaa hh:mm` (24-hour) with `time: true`.
44
69
 
45
70
  **Behavior:**
46
71
  - `'aaaa-mm-dd'` strings, and date-time strings without a time zone (`'2026-10-01T00:00:00'`), are read as written. `'2026-10-11'` gives `11/10/2026`, even though `new Date('2026-10-11')` is midnight UTC, which is still October 10 in Argentina.
47
- - `Date` objects and ISO strings with a time zone (`Z` or `±hh:mm`, as in `'2026-10-22T22:05:36.036Z'`) are shown in `America/Argentina/Buenos_Aires` time (UTC-3, no daylight saving time).
72
+ - `Date` objects are read in the system time zone, as their own getters do: `new Date(2026, 10, 1)` is November 1 in any system time zone.
73
+ - ISO strings with a time zone (`Z` or `±hh:mm`, as in `'2026-10-22T22:05:36.036Z'`) are shown in `America/Argentina/Buenos_Aires` time (UTC-3, no daylight saving time).
48
74
  - Any other string gives `'-'` (`'11/10/2026'`, `'2026-10'`, `'Oct 11 2026'`): `new Date()` would read it in the system time zone or guess the day/month order.
49
75
  - Also returns `'-'` for `null`, `undefined`, invalid dates and impossible dates such as `'2026-02-30'`.
50
76
 
@@ -58,14 +84,14 @@ Formats a date as `dd/mm/aaaa`, or `dd/mm/aaaa hh:mm` (24-hour) with `time: true
58
84
  ```typescript
59
85
  dateToShort('2026-10-11') // "11/10/2026"
60
86
  dateToShort('2026-10-01T00:00:00') // "01/10/2026"
61
- dateToShort(new Date('2026-10-22T22:05:36Z')) // "22/10/2026"
87
+ dateToShort(new Date(2026, 9, 22)) // "22/10/2026"
62
88
  dateToShort('2026-10-22T02:05:36Z', { time: true }) // "21/10/2026 23:05"
63
89
  dateToShort('11/10/2026') // "-"
64
90
  ```
65
91
 
66
92
  ### `dateToYMD(value)`
67
93
 
68
- Formats a date as `aaaa-mm-dd`, the value of an `<input type="date">`. Reads `value` like `dateToShort`, so `'2026-10-11'` stays the 11th and a `Date` is taken in Buenos Aires time.
94
+ Formats a date as `aaaa-mm-dd`, the value of an `<input type="date">`. Reads `value` like `dateToShort`, so `'2026-10-11'` stays the 11th and a `Date` is taken in the system time zone.
69
95
 
70
96
  **Parameters:**
71
97
  - `value` - `Date | string | null | undefined`
@@ -75,7 +101,7 @@ Formats a date as `aaaa-mm-dd`, the value of an `<input type="date">`. Reads `va
75
101
  **Examples:**
76
102
  ```typescript
77
103
  dateToYMD('2026-10-11') // "2026-10-11"
78
- dateToYMD(new Date('2026-10-22T02:05:36Z')) // "2026-10-21"
104
+ dateToYMD(new Date(2026, 9, 21)) // "2026-10-21"
79
105
  dateToYMD('11/10/2026') // ""
80
106
  ```
81
107
 
package/dist/format.d.ts CHANGED
@@ -32,14 +32,28 @@ export interface DateToShortOptions {
32
32
  * numberToMoney(-1234.5, { currency: 'USD', currencyDisplay: 'symbol', decimals: 2 }) // "-US$ 1.234,50"
33
33
  */
34
34
  export declare function numberToMoney(amount: number | null | undefined, options?: NumberToMoneyOptions): string;
35
+ /**
36
+ * Reads an amount typed the Argentine way: `,` for decimals and no thousands separator.
37
+ * Any dot is rejected: `350.5` and `350.000` can't be told apart without guessing.
38
+ *
39
+ * @param value - Text of a money field
40
+ * @returns The amount, or `null` when `value` has no amount or is not a valid one
41
+ *
42
+ * @example
43
+ * moneyToNumber('357672,50') // 357672.5
44
+ * moneyToNumber('1234,') // 1234
45
+ * moneyToNumber('450.000') // null
46
+ */
47
+ export declare function moneyToNumber(value: string): number | null;
35
48
  /**
36
49
  * Formats a date as `dd/mm/aaaa`, optionally with the time as `dd/mm/aaaa hh:mm`.
37
50
  *
38
51
  * - `'aaaa-mm-dd'` strings, and date-time strings without a time zone (`'2026-10-01T00:00:00'`),
39
52
  * are read as written: `'2026-10-11'` is the 11th, never the 10th
40
53
  * (`new Date('2026-10-11')` is midnight UTC, which is still the 10th in Argentina).
41
- * - `Date` objects and ISO strings with a time zone (`'2026-10-22T22:05:36.036Z'`) are shown in
42
- * `America/Argentina/Buenos_Aires` time.
54
+ * - `Date` objects are read in the system time zone, as their own getters do: `new Date(2026, 10, 1)` is
55
+ * November 1 in any system time zone.
56
+ * - ISO strings with a time zone (`'2026-10-22T22:05:36.036Z'`) are shown in `America/Argentina/Buenos_Aires` time.
43
57
  * - Any other string (`'11/10/2026'`, `'2026-10'`, `'Oct 11 2026'`) gives `'-'`: the engine would parse it
44
58
  * in the system time zone, or guess the day/month order.
45
59
  *
@@ -49,7 +63,7 @@ export declare function numberToMoney(amount: number | null | undefined, options
49
63
  *
50
64
  * @example
51
65
  * dateToShort('2026-10-11') // "11/10/2026"
52
- * dateToShort(new Date('2026-10-22T22:05:36Z')) // "22/10/2026"
66
+ * dateToShort(new Date(2026, 9, 22)) // "22/10/2026"
53
67
  * dateToShort('2026-10-22T02:05:36Z', { time: true }) // "21/10/2026 23:05"
54
68
  */
55
69
  export declare function dateToShort(value: Date | string | null | undefined, options?: DateToShortOptions): string;
@@ -62,7 +76,7 @@ export declare function dateToShort(value: Date | string | null | undefined, opt
62
76
  * @example
63
77
  * dateToYMD('2026-10-11') // "2026-10-11"
64
78
  * dateToYMD('2026-10-11T00:00:00') // "2026-10-11"
65
- * dateToYMD(new Date('2026-10-22T02:05:36Z')) // "2026-10-21"
79
+ * dateToYMD(new Date(2026, 9, 21)) // "2026-10-21"
66
80
  * dateToYMD('11/10/2026') // ""
67
81
  */
68
82
  export declare function dateToYMD(value: Date | string | null | undefined): string;
package/dist/format.js CHANGED
@@ -6,6 +6,8 @@
6
6
  /** Shown instead of a value that is missing or not a valid number/date. */
7
7
  const PLACEHOLDER = '-';
8
8
  const CURRENCY_SYMBOLS = { ARS: '$', USD: 'US$' };
9
+ /** Up to 13 integer digits: with two decimals, 15 significant digits are always exact to the cent in a `number`. */
10
+ const MONEY_INPUT_PATTERN = /^-?(?:\d{1,13}(?:,\d{0,2})?|,\d{1,2})$/;
9
11
  /** Argentina is UTC-3 all year (no daylight saving time since 2009). */
10
12
  const BUENOS_AIRES_OFFSET_MS = -3 * 60 * 60 * 1000;
11
13
  /** `aaaa-mm-dd`, optionally followed by a time and no time zone: a calendar date or Argentine wall-clock time. */
@@ -53,14 +55,34 @@ export function numberToMoney(amount, options = {}) {
53
55
  const prefix = currencyDisplay === 'symbol' ? CURRENCY_SYMBOLS[currency] : currency;
54
56
  return `${sign}${prefix} ${number}`;
55
57
  }
58
+ /**
59
+ * Reads an amount typed the Argentine way: `,` for decimals and no thousands separator.
60
+ * Any dot is rejected: `350.5` and `350.000` can't be told apart without guessing.
61
+ *
62
+ * @param value - Text of a money field
63
+ * @returns The amount, or `null` when `value` has no amount or is not a valid one
64
+ *
65
+ * @example
66
+ * moneyToNumber('357672,50') // 357672.5
67
+ * moneyToNumber('1234,') // 1234
68
+ * moneyToNumber('450.000') // null
69
+ */
70
+ export function moneyToNumber(value) {
71
+ const text = value.trim();
72
+ if (!MONEY_INPUT_PATTERN.test(text))
73
+ return null;
74
+ // `|| 0` turns -0 into 0
75
+ return Number(text.replace(',', '.')) || 0;
76
+ }
56
77
  /**
57
78
  * Formats a date as `dd/mm/aaaa`, optionally with the time as `dd/mm/aaaa hh:mm`.
58
79
  *
59
80
  * - `'aaaa-mm-dd'` strings, and date-time strings without a time zone (`'2026-10-01T00:00:00'`),
60
81
  * are read as written: `'2026-10-11'` is the 11th, never the 10th
61
82
  * (`new Date('2026-10-11')` is midnight UTC, which is still the 10th in Argentina).
62
- * - `Date` objects and ISO strings with a time zone (`'2026-10-22T22:05:36.036Z'`) are shown in
63
- * `America/Argentina/Buenos_Aires` time.
83
+ * - `Date` objects are read in the system time zone, as their own getters do: `new Date(2026, 10, 1)` is
84
+ * November 1 in any system time zone.
85
+ * - ISO strings with a time zone (`'2026-10-22T22:05:36.036Z'`) are shown in `America/Argentina/Buenos_Aires` time.
64
86
  * - Any other string (`'11/10/2026'`, `'2026-10'`, `'Oct 11 2026'`) gives `'-'`: the engine would parse it
65
87
  * in the system time zone, or guess the day/month order.
66
88
  *
@@ -70,7 +92,7 @@ export function numberToMoney(amount, options = {}) {
70
92
  *
71
93
  * @example
72
94
  * dateToShort('2026-10-11') // "11/10/2026"
73
- * dateToShort(new Date('2026-10-22T22:05:36Z')) // "22/10/2026"
95
+ * dateToShort(new Date(2026, 9, 22)) // "22/10/2026"
74
96
  * dateToShort('2026-10-22T02:05:36Z', { time: true }) // "21/10/2026 23:05"
75
97
  */
76
98
  export function dateToShort(value, options = {}) {
@@ -89,7 +111,7 @@ export function dateToShort(value, options = {}) {
89
111
  * @example
90
112
  * dateToYMD('2026-10-11') // "2026-10-11"
91
113
  * dateToYMD('2026-10-11T00:00:00') // "2026-10-11"
92
- * dateToYMD(new Date('2026-10-22T02:05:36Z')) // "2026-10-21"
114
+ * dateToYMD(new Date(2026, 9, 21)) // "2026-10-21"
93
115
  * dateToYMD('11/10/2026') // ""
94
116
  */
95
117
  export function dateToYMD(value) {
@@ -120,6 +142,17 @@ export function dateToMonthYearLong(value) {
120
142
  function toDateParts(value) {
121
143
  if (value === null || value === undefined)
122
144
  return null;
145
+ if (value instanceof Date) {
146
+ if (Number.isNaN(value.getTime()))
147
+ return null;
148
+ return {
149
+ year: value.getFullYear(),
150
+ month: value.getMonth() + 1,
151
+ day: value.getDate(),
152
+ hours: value.getHours(),
153
+ minutes: value.getMinutes(),
154
+ };
155
+ }
123
156
  if (typeof value === 'string') {
124
157
  const match = WALL_CLOCK_PATTERN.exec(value);
125
158
  if (match) {
package/dist/index.d.ts CHANGED
@@ -5,4 +5,4 @@
5
5
  export declare function numberToDecimalString(numero: number): string;
6
6
  /** @deprecated Renamed to {@link numberToDecimalString}. */
7
7
  export declare const numberToStringWithDecimals: typeof numberToDecimalString;
8
- export { numberToMoney, dateToShort, dateToYMD, dateToMonthYearLong, type Currency, type NumberToMoneyOptions, type DateToShortOptions, } from './format.js';
8
+ export { numberToMoney, moneyToNumber, dateToShort, dateToYMD, dateToMonthYearLong, type Currency, type NumberToMoneyOptions, type DateToShortOptions, } from './format.js';
package/dist/index.js CHANGED
@@ -8,4 +8,4 @@ export function numberToDecimalString(numero) {
8
8
  }
9
9
  /** @deprecated Renamed to {@link numberToDecimalString}. */
10
10
  export const numberToStringWithDecimals = numberToDecimalString;
11
- export { numberToMoney, dateToShort, dateToYMD, dateToMonthYearLong, } from './format.js';
11
+ export { numberToMoney, moneyToNumber, dateToShort, dateToYMD, dateToMonthYearLong, } from './format.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leaderty/utils",
3
- "version": "2.1.1",
3
+ "version": "3.1.0",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",