@verifyhash/iso-duration 0.1.0 → 0.1.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 (4) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +17 -13
  3. package/index.d.ts +82 -0
  4. package/package.json +4 -2
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 <OWNER-NAME PLACEHOLDER>
3
+ Copyright (c) 2026 verifyhash
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,12 +1,5 @@
1
1
  # iso-duration
2
2
 
3
- <!-- publish-prep -->
4
- > **TODO (owner): pick the final npm name/scope before publishing.**
5
- > The npm package name is **not** finalized by this project. Convention used here:
6
- > `package.json` keeps the working slug `iso-duration` as a placeholder — replace it
7
- > (and the `npm install` line below) with the real published name/scope before
8
- > running `npm publish`.
9
-
10
3
  A tiny, **zero-dependency, zero-network** Node.js library for **ISO 8601
11
4
  durations** — the `P3Y6M4DT12H30M5S` strings that show up in JSON Schema
12
5
  (`format: duration`), OpenAPI, iCalendar (`RRULE`/`DURATION`), GitHub Actions
@@ -41,7 +34,7 @@ numeric keys are `0`, and `negative` defaults to `false`:
41
34
  ## Usage
42
35
 
43
36
  ```js
44
- const iso = require('iso-duration'); // or require('./index.js')
37
+ const iso = require('@verifyhash/iso-duration'); // or require('./index.js')
45
38
 
46
39
  iso.parse('P3Y6M4DT12H30M5S');
47
40
  // { years: 3, months: 6, weeks: 0, days: 4,
@@ -66,6 +59,20 @@ start.toISOString(); // unchanged — input is never mu
66
59
  iso.subtractFromDate(start, { days: 10 }); // 2020-01-21T00:00:00.000Z
67
60
  ```
68
61
 
62
+ ## API
63
+
64
+ Five exports, all pure functions over the duration object above:
65
+
66
+ - `parse(str)` — ISO 8601 duration string → duration object. Throws
67
+ `TypeError` on malformed input (see Errors below).
68
+ - `format(obj)` — duration object → canonical ISO string (`'PT0S'` for empty).
69
+ - `humanize(obj)` — duration object → plain-English phrase like
70
+ `'3 hours 30 minutes'`.
71
+ - `addToDate(date, obj)` — returns a **new** `Date` shifted forward by the
72
+ duration; the input date is never mutated. Calendar-aware for months/years
73
+ (with the overflow clamp described below).
74
+ - `subtractFromDate(date, obj)` — same, shifted backward.
75
+
69
76
  ## Two design choices to know about
70
77
 
71
78
  Libraries genuinely disagree on these two points, so they are spelled out here
@@ -137,15 +144,12 @@ MIT.
137
144
 
138
145
  ## Install
139
146
 
140
- > Placeholder name: the `iso-duration` below is the working slug, not a finalized
141
- > npm name — see the owner TODO near the top of this README.
142
-
143
147
  ```sh
144
- npm install iso-duration
148
+ npm install @verifyhash/iso-duration
145
149
  ```
146
150
 
