329 lines
13 KiB
TypeScript
329 lines
13 KiB
TypeScript
import { apiFetch, type ApiSettings } from "@govoplan/core-webui";
|
|
|
|
export type CalendarCollection = {
|
|
id: string;
|
|
tenant_id: string;
|
|
slug: string;
|
|
name: string;
|
|
description?: string | null;
|
|
timezone: string;
|
|
color?: string | null;
|
|
owner_type: string;
|
|
owner_id?: string | null;
|
|
visibility: string;
|
|
is_default: boolean;
|
|
created_at: string;
|
|
updated_at: string;
|
|
metadata?: Record<string, unknown> | null;
|
|
};
|
|
|
|
export type CalendarEvent = {
|
|
id: string;
|
|
tenant_id: string;
|
|
calendar_id: string;
|
|
uid: string;
|
|
recurrence_id?: string | null;
|
|
sequence: number;
|
|
summary: string;
|
|
description?: string | null;
|
|
location?: string | null;
|
|
status: string;
|
|
transparency: string;
|
|
classification: string;
|
|
start_at: string;
|
|
end_at?: string | null;
|
|
duration_seconds?: number | null;
|
|
all_day: boolean;
|
|
timezone?: string | null;
|
|
organizer?: Record<string, unknown> | null;
|
|
attendees: Record<string, unknown>[];
|
|
categories: string[];
|
|
rrule?: Record<string, unknown> | null;
|
|
rdate: Record<string, unknown>[];
|
|
exdate: Record<string, unknown>[];
|
|
reminders: Record<string, unknown>[];
|
|
attachments: Record<string, unknown>[];
|
|
related_to: Record<string, unknown>[];
|
|
source_kind: string;
|
|
source_href?: string | null;
|
|
etag?: string | null;
|
|
icalendar: Record<string, unknown>;
|
|
created_at: string;
|
|
updated_at: string;
|
|
metadata?: Record<string, unknown> | null;
|
|
};
|
|
|
|
export type CalendarCollectionListResponse = { calendars: CalendarCollection[] };
|
|
export type CalendarEventListResponse = { events: CalendarEvent[] };
|
|
export type CalendarDeltaDeletedItem = { id: string; resource_type?: string | null; revision?: string | null; deleted_at?: string | null };
|
|
export type CalendarEventDeltaResponse = {
|
|
events: CalendarEvent[];
|
|
deleted: CalendarDeltaDeletedItem[];
|
|
watermark?: string | null;
|
|
has_more: boolean;
|
|
full: boolean;
|
|
};
|
|
|
|
export type CalendarCalDavAuthType = "none" | "basic" | "bearer";
|
|
export type CalendarCalDavSyncDirection = "inbound" | "two_way";
|
|
export type CalendarCalDavConflictPolicy = "etag" | "overwrite";
|
|
export type CalendarSyncSourceKind = "caldav" | "ics" | "webcal" | "graph" | "ews";
|
|
|
|
export type CalendarSyncSource = {
|
|
id: string;
|
|
tenant_id: string;
|
|
calendar_id: string;
|
|
source_kind: CalendarSyncSourceKind;
|
|
collection_url: string;
|
|
display_name?: string | null;
|
|
auth_type: CalendarCalDavAuthType;
|
|
username?: string | null;
|
|
credential_ref?: string | null;
|
|
has_credential: boolean;
|
|
sync_enabled: boolean;
|
|
sync_interval_seconds: number;
|
|
sync_direction: CalendarCalDavSyncDirection;
|
|
conflict_policy: CalendarCalDavConflictPolicy;
|
|
sync_token?: string | null;
|
|
ctag?: string | null;
|
|
last_attempt_at?: string | null;
|
|
last_synced_at?: string | null;
|
|
next_sync_at?: string | null;
|
|
last_status?: string | null;
|
|
last_error?: string | null;
|
|
created_at: string;
|
|
updated_at: string;
|
|
metadata?: Record<string, unknown> | null;
|
|
};
|
|
|
|
export type CalendarCalDavSource = CalendarSyncSource;
|
|
export type CalendarSyncSourceListResponse = { sources: CalendarSyncSource[] };
|
|
export type CalendarCalDavSourceListResponse = { sources: CalendarCalDavSource[] };
|
|
|
|
export type CalendarCalDavDiscoveryCandidate = {
|
|
collection_url: string;
|
|
href: string;
|
|
display_name?: string | null;
|
|
color?: string | null;
|
|
ctag?: string | null;
|
|
sync_token?: string | null;
|
|
};
|
|
|
|
export type CalendarCalDavDiscoveryPayload = {
|
|
url: string;
|
|
source_id?: string | null;
|
|
auth_type?: CalendarCalDavAuthType | null;
|
|
username?: string | null;
|
|
credential_ref?: string | null;
|
|
password?: string | null;
|
|
bearer_token?: string | null;
|
|
};
|
|
|
|
export type CalendarCalDavDiscoveryResponse = { calendars: CalendarCalDavDiscoveryCandidate[] };
|
|
|
|
export type CalendarSyncSourceCreatePayload = {
|
|
source_kind?: CalendarSyncSourceKind;
|
|
calendar_id: string;
|
|
collection_url: string;
|
|
display_name?: string | null;
|
|
auth_type?: CalendarCalDavAuthType;
|
|
username?: string | null;
|
|
credential_ref?: string | null;
|
|
password?: string | null;
|
|
bearer_token?: string | null;
|
|
sync_enabled?: boolean;
|
|
sync_interval_seconds?: number;
|
|
sync_direction?: CalendarCalDavSyncDirection;
|
|
conflict_policy?: CalendarCalDavConflictPolicy;
|
|
metadata?: Record<string, unknown>;
|
|
};
|
|
|
|
export type CalendarCalDavSourceCreatePayload = CalendarSyncSourceCreatePayload;
|
|
|
|
export type CalendarCalDavSourceUpdatePayload = Partial<CalendarCalDavSourceCreatePayload>;
|
|
export type CalendarSyncSourceUpdatePayload = Partial<CalendarSyncSourceCreatePayload>;
|
|
|
|
export type CalendarSyncSourceSyncPayload = {
|
|
password?: string | null;
|
|
bearer_token?: string | null;
|
|
force_full?: boolean;
|
|
};
|
|
|
|
export type CalendarCalDavSyncPayload = CalendarSyncSourceSyncPayload;
|
|
|
|
export type CalendarSyncSourceSyncResponse = {
|
|
source: CalendarSyncSource;
|
|
created: number;
|
|
updated: number;
|
|
deleted: number;
|
|
unchanged: number;
|
|
fetched: number;
|
|
full_sync: boolean;
|
|
used_sync_token: boolean;
|
|
sync_token?: string | null;
|
|
ctag?: string | null;
|
|
errors: string[];
|
|
};
|
|
|
|
export type CalendarCalDavSyncResponse = CalendarSyncSourceSyncResponse;
|
|
|
|
export type CalendarCollectionCreatePayload = {
|
|
name: string;
|
|
slug?: string | null;
|
|
description?: string | null;
|
|
timezone?: string;
|
|
color?: string | null;
|
|
owner_type?: "tenant" | "user" | "group" | "resource";
|
|
owner_id?: string | null;
|
|
visibility?: "private" | "tenant" | "shared" | "public";
|
|
is_default?: boolean;
|
|
metadata?: Record<string, unknown>;
|
|
};
|
|
|
|
export type CalendarCollectionUpdatePayload = Partial<CalendarCollectionCreatePayload>;
|
|
export type CalendarDeleteEventAction = "delete" | "move";
|
|
export type CalendarCollectionDeletePayload = {
|
|
event_action?: CalendarDeleteEventAction;
|
|
target_calendar_id?: string | null;
|
|
make_target_default?: boolean;
|
|
};
|
|
|
|
export type CalendarEventCreatePayload = {
|
|
calendar_id?: string | null;
|
|
uid?: string | null;
|
|
recurrence_id?: string | null;
|
|
sequence?: number;
|
|
summary: string;
|
|
description?: string | null;
|
|
location?: string | null;
|
|
status?: string;
|
|
transparency?: string;
|
|
classification?: string;
|
|
start_at: string;
|
|
end_at?: string | null;
|
|
duration_seconds?: number | null;
|
|
all_day?: boolean;
|
|
timezone?: string | null;
|
|
organizer?: Record<string, unknown> | null;
|
|
attendees?: Record<string, unknown>[];
|
|
categories?: string[];
|
|
rrule?: Record<string, unknown> | null;
|
|
rdate?: Record<string, unknown>[];
|
|
exdate?: Record<string, unknown>[];
|
|
reminders?: Record<string, unknown>[];
|
|
attachments?: Record<string, unknown>[];
|
|
related_to?: Record<string, unknown>[];
|
|
source_kind?: string;
|
|
source_href?: string | null;
|
|
etag?: string | null;
|
|
icalendar?: Record<string, unknown>;
|
|
metadata?: Record<string, unknown>;
|
|
};
|
|
|
|
export type CalendarEventUpdatePayload = Partial<CalendarEventCreatePayload>;
|
|
|
|
export function listCalendars(settings: ApiSettings): Promise<CalendarCollectionListResponse> {
|
|
return apiFetch<CalendarCollectionListResponse>(settings, "/api/v1/calendar/calendars");
|
|
}
|
|
|
|
export function createCalendar(settings: ApiSettings, payload: CalendarCollectionCreatePayload): Promise<CalendarCollection> {
|
|
return apiFetch<CalendarCollection>(settings, "/api/v1/calendar/calendars", { method: "POST", body: JSON.stringify(payload) });
|
|
}
|
|
|
|
export function updateCalendar(settings: ApiSettings, calendarId: string, payload: CalendarCollectionUpdatePayload): Promise<CalendarCollection> {
|
|
return apiFetch<CalendarCollection>(settings, `/api/v1/calendar/calendars/${calendarId}`, { method: "PATCH", body: JSON.stringify(payload) });
|
|
}
|
|
|
|
export function deleteCalendar(settings: ApiSettings, calendarId: string, payload: CalendarCollectionDeletePayload = { event_action: "delete" }): Promise<void> {
|
|
return apiFetch<void>(settings, `/api/v1/calendar/calendars/${calendarId}`, { method: "DELETE", body: JSON.stringify(payload) });
|
|
}
|
|
|
|
export function listSyncSources(settings: ApiSettings, params: { calendar_id?: string; source_kind?: CalendarSyncSourceKind } = {}): Promise<CalendarSyncSourceListResponse> {
|
|
const search = new URLSearchParams();
|
|
if (params.calendar_id) search.set("calendar_id", params.calendar_id);
|
|
if (params.source_kind) search.set("source_kind", params.source_kind);
|
|
const suffix = search.toString() ? `?${search.toString()}` : "";
|
|
return apiFetch<CalendarSyncSourceListResponse>(settings, `/api/v1/calendar/sync-sources${suffix}`);
|
|
}
|
|
|
|
export function listCalDavSources(settings: ApiSettings, params: { calendar_id?: string } = {}): Promise<CalendarCalDavSourceListResponse> {
|
|
const search = new URLSearchParams();
|
|
if (params.calendar_id) search.set("calendar_id", params.calendar_id);
|
|
const suffix = search.toString() ? `?${search.toString()}` : "";
|
|
return apiFetch<CalendarCalDavSourceListResponse>(settings, `/api/v1/calendar/caldav/sources${suffix}`);
|
|
}
|
|
|
|
export function discoverCalDavCalendars(settings: ApiSettings, payload: CalendarCalDavDiscoveryPayload): Promise<CalendarCalDavDiscoveryResponse> {
|
|
return apiFetch<CalendarCalDavDiscoveryResponse>(settings, "/api/v1/calendar/caldav/discover", { method: "POST", body: JSON.stringify(payload) });
|
|
}
|
|
|
|
export function createSyncSource(settings: ApiSettings, payload: CalendarSyncSourceCreatePayload): Promise<CalendarSyncSource> {
|
|
return apiFetch<CalendarSyncSource>(settings, "/api/v1/calendar/sync-sources", { method: "POST", body: JSON.stringify(payload) });
|
|
}
|
|
|
|
export function createCalDavSource(settings: ApiSettings, payload: CalendarCalDavSourceCreatePayload): Promise<CalendarCalDavSource> {
|
|
return apiFetch<CalendarCalDavSource>(settings, "/api/v1/calendar/caldav/sources", { method: "POST", body: JSON.stringify(payload) });
|
|
}
|
|
|
|
export function updateSyncSource(settings: ApiSettings, sourceId: string, payload: CalendarSyncSourceUpdatePayload): Promise<CalendarSyncSource> {
|
|
return apiFetch<CalendarSyncSource>(settings, `/api/v1/calendar/sync-sources/${sourceId}`, { method: "PATCH", body: JSON.stringify(payload) });
|
|
}
|
|
|
|
export function updateCalDavSource(settings: ApiSettings, sourceId: string, payload: CalendarCalDavSourceUpdatePayload): Promise<CalendarCalDavSource> {
|
|
return apiFetch<CalendarCalDavSource>(settings, `/api/v1/calendar/caldav/sources/${sourceId}`, { method: "PATCH", body: JSON.stringify(payload) });
|
|
}
|
|
|
|
export function deleteSyncSource(settings: ApiSettings, sourceId: string): Promise<void> {
|
|
return apiFetch<void>(settings, `/api/v1/calendar/sync-sources/${sourceId}`, { method: "DELETE" });
|
|
}
|
|
|
|
export function deleteCalDavSource(settings: ApiSettings, sourceId: string): Promise<void> {
|
|
return apiFetch<void>(settings, `/api/v1/calendar/caldav/sources/${sourceId}`, { method: "DELETE" });
|
|
}
|
|
|
|
export function syncSyncSource(settings: ApiSettings, sourceId: string, payload: CalendarSyncSourceSyncPayload = {}): Promise<CalendarSyncSourceSyncResponse> {
|
|
return apiFetch<CalendarSyncSourceSyncResponse>(settings, `/api/v1/calendar/sync-sources/${sourceId}/sync`, { method: "POST", body: JSON.stringify(payload) });
|
|
}
|
|
|
|
export function syncCalDavSource(settings: ApiSettings, sourceId: string, payload: CalendarCalDavSyncPayload = {}): Promise<CalendarCalDavSyncResponse> {
|
|
return apiFetch<CalendarCalDavSyncResponse>(settings, `/api/v1/calendar/caldav/sources/${sourceId}/sync`, { method: "POST", body: JSON.stringify(payload) });
|
|
}
|
|
|
|
export function listCalendarEvents(
|
|
settings: ApiSettings,
|
|
params: { calendar_id?: string; start_at?: string; end_at?: string } = {}
|
|
): Promise<CalendarEventListResponse> {
|
|
const search = new URLSearchParams();
|
|
if (params.calendar_id) search.set("calendar_id", params.calendar_id);
|
|
if (params.start_at) search.set("start_at", params.start_at);
|
|
if (params.end_at) search.set("end_at", params.end_at);
|
|
const suffix = search.toString() ? `?${search.toString()}` : "";
|
|
return apiFetch<CalendarEventListResponse>(settings, `/api/v1/calendar/events${suffix}`);
|
|
}
|
|
|
|
export function listCalendarEventsDelta(
|
|
settings: ApiSettings,
|
|
params: { calendar_id?: string; start_at?: string; end_at?: string; since?: string | null; limit?: number } = {}
|
|
): Promise<CalendarEventDeltaResponse> {
|
|
const search = new URLSearchParams();
|
|
if (params.calendar_id) search.set("calendar_id", params.calendar_id);
|
|
if (params.start_at) search.set("start_at", params.start_at);
|
|
if (params.end_at) search.set("end_at", params.end_at);
|
|
if (params.since) search.set("since", params.since);
|
|
if (params.limit) search.set("limit", String(params.limit));
|
|
const suffix = search.toString() ? `?${search.toString()}` : "";
|
|
return apiFetch<CalendarEventDeltaResponse>(settings, `/api/v1/calendar/events/delta${suffix}`);
|
|
}
|
|
|
|
export function createCalendarEvent(settings: ApiSettings, payload: CalendarEventCreatePayload): Promise<CalendarEvent> {
|
|
return apiFetch<CalendarEvent>(settings, "/api/v1/calendar/events", { method: "POST", body: JSON.stringify(payload) });
|
|
}
|
|
|
|
export function updateCalendarEvent(settings: ApiSettings, eventId: string, payload: CalendarEventUpdatePayload): Promise<CalendarEvent> {
|
|
return apiFetch<CalendarEvent>(settings, `/api/v1/calendar/events/${eventId}`, { method: "PATCH", body: JSON.stringify(payload) });
|
|
}
|
|
|
|
export function deleteCalendarEvent(settings: ApiSettings, eventId: string): Promise<void> {
|
|
return apiFetch<void>(settings, `/api/v1/calendar/events/${eventId}`, { method: "DELETE" });
|
|
}
|