@alwatr/parse-duration 5.5.0 → 5.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,16 @@
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.2](https://github.com/Alwatr/nanolib/compare/@alwatr/parse-duration@5.5.1...@alwatr/parse-duration@5.5.2) (2025-04-01)
7
+
8
+ **Note:** Version bump only for package @alwatr/parse-duration
9
+
10
+ ## [5.5.1](https://github.com/Alwatr/nanolib/compare/@alwatr/parse-duration@5.5.0...@alwatr/parse-duration@5.5.1) (2025-03-18)
11
+
12
+ ### Code Refactoring
13
+
14
+ * **parse-duration:** replace isNumber with toNumber for improved number conversion and enhance error handling ([4d63892](https://github.com/Alwatr/nanolib/commit/4d63892f914cebe73bd1dc1e688c2f4ea5b53de1)) by @alimd
15
+
6
16
  ## [5.5.0](https://github.com/Alwatr/nanolib/compare/@alwatr/parse-duration@5.4.0...@alwatr/parse-duration@5.5.0) (2025-03-06)
7
17
 
8
18
  ### Miscellaneous Chores
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.5.0 */
1
+ /* @alwatr/parse-duration v5.5.2 */
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.5.0");
30
- var unitConversion_ = {
29
+ __dev_mode__: import_package_tracer.packageTracer.add("@alwatr/parse-duration", "5.5.2");
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,GAAI,UAAU,QAAQ,EAAE,SAAS,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.5.0 */
1
+ /* @alwatr/parse-duration v5.5.2 */
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.5.0");
7
- var unitConversion_ = {
6
+ __dev_mode__: packageTracer.add("@alwatr/parse-duration", "5.5.2");
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.5.0",
3
+ "version": "5.5.2",
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.5.0",
74
- "@alwatr/package-tracer": "^5.5.0"
73
+ "@alwatr/is-number": "^5.6.1",
74
+ "@alwatr/package-tracer": "^5.5.2"
75
75
  },
76
76
  "devDependencies": {
77
- "@alwatr/nano-build": "^5.5.0",
77
+ "@alwatr/nano-build": "^5.5.2",
78
78
  "@alwatr/prettier-config": "^5.0.0",
79
79
  "@alwatr/tsconfig-base": "^5.0.0",
80
80
  "jest": "^29.7.0",
81
81
  "typescript": "^5.8.2"
82
82
  },
83
- "gitHead": "fdf8e6de77cca359465110a75ff18faff0649a95"
83
+ "gitHead": "2756475ba2fa108bae7af6d8d9747e0c7815dfa2"
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
  });