import { type CommaSeparatedString, type Maybe } from '@dereekb/util'; import { DateSet } from '../date'; import { type DateTimezoneBaseDateConverter } from '../date/date.timezone'; /** * Denotes a single RRule rules string. * * @semanticType * @semanticTopic string * @semanticTopic dereekb-date:rrule */ export type RRuleLineString = string; /** * RRule property name. i.e. DTSTART, RRULE, etc. * * @semanticType * @semanticTopic string * @semanticTopic dereekb-date:rrule */ export type RRulePropertyType = string; /** * Set of RRuleParams, separated by a ";". * * The first value in this set is the Type of RRule. * * @semanticType * @semanticTopic string * @semanticTopic dereekb-date:rrule */ export type RRuleRawParamSetString = string; /** * Single Param string. Formatted as = * * @semanticType * @semanticTopic string * @semanticTopic dereekb-date:rrule */ export type RRuleRawParamString = string; /** * Set of values. */ export type RRuleRawValueSetString = CommaSeparatedString; /** * A single raw value from an RRule value set. * * @semanticType * @semanticTopic string * @semanticTopic dereekb-date:rrule */ export type RRuleRawValueString = string; /** * RRule line broken into a name and value. */ export interface RRuleRawLine { params: RRuleRawParamSetString; values: RRuleRawValueSetString; } /** * Single RRuleRawParamString parsed to key-value param. */ export interface RRuleParam { key: string; value: string; } /** * RRule raw param that is broken into name and raw value. */ export interface RRuleProperty { type: RRulePropertyType; params: RRuleParam[]; values: RRuleRawValueSetString; } /** * Denotes a set of RRule strings. */ export type RRuleStringLineSet = RRuleLineString[]; /** * RFC string for an RRuleStringLineSet. * * @semanticType * @semanticTopic string * @semanticTopic dereekb-date:rrule */ export type RRuleLines = string; /** * Date formatted like "20210611". * * https://datatracker.ietf.org/doc/html/rfc5545#section-3.3.4 * * @semanticType * @semanticTopic date * @semanticTopic string * @semanticTopic dereekb-date:rrule */ export type RFC5545DateString = string; /** * Date formatted like "20210611T110000" or "20210611T110000Z". * * https://datatracker.ietf.org/doc/html/rfc5545#section-3.3.5 * * @semanticType * @semanticTopic date * @semanticTopic string * @semanticTopic dereekb-date:rrule */ export type RFC5545DateTimeString = string; /** * Result of separating an RRule string set into basic rules and parsed EXDATE exclusions. */ export interface RRuleStringSetSeparation { /** * All of the original input. */ input: RRuleStringLineSet; /** * Rules that are neither EXDATE nor RDATE, and are therefore safe to hand to RRule.parseString(). */ basic: RRuleStringLineSet; /** * Exdate values. Relative to UTC. */ exdates: DateSet; /** * Rdate values. Relative to UTC. * * These MUST be separated out rather than left in {@link basic}: rrule's parseLine() throws * "Unsupported RFC prop RDATE" for any property other than RRULE/EXRULE/DTSTART, so an RDATE left in * place does not degrade gracefully, it breaks every expansion of the rule. Separating it also preserves * the invariant that makes parseString() usable at all, since parseString() merges only its first two * parsed lines and silently discards the rest. */ rdates: DateSet; } /** * https://datatracker.ietf.org/doc/html/rfc5545#section-3.8.5.1 */ export interface RRuleExdateAttribute { /** * Parsed timezone, if applicable. */ timezone?: string; /** * Dates relative to UTC. */ dates: Date[]; } /** * Delimiter separating the property name/params from values in an RRule line. */ export declare const RRULE_STRING_SPLITTER = ":"; /** * The EXDATE property name. Values listed here are SUBTRACTED from the recurrence set. */ export declare const RRULE_EXDATE_PROPERTY_TYPE = "EXDATE"; /** * The RDATE property name. Values listed here are ADDED to the recurrence set. */ export declare const RRULE_RDATE_PROPERTY_TYPE = "RDATE"; /** * Utility class for parsing and manipulating RFC 5545 RRule strings. * * Provides static methods for separating EXDATE/RDATE rules, parsing RFC 5545 date-time strings, * and converting between raw line formats and structured property representations. * * @example * ```ts * const lines = DateRRuleParseUtility.toRRuleStringSet(rruleString); * const { basic, exdates, rdates } = DateRRuleParseUtility.separateRRuleStringSetValues(lines); * ``` */ export declare class DateRRuleParseUtility { /** * Splits an RRule line set into basic rules plus the parsed EXDATE exclusions and RDATE additions. * * @param input - The RRule string line set to separate. * @returns The separated basic rules, EXDATE exclusion dates, and RDATE additional dates. * * @example * ```ts * const result = DateRRuleParseUtility.separateRRuleStringSetValues([ * 'RRULE:FREQ=DAILY', * 'EXDATE:20210611T110000Z', * 'RDATE:20210612T110000Z' * ]); * // result.basic = ['RRULE:FREQ=DAILY'] * // result.exdates contains 2021-06-11T11:00:00Z * // result.rdates contains 2021-06-12T11:00:00Z * ``` */ static separateRRuleStringSetValues(input: RRuleStringLineSet): RRuleStringSetSeparation; /** * Parses the date values out of a set of date-list property lines (EXDATE or RDATE) into a single * {@link DateSet}. * * @param lines - The date-list property lines. May be empty. * @returns The parsed dates, relative to UTC. Empty when no lines are given. */ static parseDateSetFromLines(lines: RRuleStringLineSet): DateSet; /** * Parses an EXDATE line into its timezone and date components. * * @param line - Raw EXDATE line string to parse. * @returns Parsed EXDATE attribute with timezone and dates. * @throws {Error} If the line is not an EXDATE property. */ static parseExdateAttributeFromLine(line: RRuleLineString): RRuleExdateAttribute; /** * Extracts timezone and UTC-normalized dates from an already-parsed EXDATE property. * * @param property - Parsed EXDATE property to extract from. * @returns EXDATE attribute containing timezone and UTC-normalized dates. */ static parseExdateAttributeFromProperty(property: RRuleProperty): RRuleExdateAttribute; /** * Convenience wrapper that creates a timezone converter and delegates to {@link parseDateTimeString}. * * @param rfcDateString - RFC 5545 date or date-time string to parse. * @param timezone - Optional timezone applied when interpreting non-UTC strings. * @returns Parsed JavaScript Date. * @throws {Error} If the date string is not UTC and no timezone is provided. */ static parseDateTimeStringWithTimezone(rfcDateString: RFC5545DateString | RFC5545DateTimeString, timezone: Maybe): Date; /** * Parses an RFC 5545 date or date-time string into a JavaScript Date. * * If the string does not end in `Z` (indicating UTC), the converter is used to normalize * the local date representation to its true UTC equivalent. * * @param rfcDateString - RFC 5545 date or date-time string to parse. * @param converter - Optional timezone converter applied when interpreting non-UTC strings. * @returns Parsed JavaScript Date. * @throws {Error} If the string cannot be parsed or a non-UTC string lacks a converter. */ static parseDateTimeString(rfcDateString: RFC5545DateString | RFC5545DateTimeString, converter: Maybe): Date; /** * Formats a Date as an RFC 5545 UTC date-time string (e.g., `"20210611T110000Z"`). * * The rendered wall clock is always UTC, regardless of the system timezone, so the trailing `Z` is truthful. * * @param date - Moment to render. * @returns RFC 5545 UTC date-time representation of the moment. * * @example * ```ts * DateRRuleParseUtility.formatDateTimeString(new Date('2021-06-11T11:00:00Z')); * // => '20210611T110000Z' * ``` */ static formatDateTimeString(date: Date): RFC5545DateTimeString; /** * Parses a full RRule line string into a structured {@link RRuleProperty}. * * @param line - The raw RRule line string to parse. * @returns The structured property with type, params, and values. */ static parseProperty(line: RRuleLineString): RRuleProperty; /** * Converts an {@link RRuleRawLine} into a structured {@link RRuleProperty} by splitting the type and params. * * @param rawLine - The raw line to convert. * @returns The structured property with separated type, params, and values. */ static propertyFromRawLine(rawLine: RRuleRawLine): RRuleProperty; /** * Splits a raw param string (e.g., `"TZID=America/New_York"`) into key-value form. * * @param param - The raw param string to split. * @returns The parsed key-value param. */ static parseRawParam(param: RRuleRawParamString): RRuleParam; /** * Splits a raw line at the colon delimiter into params and values portions. * Falls back to treating a single-segment line as an RRULE value. * * @param line - The raw RRule line string to split. * @returns The raw line with separated params and values. */ static parseRawLine(line: RRuleLineString): RRuleRawLine; /** * Splits a newline-delimited RRule string into individual line strings. * * @param lines - Newline-delimited RRule string to split. * @returns Individual RRule line strings produced from the input. */ static toRRuleStringSet(lines: RRuleLines): RRuleStringLineSet; /** * Joins an array of RRule line strings into a single newline-delimited string. * * @param rruleStringSet - RRule line strings to join. * @returns Combined newline-delimited RRule representation. */ static toRRuleLines(rruleStringSet: RRuleStringLineSet): RRuleLines; /** * Asserts that the property has the expected type, throwing if it does not match. * * @param type - Expected property type. * @param property - Property under inspection. * @throws {Error} If the property type does not match the expected type. */ static assertPropertyType(type: RRulePropertyType, property: RRuleProperty): void; }