@alwatr/parse-duration 5.4.0 → 5.5.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/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [5.5.1](https://github.com/Alwatr/nanolib/compare/@alwatr/parse-duration@5.5.0...@alwatr/parse-duration@5.5.1) (2025-03-18)
7
+
8
+ ### Code Refactoring
9
+
10
+ * **parse-duration:** replace isNumber with toNumber for improved number conversion and enhance error handling ([4d63892](https://github.com/Alwatr/nanolib/commit/4d63892f914cebe73bd1dc1e688c2f4ea5b53de1)) by @alimd
11
+
12
+ ## [5.5.0](https://github.com/Alwatr/nanolib/compare/@alwatr/parse-duration@5.4.0...@alwatr/parse-duration@5.5.0) (2025-03-06)
13
+
14
+ ### Miscellaneous Chores
15
+
16
+ * update username casing in changelog entries ([9722ac9](https://github.com/Alwatr/nanolib/commit/9722ac9a078438a4e8ebfa5826ea70e0e3a52ca6)) by @
17
+
18
+ ### Dependencies update
19
+
20
+ * bump the development-dependencies group across 1 directory with 11 updates ([720c395](https://github.com/Alwatr/nanolib/commit/720c3954da55c929fe8fb16957121f4c51fb7f0c)) by @dependabot[bot]
21
+
6
22
  ## [5.4.0](https://github.com/Alwatr/nanolib/compare/@alwatr/parse-duration@1.1.8...@alwatr/parse-duration@5.4.0) (2025-02-18)
7
23
 
8
24
  ## 5.3.0 (2025-02-03)
@@ -110,7 +126,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
110
126
 
111
127
  ### Miscellaneous Chores
112
128
 
113
- - include LICENSE and LEGAL files to publish ([09f366f](https://github.com/Alwatr/nanolib/commit/09f366f680bfa9fb26acb2cd1ccbc68c5a9e9ad8)) by @AliMD
129
+ - include LICENSE and LEGAL files to publish ([09f366f](https://github.com/Alwatr/nanolib/commit/09f366f680bfa9fb26acb2cd1ccbc68c5a9e9ad8)) by @alimd
114
130
 
115
131
  ## [1.1.3](https://github.com/Alwatr/nanolib/compare/@alwatr/parse-duration@1.1.2...@alwatr/parse-duration@1.1.3) (2024-10-11)
116
132
 
@@ -130,7 +146,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
130
146
 
131
147
  ### Features
132
148
 
133
- - **parse-duration:** update parseDuration function to accept duration as number or string ([af413f5](https://github.com/Alwatr/nanolib/commit/af413f5399b7bb8c01d4e14ae1f9238e44368184)) by @AliMD
149
+ - **parse-duration:** update parseDuration function to accept duration as number or string ([af413f5](https://github.com/Alwatr/nanolib/commit/af413f5399b7bb8c01d4e14ae1f9238e44368184)) by @alimd
134
150
  - use `package-tracer` ([cc3c5f9](https://github.com/Alwatr/nanolib/commit/cc3c5f9c1a3d03f0d81b46835665f16a0426fd0d)) by @mohammadhonarvar
135
151
 
136
152
  ### Bug Fixes
@@ -140,7 +156,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
140
156
  ### Miscellaneous Chores
141
157
 
142
158
  - **parse-duration:** change the license to AGPL-3.0 ([896df6f](https://github.com/Alwatr/nanolib/commit/896df6f64bb1df5954d6c46694e18bfb3e944f22)) by @ArmanAsadian
143
- - Update build and lint scripts ([392d0b7](https://github.com/Alwatr/nanolib/commit/392d0b71f446bce336b0256119a80f07aff794ba)) by @AliMD
159
+ - Update build and lint scripts ([392d0b7](https://github.com/Alwatr/nanolib/commit/392d0b71f446bce336b0256119a80f07aff794ba)) by @alimd
144
160
 
145
161
  ### Dependencies update
146
162
 
@@ -155,7 +171,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
155
171
  ### Dependencies update
156
172
 
157
173
  - bump the development-dependencies group across 1 directory with 10 updates ([9ed98ff](https://github.com/Alwatr/nanolib/commit/9ed98ffd0668d5a36e255c82edab3af53bffda8f)) by @dependabot[bot]
158
- - update ([c36ed50](https://github.com/Alwatr/nanolib/commit/c36ed50f68da2f5608ccd96119963a16cfacb4ce)) by @AliMD
174
+ - update ([c36ed50](https://github.com/Alwatr/nanolib/commit/c36ed50f68da2f5608ccd96119963a16cfacb4ce)) by @alimd
159
175
 
160
176
  ## [1.0.9](https://github.com/Alwatr/nanolib/compare/@alwatr/parse-duration@1.0.8...@alwatr/parse-duration@1.0.9) (2024-08-31)
161
177
 
@@ -167,7 +183,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
167
183
 
168
184
  ### Dependencies update
169
185
 
170
- - update all dependencies ([1e0c30e](https://github.com/Alwatr/nanolib/commit/1e0c30e6a3a8e19deb5185814e24ab6c08dca573)) by @AliMD
186
+ - update all dependencies ([1e0c30e](https://github.com/Alwatr/nanolib/commit/1e0c30e6a3a8e19deb5185814e24ab6c08dca573)) by @alimd
171
187
 
172
188
  ## [1.0.7](https://github.com/Alwatr/nanolib/compare/@alwatr/parse-duration@1.0.6...@alwatr/parse-duration@1.0.7) (2024-07-04)
173
189
 
@@ -179,7 +195,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
179
195
 
180
196
  ### Dependencies update
181
197
 
182
- - upgrade ([6dbd300](https://github.com/Alwatr/nanolib/commit/6dbd300642c9bcc9e7d0b281e244bf1b06eb1c38)) by @AliMD
198
+ - upgrade ([6dbd300](https://github.com/Alwatr/nanolib/commit/6dbd300642c9bcc9e7d0b281e244bf1b06eb1c38)) by @alimd
183
199
 
184
200
  ## [1.0.5](https://github.com/Alwatr/nanolib/compare/@alwatr/parse-duration@1.0.4...@alwatr/parse-duration@1.0.5) (2024-04-25)
185
201
 
@@ -193,7 +209,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
193
209
 
194
210
  ### Miscellaneous Chores
195
211
 
196
- - **deps:** update ([1a45030](https://github.com/Alwatr/nanolib/commit/1a450305440b710a300787d4ca24b1ed8c6a39d7)) by @AliMD
212
+ - **deps:** update ([1a45030](https://github.com/Alwatr/nanolib/commit/1a450305440b710a300787d4ca24b1ed8c6a39d7)) by @alimd
197
213
 
198
214
  ## [1.0.2](https://github.com/Alwatr/nanolib/compare/@alwatr/parse-duration@1.0.1...@alwatr/parse-duration@1.0.2) (2024-01-24)
199
215
 
@@ -211,6 +227,6 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
211
227
 
212
228
  ### Features
213
229
 
214
- - **parse-duration:** rewrite module 🤦🏻 ([be62163](https://github.com/Alwatr/nanolib/commit/be6216345cb3d4458307f55b8ae44f5ac60dda89)) by @AliMD
230
+ - **parse-duration:** rewrite module 🤦🏻 ([be62163](https://github.com/Alwatr/nanolib/commit/be6216345cb3d4458307f55b8ae44f5ac60dda89)) by @alimd
215
231
  - **parse-duration:** rewrite with document ([43ffecc](https://github.com/Alwatr/nanolib/commit/43ffeccbc4a859ad838938a63fd52c82654cc9bb)) by @njfamirm
216
232
  - **parse-duration:** seperate parseDuration from `@alwatr/math` ([f5e32d0](https://github.com/Alwatr/nanolib/commit/f5e32d080be1b5355463f77a2f23fbd0955b8b67)) by @adltalab
package/README.md CHANGED
@@ -1,48 +1,103 @@
1
1
  # Parse-duration
2
2
 
3
- A simple utility to parse a duration string into milliseconds number.
3
+ A simple, efficient utility to parse time duration strings into milliseconds or other time units.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
+ npm install @alwatr/parse-duration
9
+ # or
8
10
  yarn add @alwatr/parse-duration
11
+ # or
12
+ pnpm add @alwatr/parse-duration
9
13
  ```
10
14
 
15
+ ## Features
16
+
17
+ - Parse duration strings (like '10s', '5m', '2h') into milliseconds
18
+ - Convert between different time units
19
+ - TypeScript support with full type safety
20
+ - Zero dependencies (except for internal Alwatr utilities)
21
+ - Optimized for performance
22
+ - Comprehensive error handling
23
+
11
24
  ## Usage
12
25
 
13
26
  ```js
14
27
  import {parseDuration} from '@alwatr/parse-duration';
15
28
 
16
- parseDuration('10s'); // 10,000
17
- parseDuration('10m'); // 600,000
18
- parseDuration('10h'); // 36,000,000
19
- parseDuration('10d'); // 864,000,000
20
- parseDuration('10w'); // 6,048,000,000
21
- parseDuration('10M'); // 25,920,000,000
22
- parseDuration('10y'); // 315,360,000,000
23
- parseDuration('10d', 'h'); // 240
29
+ // Basic usage - parse to milliseconds
30
+ parseDuration('10s'); // 10,000 (10 seconds in milliseconds)
31
+ parseDuration('5m'); // 300,000 (5 minutes in milliseconds)
32
+ parseDuration('2h'); // 7,200,000 (2 hours in milliseconds)
33
+ parseDuration('1.5d'); // 129,600,000 (1.5 days in milliseconds)
34
+
35
+ // Accept milliseconds as input
36
+ parseDuration(5000); // 5,000 (pass through)
37
+
38
+ // Convert to different units
39
+ parseDuration('10d', 'h'); // 240 (10 days in hours)
40
+ parseDuration('1h', 'm'); // 60 (1 hour in minutes)
41
+ parseDuration('120s', 'm'); // 2 (120 seconds in minutes)
42
+ parseDuration(3600000, 'h'); // 1 (3600000 milliseconds in hours)
24
43
  ```
25
44
 
26
- ### Unit Table
45
+ ## API
46
+
47
+ ### parseDuration(duration, toUnit?)
48
+
49
+ Parse a duration string or millisecond number into the specified unit (or milliseconds by default).
50
+
51
+ #### Parameters
52
+
53
+ - `duration`: `string | number` - A duration string (like '10s', '5m') or a number (treated as milliseconds)
54
+ - `toUnit`: `DurationUnit` (optional) - The unit to convert to. If omitted, returns milliseconds.
55
+
56
+ #### Returns
27
57
 
28
- | Unit | Description |
29
- | ---- | ----------- |
30
- | `s` | Second |
31
- | `m` | Minute |
32
- | `h` | Hour |
33
- | `d` | Day |
34
- | `w` | Week |
35
- | `M` | Month |
36
- | `y` | Year |
58
+ - `number`: The duration in the specified unit (or milliseconds if no unit specified)
59
+
60
+ #### Throws
61
+
62
+ - `Error('not_a_number')`: If the duration string doesn't contain a valid number
63
+ - `Error('invalid_unit')`: If the unit is not recognized
64
+ - `Error('invalid_format')`: If the duration format is invalid
65
+
66
+ ### Supported Units
67
+
68
+ | Unit | Description | Milliseconds Equivalent |
69
+ |------|-------------|-------------------------|
70
+ | `s` | Second | 1,000 |
71
+ | `m` | Minute | 60,000 |
72
+ | `h` | Hour | 3,600,000 |
73
+ | `d` | Day | 86,400,000 |
74
+ | `w` | Week | 604,800,000 |
75
+ | `M` | Month (30d) | 2,592,000,000 |
76
+ | `y` | Year (365d) | 31,536,000,000 |
77
+
78
+ ## TypeScript Support
79
+
80
+ ```typescript
81
+ import {parseDuration, DurationUnit, Duration} from '@alwatr/parse-duration';
82
+
83
+ // Type-safe unit parameter
84
+ function waitFor(time: Duration): Promise<void> {
85
+ const ms = parseDuration(time);
86
+ return new Promise(resolve => setTimeout(resolve, ms));
87
+ }
88
+
89
+ // Usage
90
+ await waitFor('5s');
91
+ ```
37
92
 
38
93
  ## Sponsors
39
94
 
40
95
  The following companies, organizations, and individuals support Nanolib ongoing maintenance and development. Become a Sponsor to get your logo on our README and website.
41
96
 
42
- ### Contributing
97
+ ## Contributing
43
98
 
44
99
  Contributions are welcome! Please read our [contribution guidelines](https://github.com/Alwatr/.github/blob/next/CONTRIBUTING.md) before submitting a pull request.
45
100
 
46
- ### License
101
+ ## License
47
102
 
48
103
  This project is licensed under the [AGPL-3.0 License](LICENSE).
package/dist/main.cjs CHANGED
@@ -1,4 +1,4 @@
1
- /* @alwatr/parse-duration v5.4.0 */
1
+ /* @alwatr/parse-duration v5.5.1 */
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -26,8 +26,8 @@ __export(main_exports, {
26
26
  module.exports = __toCommonJS(main_exports);
27
27
  var import_is_number = require("@alwatr/is-number");
28
28
  var import_package_tracer = require("@alwatr/package-tracer");
29
- __dev_mode__: import_package_tracer.packageTracer.add("@alwatr/parse-duration", "5.4.0");
30
- var unitConversion_ = {
29
+ __dev_mode__: import_package_tracer.packageTracer.add("@alwatr/parse-duration", "5.5.1");
30
+ var unitConversion = /* @__PURE__ */ Object.freeze({
31
31
  s: 1e3,
32
32
  m: 6e4,
33
33
  h: 36e5,
@@ -35,30 +35,32 @@ var unitConversion_ = {
35
35
  w: 6048e5,
36
36
  M: 2592e6,
37
37
  y: 31536e6
38
- };
38
+ });
39
39
  var parseDuration = (duration, toUnit) => {
40
40
  let ms;
41
41
  if (typeof duration === "number") {
42
42
  ms = duration;
43
43
  } else {
44
- const durationNumberStr = duration.slice(0, duration.length - 1);
45
- if (!(0, import_is_number.isNumber)(durationNumberStr)) {
46
- throw new Error(`not_a_number`);
44
+ if (duration.length < 2) {
45
+ throw new Error("invalid_format", { cause: { duration } });
47
46
  }
48
- const durationNumber = +durationNumberStr;
49
47
  const durationUnit = duration.slice(-1);
50
- const unitConversionFactor = unitConversion_[durationUnit];
48
+ const unitConversionFactor = unitConversion[durationUnit];
51
49
  if (unitConversionFactor === void 0) {
52
- throw new Error(`invalid_unit`, { cause: { duration } });
50
+ throw new Error("invalid_unit", { cause: { durationUnit } });
51
+ }
52
+ const durationNumber = (0, import_is_number.toNumber)(duration.slice(0, -1));
53
+ if (durationNumber === null) {
54
+ throw new Error("not_a_number", { cause: { duration } });
53
55
  }
54
56
  ms = durationNumber * unitConversionFactor;
55
57
  }
56
58
  if (toUnit === void 0) {
57
59
  return ms;
58
60
  }
59
- const toFactor = unitConversion_[toUnit];
61
+ const toFactor = unitConversion[toUnit];
60
62
  if (toFactor === void 0) {
61
- throw new Error(`invalid_unit`, { cause: { toUnit } });
63
+ throw new Error("invalid_unit", { cause: { toUnit } });
62
64
  }
63
65
  return ms / toFactor;
64
66
  };
package/dist/main.cjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts"],
4
- "sourcesContent": ["import {isNumber} from '@alwatr/is-number';\nimport {packageTracer} from '@alwatr/package-tracer';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\n/**\n * Unit conversion table\n */\nconst unitConversion_ = {\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n M: 2_592_000_000,\n y: 31_536_000_000,\n} as const;\n\n/**\n * Duration unit: `s` for seconds, `m` for minutes, `h` for hours, `d` for days, `w` for weeks, `M` for months, `y` for years.\n */\nexport type DurationUnit = keyof typeof unitConversion_;\n\n/**\n * Duration string format: `number + unit`, for example `10m` means 10 minutes.\n */\nexport type Duration = `${number}${DurationUnit}` | number;\n\n/**\n * Parse duration string to milliseconds number.\n *\n * @param duration - duration string or number, for example `10m` means 10 minutes.\n * @param toUnit - convert to unit, default is `ms` for milliseconds.\n * @return duration in milliseconds.\n * @example\n * ```ts\n * parseDuration('10m'); // 600000\n * parseDuration('10m', 's'); // 600\n * parseDuration(120_000, 'm'); // 2\n * ```\n */\nexport const parseDuration = (duration: Duration, toUnit?: DurationUnit): number => {\n let ms: number;\n\n if (typeof duration === 'number') {\n ms = duration;\n }\n else {\n const durationNumberStr = duration.slice(0, duration.length - 1);\n if (!isNumber(durationNumberStr)) {\n throw new Error(`not_a_number`);\n }\n const durationNumber = +durationNumberStr;\n const durationUnit = duration.slice(-1) as DurationUnit;\n const unitConversionFactor = unitConversion_[durationUnit];\n if (unitConversionFactor === undefined) {\n throw new Error(`invalid_unit`, {cause: {duration}});\n }\n ms = durationNumber * unitConversionFactor;\n }\n\n if (toUnit === undefined) {\n return ms;\n }\n\n // else\n const toFactor = unitConversion_[toUnit];\n if (toFactor === undefined) {\n throw new Error(`invalid_unit`, {cause: {toUnit}});\n }\n return ms / toFactor;\n};\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAAuB;AACvB,4BAA4B;AAE5B,aAAc,qCAAc,IAAI,0BAAkB,OAAmB;AAKrE,IAAM,kBAAkB;AAAA,EACtB,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAyBO,IAAM,gBAAgB,CAAC,UAAoB,WAAkC;AAClF,MAAI;AAEJ,MAAI,OAAO,aAAa,UAAU;AAChC,SAAK;AAAA,EACP,OACK;AACH,UAAM,oBAAoB,SAAS,MAAM,GAAG,SAAS,SAAS,CAAC;AAC/D,QAAI,KAAC,2BAAS,iBAAiB,GAAG;AAChC,YAAM,IAAI,MAAM,cAAc;AAAA,IAChC;AACA,UAAM,iBAAiB,CAAC;AACxB,UAAM,eAAe,SAAS,MAAM,EAAE;AACtC,UAAM,uBAAuB,gBAAgB,YAAY;AACzD,QAAI,yBAAyB,QAAW;AACtC,YAAM,IAAI,MAAM,gBAAgB,EAAC,OAAO,EAAC,SAAQ,EAAC,CAAC;AAAA,IACrD;AACA,SAAK,iBAAiB;AAAA,EACxB;AAEA,MAAI,WAAW,QAAW;AACxB,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,gBAAgB,MAAM;AACvC,MAAI,aAAa,QAAW;AAC1B,UAAM,IAAI,MAAM,gBAAgB,EAAC,OAAO,EAAC,OAAM,EAAC,CAAC;AAAA,EACnD;AACA,SAAO,KAAK;AACd;",
4
+ "sourcesContent": ["import {toNumber} from '@alwatr/is-number';\nimport {packageTracer} from '@alwatr/package-tracer';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\n/**\n * Unit conversion table (milliseconds)\n */\nconst unitConversion = /* #__PURE__ */ Object.freeze({\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n M: 2_592_000_000,\n y: 31_536_000_000,\n} as const);\n\n/**\n * Duration unit: `s` for seconds, `m` for minutes, `h` for hours, `d` for days, `w` for weeks, `M` for months, `y` for years.\n */\nexport type DurationUnit = keyof typeof unitConversion;\n\n/**\n * Duration string format: `number + unit`, for example `10m` means 10 minutes.\n */\nexport type Duration = `${number}${DurationUnit}` | number;\n\n/**\n * Error types that can be thrown by parseDuration\n */\nexport type DurationError = 'not_a_number' | 'invalid_unit' | 'invalid_format';\n\n/**\n * Parse duration string to milliseconds number.\n *\n * @param duration - Duration string or number, for example `10m` means 10 minutes.\n * @param toUnit - Convert to unit, default is `ms` for milliseconds.\n * @throws {Error} With message 'not_a_number' if duration string doesn't contain a valid number.\n * @throws {Error} With message 'invalid_unit' if the unit is not recognized.\n * @throws {Error} With message 'invalid_format' if the duration format is invalid.\n * @returns Duration in specified unit (or milliseconds by default).\n *\n * @example\n * ```ts\n * parseDuration('10m'); // 600000\n * parseDuration('10m', 's'); // 600\n * parseDuration(120_000, 'm'); // 2\n * ```\n */\nexport const parseDuration = (duration: Duration, toUnit?: DurationUnit): number => {\n let ms: number;\n\n // Convert input to milliseconds\n if (typeof duration === 'number') {\n ms = duration;\n }\n else {\n if (duration.length < 2) {\n throw new Error('invalid_format', {cause: {duration}});\n }\n\n const durationUnit = duration.slice(-1) as DurationUnit;\n const unitConversionFactor = unitConversion[durationUnit];\n\n if (unitConversionFactor === undefined) {\n throw new Error('invalid_unit', {cause: {durationUnit}});\n }\n\n const durationNumber = toNumber(duration.slice(0, -1));\n if (durationNumber === null) {\n throw new Error('not_a_number', {cause: {duration}});\n }\n\n ms = durationNumber * unitConversionFactor;\n }\n\n // Return as is if no conversion needed\n if (toUnit === undefined) {\n return ms;\n }\n\n // Convert to target unit\n const toFactor = unitConversion[toUnit];\n if (toFactor === undefined) {\n throw new Error('invalid_unit', {cause: {toUnit}});\n }\n\n return ms / toFactor;\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAAuB;AACvB,4BAA4B;AAE5B,aAAc,qCAAc,IAAI,0BAAkB,OAAmB;AAKrE,IAAM,iBAAiC,uBAAO,OAAO;AAAA,EACnD,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL,CAAU;AAkCH,IAAM,gBAAgB,CAAC,UAAoB,WAAkC;AAClF,MAAI;AAGJ,MAAI,OAAO,aAAa,UAAU;AAChC,SAAK;AAAA,EACP,OACK;AACH,QAAI,SAAS,SAAS,GAAG;AACvB,YAAM,IAAI,MAAM,kBAAkB,EAAC,OAAO,EAAC,SAAQ,EAAC,CAAC;AAAA,IACvD;AAEA,UAAM,eAAe,SAAS,MAAM,EAAE;AACtC,UAAM,uBAAuB,eAAe,YAAY;AAExD,QAAI,yBAAyB,QAAW;AACtC,YAAM,IAAI,MAAM,gBAAgB,EAAC,OAAO,EAAC,aAAY,EAAC,CAAC;AAAA,IACzD;AAEA,UAAM,qBAAiB,2BAAS,SAAS,MAAM,GAAG,EAAE,CAAC;AACrD,QAAI,mBAAmB,MAAM;AAC3B,YAAM,IAAI,MAAM,gBAAgB,EAAC,OAAO,EAAC,SAAQ,EAAC,CAAC;AAAA,IACrD;AAEA,SAAK,iBAAiB;AAAA,EACxB;AAGA,MAAI,WAAW,QAAW;AACxB,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,eAAe,MAAM;AACtC,MAAI,aAAa,QAAW;AAC1B,UAAM,IAAI,MAAM,gBAAgB,EAAC,OAAO,EAAC,OAAM,EAAC,CAAC;AAAA,EACnD;AAEA,SAAO,KAAK;AACd;",
6
6
  "names": []
7
7
  }
package/dist/main.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
- * Unit conversion table
2
+ * Unit conversion table (milliseconds)
3
3
  */
4
- declare const unitConversion_: {
4
+ declare const unitConversion: Readonly<{
5
5
  readonly s: 1000;
6
6
  readonly m: 60000;
7
7
  readonly h: 3600000;
@@ -9,21 +9,29 @@ declare const unitConversion_: {
9
9
  readonly w: 604800000;
10
10
  readonly M: 2592000000;
11
11
  readonly y: 31536000000;
12
- };
12
+ }>;
13
13
  /**
14
14
  * Duration unit: `s` for seconds, `m` for minutes, `h` for hours, `d` for days, `w` for weeks, `M` for months, `y` for years.
15
15
  */
16
- export type DurationUnit = keyof typeof unitConversion_;
16
+ export type DurationUnit = keyof typeof unitConversion;
17
17
  /**
18
18
  * Duration string format: `number + unit`, for example `10m` means 10 minutes.
19
19
  */
20
20
  export type Duration = `${number}${DurationUnit}` | number;
21
+ /**
22
+ * Error types that can be thrown by parseDuration
23
+ */
24
+ export type DurationError = 'not_a_number' | 'invalid_unit' | 'invalid_format';
21
25
  /**
22
26
  * Parse duration string to milliseconds number.
23
27
  *
24
- * @param duration - duration string or number, for example `10m` means 10 minutes.
25
- * @param toUnit - convert to unit, default is `ms` for milliseconds.
26
- * @return duration in milliseconds.
28
+ * @param duration - Duration string or number, for example `10m` means 10 minutes.
29
+ * @param toUnit - Convert to unit, default is `ms` for milliseconds.
30
+ * @throws {Error} With message 'not_a_number' if duration string doesn't contain a valid number.
31
+ * @throws {Error} With message 'invalid_unit' if the unit is not recognized.
32
+ * @throws {Error} With message 'invalid_format' if the duration format is invalid.
33
+ * @returns Duration in specified unit (or milliseconds by default).
34
+ *
27
35
  * @example
28
36
  * ```ts
29
37
  * parseDuration('10m'); // 600000
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,QAAA,MAAM,eAAe;;;;;;;;CAQX,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,eAAe,CAAC;AAExD;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,GAAG,MAAM,GAAG,YAAY,EAAE,GAAG,MAAM,CAAC;AAE3D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,aAAc,QAAQ,WAAW,YAAY,KAAG,MA8BzE,CAAC"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,QAAA,MAAM,cAAc;;;;;;;;EAQT,CAAC;AAEZ;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,OAAO,cAAc,CAAC;AAEvD;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,GAAG,MAAM,GAAG,YAAY,EAAE,GAAG,MAAM,CAAC;AAE3D;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG,cAAc,GAAG,gBAAgB,CAAC;AAE/E;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,GAAI,UAAU,QAAQ,EAAE,SAAS,YAAY,KAAG,MAuCzE,CAAC"}
package/dist/main.mjs CHANGED
@@ -1,10 +1,10 @@
1
- /* @alwatr/parse-duration v5.4.0 */
1
+ /* @alwatr/parse-duration v5.5.1 */
2
2
 
3
3
  // src/main.ts
4
- import { isNumber } from "@alwatr/is-number";
4
+ import { toNumber } from "@alwatr/is-number";
5
5
  import { packageTracer } from "@alwatr/package-tracer";
6
- __dev_mode__: packageTracer.add("@alwatr/parse-duration", "5.4.0");
7
- var unitConversion_ = {
6
+ __dev_mode__: packageTracer.add("@alwatr/parse-duration", "5.5.1");
7
+ var unitConversion = /* @__PURE__ */ Object.freeze({
8
8
  s: 1e3,
9
9
  m: 6e4,
10
10
  h: 36e5,
@@ -12,30 +12,32 @@ var unitConversion_ = {
12
12
  w: 6048e5,
13
13
  M: 2592e6,
14
14
  y: 31536e6
15
- };
15
+ });
16
16
  var parseDuration = (duration, toUnit) => {
17
17
  let ms;
18
18
  if (typeof duration === "number") {
19
19
  ms = duration;
20
20
  } else {
21
- const durationNumberStr = duration.slice(0, duration.length - 1);
22
- if (!isNumber(durationNumberStr)) {
23
- throw new Error(`not_a_number`);
21
+ if (duration.length < 2) {
22
+ throw new Error("invalid_format", { cause: { duration } });
24
23
  }
25
- const durationNumber = +durationNumberStr;
26
24
  const durationUnit = duration.slice(-1);
27
- const unitConversionFactor = unitConversion_[durationUnit];
25
+ const unitConversionFactor = unitConversion[durationUnit];
28
26
  if (unitConversionFactor === void 0) {
29
- throw new Error(`invalid_unit`, { cause: { duration } });
27
+ throw new Error("invalid_unit", { cause: { durationUnit } });
28
+ }
29
+ const durationNumber = toNumber(duration.slice(0, -1));
30
+ if (durationNumber === null) {
31
+ throw new Error("not_a_number", { cause: { duration } });
30
32
  }
31
33
  ms = durationNumber * unitConversionFactor;
32
34
  }
33
35
  if (toUnit === void 0) {
34
36
  return ms;
35
37
  }
36
- const toFactor = unitConversion_[toUnit];
38
+ const toFactor = unitConversion[toUnit];
37
39
  if (toFactor === void 0) {
38
- throw new Error(`invalid_unit`, { cause: { toUnit } });
40
+ throw new Error("invalid_unit", { cause: { toUnit } });
39
41
  }
40
42
  return ms / toFactor;
41
43
  };
package/dist/main.mjs.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/main.ts"],
4
- "sourcesContent": ["import {isNumber} from '@alwatr/is-number';\nimport {packageTracer} from '@alwatr/package-tracer';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\n/**\n * Unit conversion table\n */\nconst unitConversion_ = {\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n M: 2_592_000_000,\n y: 31_536_000_000,\n} as const;\n\n/**\n * Duration unit: `s` for seconds, `m` for minutes, `h` for hours, `d` for days, `w` for weeks, `M` for months, `y` for years.\n */\nexport type DurationUnit = keyof typeof unitConversion_;\n\n/**\n * Duration string format: `number + unit`, for example `10m` means 10 minutes.\n */\nexport type Duration = `${number}${DurationUnit}` | number;\n\n/**\n * Parse duration string to milliseconds number.\n *\n * @param duration - duration string or number, for example `10m` means 10 minutes.\n * @param toUnit - convert to unit, default is `ms` for milliseconds.\n * @return duration in milliseconds.\n * @example\n * ```ts\n * parseDuration('10m'); // 600000\n * parseDuration('10m', 's'); // 600\n * parseDuration(120_000, 'm'); // 2\n * ```\n */\nexport const parseDuration = (duration: Duration, toUnit?: DurationUnit): number => {\n let ms: number;\n\n if (typeof duration === 'number') {\n ms = duration;\n }\n else {\n const durationNumberStr = duration.slice(0, duration.length - 1);\n if (!isNumber(durationNumberStr)) {\n throw new Error(`not_a_number`);\n }\n const durationNumber = +durationNumberStr;\n const durationUnit = duration.slice(-1) as DurationUnit;\n const unitConversionFactor = unitConversion_[durationUnit];\n if (unitConversionFactor === undefined) {\n throw new Error(`invalid_unit`, {cause: {duration}});\n }\n ms = durationNumber * unitConversionFactor;\n }\n\n if (toUnit === undefined) {\n return ms;\n }\n\n // else\n const toFactor = unitConversion_[toUnit];\n if (toFactor === undefined) {\n throw new Error(`invalid_unit`, {cause: {toUnit}});\n }\n return ms / toFactor;\n};\n"],
5
- "mappings": ";;;AAAA,SAAQ,gBAAe;AACvB,SAAQ,qBAAoB;AAE5B,aAAc,eAAc,IAAI,0BAAkB,OAAmB;AAKrE,IAAM,kBAAkB;AAAA,EACtB,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAyBO,IAAM,gBAAgB,CAAC,UAAoB,WAAkC;AAClF,MAAI;AAEJ,MAAI,OAAO,aAAa,UAAU;AAChC,SAAK;AAAA,EACP,OACK;AACH,UAAM,oBAAoB,SAAS,MAAM,GAAG,SAAS,SAAS,CAAC;AAC/D,QAAI,CAAC,SAAS,iBAAiB,GAAG;AAChC,YAAM,IAAI,MAAM,cAAc;AAAA,IAChC;AACA,UAAM,iBAAiB,CAAC;AACxB,UAAM,eAAe,SAAS,MAAM,EAAE;AACtC,UAAM,uBAAuB,gBAAgB,YAAY;AACzD,QAAI,yBAAyB,QAAW;AACtC,YAAM,IAAI,MAAM,gBAAgB,EAAC,OAAO,EAAC,SAAQ,EAAC,CAAC;AAAA,IACrD;AACA,SAAK,iBAAiB;AAAA,EACxB;AAEA,MAAI,WAAW,QAAW;AACxB,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,gBAAgB,MAAM;AACvC,MAAI,aAAa,QAAW;AAC1B,UAAM,IAAI,MAAM,gBAAgB,EAAC,OAAO,EAAC,OAAM,EAAC,CAAC;AAAA,EACnD;AACA,SAAO,KAAK;AACd;",
4
+ "sourcesContent": ["import {toNumber} from '@alwatr/is-number';\nimport {packageTracer} from '@alwatr/package-tracer';\n\n__dev_mode__: packageTracer.add(__package_name__, __package_version__);\n\n/**\n * Unit conversion table (milliseconds)\n */\nconst unitConversion = /* #__PURE__ */ Object.freeze({\n s: 1_000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n w: 604_800_000,\n M: 2_592_000_000,\n y: 31_536_000_000,\n} as const);\n\n/**\n * Duration unit: `s` for seconds, `m` for minutes, `h` for hours, `d` for days, `w` for weeks, `M` for months, `y` for years.\n */\nexport type DurationUnit = keyof typeof unitConversion;\n\n/**\n * Duration string format: `number + unit`, for example `10m` means 10 minutes.\n */\nexport type Duration = `${number}${DurationUnit}` | number;\n\n/**\n * Error types that can be thrown by parseDuration\n */\nexport type DurationError = 'not_a_number' | 'invalid_unit' | 'invalid_format';\n\n/**\n * Parse duration string to milliseconds number.\n *\n * @param duration - Duration string or number, for example `10m` means 10 minutes.\n * @param toUnit - Convert to unit, default is `ms` for milliseconds.\n * @throws {Error} With message 'not_a_number' if duration string doesn't contain a valid number.\n * @throws {Error} With message 'invalid_unit' if the unit is not recognized.\n * @throws {Error} With message 'invalid_format' if the duration format is invalid.\n * @returns Duration in specified unit (or milliseconds by default).\n *\n * @example\n * ```ts\n * parseDuration('10m'); // 600000\n * parseDuration('10m', 's'); // 600\n * parseDuration(120_000, 'm'); // 2\n * ```\n */\nexport const parseDuration = (duration: Duration, toUnit?: DurationUnit): number => {\n let ms: number;\n\n // Convert input to milliseconds\n if (typeof duration === 'number') {\n ms = duration;\n }\n else {\n if (duration.length < 2) {\n throw new Error('invalid_format', {cause: {duration}});\n }\n\n const durationUnit = duration.slice(-1) as DurationUnit;\n const unitConversionFactor = unitConversion[durationUnit];\n\n if (unitConversionFactor === undefined) {\n throw new Error('invalid_unit', {cause: {durationUnit}});\n }\n\n const durationNumber = toNumber(duration.slice(0, -1));\n if (durationNumber === null) {\n throw new Error('not_a_number', {cause: {duration}});\n }\n\n ms = durationNumber * unitConversionFactor;\n }\n\n // Return as is if no conversion needed\n if (toUnit === undefined) {\n return ms;\n }\n\n // Convert to target unit\n const toFactor = unitConversion[toUnit];\n if (toFactor === undefined) {\n throw new Error('invalid_unit', {cause: {toUnit}});\n }\n\n return ms / toFactor;\n};\n"],
5
+ "mappings": ";;;AAAA,SAAQ,gBAAe;AACvB,SAAQ,qBAAoB;AAE5B,aAAc,eAAc,IAAI,0BAAkB,OAAmB;AAKrE,IAAM,iBAAiC,uBAAO,OAAO;AAAA,EACnD,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL,CAAU;AAkCH,IAAM,gBAAgB,CAAC,UAAoB,WAAkC;AAClF,MAAI;AAGJ,MAAI,OAAO,aAAa,UAAU;AAChC,SAAK;AAAA,EACP,OACK;AACH,QAAI,SAAS,SAAS,GAAG;AACvB,YAAM,IAAI,MAAM,kBAAkB,EAAC,OAAO,EAAC,SAAQ,EAAC,CAAC;AAAA,IACvD;AAEA,UAAM,eAAe,SAAS,MAAM,EAAE;AACtC,UAAM,uBAAuB,eAAe,YAAY;AAExD,QAAI,yBAAyB,QAAW;AACtC,YAAM,IAAI,MAAM,gBAAgB,EAAC,OAAO,EAAC,aAAY,EAAC,CAAC;AAAA,IACzD;AAEA,UAAM,iBAAiB,SAAS,SAAS,MAAM,GAAG,EAAE,CAAC;AACrD,QAAI,mBAAmB,MAAM;AAC3B,YAAM,IAAI,MAAM,gBAAgB,EAAC,OAAO,EAAC,SAAQ,EAAC,CAAC;AAAA,IACrD;AAEA,SAAK,iBAAiB;AAAA,EACxB;AAGA,MAAI,WAAW,QAAW;AACxB,WAAO;AAAA,EACT;AAGA,QAAM,WAAW,eAAe,MAAM;AACtC,MAAI,aAAa,QAAW;AAC1B,UAAM,IAAI,MAAM,gBAAgB,EAAC,OAAO,EAAC,OAAM,EAAC,CAAC;AAAA,EACnD;AAEA,SAAO,KAAK;AACd;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alwatr/parse-duration",
3
- "version": "5.4.0",
3
+ "version": "5.5.1",
4
4
  "description": "A simple utility to parse a duration string into milliseconds number.",
5
5
  "author": "S. Ali Mihandoost <ali.mihandoost@gmail.com>",
6
6
  "keywords": [
@@ -70,15 +70,15 @@
70
70
  "clean": "rm -rfv dist *.tsbuildinfo"
71
71
  },
72
72
  "dependencies": {
73
- "@alwatr/is-number": "^5.4.0",
74
- "@alwatr/package-tracer": "^5.4.0"
73
+ "@alwatr/is-number": "^5.6.0",
74
+ "@alwatr/package-tracer": "^5.5.1"
75
75
  },
76
76
  "devDependencies": {
77
- "@alwatr/nano-build": "^5.4.0",
77
+ "@alwatr/nano-build": "^5.5.1",
78
78
  "@alwatr/prettier-config": "^5.0.0",
79
79
  "@alwatr/tsconfig-base": "^5.0.0",
80
80
  "jest": "^29.7.0",
81
- "typescript": "^5.7.3"
81
+ "typescript": "^5.8.2"
82
82
  },
83
- "gitHead": "074be0d0fe780bf929e163045f8f598cd2697636"
83
+ "gitHead": "21cb1fe0f26a580944d9e72a313fc99308cd8be7"
84
84
  }
package/src/main.test.js CHANGED
@@ -1,30 +1,46 @@
1
1
  import {parseDuration} from '@alwatr/parse-duration';
2
2
 
3
3
  describe('@alwatr/parse-duration', () => {
4
- it('should parse duration in seconds', () => {
5
- expect(parseDuration('5s')).toBe(5 * 1000);
6
- });
4
+ // Basic functionality tests
5
+ it('should parse duration strings to milliseconds', () => {
6
+ // Basic time units
7
+ expect(parseDuration('5s')).toBe(5 * 1_000); // seconds
8
+ expect(parseDuration('3m')).toBe(3 * 60_000); // minutes
9
+ expect(parseDuration('2h')).toBe(2 * 3_600_000); // hours
10
+ expect(parseDuration('1d')).toBe(1 * 86_400_000); // days
11
+ expect(parseDuration('2w')).toBe(2 * 604_800_000); // weeks
7
12
 
8
- it('should parse duration in minutes', () => {
9
- expect(parseDuration('3m')).toBe(3 * 60 * 1000);
13
+ // Longer time units
14
+ expect(parseDuration('3M')).toBe(3 * 2_592_000_000); // months
15
+ expect(parseDuration('1y')).toBe(1 * 31_536_000_000); // years
10
16
  });
11
17
 
12
- it('should parse duration in hours', () => {
13
- expect(parseDuration('2h')).toBe(2 * 60 * 60 * 1000);
18
+ it('should accept numeric input as milliseconds', () => {
19
+ expect(parseDuration(5000)).toBe(5000);
20
+ expect(parseDuration(0)).toBe(0);
14
21
  });
15
22
 
16
23
  it('should convert duration to specified unit', () => {
17
24
  expect(parseDuration('2h', 'm')).toBe(2 * 60);
18
- });
19
-
20
- it('should convert duration to different units', () => {
25
+ expect(parseDuration('120s', 'm')).toBe(2);
21
26
  expect(parseDuration('1d', 'h')).toBe(24);
22
27
  expect(parseDuration('1w', 'd')).toBe(7);
23
- expect(parseDuration('1M', 'm')).toBe(30 * 24 * 60);
28
+ expect(parseDuration('1M', 'd')).toBe(30);
24
29
  expect(parseDuration('1y', 'd')).toBe(365);
30
+ expect(parseDuration(60000, 's')).toBe(60);
25
31
  });
26
32
 
27
- it('should throw error for invalid duration', () => {
33
+ it('should handle decimal values correctly', () => {
34
+ expect(parseDuration('0.5h')).toBe(0.5 * 60 * 60 * 1000);
35
+ expect(parseDuration('1.5d', 'h')).toBe(36);
36
+ });
37
+
38
+ // Error handling tests
39
+ it('should throw error for invalid duration format', () => {
40
+ expect(() => parseDuration('m')).toThrow('invalid_format');
41
+ });
42
+
43
+ it('should throw error for invalid unit', () => {
28
44
  // @ts-expect-error testing invalid input
29
45
  expect(() => parseDuration('1x')).toThrow('invalid_unit');
30
46
  });
@@ -38,4 +54,14 @@ describe('@alwatr/parse-duration', () => {
38
54
  // @ts-expect-error testing invalid input
39
55
  expect(() => parseDuration('xh')).toThrow('not_a_number');
40
56
  });
57
+
58
+ // Edge cases
59
+ it('should handle zero values', () => {
60
+ expect(parseDuration('0s')).toBe(0);
61
+ expect(parseDuration('0m', 's')).toBe(0);
62
+ });
63
+
64
+ it('should handle large values', () => {
65
+ expect(parseDuration('999999h')).toBe(999999 * 3600000);
66
+ });
41
67
  });