147
151
  ```js
148
- const iso = require('iso-duration');
152
+ const iso = require('@verifyhash/iso-duration');
149
153
 
150
154
  iso.parse('P3Y6M4DT12H30M5S'); // { years:3, months:6, days:4, hours:12, minutes:30, seconds:5, ... }
151
155
  iso.format({ hours: 3, minutes: 30 }); // 'PT3H30M'
package/index.d.ts ADDED
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Type declarations for @verifyhash/iso-duration — zero-dependency ISO 8601
3
+ * duration parse, format, calendar-correct date arithmetic, and English
4
+ * humanize.
5
+ *
6
+ * Every function is pure: no I/O, no network, no mutation of its arguments.
7
+ */
8
+
9
+ /**
10
+ * A duration object as ACCEPTED by format(), addToDate(), subtractFromDate()
11
+ * and humanize(): every key is optional. Missing/NaN/non-number unit values
12
+ * are treated as 0 and `negative` defaults to false. Unit values may be
13
+ * fractional.
14
+ */
15
+ export interface DurationInput {
16
+ years?: number;
17
+ months?: number;
18
+ weeks?: number;
19
+ days?: number;
20
+ hours?: number;
21
+ minutes?: number;
22
+ seconds?: number;
23
+ /** True for a negative duration (a leading '-' in the ISO string). */
24
+ negative?: boolean;
25
+ }
26
+
27
+ /**
28
+ * A duration object as RETURNED by parse(): every unit key is present
29
+ * (0 when the component was absent from the string) and `negative` is a
30
+ * definite boolean.
31
+ */
32
+ export interface Duration {
33
+ years: number;
34
+ months: number;
35
+ weeks: number;
36
+ days: number;
37
+ hours: number;
38
+ minutes: number;
39
+ seconds: number;
40
+ negative: boolean;
41
+ }
42
+
43
+ /**
44
+ * Parse an ISO 8601 duration string (e.g. "P1Y2M3DT4H5M6S", "PT1H30M",
45
+ * "-P2W"; fractions with '.' or ',' are accepted) into a duration object.
46
+ * Throws an Error with a clear message on malformed input (non-string, empty,
47
+ * bare "P", "T" with no time components, or anything off-grammar).
48
+ */
49
+ export function parse(str: string): Duration;
50
+
51
+ /**
52
+ * Format a duration object into a canonical ISO 8601 string. Zero components
53
+ * are omitted; an all-zero duration formats as "PT0S"; a negative duration
54
+ * gets a leading "-"; weeks are emitted as "P2W" only when weeks is the sole
55
+ * non-zero component, otherwise folded into days (1 week = 7 days) so the
56
+ * output round-trips through parse(). Throws on a non-object argument.
57
+ */
58
+ export function format(obj: DurationInput): string;
59
+
60
+ /**
61
+ * Add a duration to a Date, returning a NEW Date (the input is not mutated).
62
+ * Whole years/months step the calendar with day-of-month clamping
63
+ * (Jan 31 + P1M -> Feb 28/29); weeks/days/hours/minutes/seconds are exact
64
+ * elapsed milliseconds; a fractional year/month remainder is approximated
65
+ * with the mean Gregorian month (30.436875 days). Throws on an invalid Date
66
+ * or a non-object duration.
67
+ */
68
+ export function addToDate(date: Date, obj: DurationInput): Date;
69
+
70
+ /**
71
+ * Subtract a duration from a Date, returning a NEW Date. Same calendar rules
72
+ * as addToDate() with the sign flipped.
73
+ */
74
+ export function subtractFromDate(date: Date, obj: DurationInput): Date;
75
+
76
+ /**
77
+ * Render a duration object as an English phrase, e.g. "3 hours 30 minutes".
78
+ * Zero units are omitted; an all-zero duration returns "0 seconds". The sign
79
+ * is not rendered — inspect obj.negative for direction. Throws on a
80
+ * non-object argument.
81
+ */
82
+ export function humanize(obj: DurationInput): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verifyhash/iso-duration",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Zero-dependency ISO 8601 duration parse, format, calendar-correct date arithmetic, and English humanize for Node.js.",
5
5
  "keywords": [
6
6
  "iso8601",
@@ -14,13 +14,15 @@
14
14
  "date-arithmetic"
15
15
  ],
16
16
  "main": "index.js",
17
+ "types": "index.d.ts",
17
18
  "scripts": {
18
19
  "test": "node test/index.test.js"
19
20
  },
20
21
  "license": "MIT",
21
22
  "files": [
22
23
  "index.js",
23
- "README.md"
24
+ "README.md",
25
+ "index.d.ts"
24
26
  ],
25
27
  "publishConfig": {
26
28
  "access": "public"