import { type Maybe, type TimezoneString } from '@dereekb/util'; import { type CalendarDate } from '../date/date.calendar'; import { type DateDurationSpan } from '../date/date.duration'; import { type ICalendarUid } from './icalendar'; import { type ICalendarEvent } from './icalendar.model'; /** * Configuration for {@link iCalendarUidFactory}. */ export interface ICalendarUidFactoryConfig { /** * The right-hand side of the generated UID, per RFC 5545 3.8.4.7's guidance that a UID be globally unique. * I.E. "example.com". */ readonly domain: string; /** * Optional prefix placed before the key, separated by a dash. I.E. "job". */ readonly prefix?: Maybe; } /** * Builds a stable UID from a caller-supplied key. */ export type ICalendarUidFactory = (key: string) => ICalendarUid; /** * Creates an {@link ICalendarUidFactory}. * * There is deliberately no random or generated fallback anywhere in this library: a UID that changes between * publishes makes every client create a duplicate event rather than update the one it holds, which defeats the * entire purpose of a UID. The key must be derived from something stable — a document id plus an instance key. * * @param config - The domain and optional prefix applied to every generated UID. * @returns Builds a UID from a stable key. * * @example * ```ts * iCalendarUidFactory({ domain: 'example.com', prefix: 'job' })('abc123'); // 'job-abc123@example.com' * ``` * * @__NO_SIDE_EFFECTS__ */ export declare function iCalendarUidFactory(config: ICalendarUidFactoryConfig): ICalendarUidFactory; /** * The descriptive half of an {@link ICalendarEvent}: everything except the timing, which the factory derives. */ export type ICalendarEventForDateDurationSpanConfig = Omit; /** * Builds a timed {@link ICalendarEvent} from a {@link DateDurationSpan}. * * Both ends are emitted as absolute UTC instants, which every client reads identically and which needs no * VTIMEZONE component. * * @param span - The span the event occupies. * @param config - The event's UID and descriptive properties. * @returns The event. * * @__NO_SIDE_EFFECTS__ */ export declare function iCalendarEventForDateDurationSpan(span: DateDurationSpan, config: ICalendarEventForDateDurationSpanConfig): ICalendarEvent; /** * Configuration for {@link iCalendarEventForCalendarDate}. */ export interface ICalendarEventForCalendarDateConfig extends ICalendarEventForDateDurationSpanConfig { /** * REQUIRED for a {@link CalendarDateType.DAYS} input: the timezone the CalendarDate was created in. * Pass `false` when it was created in UTC. * * A CalendarDate stores its `startsAt` as the real instant of local midnight in its originating zone, so * the calendar day cannot be recovered without knowing that zone. Defaulting to the system zone here would * make the emitted day depend on where the serializer happens to run, which is the classic all-day bug. * * Unused for a {@link CalendarDateType.TIME} input. */ readonly timezone: TimezoneString | false; } /** * Builds an {@link ICalendarEvent} from a {@link CalendarDate}. * * A {@link CalendarDateType.TIME} input produces a timed event with UTC endpoints, exactly as * {@link iCalendarEventForDateDurationSpan} does. A {@link CalendarDateType.DAYS} input produces an all-day * event with `VALUE=DATE` endpoints. * * NOTE: an all-day DTEND is EXCLUSIVE (RFC 5545 3.8.2.2) — it names the day AFTER the last day of the event. * A one-day event on 2024-01-15 therefore ends on 2024-01-16. * * @param calendarDate - The calendar date the event occupies. * @param config - The event's UID, descriptive properties, and the zone the calendar date was created in. * @returns The event. * * @__NO_SIDE_EFFECTS__ */ export declare function iCalendarEventForCalendarDate(calendarDate: CalendarDate, config: ICalendarEventForCalendarDateConfig): ICalendarEvent;