From 8ae1a113857911112dcdddf38d8b0aba67af0d55 Mon Sep 17 00:00:00 2001 From: Dmytro Stanchiev Date: Fri, 15 Aug 2025 23:53:40 -0400 Subject: [PATCH] fix ts errors --- src/lib/ical-helpers.ts | 29 +++++++++++++++++++++++++ src/lib/ical.ts | 47 +++++++++++++++++++++++------------------ 2 files changed, 56 insertions(+), 20 deletions(-) create mode 100644 src/lib/ical-helpers.ts diff --git a/src/lib/ical-helpers.ts b/src/lib/ical-helpers.ts new file mode 100644 index 0000000..52c621f --- /dev/null +++ b/src/lib/ical-helpers.ts @@ -0,0 +1,29 @@ +import ICAL from "ical.js"; + +export function isRecur(val: unknown): val is ICAL.Recur { + return typeof val === "object" && val instanceof ICAL.Recur; +} + +export function isTime(val: unknown): val is ICAL.Time { + return typeof val === "object" && val instanceof ICAL.Time; +} + +// export function isGeo(val: unknown): val is ICAL.Geo { +// return typeof val === "object" && val instanceof ICAL.Geo; +// } + +export function isUtcOffset(val: unknown): val is ICAL.UtcOffset { + return typeof val === "object" && val instanceof ICAL.UtcOffset; +} + +export function isBinary(val: unknown): val is ICAL.Binary { + return typeof val === "object" && val instanceof ICAL.Binary; +} + +export function isDuration(val: unknown): val is ICAL.Duration { + return typeof val === "object" && val instanceof ICAL.Duration; +} + +export function isPeriod(val: unknown): val is ICAL.Period { + return typeof val === "object" && val instanceof ICAL.Period; +} diff --git a/src/lib/ical.ts b/src/lib/ical.ts index cbc867b..345c4f9 100644 --- a/src/lib/ical.ts +++ b/src/lib/ical.ts @@ -1,5 +1,25 @@ import ICAL from "ical.js"; import type { CalendarEvent } from "@/lib/types"; +import { + isRecur, + isTime, + isUtcOffset, + isBinary, + isDuration, + isPeriod, +} from "./ical-helpers"; + +function safeValueToString( + val: ReturnType, +): string | undefined { + if (val === undefined) return undefined; + if (typeof val === "string") return val; + if (isTime(val)) return val.toJSDate().toISOString(); + if (isRecur(val)) return val.toString(); + if (isUtcOffset(val)) return val.toString(); // already "±HHMM" + if (isBinary(val) || isDuration(val) || isPeriod(val)) return val.toString(); + return undefined; +} export function parseICS(icsString: string): CalendarEvent[] { const jcalData = ICAL.parse(icsString); @@ -8,30 +28,19 @@ export function parseICS(icsString: string): CalendarEvent[] { return vevents.map((v) => { const ev = new ICAL.Event(v); - const isAllDay = ev.startDate.isDate; return { id: ev.uid || crypto.randomUUID(), title: ev.summary || "Untitled Event", description: ev.description || "", location: ev.location || "", - url: v.getFirstPropertyValue("url") || undefined, + url: safeValueToString(v.getFirstPropertyValue("url")), start: ev.startDate.toJSDate().toISOString(), end: ev.endDate ? ev.endDate.toJSDate().toISOString() : undefined, - allDay: isAllDay, - createdAt: v.getFirstPropertyValue("dtstamp") - ? (v.getFirstPropertyValue("dtstamp") as ICAL.Time) - .toJSDate() - .toISOString() - : undefined, - lastModified: v.getFirstPropertyValue("last-modified") - ? (v.getFirstPropertyValue("last-modified") as ICAL.Time) - .toJSDate() - .toISOString() - : undefined, - recurrenceRule: v.getFirstPropertyValue("rrule") - ? (v.getFirstPropertyValue("rrule") as ICAL.Recur).toString() - : undefined, + allDay: ev.startDate.isDate, + createdAt: safeValueToString(v.getFirstPropertyValue("dtstamp")), + lastModified: safeValueToString(v.getFirstPropertyValue("last-modified")), + recurrenceRule: safeValueToString(v.getFirstPropertyValue("rrule")), }; }); } @@ -50,7 +59,6 @@ export function generateICS(events: CalendarEvent[]): string { if (ev.location) vevent.addPropertyWithValue("location", ev.location); if (ev.url) vevent.addPropertyWithValue("url", ev.url); - // Start/End if (ev.allDay) { vevent.addPropertyWithValue( "dtstart", @@ -66,14 +74,14 @@ export function generateICS(events: CalendarEvent[]): string { "dtstart", ICAL.Time.fromJSDate(new Date(ev.start)), ); - if (ev.end) + if (ev.end) { vevent.addPropertyWithValue( "dtend", ICAL.Time.fromJSDate(new Date(ev.end)), ); + } } - // Timestamps vevent.addPropertyWithValue( "dtstamp", ICAL.Time.fromJSDate(ev.createdAt ? new Date(ev.createdAt) : new Date()), @@ -85,7 +93,6 @@ export function generateICS(events: CalendarEvent[]): string { ); } - // Recurrence if (ev.recurrenceRule) { vevent.addPropertyWithValue( "rrule",