{"version":3,"sources":["../src/client.ts","../src/utils/encode.ts","../src/utils/parser.ts","../src/models.ts","../src/utils/common.ts","../src/errors.ts"],"sourcesContent":["import axios, { AxiosInstance, AxiosRequestConfig } from \"axios\";\nimport { XMLParser } from \"fast-xml-parser\";\nimport ICAL from \"ical.js\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport {\n  CalDAVClientCache,\n  CalDAVOptions,\n  Calendar,\n  Event,\n  EventRef,\n  SyncChangesResult,\n  SyncTodosResult,\n  Todo,\n  TodoRef,\n} from \"./models\";\nimport { formatDate } from \"./utils/encode\";\nimport { parseCalendars, parseEvents, parseTodos } from \"./utils/parser\";\nimport { first, normalizeSlashEnd } from \"./utils/common\";\nimport { CalDAVError } from \"./errors\";\n\ntype Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;\ntype PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\nconst XML_CT = \"application/xml; charset=utf-8\";\nconst ICS_CT = \"text/calendar; charset=utf-8\";\n\nexport class CalDAVClient {\n  private httpClient: AxiosInstance;\n  private prodId: string;\n  private parser = new XMLParser({\n    removeNSPrefix: true,\n    ignoreAttributes: false,\n  });\n\n  public calendarHome: string | null;\n  public userPrincipal: string | null;\n  public requestTimeout: number;\n  public baseUrl: string;\n\n  private constructor(private options: CalDAVOptions) {\n    let httpsAgent: unknown;\n    if (options.rejectUnauthorized === false) {\n      try {\n        // eslint-disable-next-line @typescript-eslint/no-require-imports\n        const https = require(\"https\");\n        httpsAgent = new https.Agent({ rejectUnauthorized: false });\n      } catch {\n        /* not a Node.js environment — skip */\n      }\n    }\n\n    this.httpClient = axios.create({\n      baseURL: options.baseUrl,\n      httpsAgent,\n      headers: {\n        Authorization:\n          options.auth.type === \"basic\"\n            ? `Basic ${btoa(`${options.auth.username}:${options.auth.password}`)}`\n            : `Bearer ${options.auth.accessToken}`,\n        \"Content-Type\": XML_CT,\n        ...options.headers,\n      },\n      timeout: options.requestTimeout || 5000,\n    });\n\n    this.prodId = options.prodId || \"-//ts-caldav.//CalDAV Client//EN\";\n    this.calendarHome = null;\n    this.userPrincipal = null;\n    this.requestTimeout = options.requestTimeout || 5000;\n    this.baseUrl = options.baseUrl;\n\n    if (options.logRequests) {\n      this.httpClient.interceptors.request.use((request) => {\n        const base = this.baseUrl.replace(/\\/+$/, \"\");\n        const path = (request.url || \"\").replace(/^\\/+/, \"\");\n        console.log(\n          `Request: ${request.method?.toUpperCase()} ${base}/${path}`,\n        );\n        return request;\n      });\n    }\n  }\n\n  /**\n   * Creates a new CalDAVClient instance and validates the provided credentials.\n   * @param options - The CalDAV client options.\n   * @returns A new CalDAVClient instance.\n   * @throws An error if the provided credentials are invalid.\n   * @example\n   * ```typescript\n   * const client = await CalDAVClient.create({\n   *  baseUrl: \"https://caldav.example.com\",\n   *  username: \"user\",\n   *  password: \"password\",\n   * });\n   * ```\n   */\n  static async create(options: CalDAVOptions): Promise<CalDAVClient> {\n    const client = new CalDAVClient(options);\n    await client.discover();\n    return client;\n  }\n\n  /**\n   * Creates a CalDAVClient instance from a cache object.\n   * This is useful for restoring a client state without re-fetching the calendar home.\n   * @param options - The CalDAV client options.\n   * @param cache - The cached client state.\n   * @return A new CalDAVClient instance initialized with the cached state.\n   * @throws An error if the cache is invalid or incomplete.\n   */\n  static createFromCache(\n    options: CalDAVOptions,\n    cache: CalDAVClientCache,\n  ): CalDAVClient {\n    const client = new CalDAVClient(options);\n    client.userPrincipal = client.resolveUrl(cache.userPrincipal);\n    client.calendarHome = client.resolveUrl(cache.calendarHome);\n    if (cache.prodId) client.prodId = cache.prodId;\n    return client;\n  }\n\n  public getCalendarHome(): string | null {\n    return this.calendarHome;\n  }\n\n  /**\n   * Exports the current client state to a cache object.\n   * This can be used to restore the client state later without re-fetching the calendar home.\n   * @returns A CalDAVClientCache object containing the current client state.\n   */\n  public exportCache(): CalDAVClientCache {\n    return {\n      userPrincipal: this.userPrincipal!,\n      calendarHome: this.calendarHome!,\n      prodId: this.prodId,\n    };\n  }\n\n  /*\n   * Discovery\n   */\n\n  private async tryDiscoveryRoots(): Promise<string> {\n    try {\n      const wk = this.absolutize(\"/.well-known/caldav\");\n      const redirected = await this.followRedirectOnce(wk);\n\n      const res = await this.httpClient.request({\n        method: \"OPTIONS\",\n        url: redirected,\n        validateStatus: (s) => s < 400,\n      });\n\n      if (res.status < 400) return redirected;\n    } catch {\n      /* fall through to candidates if .well-known 404s or fails */\n    }\n\n    const candidates = [\n      \"/\",\n      \"/dav\",\n      \"/caldav\",\n      \"/caldav.php\",\n      \"/remote.php/dav\",\n    ];\n\n    for (const p of candidates) {\n      try {\n        const abs = this.absolutize(p);\n        const res = await this.httpClient.request({\n          method: \"OPTIONS\",\n          url: abs,\n          validateStatus: () => true,\n        });\n\n        const allow = String(res.headers[\"allow\"] || \"\").toUpperCase();\n        const dav = String(res.headers[\"dav\"] || \"\").toLowerCase();\n\n        const looksDav = allow.includes(\"PROPFIND\") || dav.includes(\"1\");\n\n        if (res.status < 400 && looksDav) return abs;\n      } catch {\n        /* try next */\n      }\n    }\n\n    return this.baseUrl;\n  }\n\n  private async discover(): Promise<void> {\n    const discoveryRoot = await this.tryDiscoveryRoots();\n\n    const cupXml = `\n      <d:propfind xmlns:d=\"DAV:\">\n        <d:prop><d:current-user-principal/></d:prop>\n      </d:propfind>`;\n    const cup = await this.propfind(discoveryRoot, \"0\", cupXml);\n\n    const principalHref = this.getHrefFromProp(cup, \"current-user-principal\");\n    if (!principalHref) {\n      throw new CalDAVError(\n        \"User principal not found: credentials rejected or server misconfigured.\",\n      );\n    }\n    const principalUrl = this.absolutize(this.resolveUrl(principalHref));\n    this.userPrincipal = principalUrl;\n\n    const chsXml = `\n      <d:propfind xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n        <d:prop><c:calendar-home-set/></d:prop>\n      </d:propfind>`;\n    const chs = await this.propfind(principalUrl, \"0\", chsXml);\n\n    const homeHref = this.getHrefFromProp(chs, \"calendar-home-set\");\n    if (!homeHref)\n      throw new CalDAVError(\"calendar-home-set not found for principal.\");\n    const homeUrl = this.absolutize(this.resolveUrl(homeHref));\n    this.calendarHome = homeUrl;\n\n    try {\n      await this.propfind(\n        homeUrl,\n        \"0\",\n        `<d:propfind xmlns:d=\"DAV:\"><d:prop><d:displayname/></d:prop></d:propfind>`,\n      );\n    } catch (e) {\n      throw new CalDAVError(\n        `Authenticated but failed to access calendar home at ${homeUrl}.`,\n        undefined,\n        { cause: e },\n      );\n    }\n  }\n\n  /*\n   * Calendars\n   */\n\n  public async getCalendars(): Promise<Calendar[]> {\n    if (!this.calendarHome) throw new CalDAVError(\"Calendar home not found.\");\n\n    const requestBody = `\n      <d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\" xmlns:apple=\"http://apple.com/ns/ical/\">\n        <d:prop>\n          <d:resourcetype/>\n          <d:displayname/>\n          <cs:getctag/>\n          <c:supported-calendar-component-set/>\n          <apple:calendar-color/>\n        </d:prop>\n      </d:propfind>`;\n\n    const response = await this.httpClient.request({\n      method: \"PROPFIND\",\n      url: this.calendarHome,\n      data: requestBody,\n      headers: { Depth: \"1\", \"Content-Type\": XML_CT },\n      validateStatus: (s) => s >= 200 && s < 300,\n    });\n\n    const calendars = await parseCalendars(response.data);\n    return calendars.map((cal) => ({\n      ...cal,\n      url: this.resolveUrl(cal.url),\n    }));\n  }\n\n  /*\n   * Event CRUD Operations\n   */\n\n  /**\n   * Fetches all events from a specific calendar.\n   * @param calendarUrl - The URL of the calendar to fetch events from.\n   * @param options - Optional parameters for fetching events.\n   * @returns An array of Event objects.\n   */\n  public async getEvents(\n    calendarUrl: string,\n    options?: { start?: Date; end?: Date; all?: boolean },\n  ): Promise<Event[]> {\n    return this.getComponents<Event>(\n      calendarUrl,\n      \"VEVENT\",\n      parseEvents,\n      options,\n    );\n  }\n\n  /**\n   * Creates a new event in the specified calendar.\n   * @param calendarUrl - The URL of the calendar to create the event in.\n   * @param eventData - The data for the event to create.\n   * @returns The created event's metadata.\n   */\n  public async createEvent(\n    calendarUrl: string,\n    eventData: PartialBy<Event, \"uid\" | \"href\" | \"etag\">,\n  ): Promise<{ uid: string; href: string; etag: string; newCtag: string }> {\n    return this.createItem<Event>(\n      calendarUrl,\n      eventData,\n      this.buildICSData.bind(this),\n      \"event\",\n    );\n  }\n\n  /**\n   * Updates an existing event in the specified calendar.\n   * @param calendarUrl - The URL of the calendar containing the event.\n   * @param event - The event object with updated data.\n   * @returns The updated event's metadata.\n   */\n  public async updateEvent(\n    calendarUrl: string,\n    event: Event,\n  ): Promise<{ uid: string; href: string; etag: string; newCtag: string }> {\n    return this.updateItem<Event>(\n      calendarUrl,\n      event,\n      this.buildICSData.bind(this),\n      \"event\",\n    );\n  }\n\n  public async deleteEvent(\n    calendarUrl: string,\n    eventUid: string,\n    etag?: string,\n  ): Promise<void> {\n    return this.deleteItem(calendarUrl, eventUid, \"event\", etag);\n  }\n\n  /*\n   * Todo CRUD Operations\n   */\n\n  /**\n   * Fetches all todos from a specific calendar.\n   * @param calendarUrl - The URL of the calendar to fetch todos from.\n   * @param options - Optional parameters for fetching todos.\n   * @returns An array of Todo objects.\n   */\n  public async getTodos(\n    calendarUrl: string,\n    options?: { start?: Date; end?: Date; all?: boolean },\n  ): Promise<Todo[]> {\n    return this.getComponents<Todo>(calendarUrl, \"VTODO\", parseTodos, {\n      all: true,\n      ...options,\n    });\n  }\n\n  /**\n   * Creates a new todo in the specified calendar.\n   * @param calendarUrl - The URL of the calendar to create the todo in.\n   * @param todoData - The data for the todo to create.\n   * @returns The created todo's metadata.\n   */\n  public async createTodo(\n    calendarUrl: string,\n    todoData: PartialBy<Todo, \"uid\" | \"href\" | \"etag\">,\n  ): Promise<{ uid: string; href: string; etag: string; newCtag: string }> {\n    return this.createItem<Todo>(\n      calendarUrl,\n      todoData,\n      this.buildTodoICSData.bind(this),\n      \"todo\",\n    );\n  }\n\n  /**\n   * Updates an existing todo in the specified calendar.\n   * @param calendarUrl - The URL of the calendar containing the todo.\n   * @param todo - The todo object with updated data.\n   * @returns The updated todo's metadata.\n   */\n  public async updateTodo(\n    calendarUrl: string,\n    todo: Todo,\n  ): Promise<{ uid: string; href: string; etag: string; newCtag: string }> {\n    return this.updateItem<Todo>(\n      calendarUrl,\n      todo,\n      this.buildTodoICSData.bind(this),\n      \"todo\",\n    );\n  }\n\n  /**\n   * Deletes a todo from the specified calendar.\n   * @param calendarUrl - The URL of the calendar containing the todo.\n   * @param todoUid - The UID of the todo to delete.\n   * @param etag - Optional ETag for concurrency control.\n   */\n  public async deleteTodo(\n    calendarUrl: string,\n    todoUid: string,\n    etag?: string,\n  ): Promise<void> {\n    return this.deleteItem(calendarUrl, todoUid, \"todo\", etag);\n  }\n\n  /*\n   * Synchronization\n   */\n\n  /**\n   * Fetches the current ETag for a given event href.\n   * Useful when the server does not return an ETag on creation (e.g. Yahoo).\n   * @param href - The full CalDAV event URL (ending in .ics).\n   * @returns The ETag string, or throws an error if not found.\n   */\n  public async getETag(href: string): Promise<string> {\n    try {\n      const data = await this.propfind(\n        this.absolutize(href),\n        \"0\",\n        `<d:propfind xmlns:d=\"DAV:\"><d:prop><d:getetag/></d:prop></d:propfind>`,\n      );\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      const parsed: any = data;\n      const etagRaw =\n        parsed?.multistatus?.response?.propstat?.prop?.getetag ??\n        parsed?.multistatus?.response?.[0]?.propstat?.prop?.getetag;\n      if (!etagRaw)\n        throw new CalDAVError(\"ETag not found in PROPFIND response.\");\n      return String(etagRaw).replace(/^W\\//, \"\");\n    } catch (error) {\n      if (error instanceof CalDAVError) throw error;\n      throw new CalDAVError(\n        `Failed to retrieve ETag for ${href}.`,\n        axios.isAxiosError(error) ? error.response?.status : undefined,\n        { cause: error },\n      );\n    }\n  }\n\n  /**\n   * Fetches the current CTag for a given calendar URL.\n   * @param calendarUrl - The URL of the calendar.\n   * @returns The CTag string.\n   */\n  public async getCtag(calendarUrl: string): Promise<string> {\n    const requestBody = `\n      <d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\">\n        <d:prop><cs:getctag/></d:prop>\n      </d:propfind>`;\n\n    const res = await this.httpClient.request({\n      method: \"PROPFIND\",\n      url: calendarUrl,\n      data: requestBody,\n      headers: { Depth: \"0\", \"Content-Type\": XML_CT },\n      validateStatus: (s) => s === 207,\n    });\n\n    const json = this.parser.parse(res.data);\n    return json?.multistatus?.response?.propstat?.prop?.getctag;\n  }\n\n  private diffRefs(\n    remoteRefs: { href: string; etag: string }[],\n    localRefs: { href: string; etag: string }[],\n  ): { newItems: string[]; updatedItems: string[]; deletedItems: string[] } {\n    const localMap = new Map(localRefs.map((i) => [i.href, i.etag]));\n    const remoteMap = new Map(remoteRefs.map((i) => [i.href, i.etag]));\n\n    const newItems: string[] = [];\n    const updatedItems: string[] = [];\n    const deletedItems: string[] = [];\n\n    for (const { href, etag } of remoteRefs) {\n      if (!localMap.has(href)) newItems.push(href);\n      else if (localMap.get(href) !== etag) updatedItems.push(href);\n    }\n    for (const { href } of localRefs) {\n      if (!remoteMap.has(href)) deletedItems.push(href);\n    }\n    return { newItems, updatedItems, deletedItems };\n  }\n\n  /**\n   * Synchronizes changes between local events and remote calendar.\n   * @param calendarUrl - The URL of the calendar to sync with.\n   * @param ctag - The current CTag of the calendar.\n   * @param localEvents - The local events to compare against remote.\n   * @returns An object containing the sync results.\n   */\n  public async syncChanges(\n    calendarUrl: string,\n    ctag: string,\n    localEvents: EventRef[],\n  ): Promise<SyncChangesResult> {\n    const remoteCtag = await this.getCtag(calendarUrl);\n    if (ctag === remoteCtag) {\n      return {\n        changed: false,\n        newCtag: remoteCtag,\n        newEvents: [],\n        updatedEvents: [],\n        deletedEvents: [],\n      };\n    }\n\n    const remoteRefs = await this.getItemRefs(calendarUrl, \"VEVENT\");\n    const { newItems, updatedItems, deletedItems } = this.diffRefs(\n      remoteRefs,\n      localEvents,\n    );\n\n    return {\n      changed: true,\n      newCtag: remoteCtag,\n      newEvents: newItems,\n      updatedEvents: updatedItems,\n      deletedEvents: deletedItems,\n    };\n  }\n\n  /**\n   * Synchronizes changes between local todos and remote calendar.\n   * @param calendarUrl - The URL of the calendar to sync with.\n   * @param ctag - The current CTag of the calendar.\n   * @param localTodos - The local todos to compare against remote.\n   * @returns An object containing the sync results.\n   */\n  public async syncTodoChanges(\n    calendarUrl: string,\n    ctag: string,\n    localTodos: TodoRef[],\n  ): Promise<SyncTodosResult> {\n    const remoteCtag = await this.getCtag(calendarUrl);\n    if (ctag === remoteCtag) {\n      return {\n        changed: false,\n        newCtag: remoteCtag,\n        newTodos: [],\n        updatedTodos: [],\n        deletedTodos: [],\n      };\n    }\n\n    const remoteRefs = await this.getItemRefs(calendarUrl, \"VTODO\");\n    const { newItems, updatedItems, deletedItems } = this.diffRefs(\n      remoteRefs,\n      localTodos,\n    );\n\n    return {\n      changed: true,\n      newCtag: remoteCtag,\n      newTodos: newItems,\n      updatedTodos: updatedItems,\n      deletedTodos: deletedItems,\n    };\n  }\n\n  /*\n   * Internal Methods\n   */\n\n  private async getComponents<T>(\n    calendarUrl: string,\n    component: \"VEVENT\" | \"VTODO\",\n    parseFn: (xml: string) => Promise<T[]>,\n    options?: { start?: Date; end?: Date; all?: boolean },\n  ): Promise<T[]> {\n    const now = new Date();\n    const defaultEnd = new Date(now.getTime() + 3 * 7 * 24 * 60 * 60 * 1000);\n    const { start = now, end = defaultEnd, all } = options || {};\n\n    const timeRangeFilter =\n      start && end && !all\n        ? `<c:comp-filter name=\"${component}\">\n             <c:time-range start=\"${formatDate(start)}\" end=\"${formatDate(\n               end,\n             )}\"/>\n           </c:comp-filter>`\n        : `<c:comp-filter name=\"${component}\"/>`;\n\n    const requestBody = `\n      <c:calendar-query xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n        <d:prop>\n          <d:getetag/>\n          <c:calendar-data/>\n        </d:prop>\n        <c:filter>\n          <c:comp-filter name=\"VCALENDAR\">\n            ${timeRangeFilter}\n          </c:comp-filter>\n        </c:filter>\n      </c:calendar-query>`;\n\n    try {\n      const xml = await this.report(calendarUrl, requestBody, \"1\");\n      return await parseFn(xml);\n    } catch (error) {\n      throw new CalDAVError(\n        `Failed to retrieve ${component.toLowerCase()}s from the CalDAV server.`,\n        axios.isAxiosError(error) ? error.response?.status : undefined,\n        { cause: error },\n      );\n    }\n  }\n\n  private buildICSData(\n    event: PartialBy<Event, \"uid\" | \"etag\" | \"href\">,\n    uid: string,\n  ): string {\n    const vcalendar = new ICAL.Component([\"vcalendar\", [], []]);\n    vcalendar.addPropertyWithValue(\"version\", \"2.0\");\n    vcalendar.addPropertyWithValue(\"prodid\", this.prodId);\n\n    const vevent = new ICAL.Component(\"vevent\");\n    const e = new ICAL.Event(vevent);\n    e.uid = uid;\n    vevent.addPropertyWithValue(\n      \"dtstamp\",\n      ICAL.Time.fromJSDate(new Date(), true),\n    );\n\n    if (event.wholeDay) {\n      const startDateStr = event.start.toISOString().split(\"T\")[0];\n      const endDateStr = event.end\n        ? event.end.toISOString().split(\"T\")[0]\n        : startDateStr;\n\n      const endExclusive = new Date(endDateStr + \"T00:00:00Z\");\n      endExclusive.setUTCDate(endExclusive.getUTCDate() + 1);\n\n      e.startDate = ICAL.Time.fromDateString(startDateStr);\n      e.endDate = ICAL.Time.fromDateString(\n        endExclusive.toISOString().split(\"T\")[0],\n      );\n    } else {\n      const start = ICAL.Time.fromJSDate(event.start, true);\n      const end = ICAL.Time.fromJSDate(event.end, true);\n\n      if (event.startTzid) {\n        const prop = vevent.addPropertyWithValue(\"dtstart\", start);\n        prop.setParameter(\"tzid\", event.startTzid);\n      } else {\n        e.startDate = start;\n      }\n\n      if (event.endTzid) {\n        const prop = vevent.addPropertyWithValue(\"dtend\", end);\n        prop.setParameter(\"tzid\", event.endTzid);\n      } else {\n        e.endDate = end;\n      }\n    }\n\n    e.summary = event.summary;\n    e.description = event.description || \"\";\n    e.location = event.location || \"\";\n\n    if (event.recurrenceRule) {\n      const r = event.recurrenceRule;\n      const rruleProps: Record<string, string | number> = {};\n      if (r.freq) rruleProps.FREQ = r.freq;\n      if (r.interval) rruleProps.INTERVAL = r.interval;\n      if (r.count) rruleProps.COUNT = r.count;\n      if (event.wholeDay && r.until) {\n        rruleProps.UNTIL = ICAL.Time.fromDateString(\n          r.until.toISOString().split(\"T\")[0],\n        ).toString();\n      } else if (r.until) {\n        rruleProps.UNTIL = ICAL.Time.fromJSDate(r.until, true).toString();\n      }\n\n      if (r.byday) rruleProps.BYDAY = r.byday.join(\",\");\n      if (r.bymonthday) rruleProps.BYMONTHDAY = r.bymonthday.join(\",\");\n      if (r.bymonth) rruleProps.BYMONTH = r.bymonth.join(\",\");\n      vevent.addPropertyWithValue(\"rrule\", rruleProps);\n    }\n\n    if (event.customFields) {\n      for (const [key, value] of Object.entries(event.customFields)) {\n        const values = Array.isArray(value) ? value : [value];\n        for (const v of values) {\n          vevent.addPropertyWithValue(key.toLowerCase(), v);\n        }\n      }\n    }\n\n    if (event.alarms) {\n      for (const alarm of event.alarms) {\n        const valarm = new ICAL.Component(\"valarm\");\n        valarm.addPropertyWithValue(\"trigger\", alarm.trigger);\n        valarm.addPropertyWithValue(\"action\", alarm.action);\n\n        if (alarm.action === \"DISPLAY\" && alarm.description) {\n          valarm.addPropertyWithValue(\"description\", alarm.description);\n        } else if (alarm.action === \"EMAIL\") {\n          if (alarm.summary)\n            valarm.addPropertyWithValue(\"summary\", alarm.summary);\n          if (alarm.description)\n            valarm.addPropertyWithValue(\"description\", alarm.description);\n          for (const attendee of alarm.attendees) {\n            valarm.addPropertyWithValue(\"attendee\", attendee);\n          }\n        }\n        vevent.addSubcomponent(valarm);\n      }\n    }\n\n    vcalendar.addSubcomponent(vevent);\n    return vcalendar.toString();\n  }\n\n  private buildTodoICSData(\n    todo: PartialBy<Todo, \"uid\" | \"etag\" | \"href\">,\n    uid: string,\n  ): string {\n    const vcalendar = new ICAL.Component([\"vcalendar\", [], []]);\n    vcalendar.addPropertyWithValue(\"version\", \"2.0\");\n    vcalendar.addPropertyWithValue(\"prodid\", this.prodId);\n\n    const vtodo = new ICAL.Component(\"vtodo\");\n    vtodo.addPropertyWithValue(\"uid\", uid);\n    vtodo.addPropertyWithValue(\n      \"dtstamp\",\n      ICAL.Time.fromJSDate(new Date(), true),\n    );\n\n    if (todo.start)\n      vtodo.addPropertyWithValue(\n        \"dtstart\",\n        ICAL.Time.fromJSDate(todo.start, true),\n      );\n    if (todo.due)\n      vtodo.addPropertyWithValue(\"due\", ICAL.Time.fromJSDate(todo.due, true));\n    if (todo.completed)\n      vtodo.addPropertyWithValue(\n        \"completed\",\n        ICAL.Time.fromJSDate(todo.completed, true),\n      );\n    vtodo.addPropertyWithValue(\"summary\", todo.summary);\n    if (todo.description)\n      vtodo.addPropertyWithValue(\"description\", todo.description);\n    if (todo.location) vtodo.addPropertyWithValue(\"location\", todo.location);\n    if (todo.status) vtodo.addPropertyWithValue(\"status\", todo.status);\n    if (todo.sortOrder !== undefined)\n      vtodo.addPropertyWithValue(\"X-APPLE-SORT-ORDER\", todo.sortOrder);\n\n    if (todo.customFields) {\n      for (const [key, value] of Object.entries(todo.customFields)) {\n        const values = Array.isArray(value) ? value : [value];\n        for (const v of values) {\n          vtodo.addPropertyWithValue(key.toLowerCase(), v);\n        }\n      }\n    }\n\n    if (todo.alarms) {\n      for (const alarm of todo.alarms) {\n        const valarm = new ICAL.Component(\"valarm\");\n        valarm.addPropertyWithValue(\"trigger\", alarm.trigger);\n        valarm.addPropertyWithValue(\"action\", alarm.action);\n        if (alarm.action === \"DISPLAY\" && alarm.description) {\n          valarm.addPropertyWithValue(\"description\", alarm.description);\n        } else if (alarm.action === \"EMAIL\") {\n          if (alarm.summary)\n            valarm.addPropertyWithValue(\"summary\", alarm.summary);\n          if (alarm.description)\n            valarm.addPropertyWithValue(\"description\", alarm.description);\n          for (const attendee of alarm.attendees) {\n            valarm.addPropertyWithValue(\"attendee\", attendee);\n          }\n        }\n        vtodo.addSubcomponent(valarm);\n      }\n    }\n\n    vcalendar.addSubcomponent(vtodo);\n    return vcalendar.toString();\n  }\n\n  private async createItem<\n    T extends { uid?: string; href?: string; etag?: string },\n  >(\n    calendarUrl: string,\n    data: PartialBy<T, \"uid\" | \"href\" | \"etag\">,\n    buildFn: (\n      data: PartialBy<T, \"uid\" | \"href\" | \"etag\">,\n      uid: string,\n    ) => string,\n    itemType: \"event\" | \"todo\",\n  ): Promise<{ uid: string; href: string; etag: string; newCtag: string }> {\n    if (!calendarUrl)\n      throw new CalDAVError(\n        `Calendar URL is required to create a ${itemType}.`,\n      );\n\n    const base = normalizeSlashEnd(calendarUrl);\n    const uid = data.uid || uuidv4();\n    const href = `${base}/${uid}.ics`;\n    const ics = buildFn(data, uid);\n\n    try {\n      const response = await this.mkIcsPut(\n        href,\n        ics,\n        { \"If-None-Match\": \"*\" },\n        (s) => s === 201 || s === 204,\n      );\n      const etag = response.headers[\"etag\"] || \"\";\n      const newCtag = await this.getCtag(calendarUrl);\n      return { uid, href: `${base}/${uid}.ics`, etag, newCtag };\n    } catch (error) {\n      if (axios.isAxiosError(error) && error.response?.status === 412) {\n        throw new CalDAVError(\n          `${itemType[0].toUpperCase() + itemType.slice(1)} with the specified uid already exists.`,\n          412,\n          { cause: error },\n        );\n      }\n      throw new CalDAVError(\n        `Failed to create ${itemType}.`,\n        axios.isAxiosError(error) ? error.response?.status : undefined,\n        { cause: error },\n      );\n    }\n  }\n\n  private async updateItem<\n    T extends { uid: string; href: string; etag?: string },\n  >(\n    calendarUrl: string,\n    item: T,\n    buildFn: (item: T, uid: string) => string,\n    itemType: \"event\" | \"todo\",\n  ): Promise<{ uid: string; href: string; etag: string; newCtag: string }> {\n    if (!item.uid || !item.href) {\n      throw new CalDAVError(\n        `Both 'uid' and 'href' are required to update a ${itemType}.`,\n      );\n    }\n\n    const ics = buildFn(item, item.uid);\n\n    const ifMatch = this.cleanEtag(item.etag);\n    const extraHeaders: Record<string, string> = {};\n    if (ifMatch && !this.isWeak(item.etag)) {\n      extraHeaders[\"If-Match\"] = ifMatch;\n    }\n    try {\n      const response = await this.mkIcsPut(\n        this.absolutize(item.href),\n        ics,\n        extraHeaders,\n      );\n      const newEtag = response.headers[\"etag\"] || \"\";\n      const newCtag = await this.getCtag(calendarUrl);\n      return { uid: item.uid, href: item.href, etag: newEtag, newCtag };\n    } catch (error) {\n      if (axios.isAxiosError(error) && error.response?.status === 412) {\n        throw new CalDAVError(\n          `${itemType[0].toUpperCase() + itemType.slice(1)} with the specified uid does not match.`,\n          412,\n          { cause: error },\n        );\n      }\n      throw new CalDAVError(\n        `Failed to update ${itemType}.`,\n        axios.isAxiosError(error) ? error.response?.status : undefined,\n        { cause: error },\n      );\n    }\n  }\n\n  private async deleteItem(\n    calendarUrl: string,\n    uid: string,\n    itemType: \"event\" | \"todo\",\n    etag?: string,\n  ): Promise<void> {\n    const base = normalizeSlashEnd(calendarUrl);\n    const href = `${base}/${uid}.ics`;\n    try {\n      await this.httpClient.delete(href, {\n        headers: { \"If-Match\": etag ?? \"*\" },\n        validateStatus: (s) => s === 204 || s === 200,\n      });\n    } catch (error) {\n      throw new CalDAVError(\n        `Failed to delete ${itemType}.`,\n        axios.isAxiosError(error) ? error.response?.status : undefined,\n        { cause: error },\n      );\n    }\n  }\n\n  private async getItemRefs(\n    calendarUrl: string,\n    component: \"VEVENT\" | \"VTODO\",\n  ): Promise<{ href: string; etag: string }[]> {\n    const requestBody = `\n      <c:calendar-query xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n        <d:prop><d:getetag/></d:prop>\n        <c:filter>\n          <c:comp-filter name=\"VCALENDAR\">\n            <c:comp-filter name=\"${component}\"/>\n          </c:comp-filter>\n        </c:filter>\n      </c:calendar-query>`;\n\n    const data = await this.report(calendarUrl, requestBody, \"1\");\n    const jsonData = this.parser.parse(data);\n\n    const raw = jsonData?.multistatus?.response;\n    const responses = Array.isArray(raw) ? raw : raw ? [raw] : [];\n\n    const refs: { href: string; etag: string }[] = [];\n    for (const obj of responses) {\n      if (!obj || typeof obj !== \"object\") continue;\n      const href = obj[\"href\"];\n      const etag = obj?.propstat?.prop?.getetag;\n      if (href && etag) refs.push({ href, etag });\n    }\n    return refs;\n  }\n\n  public async getEventsByHref(\n    calendarUrl: string,\n    hrefs: string[],\n  ): Promise<Event[]> {\n    return this.getItemsByHref<Event>(calendarUrl, hrefs, parseEvents);\n  }\n\n  public async getTodosByHref(\n    calendarUrl: string,\n    hrefs: string[],\n  ): Promise<Todo[]> {\n    return this.getItemsByHref<Todo>(calendarUrl, hrefs, parseTodos);\n  }\n\n  private async getItemsByHref<T>(\n    calendarUrl: string,\n    hrefs: string[],\n    parseFn: (xml: string) => Promise<T[]>,\n  ): Promise<T[]> {\n    if (!hrefs.length) return [];\n\n    const filtered = hrefs.filter((h) => h.endsWith(\".ics\"));\n    if (!filtered.length) return [];\n\n    const requestBody = `\n      <c:calendar-multiget xmlns:d=\"DAV:\" xmlns:c=\"urn:ietf:params:xml:ns:caldav\">\n        <d:prop>\n          <d:getetag/>\n          <c:calendar-data/>\n        </d:prop>\n        ${filtered.map((h) => `<d:href>${h}</d:href>`).join(\"\")}\n      </c:calendar-multiget>`;\n\n    const xml = await this.report(calendarUrl, requestBody, \"1\");\n    return await parseFn(xml);\n  }\n\n  /*\n   * Utility Methods\n   */\n\n  private absolutize(urlOrPath: string): string {\n    return new URL(urlOrPath, this.baseUrl).toString();\n  }\n\n  private resolveUrl(path: string): string {\n    try {\n      if (path.startsWith(\"http\")) {\n        return path;\n      }\n      const resolved = new URL(path, this.baseUrl);\n\n      return resolved.pathname + resolved.search;\n    } catch {\n      return path;\n    }\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  private getHrefFromProp(parsed: any, propName: string): string | null {\n    const ms = parsed?.multistatus;\n    const resp = first(ms?.response);\n    const pstat = first(resp?.propstat);\n    const prop = pstat?.prop;\n    const node = prop?.[propName];\n    if (!node) return null;\n\n    if (typeof node === \"string\") return node;\n    if (typeof node?.href === \"string\") return node.href;\n\n    const maybe = first(node);\n    if (typeof maybe === \"string\") return maybe;\n    if (maybe && typeof maybe.href === \"string\") return maybe.href;\n\n    return null;\n  }\n\n  private isWeak(etag?: string): boolean {\n    return !!etag && (etag.startsWith('W/\"') || etag.startsWith(\"W/\"));\n  }\n\n  private cleanEtag(etag?: string): string | undefined {\n    if (!etag) return undefined;\n    return etag.replace(/^W\\//, \"\").trim();\n  }\n\n  /*\n   * HTTP Methods\n   */\n\n  private async propfind(\n    url: string,\n    depth: \"0\" | \"1\",\n    body: string,\n    extra?: AxiosRequestConfig,\n  ): Promise<unknown> {\n    const res = await this.httpClient.request({\n      method: \"PROPFIND\",\n      url,\n      data: body,\n      headers: {\n        Depth: depth,\n        Prefer: \"return=minimal\",\n        \"Content-Type\": XML_CT,\n      },\n      validateStatus: (s) => s === 207 || s === 200,\n      ...extra,\n    });\n    return this.parser.parse(res.data);\n  }\n\n  private async report(\n    url: string,\n    body: string,\n    depth: \"0\" | \"1\" = \"1\",\n    extra?: AxiosRequestConfig,\n  ): Promise<string> {\n    const res = await this.httpClient.request({\n      method: \"REPORT\",\n      url,\n      data: body,\n      headers: { Depth: depth, \"Content-Type\": XML_CT },\n      validateStatus: (s) => s >= 200 && s < 300,\n      ...extra,\n    });\n    return res.data as string;\n  }\n\n  private async mkIcsPut(\n    href: string,\n    ics: string,\n    headers?: Record<string, string>,\n    validate?: (status: number) => boolean,\n  ) {\n    return this.httpClient.put(href, ics, {\n      headers: { \"Content-Type\": ICS_CT, ...(headers || {}) },\n      validateStatus: validate ?? ((s) => s >= 200 && s < 300),\n    });\n  }\n\n  private async followRedirectOnce(url: string): Promise<string> {\n    try {\n      const res = await this.httpClient.request({\n        method: \"GET\",\n        url,\n        maxRedirects: 0,\n        validateStatus: (s) => (s >= 200 && s < 300) || (s >= 300 && s < 400),\n      });\n      if (res.status >= 300 && res.status < 400) {\n        const loc = res.headers[\"location\"];\n        if (!loc) throw new Error(`Redirect without Location from ${url}`);\n        return this.absolutize(loc);\n      }\n      return url;\n    } catch {\n      return url;\n    }\n  }\n}\n","/**\n * Helper function to format dates for iCalendar.\n * @param date - The date to format.\n * @param utc - Whether to format in UTC (default: true)\n * @returns A formatted date string.\n */\nexport const formatDate = (date: Date, utc: boolean = true): string => {\n  const pad = (n: number): string => n.toString().padStart(2, \"0\");\n\n  if (utc) {\n    return date.toISOString().replace(/[-:]/g, \"\").split(\".\")[0] + \"Z\";\n  } else {\n    return (\n      date.getFullYear().toString() +\n      pad(date.getMonth() + 1) +\n      pad(date.getDate()) +\n      \"T\" +\n      pad(date.getHours()) +\n      pad(date.getMinutes()) +\n      pad(date.getSeconds())\n    );\n  }\n};\n\n/**\n * Helper function to format dates for all-day iCalendar events.\n * @param date - The date to format.\n * @returns A formatted date-only string (YYYYMMDD).\n */\nexport const formatDateOnly = (date: Date): string => {\n  return date.toISOString().split(\"T\")[0].replace(/-/g, \"\");\n};\n","import { XMLParser } from \"fast-xml-parser\";\nimport {\n  Alarm,\n  Calendar,\n  Event,\n  EVENT_STATUSES,\n  EventStatus,\n  RecurrenceRule,\n  SupportedComponent,\n  Todo,\n  TODO_STATUSES,\n  TodoStatus,\n} from \"../models\";\nimport ICAL from \"ical.js\";\n\nconst normalizeParam = (\n  value: string | string[] | undefined,\n): string | undefined => {\n  if (Array.isArray(value)) {\n    return value[0];\n  }\n  return value;\n};\n\nconst generateCustomFields = (\n  component: ICAL.Component,\n  knownProps: Set<string>,\n): Record<string, string | string[]> => {\n  const customFields: Record<string, string | string[]> = {};\n  for (const prop of component.getAllProperties()) {\n    const name = prop.name;\n    if (knownProps.has(name)) continue;\n    const value = prop.getFirstValue()?.toString();\n    if (value == null) continue;\n    const existing = customFields[name];\n    if (existing === undefined) {\n      customFields[name] = value;\n    } else if (Array.isArray(existing)) {\n      existing.push(value);\n    } else {\n      customFields[name] = [existing, value];\n    }\n  }\n  return customFields;\n};\n\nconst parseRecurrence = (recur: ICAL.Recur): RecurrenceRule => {\n  const freqMap = {\n    DAILY: \"DAILY\",\n    WEEKLY: \"WEEKLY\",\n    MONTHLY: \"MONTHLY\",\n    YEARLY: \"YEARLY\",\n  } as const;\n  const freq = freqMap[recur.freq as keyof typeof freqMap] || undefined;\n\n  const byday = recur.parts.BYDAY\n    ? recur.parts.BYDAY.map((day: string) => day)\n    : undefined;\n  const bymonthday = recur.parts.BYMONTHDAY\n    ? recur.parts.BYMONTHDAY.map((day: number) => day)\n    : undefined;\n  const bymonth = recur.parts.BYMONTH\n    ? recur.parts.BYMONTH.map((month: number) => month)\n    : undefined;\n  const wkst = recur.wkst ? recur.wkst.toString() : undefined;\n\n  return {\n    freq,\n    interval: recur.interval,\n    count: recur.count ? recur.count : undefined,\n    until: recur.until ? recur.until.toJSDate() : undefined,\n    wkst,\n    byday,\n    bymonthday,\n    bymonth,\n  };\n};\n\nconst toArray = <T>(value: T | T[] | undefined): T[] =>\n  Array.isArray(value) ? value : value ? [value] : [];\n\nexport const parseCalendars = async (\n  responseData: string,\n  baseUrl?: string,\n): Promise<Calendar[]> => {\n  const calendars: Calendar[] = [];\n\n  const parser = new XMLParser({\n    removeNSPrefix: true,\n    ignoreAttributes: false,\n    attributeNamePrefix: \"\",\n  });\n\n  const jsonData = parser.parse(responseData);\n  const responses = toArray(jsonData?.multistatus?.response);\n\n  for (const res of responses) {\n    const propstats = toArray(res?.propstat);\n\n    const okPropstat = propstats.find(\n      (p) =>\n        typeof p?.status === \"string\" &&\n        p.status.toLowerCase().includes(\"200 ok\"),\n    );\n    if (!okPropstat) continue;\n\n    const prop = okPropstat.prop;\n    const compArray = toArray(prop?.[\"supported-calendar-component-set\"]?.comp);\n\n    const supportedComponents = compArray\n      .map((c) => c.name)\n      .filter((name): name is SupportedComponent =>\n        [\n          \"VEVENT\",\n          \"VTODO\",\n          \"VJOURNAL\",\n          \"VFREEBUSY\",\n          \"VTIMEZONE\",\n          \"VAVAILABILITY\",\n        ].includes(name),\n      );\n\n    if (\n      !supportedComponents.includes(\"VEVENT\") &&\n      !supportedComponents.includes(\"VTODO\")\n    )\n      continue;\n\n    calendars.push({\n      displayName: prop?.displayname ?? \"\",\n      url: baseUrl ? new URL(res.href, baseUrl).toString() : res.href,\n      ctag: prop?.getctag,\n      supportedComponents,\n      color: prop?.[\"calendar-color\"],\n    });\n  }\n\n  return calendars;\n};\n\nconst KNOWN_EVENT_PROPERTIES = new Set([\n  \"uid\",\n  \"summary\",\n  \"description\",\n  \"location\",\n  \"status\",\n  \"dtstart\",\n  \"dtend\",\n  \"rrule\",\n  \"dtstamp\",\n  \"created\",\n  \"last-modified\",\n  \"sequence\",\n]);\n\nexport const parseEvents = async (\n  responseData: string,\n  baseUrl?: string,\n): Promise<Event[]> => {\n  const events: Event[] = [];\n  const parser = new XMLParser({ removeNSPrefix: true });\n  const jsonData = parser.parse(responseData);\n  let response = jsonData[\"multistatus\"]?.[\"response\"];\n  if (!response) return events;\n\n  if (!Array.isArray(response)) response = [response];\n\n  for (const obj of response) {\n    const eventData = obj[\"propstat\"]?.[\"prop\"];\n    if (!eventData) continue;\n\n    const rawCalendarData = eventData[\"calendar-data\"];\n    if (!rawCalendarData) continue;\n\n    const cleanedCalendarData = rawCalendarData.replace(/&#13;/g, \"\\r\");\n\n    const jcalData = ICAL.parse(cleanedCalendarData);\n    const vcalendar = new ICAL.Component(jcalData);\n\n    const vevents = vcalendar.getAllSubcomponents(\"vevent\");\n    for (const vevent of vevents) {\n      const icalEvent = new ICAL.Event(vevent);\n\n      const dtStartProp = vevent.getFirstProperty(\"dtstart\");\n      const dtEndProp = vevent.getFirstProperty(\"dtend\");\n\n      const isWholeDay = icalEvent.startDate.isDate;\n      const startDate = icalEvent.startDate.toJSDate();\n      const endDate = icalEvent.endDate?.toJSDate() ?? startDate;\n\n      const adjustedEnd = isWholeDay ? new Date(endDate.getTime()) : endDate;\n\n      const startTzid = normalizeParam(dtStartProp?.getParameter(\"tzid\"));\n      const endTzid = normalizeParam(dtEndProp?.getParameter(\"tzid\"));\n\n      const rruleProp = vevent.getFirstProperty(\"rrule\");\n      let recurrenceRule: RecurrenceRule | undefined;\n      if (rruleProp) {\n        const rruleValue = rruleProp.getFirstValue();\n        if (rruleValue) {\n          const recur = ICAL.Recur.fromString(rruleValue.toString());\n          recurrenceRule = parseRecurrence(recur);\n        }\n      }\n\n      const alarms: Alarm[] = [];\n      const valarms = vevent.getAllSubcomponents(\"valarm\") || [];\n\n      for (const valarm of valarms) {\n        const action = valarm.getFirstPropertyValue(\"action\");\n        const trigger = valarm.getFirstPropertyValue(\"trigger\")?.toString();\n\n        if (!action || !trigger) continue;\n\n        if (action === \"DISPLAY\") {\n          alarms.push({\n            action: \"DISPLAY\",\n            trigger,\n            description: valarm\n              .getFirstPropertyValue(\"description\")\n              ?.toString(),\n          });\n        } else if (action === \"EMAIL\") {\n          const attendees =\n            valarm\n              .getAllProperties(\"attendee\")\n              ?.map((p) => p.getFirstValue())\n              .filter((v): v is string => typeof v === \"string\") || [];\n\n          alarms.push({\n            action: \"EMAIL\",\n            trigger,\n            description: valarm\n              .getFirstPropertyValue(\"description\")\n              ?.toString(),\n            summary: valarm.getFirstPropertyValue(\"summary\")?.toString(),\n            attendees,\n          });\n        } else if (action === \"AUDIO\") {\n          alarms.push({ action: \"AUDIO\", trigger });\n        }\n      }\n\n      const rawStatus = vevent.getFirstPropertyValue(\"status\")?.toString();\n      const status = EVENT_STATUSES.includes(rawStatus as EventStatus)\n        ? (rawStatus as EventStatus)\n        : undefined;\n\n      const customFields = generateCustomFields(\n        vevent,\n        KNOWN_EVENT_PROPERTIES,\n      );\n\n      events.push({\n        uid: icalEvent.uid,\n        summary: icalEvent.summary || \"Untitled Event\",\n        start: startDate,\n        end: adjustedEnd,\n        description: icalEvent.description || undefined,\n        location: icalEvent.location || undefined,\n        status: status || undefined,\n        etag: eventData[\"getetag\"] || \"\",\n        href: baseUrl\n          ? new URL(obj[\"href\"], baseUrl).toString()\n          : obj[\"href\"],\n        wholeDay: isWholeDay,\n        recurrenceRule,\n        startTzid,\n        endTzid,\n        alarms,\n        ...(Object.keys(customFields).length > 0 ? { customFields } : {}),\n      });\n    }\n  }\n\n  return events;\n};\n\nconst KNOWN_TODO_PROPERTIES = new Set([\n  \"uid\",\n  \"summary\",\n  \"description\",\n  \"location\",\n  \"status\",\n  \"x-apple-sort-order\",\n  \"dtstart\",\n  \"due\",\n  \"completed\",\n  \"dtstamp\",\n  \"created\",\n  \"last-modified\",\n  \"sequence\",\n]);\n\nexport const parseTodos = async (\n  responseData: string,\n  baseUrl?: string,\n): Promise<Todo[]> => {\n  const todos: Todo[] = [];\n  const parser = new XMLParser({ removeNSPrefix: true });\n  const jsonData = parser.parse(responseData);\n  let response = jsonData[\"multistatus\"]?.[\"response\"];\n  if (!response) return todos;\n\n  if (!Array.isArray(response)) response = [response];\n\n  for (const obj of response) {\n    const todoData = obj[\"propstat\"]?.[\"prop\"];\n    if (!todoData) continue;\n\n    const rawCalendarData = todoData[\"calendar-data\"];\n    if (!rawCalendarData) continue;\n\n    const cleanedCalendarData = rawCalendarData.replace(/&#13;/g, \"\\r\\n\");\n\n    const jcalData = ICAL.parse(cleanedCalendarData);\n    const vcalendar = new ICAL.Component(jcalData);\n\n    const vtodos = vcalendar.getAllSubcomponents(\"vtodo\");\n    for (const vtodo of vtodos) {\n      const uid = vtodo.getFirstPropertyValue(\"uid\") as string;\n      const summary =\n        (vtodo.getFirstPropertyValue(\"summary\") as string) || \"Untitled Todo\";\n      const description = vtodo.getFirstPropertyValue(\"description\") as\n        | string\n        | undefined;\n      const location = vtodo.getFirstPropertyValue(\"location\") as\n        | string\n        | undefined;\n\n      const rawStatus = vtodo.getFirstPropertyValue(\"status\") as\n        | string\n        | undefined;\n      const status = TODO_STATUSES.includes(rawStatus as TodoStatus)\n        ? (rawStatus as TodoStatus)\n        : undefined;\n\n      const sortOrderRaw = vtodo.getFirstPropertyValue(\n        \"x-apple-sort-order\",\n      ) as string | number | null | undefined;\n      const sortOrder =\n        sortOrderRaw !== undefined && sortOrderRaw !== null\n          ? Number(sortOrderRaw)\n          : undefined;\n\n      const dtStartProp = vtodo.getFirstProperty(\"dtstart\");\n      const dueProp = vtodo.getFirstProperty(\"due\");\n      const completedProp = vtodo.getFirstProperty(\"completed\");\n\n      const start = dtStartProp\n        ? (dtStartProp.getFirstValue() as ICAL.Time).toJSDate()\n        : undefined;\n      const due = dueProp\n        ? (dueProp.getFirstValue() as ICAL.Time).toJSDate()\n        : undefined;\n      const completed = completedProp\n        ? (completedProp.getFirstValue() as ICAL.Time).toJSDate()\n        : undefined;\n\n      const alarms: Alarm[] = [];\n      const valarms = vtodo.getAllSubcomponents(\"valarm\") || [];\n\n      for (const valarm of valarms) {\n        const action = valarm.getFirstPropertyValue(\"action\");\n        const trigger = valarm.getFirstPropertyValue(\"trigger\")?.toString();\n\n        if (!action || !trigger) continue;\n\n        if (action === \"DISPLAY\") {\n          alarms.push({\n            action: \"DISPLAY\",\n            trigger,\n            description: valarm\n              .getFirstPropertyValue(\"description\")\n              ?.toString(),\n          });\n        } else if (action === \"EMAIL\") {\n          const attendees =\n            valarm\n              .getAllProperties(\"attendee\")\n              ?.map((p) => p.getFirstValue())\n              .filter((v): v is string => typeof v === \"string\") || [];\n\n          alarms.push({\n            action: \"EMAIL\",\n            trigger,\n            description: valarm\n              .getFirstPropertyValue(\"description\")\n              ?.toString(),\n            summary: valarm.getFirstPropertyValue(\"summary\")?.toString(),\n            attendees,\n          });\n        } else if (action === \"AUDIO\") {\n          alarms.push({ action: \"AUDIO\", trigger });\n        }\n      }\n\n      const customFields = generateCustomFields(vtodo, KNOWN_TODO_PROPERTIES);\n\n      todos.push({\n        uid,\n        summary,\n        start,\n        due,\n        completed,\n        status,\n        description,\n        location,\n        etag: todoData[\"getetag\"] || \"\",\n        href: baseUrl\n          ? new URL(obj[\"href\"], baseUrl).toString()\n          : obj[\"href\"],\n        alarms,\n        sortOrder,\n        ...(Object.keys(customFields).length > 0 ? { customFields } : {}),\n      });\n    }\n  }\n\n  return todos;\n};\n","import { AxiosHeaders } from \"axios\";\n\nexport interface CalDAVOptions {\n  baseUrl: string;\n  auth: AuthOptions;\n  requestTimeout?: number;\n  logRequests?: boolean;\n  prodId?: string;\n  headers?: AxiosHeaders;\n  rejectUnauthorized?: boolean;\n}\n\nexport type AuthOptions =\n  | { type: \"basic\"; username: string; password: string }\n  | { type: \"oauth\"; accessToken: string };\n\nexport type SupportedComponent =\n  | \"VEVENT\"\n  | \"VTODO\"\n  | \"VJOURNAL\"\n  | \"VFREEBUSY\"\n  | \"VTIMEZONE\";\n\nexport type RecurrenceRule = {\n  freq?: \"DAILY\" | \"WEEKLY\" | \"MONTHLY\" | \"YEARLY\";\n  interval?: number;\n  count?: number;\n  until?: Date;\n  wkst?: string;\n  byday?: string[];\n  bymonthday?: number[];\n  bymonth?: number[];\n};\n\nexport type Alarm =\n  | {\n      action: \"DISPLAY\";\n      trigger: string;\n      description?: string;\n    }\n  | {\n      action: \"EMAIL\";\n      trigger: string;\n      description?: string;\n      summary?: string;\n      attendees: string[];\n    }\n  | {\n      action: \"AUDIO\";\n      trigger: string;\n    };\n\nexport interface EventRef {\n  href: string;\n  etag: string;\n}\n\nexport interface SyncChangesResult {\n  changed: boolean;\n  newCtag: string;\n  newEvents: string[];\n  updatedEvents: string[];\n  deletedEvents: string[];\n}\n\nexport interface Calendar {\n  displayName: string;\n  url: string;\n  ctag?: string;\n  supportedComponents: SupportedComponent[];\n  color?: string;\n}\n\nexport const EVENT_STATUSES = [\"TENTATIVE\", \"CONFIRMED\", \"CANCELLED\"] as const;\n\nexport type EventStatus = (typeof EVENT_STATUSES)[number];\n\nexport interface Event {\n  uid: string;\n  summary: string;\n  start: Date;\n  end: Date;\n  description?: string;\n  location?: string;\n  status?: EventStatus;\n  etag: string;\n  href: string;\n  wholeDay?: boolean;\n  recurrenceRule?: RecurrenceRule;\n  startTzid?: string;\n  endTzid?: string;\n  alarms?: Alarm[];\n  customFields?: Record<string, string | string[]>;\n}\n\nexport type TodoRef = EventRef;\n\nexport interface VTimezone {\n  tzid: string;\n  raw: string;\n}\n\nexport interface SyncTodosResult {\n  changed: boolean;\n  newCtag: string;\n  newTodos: string[];\n  updatedTodos: string[];\n  deletedTodos: string[];\n}\n\nexport const TODO_STATUSES = [\n  \"NEEDS-ACTION\",\n  \"COMPLETED\",\n  \"IN-PROCESS\",\n  \"CANCELLED\",\n] as const;\n\nexport type TodoStatus = (typeof TODO_STATUSES)[number];\n\nexport interface Todo {\n  uid: string;\n  summary: string;\n  start?: Date;\n  due?: Date;\n  completed?: Date;\n  status?: TodoStatus;\n  description?: string;\n  location?: string;\n  etag?: string;\n  href: string;\n  alarms?: Alarm[];\n  sortOrder?: number;\n  customFields?: Record<string, string | string[]>;\n}\n\nexport interface CalDAVClientCache {\n  userPrincipal: string;\n  calendarHome: string;\n  prodId?: string;\n}\n","export const normalizeSlashEnd = (u: string) => {\n  return u.endsWith(\"/\") ? u.slice(0, -1) : u;\n};\n\nexport const first = <T>(val: T | T[] | undefined): T | undefined => {\n  return Array.isArray(val) ? val[0] : val;\n};\n","export class CalDAVError extends Error {\n  constructor(\n    message: string,\n    public readonly status?: number,\n    options?: ErrorOptions,\n  ) {\n    super(message, options);\n    this.name = \"CalDAVError\";\n  }\n}\n"],"mappings":"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","names":["XMLParser","ICAL","XMLParser","ICAL"]}