1 | import { UnavailabilityError } from '@unimodules/core';
|
2 | import { Platform, processColor } from 'react-native';
|
3 | import { PermissionResponse, PermissionStatus } from 'unimodules-permissions-interface';
|
4 |
|
5 | import ExpoCalendar from './ExpoCalendar';
|
6 |
|
7 | export type RecurringEventOptions = {
|
8 | futureEvents?: boolean;
|
9 | instanceStartDate?: string | Date;
|
10 | };
|
11 |
|
12 | export interface Calendar {
|
13 | id: string;
|
14 | title: string;
|
15 | sourceId?: string;
|
16 | source: Source;
|
17 | type?: string;
|
18 | color: string;
|
19 | entityType?: string;
|
20 | allowsModifications: boolean;
|
21 | allowedAvailabilities: string[];
|
22 | isPrimary?: boolean;
|
23 | name?: string | null;
|
24 | ownerAccount?: string;
|
25 | timeZone?: string;
|
26 | allowedReminders?: string[];
|
27 | allowedAttendeeTypes?: string[];
|
28 | isVisible?: boolean;
|
29 | isSynced?: boolean;
|
30 | accessLevel?: string;
|
31 | }
|
32 |
|
33 | export type Source = {
|
34 | id?: string;
|
35 | type: string;
|
36 | name: string;
|
37 | isLocalAccount?: boolean;
|
38 | };
|
39 |
|
40 | export type Event = {
|
41 | id: string;
|
42 | calendarId: string;
|
43 | title: string;
|
44 | location: string;
|
45 | creationDate?: string | Date;
|
46 | lastModifiedDate?: string | Date;
|
47 | timeZone: string;
|
48 | endTimeZone?: string;
|
49 | url?: string;
|
50 | notes: string;
|
51 | alarms: Alarm[];
|
52 | recurrenceRule: RecurrenceRule;
|
53 | startDate: string | Date;
|
54 | endDate: string | Date;
|
55 | originalStartDate?: string | Date;
|
56 | isDetached?: boolean;
|
57 | allDay: boolean;
|
58 | availability: string;
|
59 | status: string;
|
60 | organizer?: string;
|
61 | organizerEmail?: string;
|
62 | accessLevel?: string;
|
63 | guestsCanModify?: boolean;
|
64 | guestsCanInviteOthers?: boolean;
|
65 | guestsCanSeeGuests?: boolean;
|
66 | originalId?: string;
|
67 | instanceId?: string;
|
68 | };
|
69 |
|
70 | export interface Reminder {
|
71 | id?: string;
|
72 | calendarId?: string;
|
73 | title?: string;
|
74 | location?: string;
|
75 | creationDate?: string | Date;
|
76 | lastModifiedDate?: string | Date;
|
77 | timeZone?: string;
|
78 | url?: string;
|
79 | notes?: string;
|
80 | alarms?: Alarm[];
|
81 | recurrenceRule?: RecurrenceRule;
|
82 | startDate?: string | Date;
|
83 | dueDate?: string | Date;
|
84 | completed?: boolean;
|
85 | completionDate?: string | Date;
|
86 | }
|
87 |
|
88 | export type Attendee = {
|
89 | id?: string;
|
90 | isCurrentUser?: boolean;
|
91 | name: string;
|
92 | role: string;
|
93 | status: string;
|
94 | type: string;
|
95 | url?: string;
|
96 | email?: string;
|
97 | };
|
98 |
|
99 | export type Alarm = {
|
100 | absoluteDate?: string;
|
101 | relativeOffset?: number;
|
102 | structuredLocation?: {
|
103 |
|
104 | title?: string;
|
105 | proximity?: string;
|
106 | radius?: number;
|
107 | coords?: {
|
108 | latitude?: number;
|
109 | longitude?: number;
|
110 | };
|
111 | };
|
112 | method?: string;
|
113 | };
|
114 |
|
115 | export enum DayOfTheWeek {
|
116 | Sunday = 1,
|
117 | Monday = 2,
|
118 | Tuesday = 3,
|
119 | Wednesday = 4,
|
120 | Thursday = 5,
|
121 | Friday = 6,
|
122 | Saturday = 7,
|
123 | }
|
124 |
|
125 | export enum MonthOfTheYear {
|
126 | January = 1,
|
127 | February = 2,
|
128 | March = 3,
|
129 | April = 4,
|
130 | May = 5,
|
131 | June = 6,
|
132 | July = 7,
|
133 | August = 8,
|
134 | September = 9,
|
135 | October = 10,
|
136 | November = 11,
|
137 | December = 12,
|
138 | }
|
139 |
|
140 | export type RecurrenceRule = {
|
141 | frequency: string;
|
142 | interval?: number;
|
143 | endDate?: string | Date;
|
144 | occurrence?: number;
|
145 |
|
146 | daysOfTheWeek?: { dayOfTheWeek: DayOfTheWeek; weekNumber?: number }[];
|
147 | daysOfTheMonth?: number[];
|
148 | monthsOfTheYear?: MonthOfTheYear[];
|
149 | weeksOfTheYear?: number[];
|
150 | daysOfTheYear?: number[];
|
151 | setPositions?: number[];
|
152 | };
|
153 |
|
154 | export { PermissionResponse, PermissionStatus };
|
155 |
|
156 | type OptionalKeys<T> = {
|
157 | [P in keyof T]?: T[P] | null;
|
158 | };
|
159 |
|
160 |
|
161 |
|
162 |
|
163 |
|
164 |
|
165 | export async function isAvailableAsync(): Promise<boolean> {
|
166 | return !!ExpoCalendar.getCalendarsAsync;
|
167 | }
|
168 |
|
169 | export async function getCalendarsAsync(entityType?: string): Promise<Calendar[]> {
|
170 | if (!ExpoCalendar.getCalendarsAsync) {
|
171 | throw new UnavailabilityError('Calendar', 'getCalendarsAsync');
|
172 | }
|
173 | if (!entityType) {
|
174 | return ExpoCalendar.getCalendarsAsync(null);
|
175 | }
|
176 | return ExpoCalendar.getCalendarsAsync(entityType);
|
177 | }
|
178 |
|
179 | export async function createCalendarAsync(details: OptionalKeys<Calendar> = {}): Promise<string> {
|
180 | if (!ExpoCalendar.saveCalendarAsync) {
|
181 | throw new UnavailabilityError('Calendar', 'createCalendarAsync');
|
182 | }
|
183 | const color = details.color ? processColor(details.color) : undefined;
|
184 | const newDetails = { ...details, id: undefined, color };
|
185 | return ExpoCalendar.saveCalendarAsync(newDetails);
|
186 | }
|
187 |
|
188 | export async function updateCalendarAsync(
|
189 | id: string,
|
190 | details: OptionalKeys<Calendar> = {}
|
191 | ): Promise<string> {
|
192 | if (!ExpoCalendar.saveCalendarAsync) {
|
193 | throw new UnavailabilityError('Calendar', 'updateCalendarAsync');
|
194 | }
|
195 | if (!id) {
|
196 | throw new Error(
|
197 | 'updateCalendarAsync must be called with an id (string) of the target calendar'
|
198 | );
|
199 | }
|
200 | const color = details.color ? processColor(details.color) : undefined;
|
201 |
|
202 | if (Platform.OS === 'android') {
|
203 | if (
|
204 | details.hasOwnProperty('source') ||
|
205 | details.hasOwnProperty('color') ||
|
206 | details.hasOwnProperty('allowsModifications') ||
|
207 | details.hasOwnProperty('allowedAvailabilities') ||
|
208 | details.hasOwnProperty('isPrimary') ||
|
209 | details.hasOwnProperty('ownerAccount') ||
|
210 | details.hasOwnProperty('timeZone') ||
|
211 | details.hasOwnProperty('allowedReminders') ||
|
212 | details.hasOwnProperty('allowedAttendeeTypes') ||
|
213 | details.hasOwnProperty('accessLevel')
|
214 | ) {
|
215 | console.warn(
|
216 | 'updateCalendarAsync was called with one or more read-only properties, which will not be updated'
|
217 | );
|
218 | }
|
219 | } else {
|
220 | if (
|
221 | details.hasOwnProperty('source') ||
|
222 | details.hasOwnProperty('type') ||
|
223 | details.hasOwnProperty('entityType') ||
|
224 | details.hasOwnProperty('allowsModifications') ||
|
225 | details.hasOwnProperty('allowedAvailabilities')
|
226 | ) {
|
227 | console.warn(
|
228 | 'updateCalendarAsync was called with one or more read-only properties, which will not be updated'
|
229 | );
|
230 | }
|
231 | }
|
232 |
|
233 | const newDetails = { ...details, id, color };
|
234 | return ExpoCalendar.saveCalendarAsync(newDetails);
|
235 | }
|
236 |
|
237 | export async function deleteCalendarAsync(id: string): Promise<void> {
|
238 | if (!ExpoCalendar.deleteCalendarAsync) {
|
239 | throw new UnavailabilityError('Calendar', 'deleteCalendarAsync');
|
240 | }
|
241 | if (!id) {
|
242 | throw new Error(
|
243 | 'deleteCalendarAsync must be called with an id (string) of the target calendar'
|
244 | );
|
245 | }
|
246 | return ExpoCalendar.deleteCalendarAsync(id);
|
247 | }
|
248 |
|
249 | export async function getEventsAsync(
|
250 | calendarIds: string[],
|
251 | startDate: Date,
|
252 | endDate: Date
|
253 | ): Promise<Event[]> {
|
254 | if (!ExpoCalendar.getEventsAsync) {
|
255 | throw new UnavailabilityError('Calendar', 'getEventsAsync');
|
256 | }
|
257 | if (!startDate) {
|
258 | throw new Error('getEventsAsync must be called with a startDate (date) to search for events');
|
259 | }
|
260 | if (!endDate) {
|
261 | throw new Error('getEventsAsync must be called with an endDate (date) to search for events');
|
262 | }
|
263 | if (!calendarIds || !calendarIds.length) {
|
264 | throw new Error(
|
265 | 'getEventsAsync must be called with a non-empty array of calendarIds to search'
|
266 | );
|
267 | }
|
268 | return ExpoCalendar.getEventsAsync(
|
269 | stringifyIfDate(startDate),
|
270 | stringifyIfDate(endDate),
|
271 | calendarIds
|
272 | );
|
273 | }
|
274 |
|
275 | export async function getEventAsync(
|
276 | id: string,
|
277 | { futureEvents = false, instanceStartDate }: RecurringEventOptions = {}
|
278 | ): Promise<Event> {
|
279 | if (!ExpoCalendar.getEventByIdAsync) {
|
280 | throw new UnavailabilityError('Calendar', 'getEventAsync');
|
281 | }
|
282 | if (!id) {
|
283 | throw new Error('getEventAsync must be called with an id (string) of the target event');
|
284 | }
|
285 | if (Platform.OS === 'ios') {
|
286 | return ExpoCalendar.getEventByIdAsync(id, instanceStartDate);
|
287 | } else {
|
288 | return ExpoCalendar.getEventByIdAsync(id);
|
289 | }
|
290 | }
|
291 |
|
292 | export async function createEventAsync(
|
293 | calendarId: string,
|
294 | { id, ...details }: OptionalKeys<Event> = {}
|
295 | ): Promise<string> {
|
296 | if (!ExpoCalendar.saveEventAsync) {
|
297 | throw new UnavailabilityError('Calendar', 'createEventAsync');
|
298 | }
|
299 | if (!calendarId) {
|
300 | throw new Error('createEventAsync must be called with an id (string) of the target calendar');
|
301 | }
|
302 |
|
303 | if (Platform.OS === 'android') {
|
304 | if (!details.startDate) {
|
305 | throw new Error('createEventAsync requires a startDate (Date)');
|
306 | }
|
307 | if (!details.endDate) {
|
308 | throw new Error('createEventAsync requires an endDate (Date)');
|
309 | }
|
310 | }
|
311 |
|
312 | const newDetails = {
|
313 | ...details,
|
314 | calendarId,
|
315 | };
|
316 |
|
317 | return ExpoCalendar.saveEventAsync(stringifyDateValues(newDetails), {});
|
318 | }
|
319 |
|
320 | export async function updateEventAsync(
|
321 | id: string,
|
322 | details: OptionalKeys<Event> = {},
|
323 | { futureEvents = false, instanceStartDate }: RecurringEventOptions = {}
|
324 | ): Promise<string> {
|
325 | if (!ExpoCalendar.saveEventAsync) {
|
326 | throw new UnavailabilityError('Calendar', 'updateEventAsync');
|
327 | }
|
328 | if (!id) {
|
329 | throw new Error('updateEventAsync must be called with an id (string) of the target event');
|
330 | }
|
331 |
|
332 | if (Platform.OS === 'ios') {
|
333 | if (
|
334 | details.hasOwnProperty('creationDate') ||
|
335 | details.hasOwnProperty('lastModifiedDate') ||
|
336 | details.hasOwnProperty('originalStartDate') ||
|
337 | details.hasOwnProperty('isDetached') ||
|
338 | details.hasOwnProperty('status') ||
|
339 | details.hasOwnProperty('organizer')
|
340 | ) {
|
341 | console.warn(
|
342 | 'updateEventAsync was called with one or more read-only properties, which will not be updated'
|
343 | );
|
344 | }
|
345 | }
|
346 |
|
347 | const newDetails = { ...details, id, instanceStartDate };
|
348 | return ExpoCalendar.saveEventAsync(stringifyDateValues(newDetails), { futureEvents });
|
349 | }
|
350 |
|
351 | export async function deleteEventAsync(
|
352 | id: string,
|
353 | { futureEvents = false, instanceStartDate }: RecurringEventOptions = {}
|
354 | ): Promise<void> {
|
355 | if (!ExpoCalendar.deleteEventAsync) {
|
356 | throw new UnavailabilityError('Calendar', 'deleteEventAsync');
|
357 | }
|
358 | if (!id) {
|
359 | throw new Error('deleteEventAsync must be called with an id (string) of the target event');
|
360 | }
|
361 | return ExpoCalendar.deleteEventAsync({ id, instanceStartDate }, { futureEvents });
|
362 | }
|
363 |
|
364 | export async function getAttendeesForEventAsync(
|
365 | id: string,
|
366 | { futureEvents = false, instanceStartDate }: RecurringEventOptions = {}
|
367 | ): Promise<Attendee[]> {
|
368 | if (!ExpoCalendar.getAttendeesForEventAsync) {
|
369 | throw new UnavailabilityError('Calendar', 'getAttendeesForEventAsync');
|
370 | }
|
371 | if (!id) {
|
372 | throw new Error(
|
373 | 'getAttendeesForEventAsync must be called with an id (string) of the target event'
|
374 | );
|
375 | }
|
376 |
|
377 | const params = Platform.OS === 'ios' ? { id, instanceStartDate } : id;
|
378 | return ExpoCalendar.getAttendeesForEventAsync(params);
|
379 | }
|
380 |
|
381 | export async function createAttendeeAsync(
|
382 | eventId: string,
|
383 | details: OptionalKeys<Attendee> = {}
|
384 | ): Promise<string> {
|
385 | if (!ExpoCalendar.saveAttendeeForEventAsync) {
|
386 | throw new UnavailabilityError('Calendar', 'createAttendeeAsync');
|
387 | }
|
388 | if (!eventId) {
|
389 | throw new Error('createAttendeeAsync must be called with an id (string) of the target event');
|
390 | }
|
391 | if (!details.email) {
|
392 | throw new Error('createAttendeeAsync requires an email (string)');
|
393 | }
|
394 | if (!details.role) {
|
395 | throw new Error('createAttendeeAsync requires a role (string)');
|
396 | }
|
397 | if (!details.type) {
|
398 | throw new Error('createAttendeeAsync requires a type (string)');
|
399 | }
|
400 | if (!details.status) {
|
401 | throw new Error('createAttendeeAsync requires a status (string)');
|
402 | }
|
403 | const newDetails = { ...details, id: undefined };
|
404 | return ExpoCalendar.saveAttendeeForEventAsync(newDetails, eventId);
|
405 | }
|
406 |
|
407 | export async function updateAttendeeAsync(
|
408 | id: string,
|
409 | details: OptionalKeys<Attendee> = {}
|
410 | ): Promise<string> {
|
411 | if (!ExpoCalendar.saveAttendeeForEventAsync) {
|
412 | throw new UnavailabilityError('Calendar', 'updateAttendeeAsync');
|
413 | }
|
414 | if (!id) {
|
415 | throw new Error('updateAttendeeAsync must be called with an id (string) of the target event');
|
416 | }
|
417 | const newDetails = { ...details, id };
|
418 | return ExpoCalendar.saveAttendeeForEventAsync(newDetails, null);
|
419 | }
|
420 |
|
421 | export async function getDefaultCalendarAsync(): Promise<Calendar> {
|
422 | if (!ExpoCalendar.getDefaultCalendarAsync) {
|
423 | throw new UnavailabilityError('Calendar', 'getDefaultCalendarAsync');
|
424 | }
|
425 | return ExpoCalendar.getDefaultCalendarAsync();
|
426 | }
|
427 |
|
428 | export async function deleteAttendeeAsync(id: string): Promise<void> {
|
429 | if (!ExpoCalendar.deleteAttendeeAsync) {
|
430 | throw new UnavailabilityError('Calendar', 'deleteAttendeeAsync');
|
431 | }
|
432 | if (!id) {
|
433 | throw new Error('deleteAttendeeAsync must be called with an id (string) of the target event');
|
434 | }
|
435 | return ExpoCalendar.deleteAttendeeAsync(id);
|
436 | }
|
437 |
|
438 | export async function getRemindersAsync(
|
439 | calendarIds: (string | null)[],
|
440 | status: string | null,
|
441 | startDate: Date,
|
442 | endDate: Date
|
443 | ): Promise<Reminder[]> {
|
444 | if (!ExpoCalendar.getRemindersAsync) {
|
445 | throw new UnavailabilityError('Calendar', 'getRemindersAsync');
|
446 | }
|
447 | if (status && !startDate) {
|
448 | throw new Error(
|
449 | 'getRemindersAsync must be called with a startDate (date) to search for reminders'
|
450 | );
|
451 | }
|
452 | if (status && !endDate) {
|
453 | throw new Error(
|
454 | 'getRemindersAsync must be called with an endDate (date) to search for reminders'
|
455 | );
|
456 | }
|
457 | if (!calendarIds || !calendarIds.length) {
|
458 | throw new Error(
|
459 | 'getRemindersAsync must be called with a non-empty array of calendarIds to search'
|
460 | );
|
461 | }
|
462 | return ExpoCalendar.getRemindersAsync(
|
463 | stringifyIfDate(startDate) || null,
|
464 | stringifyIfDate(endDate) || null,
|
465 | calendarIds,
|
466 | status || null
|
467 | );
|
468 | }
|
469 |
|
470 | export async function getReminderAsync(id: string): Promise<Reminder> {
|
471 | if (!ExpoCalendar.getReminderByIdAsync) {
|
472 | throw new UnavailabilityError('Calendar', 'getReminderAsync');
|
473 | }
|
474 | if (!id) {
|
475 | throw new Error('getReminderAsync must be called with an id (string) of the target reminder');
|
476 | }
|
477 | return ExpoCalendar.getReminderByIdAsync(id);
|
478 | }
|
479 |
|
480 | export async function createReminderAsync(
|
481 | calendarId: string | null,
|
482 | { id, ...details }: Reminder = {}
|
483 | ): Promise<string> {
|
484 | if (!ExpoCalendar.saveReminderAsync) {
|
485 | throw new UnavailabilityError('Calendar', 'createReminderAsync');
|
486 | }
|
487 |
|
488 | const newDetails = {
|
489 | ...details,
|
490 | calendarId: calendarId === null ? undefined : calendarId,
|
491 | };
|
492 | return ExpoCalendar.saveReminderAsync(stringifyDateValues(newDetails));
|
493 | }
|
494 |
|
495 | export async function updateReminderAsync(id: string, details: Reminder = {}): Promise<string> {
|
496 | if (!ExpoCalendar.saveReminderAsync) {
|
497 | throw new UnavailabilityError('Calendar', 'updateReminderAsync');
|
498 | }
|
499 | if (!id) {
|
500 | throw new Error(
|
501 | 'updateReminderAsync must be called with an id (string) of the target reminder'
|
502 | );
|
503 | }
|
504 |
|
505 | if (details.hasOwnProperty('creationDate') || details.hasOwnProperty('lastModifiedDate')) {
|
506 | console.warn(
|
507 | 'updateReminderAsync was called with one or more read-only properties, which will not be updated'
|
508 | );
|
509 | }
|
510 |
|
511 | const newDetails = { ...details, id };
|
512 | return ExpoCalendar.saveReminderAsync(stringifyDateValues(newDetails));
|
513 | }
|
514 |
|
515 | export async function deleteReminderAsync(id: string): Promise<void> {
|
516 | if (!ExpoCalendar.deleteReminderAsync) {
|
517 | throw new UnavailabilityError('Calendar', 'deleteReminderAsync');
|
518 | }
|
519 | if (!id) {
|
520 | throw new Error(
|
521 | 'deleteReminderAsync must be called with an id (string) of the target reminder'
|
522 | );
|
523 | }
|
524 | return ExpoCalendar.deleteReminderAsync(id);
|
525 | }
|
526 |
|
527 | export async function getSourcesAsync(): Promise<Source[]> {
|
528 | if (!ExpoCalendar.getSourcesAsync) {
|
529 | throw new UnavailabilityError('Calendar', 'getSourcesAsync');
|
530 | }
|
531 | return ExpoCalendar.getSourcesAsync();
|
532 | }
|
533 |
|
534 | export async function getSourceAsync(id: string): Promise<Source> {
|
535 | if (!ExpoCalendar.getSourceByIdAsync) {
|
536 | throw new UnavailabilityError('Calendar', 'getSourceAsync');
|
537 | }
|
538 | if (!id) {
|
539 | throw new Error('getSourceAsync must be called with an id (string) of the target source');
|
540 | }
|
541 | return ExpoCalendar.getSourceByIdAsync(id);
|
542 | }
|
543 |
|
544 | export function openEventInCalendar(id: string): void {
|
545 | if (!ExpoCalendar.openEventInCalendar) {
|
546 | console.warn(`openEventInCalendar is not available on platform: ${Platform.OS}`);
|
547 | return;
|
548 | }
|
549 | if (!id) {
|
550 | throw new Error('openEventInCalendar must be called with an id (string) of the target event');
|
551 | }
|
552 | return ExpoCalendar.openEventInCalendar(parseInt(id, 10));
|
553 | }
|
554 |
|
555 |
|
556 |
|
557 |
|
558 | export async function requestPermissionsAsync(): Promise<PermissionResponse> {
|
559 | console.warn(
|
560 | 'requestPermissionsAsync is deprecated. Use requestCalendarPermissionsAsync instead.'
|
561 | );
|
562 | return requestCalendarPermissionsAsync();
|
563 | }
|
564 |
|
565 | export async function getCalendarPermissionsAsync(): Promise<PermissionResponse> {
|
566 | if (!ExpoCalendar.getCalendarPermissionsAsync) {
|
567 | throw new UnavailabilityError('Calendar', 'getCalendarPermissionsAsync');
|
568 | }
|
569 | return ExpoCalendar.getCalendarPermissionsAsync();
|
570 | }
|
571 |
|
572 | export async function getRemindersPermissionsAsync(): Promise<PermissionResponse> {
|
573 | if (!ExpoCalendar.getRemindersPermissionsAsync) {
|
574 | throw new UnavailabilityError('Calendar', 'getRemindersPermissionsAsync');
|
575 | }
|
576 | return ExpoCalendar.getRemindersPermissionsAsync();
|
577 | }
|
578 |
|
579 | export async function requestCalendarPermissionsAsync(): Promise<PermissionResponse> {
|
580 | if (!ExpoCalendar.requestCalendarPermissionsAsync) {
|
581 | throw new UnavailabilityError('Calendar', 'requestCalendarPermissionsAsync');
|
582 | }
|
583 | return await ExpoCalendar.requestCalendarPermissionsAsync();
|
584 | }
|
585 |
|
586 | export async function requestRemindersPermissionsAsync(): Promise<PermissionResponse> {
|
587 | if (!ExpoCalendar.requestRemindersPermissionsAsync) {
|
588 | throw new UnavailabilityError('Calendar', 'requestRemindersPermissionsAsync');
|
589 | }
|
590 | return await ExpoCalendar.requestRemindersPermissionsAsync();
|
591 | }
|
592 |
|
593 | export const EntityTypes = {
|
594 | EVENT: 'event',
|
595 | REMINDER: 'reminder',
|
596 | };
|
597 |
|
598 | export const Frequency = {
|
599 | DAILY: 'daily',
|
600 | WEEKLY: 'weekly',
|
601 | MONTHLY: 'monthly',
|
602 | YEARLY: 'yearly',
|
603 | };
|
604 |
|
605 | export const Availability = {
|
606 | NOT_SUPPORTED: 'notSupported',
|
607 | BUSY: 'busy',
|
608 | FREE: 'free',
|
609 | TENTATIVE: 'tentative',
|
610 | UNAVAILABLE: 'unavailable',
|
611 | };
|
612 |
|
613 | export const CalendarType = {
|
614 | LOCAL: 'local',
|
615 | CALDAV: 'caldav',
|
616 | EXCHANGE: 'exchange',
|
617 | SUBSCRIBED: 'subscribed',
|
618 | BIRTHDAYS: 'birthdays',
|
619 | UNKNOWN: 'unknown',
|
620 | };
|
621 |
|
622 | export const EventStatus = {
|
623 | NONE: 'none',
|
624 | CONFIRMED: 'confirmed',
|
625 | TENTATIVE: 'tentative',
|
626 | CANCELED: 'canceled',
|
627 | };
|
628 |
|
629 | export const SourceType = {
|
630 | LOCAL: 'local',
|
631 | EXCHANGE: 'exchange',
|
632 | CALDAV: 'caldav',
|
633 | MOBILEME: 'mobileme',
|
634 | SUBSCRIBED: 'subscribed',
|
635 | BIRTHDAYS: 'birthdays',
|
636 | };
|
637 |
|
638 | export const AttendeeRole = {
|
639 | UNKNOWN: 'unknown',
|
640 | REQUIRED: 'required',
|
641 | OPTIONAL: 'optional',
|
642 | CHAIR: 'chair',
|
643 | NON_PARTICIPANT: 'nonParticipant',
|
644 | ATTENDEE: 'attendee',
|
645 | ORGANIZER: 'organizer',
|
646 | PERFORMER: 'performer',
|
647 | SPEAKER: 'speaker',
|
648 | NONE: 'none',
|
649 | };
|
650 |
|
651 | export const AttendeeStatus = {
|
652 | UNKNOWN: 'unknown',
|
653 | PENDING: 'pending',
|
654 | ACCEPTED: 'accepted',
|
655 | DECLINED: 'declined',
|
656 | TENTATIVE: 'tentative',
|
657 | DELEGATED: 'delegated',
|
658 | COMPLETED: 'completed',
|
659 | IN_PROCESS: 'inProcess',
|
660 | INVITED: 'invited',
|
661 | NONE: 'none',
|
662 | };
|
663 |
|
664 | export const AttendeeType = {
|
665 | UNKNOWN: 'unknown',
|
666 | PERSON: 'person',
|
667 | ROOM: 'room',
|
668 | GROUP: 'group',
|
669 | RESOURCE: 'resource',
|
670 | OPTIONAL: 'optional',
|
671 | REQUIRED: 'required',
|
672 | NONE: 'none',
|
673 | };
|
674 |
|
675 | export const AlarmMethod = {
|
676 | ALARM: 'alarm',
|
677 | ALERT: 'alert',
|
678 | EMAIL: 'email',
|
679 | SMS: 'sms',
|
680 | DEFAULT: 'default',
|
681 | };
|
682 |
|
683 | export const EventAccessLevel = {
|
684 | CONFIDENTIAL: 'confidential',
|
685 | PRIVATE: 'private',
|
686 | PUBLIC: 'public',
|
687 | DEFAULT: 'default',
|
688 | };
|
689 |
|
690 | export const CalendarAccessLevel = {
|
691 | CONTRIBUTOR: 'contributor',
|
692 | EDITOR: 'editor',
|
693 | FREEBUSY: 'freebusy',
|
694 | OVERRIDE: 'override',
|
695 | OWNER: 'owner',
|
696 | READ: 'read',
|
697 | RESPOND: 'respond',
|
698 | ROOT: 'root',
|
699 | NONE: 'none',
|
700 | };
|
701 |
|
702 | export const ReminderStatus = {
|
703 | COMPLETED: 'completed',
|
704 | INCOMPLETE: 'incomplete',
|
705 | };
|
706 |
|
707 | function stringifyIfDate(date: any): any {
|
708 | return date instanceof Date ? date.toISOString() : date;
|
709 | }
|
710 |
|
711 | function stringifyDateValues(obj: object): object {
|
712 | return Object.keys(obj).reduce((acc, key) => {
|
713 | const value = obj[key];
|
714 | if (value != null && typeof value === 'object' && !(value instanceof Date)) {
|
715 | if (Array.isArray(value)) {
|
716 | return { ...acc, [key]: value.map(stringifyDateValues) };
|
717 | }
|
718 | return { ...acc, [key]: stringifyDateValues(value) };
|
719 | }
|
720 | acc[key] = stringifyIfDate(value);
|
721 | return acc;
|
722 | }, {});
|
723 | }
|