rrule-ts 0.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.
@@ -0,0 +1,14 @@
1
+ export type Result<T, E> = Ok<T> | Err<E>;
2
+ export interface Ok<T> {
3
+ readonly ok: true;
4
+ readonly value: T;
5
+ }
6
+ export interface Err<E> {
7
+ readonly ok: false;
8
+ readonly error: E;
9
+ }
10
+ /** Wrap a success value in a Result. */
11
+ export declare function ok<T>(value: T): Ok<T>;
12
+ /** Wrap an error value in a Result. */
13
+ export declare function err<E>(error: E): Err<E>;
14
+ //# sourceMappingURL=result.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAA;AAEzC,MAAM,WAAW,EAAE,CAAC,CAAC;IACnB,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAA;IACjB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAClB;AAED,MAAM,WAAW,GAAG,CAAC,CAAC;IACpB,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAA;IAClB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAClB;AAED,wCAAwC;AACxC,wBAAgB,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAErC;AAED,uCAAuC;AACvC,wBAAgB,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAEvC"}
package/dist/result.js ADDED
@@ -0,0 +1,11 @@
1
+ // Discriminated Result type. Never throws on user input: callers get back a
2
+ // typed success or failure value and can decide how to handle it.
3
+ /** Wrap a success value in a Result. */
4
+ export function ok(value) {
5
+ return { ok: true, value };
6
+ }
7
+ /** Wrap an error value in a Result. */
8
+ export function err(error) {
9
+ return { ok: false, error };
10
+ }
11
+ //# sourceMappingURL=result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../src/result.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,kEAAkE;AAclE,wCAAwC;AACxC,MAAM,UAAU,EAAE,CAAI,KAAQ;IAC5B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AAC5B,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,GAAG,CAAI,KAAQ;IAC7B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAA;AAC7B,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { RRuleOptions } from './types.js';
2
+ /**
3
+ * Serialize `RRuleOptions` to a canonical RRULE string.
4
+ *
5
+ * When `dtstart` is present the output includes a `DTSTART` content line
6
+ * (with `TZID=` if `tzid` is set) followed by the `RRULE:` line. This
7
+ * guarantees `parse(stringify(x))` deep-equals `x` for all valid `x`.
8
+ *
9
+ * The RRULE property order is:
10
+ * FREQ, UNTIL, COUNT, INTERVAL, WKST, BYSECOND, BYMINUTE, BYHOUR,
11
+ * BYDAY, BYMONTHDAY, BYYEARDAY, BYWEEKNO, BYMONTH, BYSETPOS.
12
+ */
13
+ export declare function stringify(options: RRuleOptions): string;
14
+ //# sourceMappingURL=stringify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stringify.d.ts","sourceRoot":"","sources":["../src/stringify.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAgB,YAAY,EAAmC,MAAM,YAAY,CAAA;AAoG7F;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CA2DvD"}
@@ -0,0 +1,150 @@
1
+ // RFC 5545 RRULE stringifier.
2
+ //
3
+ // Emits a canonical RRULE string. When `dtstart` is present in the options the
4
+ // output includes a DTSTART content line followed by the RRULE line so that
5
+ // round-trip is guaranteed: parse(stringify(x)) deep-equals x for all valid x.
6
+ // ---------------------------------------------------------------------------
7
+ // Temporal value discriminators (duck-typed, works with native + polyfill)
8
+ // ---------------------------------------------------------------------------
9
+ function isInstant(v) {
10
+ // Temporal.Instant has epochMilliseconds but no year/hour/timeZoneId
11
+ return typeof v === 'object' && v !== null && 'epochMilliseconds' in v && !('year' in v);
12
+ }
13
+ function isZonedDateTime(v) {
14
+ return typeof v === 'object' && v !== null && 'timeZoneId' in v;
15
+ }
16
+ function isPlainDateTime(v) {
17
+ // PlainDateTime has both year and hour but no timeZoneId
18
+ return typeof v === 'object' && v !== null && 'year' in v && 'hour' in v && !('timeZoneId' in v);
19
+ }
20
+ function isPlainDate(v) {
21
+ // PlainDate has year but no hour or timeZoneId
22
+ return (typeof v === 'object' && v !== null && 'year' in v && !('hour' in v) && !('timeZoneId' in v));
23
+ }
24
+ // ---------------------------------------------------------------------------
25
+ // iCalendar date/datetime formatters
26
+ // ---------------------------------------------------------------------------
27
+ function pad2(n) {
28
+ return String(n).padStart(2, '0');
29
+ }
30
+ function pad4(n) {
31
+ return String(n).padStart(4, '0');
32
+ }
33
+ /** Format a PlainDate as YYYYMMDD. */
34
+ function formatPlainDate(d) {
35
+ return `${pad4(d.year)}${pad2(d.month)}${pad2(d.day)}`;
36
+ }
37
+ /** Format a PlainDateTime as YYYYMMDDTHHmmss. */
38
+ function formatPlainDateTime(dt) {
39
+ return (`${pad4(dt.year)}${pad2(dt.month)}${pad2(dt.day)}` +
40
+ `T${pad2(dt.hour)}${pad2(dt.minute)}${pad2(dt.second)}`);
41
+ }
42
+ /** Format an Instant as YYYYMMDDTHHmmssZ. */
43
+ function formatInstant(inst) {
44
+ const zdt = inst.toZonedDateTimeISO('UTC');
45
+ return (`${pad4(zdt.year)}${pad2(zdt.month)}${pad2(zdt.day)}` +
46
+ `T${pad2(zdt.hour)}${pad2(zdt.minute)}${pad2(zdt.second)}Z`);
47
+ }
48
+ /** Serialize a DTSTART value to an iCalendar string (value portion only). */
49
+ function dtstartToIcal(dtstart) {
50
+ if (isInstant(dtstart))
51
+ return formatInstant(dtstart);
52
+ if (isZonedDateTime(dtstart)) {
53
+ return (`${pad4(dtstart.year)}${pad2(dtstart.month)}${pad2(dtstart.day)}` +
54
+ `T${pad2(dtstart.hour)}${pad2(dtstart.minute)}${pad2(dtstart.second)}`);
55
+ }
56
+ if (isPlainDateTime(dtstart))
57
+ return formatPlainDateTime(dtstart);
58
+ if (isPlainDate(dtstart))
59
+ return formatPlainDate(dtstart);
60
+ throw new Error('unrecognized DTSTART Temporal value');
61
+ }
62
+ /** Serialize an UNTIL value to an iCalendar string. */
63
+ function untilToIcal(until) {
64
+ if (isInstant(until))
65
+ return formatInstant(until);
66
+ if (isPlainDateTime(until))
67
+ return formatPlainDateTime(until);
68
+ if (isPlainDate(until))
69
+ return formatPlainDate(until);
70
+ throw new Error('unrecognized UNTIL Temporal value');
71
+ }
72
+ // ---------------------------------------------------------------------------
73
+ // BYDAY and list formatters
74
+ // ---------------------------------------------------------------------------
75
+ function weekdayNumToString(w) {
76
+ if (w.ordinal === undefined)
77
+ return w.weekday;
78
+ return `${w.ordinal}${w.weekday}`;
79
+ }
80
+ function weekdayToString(w) {
81
+ return w;
82
+ }
83
+ // ---------------------------------------------------------------------------
84
+ // Main stringifier
85
+ // ---------------------------------------------------------------------------
86
+ /**
87
+ * Serialize `RRuleOptions` to a canonical RRULE string.
88
+ *
89
+ * When `dtstart` is present the output includes a `DTSTART` content line
90
+ * (with `TZID=` if `tzid` is set) followed by the `RRULE:` line. This
91
+ * guarantees `parse(stringify(x))` deep-equals `x` for all valid `x`.
92
+ *
93
+ * The RRULE property order is:
94
+ * FREQ, UNTIL, COUNT, INTERVAL, WKST, BYSECOND, BYMINUTE, BYHOUR,
95
+ * BYDAY, BYMONTHDAY, BYYEARDAY, BYWEEKNO, BYMONTH, BYSETPOS.
96
+ */
97
+ export function stringify(options) {
98
+ const parts = [];
99
+ parts.push(`FREQ=${options.freq}`);
100
+ if (options.until !== undefined) {
101
+ parts.push(`UNTIL=${untilToIcal(options.until)}`);
102
+ }
103
+ if (options.count !== undefined) {
104
+ parts.push(`COUNT=${options.count}`);
105
+ }
106
+ if (options.interval !== undefined) {
107
+ parts.push(`INTERVAL=${options.interval}`);
108
+ }
109
+ if (options.wkst !== undefined) {
110
+ parts.push(`WKST=${weekdayToString(options.wkst)}`);
111
+ }
112
+ if (options.bySecond !== undefined) {
113
+ parts.push(`BYSECOND=${options.bySecond.join(',')}`);
114
+ }
115
+ if (options.byMinute !== undefined) {
116
+ parts.push(`BYMINUTE=${options.byMinute.join(',')}`);
117
+ }
118
+ if (options.byHour !== undefined) {
119
+ parts.push(`BYHOUR=${options.byHour.join(',')}`);
120
+ }
121
+ if (options.byDay !== undefined) {
122
+ parts.push(`BYDAY=${options.byDay.map(weekdayNumToString).join(',')}`);
123
+ }
124
+ if (options.byMonthDay !== undefined) {
125
+ parts.push(`BYMONTHDAY=${options.byMonthDay.join(',')}`);
126
+ }
127
+ if (options.byYearDay !== undefined) {
128
+ parts.push(`BYYEARDAY=${options.byYearDay.join(',')}`);
129
+ }
130
+ if (options.byWeekNo !== undefined) {
131
+ parts.push(`BYWEEKNO=${options.byWeekNo.join(',')}`);
132
+ }
133
+ if (options.byMonth !== undefined) {
134
+ parts.push(`BYMONTH=${options.byMonth.join(',')}`);
135
+ }
136
+ if (options.bySetPos !== undefined) {
137
+ parts.push(`BYSETPOS=${options.bySetPos.join(',')}`);
138
+ }
139
+ const rruleLine = `RRULE:${parts.join(';')}`;
140
+ if (options.dtstart === undefined) {
141
+ return rruleLine;
142
+ }
143
+ // Prefix with DTSTART content line for round-trip fidelity
144
+ const dtstartValue = dtstartToIcal(options.dtstart);
145
+ const dtstartLine = options.tzid !== undefined
146
+ ? `DTSTART;TZID=${options.tzid}:${dtstartValue}`
147
+ : `DTSTART:${dtstartValue}`;
148
+ return `${dtstartLine}\n${rruleLine}`;
149
+ }
150
+ //# sourceMappingURL=stringify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stringify.js","sourceRoot":"","sources":["../src/stringify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Inject a Temporal implementation. Used by application code on Node < 26 and
3
+ * by test setup (test/setup-temporal.ts) on the Node 22 CI matrix leg.
4
+ *
5
+ * Example:
6
+ * ```ts
7
+ * import { setTemporal } from 'rrule-ts'
8
+ * import { Temporal } from 'temporal-polyfill'
9
+ * setTemporal(Temporal)
10
+ * ```
11
+ */
12
+ export declare function setTemporal(impl: typeof Temporal): void;
13
+ /**
14
+ * Return the available Temporal namespace.
15
+ * Prefers the native global (`globalThis.Temporal`, present on Node >= 26 and
16
+ * modern browsers); falls back to the implementation injected via setTemporal().
17
+ *
18
+ * Throws a descriptive error if neither is available so callers get a clear
19
+ * message instead of a cryptic TypeError.
20
+ */
21
+ export declare function getTemporal(): typeof Temporal;
22
+ //# sourceMappingURL=temporal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temporal.d.ts","sourceRoot":"","sources":["../src/temporal.ts"],"names":[],"mappings":"AAYA;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,QAAQ,GAAG,IAAI,CAEvD;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,IAAI,OAAO,QAAQ,CAa7C"}
@@ -0,0 +1,45 @@
1
+ // Temporal accessor and injector.
2
+ //
3
+ // The library has zero runtime dependencies: it reads globalThis.Temporal when
4
+ // present (Node >= 26, modern browsers that ship the TC39 Temporal proposal)
5
+ // and falls back to an instance injected by the caller via setTemporal().
6
+ //
7
+ // Test setup (test/setup-temporal.ts) injects temporal-polyfill on Node 22.
8
+ // We store the injected implementation separately so it can be swapped in
9
+ // tests without mutating globalThis.
10
+ let _injected;
11
+ /**
12
+ * Inject a Temporal implementation. Used by application code on Node < 26 and
13
+ * by test setup (test/setup-temporal.ts) on the Node 22 CI matrix leg.
14
+ *
15
+ * Example:
16
+ * ```ts
17
+ * import { setTemporal } from 'rrule-ts'
18
+ * import { Temporal } from 'temporal-polyfill'
19
+ * setTemporal(Temporal)
20
+ * ```
21
+ */
22
+ export function setTemporal(impl) {
23
+ _injected = impl;
24
+ }
25
+ /**
26
+ * Return the available Temporal namespace.
27
+ * Prefers the native global (`globalThis.Temporal`, present on Node >= 26 and
28
+ * modern browsers); falls back to the implementation injected via setTemporal().
29
+ *
30
+ * Throws a descriptive error if neither is available so callers get a clear
31
+ * message instead of a cryptic TypeError.
32
+ */
33
+ export function getTemporal() {
34
+ const native = globalThis.Temporal;
35
+ if (native !== undefined) {
36
+ return native;
37
+ }
38
+ if (_injected !== undefined) {
39
+ return _injected;
40
+ }
41
+ throw new Error('Temporal is not available. On Node.js < 26, inject a polyfill with setTemporal() ' +
42
+ 'before using date-aware RRULE features (DTSTART, UNTIL). ' +
43
+ 'See https://github.com/codewithagents/rrule#readme for the setup pattern.');
44
+ }
45
+ //# sourceMappingURL=temporal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"temporal.js","sourceRoot":"","sources":["../src/temporal.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,EAAE;AACF,+EAA+E;AAC/E,6EAA6E;AAC7E,0EAA0E;AAC1E,EAAE;AACF,4EAA4E;AAE5E,0EAA0E;AAC1E,qCAAqC;AACrC,IAAI,SAAsC,CAAA;AAE1C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,WAAW,CAAC,IAAqB;IAC/C,SAAS,GAAG,IAAI,CAAA;AAClB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,MAAM,GAAI,UAAsC,CAAC,QAAQ,CAAA;IAC/D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,MAAyB,CAAA;IAClC,CAAC;IACD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAA;IAClB,CAAC;IACD,MAAM,IAAI,KAAK,CACb,mFAAmF;QACjF,2DAA2D;QAC3D,2EAA2E,CAC9E,CAAA;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ import type { RRuleOptions } from '../types.js';
2
+ /** Options accepted by toText. */
3
+ export interface TextOptions {
4
+ /** Locale identifier, e.g. 'en' or 'de'. Defaults to 'en'. */
5
+ locale?: string;
6
+ }
7
+ /**
8
+ * Convert `RRuleOptions` to a human-readable recurrence description.
9
+ *
10
+ * @example toText({ freq: 'WEEKLY', byDay: [{ weekday: 'MO', ordinal: undefined }] })
11
+ * // 'every week on Monday' (expansion phase)
12
+ *
13
+ * @stub Not yet implemented.
14
+ * TODO(expansion-phase): implement locale-aware text rendering.
15
+ */
16
+ export declare function toText(_options: RRuleOptions, _textOptions?: TextOptions): never;
17
+ /**
18
+ * Parse a human-readable recurrence description into `RRuleOptions`.
19
+ *
20
+ * @stub Not yet implemented.
21
+ * TODO(expansion-phase): implement natural-language RRULE parser.
22
+ */
23
+ export declare function fromText(_text: string, _locale?: string): never;
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/text/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C,kCAAkC;AAClC,MAAM,WAAW,WAAW;IAC1B,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;GAQG;AAEH,wBAAgB,MAAM,CAAC,QAAQ,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,WAAW,GAAG,KAAK,CAEhF;AAED;;;;;GAKG;AAEH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAE/D"}
@@ -0,0 +1,28 @@
1
+ // Human-readable RRULE text rendering (import 'rrule-ts/text').
2
+ //
3
+ // Stubs for the expansion phase.
4
+ // TODO(expansion-phase): implement toText and fromText with i18n locale packs.
5
+ /**
6
+ * Convert `RRuleOptions` to a human-readable recurrence description.
7
+ *
8
+ * @example toText({ freq: 'WEEKLY', byDay: [{ weekday: 'MO', ordinal: undefined }] })
9
+ * // 'every week on Monday' (expansion phase)
10
+ *
11
+ * @stub Not yet implemented.
12
+ * TODO(expansion-phase): implement locale-aware text rendering.
13
+ */
14
+ // v8 ignore next 3
15
+ export function toText(_options, _textOptions) {
16
+ throw new Error('not implemented: toText (coming in expansion phase)');
17
+ }
18
+ /**
19
+ * Parse a human-readable recurrence description into `RRuleOptions`.
20
+ *
21
+ * @stub Not yet implemented.
22
+ * TODO(expansion-phase): implement natural-language RRULE parser.
23
+ */
24
+ // v8 ignore next 3
25
+ export function fromText(_text, _locale) {
26
+ throw new Error('not implemented: fromText (coming in expansion phase)');
27
+ }
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/text/index.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,EAAE;AACF,iCAAiC;AACjC,+EAA+E;AAU/E;;;;;;;;GAQG;AACH,mBAAmB;AACnB,MAAM,UAAU,MAAM,CAAC,QAAsB,EAAE,YAA0B;IACvE,MAAM,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAA;AACxE,CAAC;AAED;;;;;GAKG;AACH,mBAAmB;AACnB,MAAM,UAAU,QAAQ,CAAC,KAAa,EAAE,OAAgB;IACtD,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;AAC1E,CAAC"}
@@ -0,0 +1,83 @@
1
+ /** Recurrence frequency, ordered from finest to coarsest (RFC 5545 §3.3.10). */
2
+ export type Frequency = 'SECONDLY' | 'MINUTELY' | 'HOURLY' | 'DAILY' | 'WEEKLY' | 'MONTHLY' | 'YEARLY';
3
+ /** ISO weekday abbreviations used in BYDAY and WKST values. */
4
+ export type Weekday = 'MO' | 'TU' | 'WE' | 'TH' | 'FR' | 'SA' | 'SU';
5
+ /**
6
+ * A BYDAY entry such as `MO`, `3MO`, or `-1FR`.
7
+ * When `ordinal` is undefined the entry applies to every occurrence of that
8
+ * weekday within the recurrence period (e.g. BYDAY=MO in a WEEKLY rule).
9
+ * When `ordinal` is set, it selects the nth (or nth-from-last) occurrence
10
+ * within a MONTHLY or YEARLY period (e.g. `2MO` = 2nd Monday).
11
+ */
12
+ export interface WeekdayNum {
13
+ /** The ordinal position, e.g. 2 or -1. undefined means "all". */
14
+ ordinal: number | undefined;
15
+ weekday: Weekday;
16
+ }
17
+ /**
18
+ * A DTSTART value. Covers all four Temporal representations that iCalendar
19
+ * DTSTART can express:
20
+ * - Date-only: Temporal.PlainDate
21
+ * - Floating datetime: Temporal.PlainDateTime
22
+ * - UTC datetime: Temporal.Instant
23
+ * - Zoned datetime: Temporal.ZonedDateTime (when TZID= is present)
24
+ */
25
+ export type RRuleDtstart = Temporal.PlainDate | Temporal.PlainDateTime | Temporal.Instant | Temporal.ZonedDateTime;
26
+ /**
27
+ * A UNTIL value. RFC 5545 mandates the same value type as DTSTART, so
28
+ * ZonedDateTime is not used here (UNTIL is always UTC or plain per spec).
29
+ */
30
+ export type RRuleUntil = Temporal.PlainDate | Temporal.PlainDateTime | Temporal.Instant;
31
+ /**
32
+ * Parsed and typed representation of an RFC 5545 RRULE, plus optional DTSTART
33
+ * and TZID context.
34
+ *
35
+ * Fields map directly to RRULE parts:
36
+ * - `freq` FREQ (required)
37
+ * - `interval` INTERVAL (default 1 when absent)
38
+ * - `count` COUNT
39
+ * - `until` UNTIL
40
+ * - `wkst` WKST
41
+ * - `byMonth` BYMONTH
42
+ * - `byMonthDay` BYMONTHDAY
43
+ * - `byDay` BYDAY
44
+ * - `byYearDay` BYYEARDAY
45
+ * - `byWeekNo` BYWEEKNO
46
+ * - `byHour` BYHOUR
47
+ * - `byMinute` BYMINUTE
48
+ * - `bySecond` BYSECOND
49
+ * - `bySetPos` BYSETPOS
50
+ * - `dtstart` from a DTSTART content line (not part of the RRULE value)
51
+ * - `tzid` from DTSTART;TZID= (not part of the RRULE value)
52
+ */
53
+ export interface RRuleOptions {
54
+ freq: Frequency;
55
+ interval?: number;
56
+ count?: number;
57
+ until?: RRuleUntil;
58
+ wkst?: Weekday;
59
+ byMonth?: number[];
60
+ byMonthDay?: number[];
61
+ byDay?: WeekdayNum[];
62
+ byYearDay?: number[];
63
+ byWeekNo?: number[];
64
+ byHour?: number[];
65
+ byMinute?: number[];
66
+ bySecond?: number[];
67
+ bySetPos?: number[];
68
+ dtstart?: RRuleDtstart;
69
+ tzid?: string;
70
+ }
71
+ /** A single RFC validation failure. */
72
+ export interface ValidationError {
73
+ /** The RRULE field that failed, e.g. "COUNT", "UNTIL", "BYDAY". */
74
+ field: string;
75
+ /**
76
+ * Stable machine-readable identifier for the rule, e.g. "COUNT_XNOR_UNTIL".
77
+ * Safe to use in translations and error maps.
78
+ */
79
+ ruleId: string;
80
+ /** Human-readable description of the failure. */
81
+ message: string;
82
+ }
83
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAOA,gFAAgF;AAChF,MAAM,MAAM,SAAS,GACnB,UAAU,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;AAEhF,+DAA+D;AAC/D,MAAM,MAAM,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;AAEpE;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,iEAAiE;IACjE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,OAAO,EAAE,OAAO,CAAA;CACjB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,YAAY,GACtB,QAAQ,CAAC,SAAS,GAAG,QAAQ,CAAC,aAAa,GAAG,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAA;AAEzF;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,GAAG,QAAQ,CAAC,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAA;AAEvF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,SAAS,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IACrB,KAAK,CAAC,EAAE,UAAU,EAAE,CAAA;IACpB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,uCAAuC;AACvC,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAA;IACb;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAA;CAChB"}
package/dist/types.js ADDED
@@ -0,0 +1,8 @@
1
+ // Public type model for RFC 5545 RRULE options.
2
+ //
3
+ // Temporal types (Temporal.Instant, Temporal.PlainDate, etc.) are used
4
+ // directly. They are available as globals from TypeScript's lib.es2025.temporal
5
+ // declarations (TypeScript >= 5.8 / 6.x). At runtime the library reads them
6
+ // from globalThis.Temporal (Node >= 26) or from an injected polyfill.
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,EAAE;AACF,uEAAuE;AACvE,gFAAgF;AAChF,4EAA4E;AAC5E,sEAAsE"}
@@ -0,0 +1,22 @@
1
+ import type { RRuleOptions, ValidationError } from './types.js';
2
+ import type { Result } from './result.js';
3
+ /**
4
+ * Validate cross-field RFC 5545 constraints on parsed `RRuleOptions`.
5
+ *
6
+ * Returns all errors found in a single pass; the caller sees the complete
7
+ * picture, not just the first problem. Never throws on user input.
8
+ *
9
+ * Rules checked:
10
+ * - COUNT and UNTIL are mutually exclusive
11
+ * - INTERVAL >= 1
12
+ * - COUNT >= 1
13
+ * - UNTIL value type matches DTSTART value type (RFC 5545 §3.3.10)
14
+ * - BYDAY ordinals only allowed for MONTHLY/YEARLY, not with BYWEEKNO
15
+ * - BYWEEKNO only valid with FREQ=YEARLY (RFC 5545 §3.3.10 Table 1)
16
+ * - BYYEARDAY not valid with DAILY, WEEKLY, MONTHLY (RFC 5545 §3.3.10 Table 1)
17
+ * - BYMONTHDAY not valid with FREQ=WEEKLY (RFC 5545 §3.3.10 Table 1)
18
+ * - BYSETPOS requires at least one other BYxxx rule (RFC 5545 §3.3.10)
19
+ * - BY* value ranges (BYMONTH 1-12, BYMONTHDAY ±1-31, BYHOUR 0-23, etc.)
20
+ */
21
+ export declare function validate(options: RRuleOptions): Result<RRuleOptions, ValidationError[]>;
22
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAE/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAuPzC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAAC,YAAY,EAAE,eAAe,EAAE,CAAC,CAgBvF"}