@symbiote-native/calendar 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +189 -0
- package/build/angular/index.d.ts +3 -0
- package/build/angular/index.js +3 -0
- package/build/angular/services/calendar-permissions.service/index.d.ts +5 -0
- package/build/angular/services/calendar-permissions.service/index.js +60 -0
- package/build/angular/services/reminders-permissions.service/index.d.ts +5 -0
- package/build/angular/services/reminders-permissions.service/index.js +60 -0
- package/build/core/attendee.d.ts +9 -0
- package/build/core/attendee.js +28 -0
- package/build/core/calendar-permission-api.d.ts +9 -0
- package/build/core/calendar-permission-api.js +9 -0
- package/build/core/calendar.d.ts +34 -0
- package/build/core/calendar.js +118 -0
- package/build/core/enums.d.ts +141 -0
- package/build/core/enums.js +157 -0
- package/build/core/event.d.ts +14 -0
- package/build/core/event.js +40 -0
- package/build/core/index.d.ts +6 -0
- package/build/core/index.js +6 -0
- package/build/core/native-module.d.ts +154 -0
- package/build/core/native-module.js +3 -0
- package/build/core/reminder.d.ts +10 -0
- package/build/core/reminder.js +34 -0
- package/build/core/types.d.ts +184 -0
- package/build/core/types.js +1 -0
- package/build/core/utils.d.ts +7 -0
- package/build/core/utils.js +29 -0
- package/build/legacy/calendar.d.ts +23 -0
- package/build/legacy/calendar.js +261 -0
- package/build/legacy/enums.d.ts +1 -0
- package/build/legacy/enums.js +2 -0
- package/build/legacy/index.d.ts +5 -0
- package/build/legacy/index.js +5 -0
- package/build/legacy/native-module.d.ts +39 -0
- package/build/legacy/native-module.js +3 -0
- package/build/legacy/permissions.d.ts +9 -0
- package/build/legacy/permissions.js +33 -0
- package/build/legacy/reminders.d.ts +6 -0
- package/build/legacy/reminders.js +56 -0
- package/build/legacy/types.d.ts +147 -0
- package/build/legacy/types.js +1 -0
- package/build/react/index.d.ts +3 -0
- package/build/react/index.js +3 -0
- package/build/react/use-calendar-permissions.d.ts +10 -0
- package/build/react/use-calendar-permissions.js +7 -0
- package/build/react/use-reminders-permissions.d.ts +8 -0
- package/build/react/use-reminders-permissions.js +10 -0
- package/build/solid/index.d.ts +3 -0
- package/build/solid/index.js +3 -0
- package/build/solid/use-calendar-permissions.d.ts +11 -0
- package/build/solid/use-calendar-permissions.js +7 -0
- package/build/solid/use-reminders-permissions.d.ts +9 -0
- package/build/solid/use-reminders-permissions.js +10 -0
- package/build/svelte/index.d.ts +3 -0
- package/build/svelte/index.js +3 -0
- package/build/svelte/use-calendar-permissions.svelte.d.ts +10 -0
- package/build/svelte/use-calendar-permissions.svelte.js +7 -0
- package/build/svelte/use-reminders-permissions.svelte.d.ts +8 -0
- package/build/svelte/use-reminders-permissions.svelte.js +10 -0
- package/build/vue/index.d.ts +3 -0
- package/build/vue/index.js +3 -0
- package/build/vue/use-calendar-permissions.d.ts +11 -0
- package/build/vue/use-calendar-permissions.js +7 -0
- package/build/vue/use-reminders-permissions.d.ts +9 -0
- package/build/vue/use-reminders-permissions.js +10 -0
- package/build-ngc/angular/index.d.ts +3 -0
- package/build-ngc/angular/index.js +4 -0
- package/build-ngc/angular/index.js.map +1 -0
- package/build-ngc/angular/services/calendar-permissions.service/index.d.ts +8 -0
- package/build-ngc/angular/services/calendar-permissions.service/index.js +17 -0
- package/build-ngc/angular/services/calendar-permissions.service/index.js.map +1 -0
- package/build-ngc/angular/services/reminders-permissions.service/index.d.ts +8 -0
- package/build-ngc/angular/services/reminders-permissions.service/index.js +17 -0
- package/build-ngc/angular/services/reminders-permissions.service/index.js.map +1 -0
- package/build-ngc/core/attendee.d.ts +9 -0
- package/build-ngc/core/attendee.js +29 -0
- package/build-ngc/core/attendee.js.map +1 -0
- package/build-ngc/core/calendar-permission-api.d.ts +9 -0
- package/build-ngc/core/calendar-permission-api.js +10 -0
- package/build-ngc/core/calendar-permission-api.js.map +1 -0
- package/build-ngc/core/calendar.d.ts +34 -0
- package/build-ngc/core/calendar.js +119 -0
- package/build-ngc/core/calendar.js.map +1 -0
- package/build-ngc/core/enums.d.ts +141 -0
- package/build-ngc/core/enums.js +158 -0
- package/build-ngc/core/enums.js.map +1 -0
- package/build-ngc/core/event.d.ts +14 -0
- package/build-ngc/core/event.js +41 -0
- package/build-ngc/core/event.js.map +1 -0
- package/build-ngc/core/index.d.ts +6 -0
- package/build-ngc/core/index.js +7 -0
- package/build-ngc/core/index.js.map +1 -0
- package/build-ngc/core/native-module.d.ts +154 -0
- package/build-ngc/core/native-module.js +4 -0
- package/build-ngc/core/native-module.js.map +1 -0
- package/build-ngc/core/reminder.d.ts +10 -0
- package/build-ngc/core/reminder.js +35 -0
- package/build-ngc/core/reminder.js.map +1 -0
- package/build-ngc/core/types.d.ts +184 -0
- package/build-ngc/core/types.js +2 -0
- package/build-ngc/core/types.js.map +1 -0
- package/build-ngc/core/utils.d.ts +7 -0
- package/build-ngc/core/utils.js +30 -0
- package/build-ngc/core/utils.js.map +1 -0
- package/native-link.json +29 -0
- package/package.json +155 -0
- package/src/angular/index.ts +3 -0
- package/src/angular/services/calendar-permissions.service/index.ts +19 -0
- package/src/angular/services/reminders-permissions.service/index.ts +16 -0
- package/src/core/attendee.ts +43 -0
- package/src/core/calendar-permission-api.ts +16 -0
- package/src/core/calendar.ts +197 -0
- package/src/core/enums.ts +156 -0
- package/src/core/event.ts +70 -0
- package/src/core/index.ts +18 -0
- package/src/core/native-module.ts +212 -0
- package/src/core/reminder.ts +52 -0
- package/src/core/types.ts +209 -0
- package/src/core/utils.ts +39 -0
- package/src/legacy/calendar.ts +401 -0
- package/src/legacy/enums.ts +2 -0
- package/src/legacy/index.ts +5 -0
- package/src/legacy/native-module.ts +77 -0
- package/src/legacy/permissions.ts +47 -0
- package/src/legacy/reminders.ts +98 -0
- package/src/legacy/types.ts +183 -0
- package/src/react/index.ts +3 -0
- package/src/react/use-calendar-permissions.ts +25 -0
- package/src/react/use-reminders-permissions.ts +25 -0
- package/src/solid/index.ts +3 -0
- package/src/solid/use-calendar-permissions.ts +26 -0
- package/src/solid/use-reminders-permissions.ts +26 -0
- package/src/svelte/index.ts +3 -0
- package/src/svelte/svelte-ambient.d.ts +3 -0
- package/src/svelte/svelte-compile.test-helper.ts +7 -0
- package/src/svelte/use-calendar-permissions.svelte.ts +25 -0
- package/src/svelte/use-reminders-permissions.svelte.ts +25 -0
- package/src/vue/index.ts +3 -0
- package/src/vue/use-calendar-permissions.ts +26 -0
- package/src/vue/use-reminders-permissions.ts +26 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import type { AlarmMethod, AttendeeRole, AttendeeStatus, AttendeeType, CalendarAccessLevel, CalendarDialogResultActions, DayOfTheWeek, Frequency, MonthOfTheYear } from './enums';
|
|
2
|
+
export type ISource = {
|
|
3
|
+
id?: string;
|
|
4
|
+
type?: string;
|
|
5
|
+
name?: string;
|
|
6
|
+
isLocalAccount?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type IDaysOfTheWeek = {
|
|
9
|
+
dayOfTheWeek: DayOfTheWeek;
|
|
10
|
+
/** `-53` to `53`; `0` ignores this field. */
|
|
11
|
+
weekNumber?: number;
|
|
12
|
+
};
|
|
13
|
+
export type IRecurrenceRule = {
|
|
14
|
+
frequency: Frequency;
|
|
15
|
+
/** @default 1 */
|
|
16
|
+
interval?: number;
|
|
17
|
+
endDate?: string | Date | null;
|
|
18
|
+
occurrence?: number | null;
|
|
19
|
+
/** @platform ios */
|
|
20
|
+
daysOfTheWeek?: IDaysOfTheWeek[] | null;
|
|
21
|
+
/** @platform ios */
|
|
22
|
+
daysOfTheMonth?: number[] | null;
|
|
23
|
+
/** @platform ios */
|
|
24
|
+
monthsOfTheYear?: MonthOfTheYear[] | null;
|
|
25
|
+
/** @platform ios */
|
|
26
|
+
weeksOfTheYear?: number[] | null;
|
|
27
|
+
/** @platform ios */
|
|
28
|
+
daysOfTheYear?: number[] | null;
|
|
29
|
+
/** @platform ios */
|
|
30
|
+
setPositions?: number[] | null;
|
|
31
|
+
};
|
|
32
|
+
export type IAlarmLocation = {
|
|
33
|
+
title?: string;
|
|
34
|
+
proximity?: string;
|
|
35
|
+
radius?: number;
|
|
36
|
+
coords?: {
|
|
37
|
+
latitude?: number;
|
|
38
|
+
longitude?: number;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
export type IAlarm = {
|
|
42
|
+
/** @platform ios */
|
|
43
|
+
absoluteDate?: string;
|
|
44
|
+
relativeOffset?: number;
|
|
45
|
+
structuredLocation?: IAlarmLocation;
|
|
46
|
+
/** @platform android */
|
|
47
|
+
method?: AlarmMethod;
|
|
48
|
+
};
|
|
49
|
+
/** Fields for `createCalendar()` - all optional, matches upstream's `Partial<Calendar>`. */
|
|
50
|
+
export type ICalendarInput = {
|
|
51
|
+
title?: string;
|
|
52
|
+
/** @platform android */
|
|
53
|
+
name?: string;
|
|
54
|
+
source?: ISource;
|
|
55
|
+
color?: string;
|
|
56
|
+
/** @platform android */
|
|
57
|
+
isVisible?: boolean;
|
|
58
|
+
/** @platform android */
|
|
59
|
+
isSynced?: boolean;
|
|
60
|
+
/** @platform android */
|
|
61
|
+
timeZone?: string;
|
|
62
|
+
/** @platform android */
|
|
63
|
+
isPrimary?: boolean;
|
|
64
|
+
allowedAvailabilities?: string[];
|
|
65
|
+
/** @platform android */
|
|
66
|
+
allowedReminders?: AlarmMethod[];
|
|
67
|
+
/** @platform android */
|
|
68
|
+
allowedAttendeeTypes?: AttendeeType[];
|
|
69
|
+
/** @platform android */
|
|
70
|
+
ownerAccount?: string;
|
|
71
|
+
/** @platform android */
|
|
72
|
+
accessLevel?: CalendarAccessLevel;
|
|
73
|
+
/** @platform ios */
|
|
74
|
+
sourceId?: string;
|
|
75
|
+
};
|
|
76
|
+
/** Fields for `calendar.update()`; a field set to `null` clears it natively. */
|
|
77
|
+
export type ICalendarPatch = {
|
|
78
|
+
title?: string | null;
|
|
79
|
+
/** @platform android */
|
|
80
|
+
name?: string | null;
|
|
81
|
+
color?: string | null;
|
|
82
|
+
/** @platform android */
|
|
83
|
+
isVisible?: boolean | null;
|
|
84
|
+
/** @platform android */
|
|
85
|
+
isSynced?: boolean | null;
|
|
86
|
+
/** @platform android */
|
|
87
|
+
timeZone?: string | null;
|
|
88
|
+
};
|
|
89
|
+
/** Fields for `calendar.createEvent()` - all optional, matches upstream's `Omit<Partial<...>>`. */
|
|
90
|
+
export type IEventInput = {
|
|
91
|
+
startDate?: string | Date;
|
|
92
|
+
endDate?: string | Date;
|
|
93
|
+
title?: string;
|
|
94
|
+
location?: string;
|
|
95
|
+
timeZone?: string;
|
|
96
|
+
/** @platform android */
|
|
97
|
+
endTimeZone?: string;
|
|
98
|
+
notes?: string;
|
|
99
|
+
alarms?: IAlarm[];
|
|
100
|
+
recurrenceRule?: IRecurrenceRule;
|
|
101
|
+
allDay?: boolean;
|
|
102
|
+
availability?: string;
|
|
103
|
+
/** @platform android */
|
|
104
|
+
status?: string;
|
|
105
|
+
/** @platform android */
|
|
106
|
+
organizerEmail?: string;
|
|
107
|
+
/** @platform android */
|
|
108
|
+
accessLevel?: string;
|
|
109
|
+
/** @platform android */
|
|
110
|
+
guestsCanModify?: boolean;
|
|
111
|
+
/** @platform android */
|
|
112
|
+
guestsCanInviteOthers?: boolean;
|
|
113
|
+
/** @platform android */
|
|
114
|
+
guestsCanSeeGuests?: boolean;
|
|
115
|
+
};
|
|
116
|
+
/** Fields for `event.update()`; a field set to `null` clears it natively. */
|
|
117
|
+
export type IEventPatch = Partial<{
|
|
118
|
+
[K in keyof IEventInput]: IEventInput[K] | null;
|
|
119
|
+
}>;
|
|
120
|
+
/** Fields for `event.createAttendee()`. @platform android */
|
|
121
|
+
export type IAttendeeInput = {
|
|
122
|
+
name: string;
|
|
123
|
+
role: AttendeeRole;
|
|
124
|
+
status: AttendeeStatus;
|
|
125
|
+
type: AttendeeType;
|
|
126
|
+
email: string;
|
|
127
|
+
};
|
|
128
|
+
/** Fields for `attendee.update()`. @platform android */
|
|
129
|
+
export type IAttendeePatch = Partial<{
|
|
130
|
+
[K in keyof IAttendeeInput]: IAttendeeInput[K] | null;
|
|
131
|
+
}>;
|
|
132
|
+
/** Fields for `calendar.createReminder()`. @platform ios */
|
|
133
|
+
export type IReminderInput = {
|
|
134
|
+
title?: string;
|
|
135
|
+
location?: string;
|
|
136
|
+
notes?: string;
|
|
137
|
+
startDate?: string | Date;
|
|
138
|
+
dueDate?: string | Date;
|
|
139
|
+
completionDate?: string | Date;
|
|
140
|
+
timeZone?: string;
|
|
141
|
+
alarms?: IAlarm[];
|
|
142
|
+
recurrenceRule?: IRecurrenceRule;
|
|
143
|
+
url?: string;
|
|
144
|
+
allDay?: boolean;
|
|
145
|
+
completed?: boolean;
|
|
146
|
+
};
|
|
147
|
+
/** Fields for `reminder.update()`; a field set to `null` clears it natively. @platform ios */
|
|
148
|
+
export type IReminderPatch = Partial<{
|
|
149
|
+
[K in keyof IReminderInput]: IReminderInput[K] | null;
|
|
150
|
+
}>;
|
|
151
|
+
export type IRecurringEventOptions = {
|
|
152
|
+
/** Applies to `instanceStartDate` and every future occurrence when `true`. */
|
|
153
|
+
futureEvents?: boolean;
|
|
154
|
+
instanceStartDate?: string | Date;
|
|
155
|
+
};
|
|
156
|
+
export type IPresentationOptions = {
|
|
157
|
+
/** `true` resolves `'done'` right after opening. @default true @platform android */
|
|
158
|
+
startNewActivityTask?: boolean;
|
|
159
|
+
};
|
|
160
|
+
export type IOpenEventPresentationOptions = IPresentationOptions & {
|
|
161
|
+
/** @default false @platform ios */
|
|
162
|
+
allowsEditing?: boolean;
|
|
163
|
+
/** @default false @platform ios */
|
|
164
|
+
allowsCalendarPreview?: boolean;
|
|
165
|
+
};
|
|
166
|
+
/** Fields for `calendar.addEventWithForm()`. */
|
|
167
|
+
export type IAddEventWithFormOptions = {
|
|
168
|
+
title?: string;
|
|
169
|
+
location?: string;
|
|
170
|
+
notes?: string;
|
|
171
|
+
url?: string;
|
|
172
|
+
/** @platform android */
|
|
173
|
+
timeZone?: string;
|
|
174
|
+
availability?: string;
|
|
175
|
+
allDay?: boolean;
|
|
176
|
+
startDate?: string | Date;
|
|
177
|
+
endDate?: string | Date;
|
|
178
|
+
recurrenceRule?: IRecurrenceRule;
|
|
179
|
+
alarms?: IAlarm[];
|
|
180
|
+
} & IPresentationOptions;
|
|
181
|
+
export type IDialogEventResult = {
|
|
182
|
+
action: CalendarDialogResultActions;
|
|
183
|
+
id?: string | null;
|
|
184
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function stringifyIfDate(value: Date): string;
|
|
2
|
+
export declare function stringifyIfDate(value: unknown): unknown;
|
|
3
|
+
/** Recursively converts every `Date` field of `obj` to an ISO string for the native bridge. */
|
|
4
|
+
export declare function stringifyDateValues(obj: Record<string, unknown>): Record<string, unknown>;
|
|
5
|
+
/** `null` in a patch means "clear natively" - the native `update()` needs the field named
|
|
6
|
+
* separately, in addition to staying in the stringified record with its `null` value. */
|
|
7
|
+
export declare function getNullableDetailsFields(details: Record<string, unknown>): string[];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export function stringifyIfDate(value) {
|
|
2
|
+
return value instanceof Date ? value.toISOString() : value;
|
|
3
|
+
}
|
|
4
|
+
function isPlainObject(value) {
|
|
5
|
+
return (typeof value === 'object' &&
|
|
6
|
+
value !== null &&
|
|
7
|
+
!Array.isArray(value) &&
|
|
8
|
+
!(value instanceof Date));
|
|
9
|
+
}
|
|
10
|
+
function stringifyValue(value) {
|
|
11
|
+
if (Array.isArray(value))
|
|
12
|
+
return value.map(stringifyValue);
|
|
13
|
+
if (isPlainObject(value))
|
|
14
|
+
return stringifyDateValues(value);
|
|
15
|
+
return stringifyIfDate(value);
|
|
16
|
+
}
|
|
17
|
+
/** Recursively converts every `Date` field of `obj` to an ISO string for the native bridge. */
|
|
18
|
+
export function stringifyDateValues(obj) {
|
|
19
|
+
const result = {};
|
|
20
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
21
|
+
result[key] = stringifyValue(value);
|
|
22
|
+
}
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
/** `null` in a patch means "clear natively" - the native `update()` needs the field named
|
|
26
|
+
* separately, in addition to staying in the stringified record with its `null` value. */
|
|
27
|
+
export function getNullableDetailsFields(details) {
|
|
28
|
+
return Object.keys(details).filter(key => details[key] === null);
|
|
29
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { IAttendee, ICalendar, ICalendarDialogParams, IDialogEventResult, IEvent, IOpenEventDialogResult, IOpenEventPresentationOptions, IPresentationOptions, IRecurringEventOptions, ISource } from './types';
|
|
2
|
+
export declare function createEventInCalendarAsync(eventData?: Omit<Partial<IEvent>, 'id'>, presentationOptions?: IPresentationOptions): Promise<IDialogEventResult>;
|
|
3
|
+
export declare function openEventInCalendarAsync(params: ICalendarDialogParams, presentationOptions?: IOpenEventPresentationOptions): Promise<IOpenEventDialogResult>;
|
|
4
|
+
export declare function editEventInCalendarAsync(params: ICalendarDialogParams, presentationOptions?: IPresentationOptions): Promise<IDialogEventResult>;
|
|
5
|
+
export declare function isAvailableAsync(): Promise<boolean>;
|
|
6
|
+
export declare function getCalendarsAsync(entityType?: string): Promise<ICalendar[]>;
|
|
7
|
+
export declare function createCalendarAsync(details?: Partial<ICalendar>): Promise<string>;
|
|
8
|
+
export declare function updateCalendarAsync(id: string, details?: Partial<ICalendar>): Promise<string>;
|
|
9
|
+
export declare function deleteCalendarAsync(id: string): Promise<void>;
|
|
10
|
+
export declare function getEventsAsync(calendarIds: string[], startDate: Date, endDate: Date): Promise<IEvent[]>;
|
|
11
|
+
export declare function getEventAsync(id: string, recurringEventOptions?: IRecurringEventOptions): Promise<IEvent>;
|
|
12
|
+
export declare function createEventAsync(calendarId: string, eventData?: Omit<Partial<IEvent>, 'id' | 'organizer'>): Promise<string>;
|
|
13
|
+
export declare function updateEventAsync(id: string, details?: Omit<Partial<IEvent>, 'id'>, recurringEventOptions?: IRecurringEventOptions): Promise<string>;
|
|
14
|
+
export declare function deleteEventAsync(id: string, recurringEventOptions?: IRecurringEventOptions): Promise<void>;
|
|
15
|
+
export declare function getAttendeesForEventAsync(id: string, recurringEventOptions?: IRecurringEventOptions): Promise<IAttendee[]>;
|
|
16
|
+
export declare function createAttendeeAsync(eventId: string, details?: Partial<IAttendee>): Promise<string>;
|
|
17
|
+
export declare function updateAttendeeAsync(id: string, details?: Partial<IAttendee>): Promise<string>;
|
|
18
|
+
export declare function deleteAttendeeAsync(id: string): Promise<void>;
|
|
19
|
+
export declare function getDefaultCalendarAsync(): Promise<ICalendar>;
|
|
20
|
+
export declare function getSourcesAsync(): Promise<ISource[]>;
|
|
21
|
+
export declare function getSourceAsync(id: string): Promise<ISource>;
|
|
22
|
+
/** @platform android */
|
|
23
|
+
export declare function openEventInCalendar(id: string): void;
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { Platform, UnavailabilityError } from 'expo-modules-core';
|
|
2
|
+
import { expoCalendar } from './native-module.js';
|
|
3
|
+
import { stringifyDateValues, stringifyIfDate } from '../core/utils.js';
|
|
4
|
+
export async function createEventInCalendarAsync(eventData = {}, presentationOptions) {
|
|
5
|
+
if (!expoCalendar.createEventInCalendarAsync) {
|
|
6
|
+
throw new UnavailabilityError('Calendar', 'createEventInCalendarAsync');
|
|
7
|
+
}
|
|
8
|
+
if ('id' in eventData && eventData.id) {
|
|
9
|
+
console.warn('You attempted to create an event with an id. Event ids are assigned by the system.');
|
|
10
|
+
}
|
|
11
|
+
const params = { ...stringifyDateValues(eventData), ...presentationOptions };
|
|
12
|
+
return expoCalendar.createEventInCalendarAsync(params);
|
|
13
|
+
}
|
|
14
|
+
export async function openEventInCalendarAsync(params, presentationOptions) {
|
|
15
|
+
if (!expoCalendar.openEventInCalendarAsync) {
|
|
16
|
+
throw new UnavailabilityError('Calendar', 'openEventInCalendarAsync');
|
|
17
|
+
}
|
|
18
|
+
if (!params.id) {
|
|
19
|
+
throw new Error('openEventInCalendarAsync must be called with an id (string) of the target event');
|
|
20
|
+
}
|
|
21
|
+
return expoCalendar.openEventInCalendarAsync({
|
|
22
|
+
...params,
|
|
23
|
+
...presentationOptions,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export async function editEventInCalendarAsync(params, presentationOptions) {
|
|
27
|
+
if (!expoCalendar.editEventInCalendarAsync) {
|
|
28
|
+
throw new UnavailabilityError('Calendar', 'editEventInCalendarAsync');
|
|
29
|
+
}
|
|
30
|
+
if (!params.id) {
|
|
31
|
+
throw new Error('editEventInCalendarAsync must be called with an id (string) of the target event');
|
|
32
|
+
}
|
|
33
|
+
return expoCalendar.editEventInCalendarAsync({
|
|
34
|
+
...params,
|
|
35
|
+
...presentationOptions,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export async function isAvailableAsync() {
|
|
39
|
+
return !!expoCalendar.getCalendarsAsync;
|
|
40
|
+
}
|
|
41
|
+
export async function getCalendarsAsync(entityType) {
|
|
42
|
+
if (!expoCalendar.getCalendarsAsync) {
|
|
43
|
+
throw new UnavailabilityError('Calendar', 'getCalendarsAsync');
|
|
44
|
+
}
|
|
45
|
+
return expoCalendar.getCalendarsAsync(entityType ?? null);
|
|
46
|
+
}
|
|
47
|
+
export async function createCalendarAsync(details = {}) {
|
|
48
|
+
if (!expoCalendar.saveCalendarAsync) {
|
|
49
|
+
throw new UnavailabilityError('Calendar', 'createCalendarAsync');
|
|
50
|
+
}
|
|
51
|
+
const newDetails = { ...details, id: undefined };
|
|
52
|
+
return expoCalendar.saveCalendarAsync(stringifyDateValues(newDetails));
|
|
53
|
+
}
|
|
54
|
+
const ANDROID_READ_ONLY_CALENDAR_FIELDS = [
|
|
55
|
+
'source',
|
|
56
|
+
'color',
|
|
57
|
+
'allowsModifications',
|
|
58
|
+
'allowedAvailabilities',
|
|
59
|
+
'isPrimary',
|
|
60
|
+
'ownerAccount',
|
|
61
|
+
'timeZone',
|
|
62
|
+
'allowedReminders',
|
|
63
|
+
'allowedAttendeeTypes',
|
|
64
|
+
'accessLevel',
|
|
65
|
+
];
|
|
66
|
+
const IOS_READ_ONLY_CALENDAR_FIELDS = [
|
|
67
|
+
'source',
|
|
68
|
+
'type',
|
|
69
|
+
'entityType',
|
|
70
|
+
'allowsModifications',
|
|
71
|
+
'allowedAvailabilities',
|
|
72
|
+
];
|
|
73
|
+
export async function updateCalendarAsync(id, details = {}) {
|
|
74
|
+
if (!expoCalendar.saveCalendarAsync) {
|
|
75
|
+
throw new UnavailabilityError('Calendar', 'updateCalendarAsync');
|
|
76
|
+
}
|
|
77
|
+
if (!id) {
|
|
78
|
+
throw new Error('updateCalendarAsync must be called with an id (string) of the target calendar');
|
|
79
|
+
}
|
|
80
|
+
const readOnlyFields = Platform.OS === 'android'
|
|
81
|
+
? ANDROID_READ_ONLY_CALENDAR_FIELDS
|
|
82
|
+
: IOS_READ_ONLY_CALENDAR_FIELDS;
|
|
83
|
+
if (readOnlyFields.some(field => Object.hasOwn(details, field))) {
|
|
84
|
+
console.warn('updateCalendarAsync was called with one or more read-only properties, which will not be updated');
|
|
85
|
+
}
|
|
86
|
+
const newDetails = { ...details, id };
|
|
87
|
+
return expoCalendar.saveCalendarAsync(stringifyDateValues(newDetails));
|
|
88
|
+
}
|
|
89
|
+
export async function deleteCalendarAsync(id) {
|
|
90
|
+
if (!expoCalendar.deleteCalendarAsync) {
|
|
91
|
+
throw new UnavailabilityError('Calendar', 'deleteCalendarAsync');
|
|
92
|
+
}
|
|
93
|
+
if (!id) {
|
|
94
|
+
throw new Error('deleteCalendarAsync must be called with an id (string) of the target calendar');
|
|
95
|
+
}
|
|
96
|
+
return expoCalendar.deleteCalendarAsync(id);
|
|
97
|
+
}
|
|
98
|
+
export async function getEventsAsync(calendarIds, startDate, endDate) {
|
|
99
|
+
if (!expoCalendar.getEventsAsync) {
|
|
100
|
+
throw new UnavailabilityError('Calendar', 'getEventsAsync');
|
|
101
|
+
}
|
|
102
|
+
if (!startDate) {
|
|
103
|
+
throw new Error('getEventsAsync must be called with a startDate (date) to search for events');
|
|
104
|
+
}
|
|
105
|
+
if (!endDate) {
|
|
106
|
+
throw new Error('getEventsAsync must be called with an endDate (date) to search for events');
|
|
107
|
+
}
|
|
108
|
+
if (!calendarIds || !calendarIds.length) {
|
|
109
|
+
throw new Error('getEventsAsync must be called with a non-empty array of calendarIds to search');
|
|
110
|
+
}
|
|
111
|
+
return expoCalendar.getEventsAsync(stringifyIfDate(startDate), stringifyIfDate(endDate), calendarIds);
|
|
112
|
+
}
|
|
113
|
+
export async function getEventAsync(id, recurringEventOptions = {}) {
|
|
114
|
+
if (!expoCalendar.getEventByIdAsync) {
|
|
115
|
+
throw new UnavailabilityError('Calendar', 'getEventAsync');
|
|
116
|
+
}
|
|
117
|
+
if (!id) {
|
|
118
|
+
throw new Error('getEventAsync must be called with an id (string) of the target event');
|
|
119
|
+
}
|
|
120
|
+
if (Platform.OS === 'ios') {
|
|
121
|
+
return expoCalendar.getEventByIdAsync(id, recurringEventOptions.instanceStartDate);
|
|
122
|
+
}
|
|
123
|
+
return expoCalendar.getEventByIdAsync(id);
|
|
124
|
+
}
|
|
125
|
+
export async function createEventAsync(calendarId, eventData = {}) {
|
|
126
|
+
if (!expoCalendar.saveEventAsync) {
|
|
127
|
+
throw new UnavailabilityError('Calendar', 'createEventAsync');
|
|
128
|
+
}
|
|
129
|
+
if (!calendarId) {
|
|
130
|
+
throw new Error('createEventAsync must be called with an id (string) of the target calendar');
|
|
131
|
+
}
|
|
132
|
+
if ('id' in eventData && eventData.id) {
|
|
133
|
+
console.warn('You attempted to create an event with an id. Event ids are assigned by the system.');
|
|
134
|
+
}
|
|
135
|
+
if (Platform.OS === 'android') {
|
|
136
|
+
if (!eventData.startDate) {
|
|
137
|
+
throw new Error('createEventAsync requires a startDate (Date)');
|
|
138
|
+
}
|
|
139
|
+
if (!eventData.endDate) {
|
|
140
|
+
throw new Error('createEventAsync requires an endDate (Date)');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return expoCalendar.saveEventAsync(stringifyDateValues({ ...eventData, calendarId }), {});
|
|
144
|
+
}
|
|
145
|
+
const IOS_READ_ONLY_EVENT_FIELDS = [
|
|
146
|
+
'creationDate',
|
|
147
|
+
'lastModifiedDate',
|
|
148
|
+
'originalStartDate',
|
|
149
|
+
'isDetached',
|
|
150
|
+
'status',
|
|
151
|
+
'organizer',
|
|
152
|
+
];
|
|
153
|
+
export async function updateEventAsync(id, details = {}, recurringEventOptions = {}) {
|
|
154
|
+
if (!expoCalendar.saveEventAsync) {
|
|
155
|
+
throw new UnavailabilityError('Calendar', 'updateEventAsync');
|
|
156
|
+
}
|
|
157
|
+
if (!id) {
|
|
158
|
+
throw new Error('updateEventAsync must be called with an id (string) of the target event');
|
|
159
|
+
}
|
|
160
|
+
if (Platform.OS === 'ios' &&
|
|
161
|
+
IOS_READ_ONLY_EVENT_FIELDS.some(field => Object.hasOwn(details, field))) {
|
|
162
|
+
console.warn('updateEventAsync was called with one or more read-only properties, which will not be updated');
|
|
163
|
+
}
|
|
164
|
+
const { futureEvents = false, instanceStartDate } = recurringEventOptions;
|
|
165
|
+
const newDetails = { ...details, id, instanceStartDate };
|
|
166
|
+
return expoCalendar.saveEventAsync(stringifyDateValues(newDetails), {
|
|
167
|
+
futureEvents,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
export async function deleteEventAsync(id, recurringEventOptions = {}) {
|
|
171
|
+
if (!expoCalendar.deleteEventAsync) {
|
|
172
|
+
throw new UnavailabilityError('Calendar', 'deleteEventAsync');
|
|
173
|
+
}
|
|
174
|
+
if (!id) {
|
|
175
|
+
throw new Error('deleteEventAsync must be called with an id (string) of the target event');
|
|
176
|
+
}
|
|
177
|
+
const { futureEvents = false, instanceStartDate } = recurringEventOptions;
|
|
178
|
+
return expoCalendar.deleteEventAsync({ id, instanceStartDate }, { futureEvents });
|
|
179
|
+
}
|
|
180
|
+
export async function getAttendeesForEventAsync(id, recurringEventOptions = {}) {
|
|
181
|
+
if (!expoCalendar.getAttendeesForEventAsync) {
|
|
182
|
+
throw new UnavailabilityError('Calendar', 'getAttendeesForEventAsync');
|
|
183
|
+
}
|
|
184
|
+
if (!id) {
|
|
185
|
+
throw new Error('getAttendeesForEventAsync must be called with an id (string) of the target event');
|
|
186
|
+
}
|
|
187
|
+
const { instanceStartDate } = recurringEventOptions;
|
|
188
|
+
const params = Platform.OS === 'ios' ? { id, instanceStartDate } : id;
|
|
189
|
+
return expoCalendar.getAttendeesForEventAsync(params);
|
|
190
|
+
}
|
|
191
|
+
export async function createAttendeeAsync(eventId, details = {}) {
|
|
192
|
+
if (!expoCalendar.saveAttendeeForEventAsync) {
|
|
193
|
+
throw new UnavailabilityError('Calendar', 'createAttendeeAsync');
|
|
194
|
+
}
|
|
195
|
+
if (!eventId) {
|
|
196
|
+
throw new Error('createAttendeeAsync must be called with an id (string) of the target event');
|
|
197
|
+
}
|
|
198
|
+
if (!details.email) {
|
|
199
|
+
throw new Error('createAttendeeAsync requires an email (string)');
|
|
200
|
+
}
|
|
201
|
+
if (!details.role) {
|
|
202
|
+
throw new Error('createAttendeeAsync requires a role (string)');
|
|
203
|
+
}
|
|
204
|
+
if (!details.type) {
|
|
205
|
+
throw new Error('createAttendeeAsync requires a type (string)');
|
|
206
|
+
}
|
|
207
|
+
if (!details.status) {
|
|
208
|
+
throw new Error('createAttendeeAsync requires a status (string)');
|
|
209
|
+
}
|
|
210
|
+
return expoCalendar.saveAttendeeForEventAsync({ ...details, id: undefined }, eventId);
|
|
211
|
+
}
|
|
212
|
+
export async function updateAttendeeAsync(id, details = {}) {
|
|
213
|
+
if (!expoCalendar.saveAttendeeForEventAsync) {
|
|
214
|
+
throw new UnavailabilityError('Calendar', 'updateAttendeeAsync');
|
|
215
|
+
}
|
|
216
|
+
if (!id) {
|
|
217
|
+
throw new Error('updateAttendeeAsync must be called with an id (string) of the target event');
|
|
218
|
+
}
|
|
219
|
+
return expoCalendar.saveAttendeeForEventAsync({ ...details, id }, null);
|
|
220
|
+
}
|
|
221
|
+
export async function deleteAttendeeAsync(id) {
|
|
222
|
+
if (!expoCalendar.deleteAttendeeAsync) {
|
|
223
|
+
throw new UnavailabilityError('Calendar', 'deleteAttendeeAsync');
|
|
224
|
+
}
|
|
225
|
+
if (!id) {
|
|
226
|
+
throw new Error('deleteAttendeeAsync must be called with an id (string) of the target event');
|
|
227
|
+
}
|
|
228
|
+
return expoCalendar.deleteAttendeeAsync(id);
|
|
229
|
+
}
|
|
230
|
+
export async function getDefaultCalendarAsync() {
|
|
231
|
+
if (!expoCalendar.getDefaultCalendarAsync) {
|
|
232
|
+
throw new UnavailabilityError('Calendar', 'getDefaultCalendarAsync');
|
|
233
|
+
}
|
|
234
|
+
return expoCalendar.getDefaultCalendarAsync();
|
|
235
|
+
}
|
|
236
|
+
export async function getSourcesAsync() {
|
|
237
|
+
if (!expoCalendar.getSourcesAsync) {
|
|
238
|
+
throw new UnavailabilityError('Calendar', 'getSourcesAsync');
|
|
239
|
+
}
|
|
240
|
+
return expoCalendar.getSourcesAsync();
|
|
241
|
+
}
|
|
242
|
+
export async function getSourceAsync(id) {
|
|
243
|
+
if (!expoCalendar.getSourceByIdAsync) {
|
|
244
|
+
throw new UnavailabilityError('Calendar', 'getSourceAsync');
|
|
245
|
+
}
|
|
246
|
+
if (!id) {
|
|
247
|
+
throw new Error('getSourceAsync must be called with an id (string) of the target source');
|
|
248
|
+
}
|
|
249
|
+
return expoCalendar.getSourceByIdAsync(id);
|
|
250
|
+
}
|
|
251
|
+
/** @platform android */
|
|
252
|
+
export function openEventInCalendar(id) {
|
|
253
|
+
if (!expoCalendar.openEventInCalendar) {
|
|
254
|
+
console.warn(`openEventInCalendar is not available on platform: ${Platform.OS}`);
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (!id) {
|
|
258
|
+
throw new Error('openEventInCalendar must be called with an id (string) of the target event');
|
|
259
|
+
}
|
|
260
|
+
return expoCalendar.openEventInCalendar(id);
|
|
261
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '../core/enums';
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { IAttendee, ICalendar, ICalendarDialogParams, IDialogEventResult, IEvent, IOpenEventDialogResult, IOpenEventPresentationOptions, IPresentationOptions, IReminder, ISource, PermissionResponse } from './types';
|
|
2
|
+
export type INativeCalendarModule = {
|
|
3
|
+
createEventInCalendarAsync?(params: Record<string, unknown>): Promise<IDialogEventResult>;
|
|
4
|
+
openEventInCalendarAsync?(params: ICalendarDialogParams & IOpenEventPresentationOptions): Promise<IOpenEventDialogResult>;
|
|
5
|
+
editEventInCalendarAsync?(params: ICalendarDialogParams & IPresentationOptions): Promise<IDialogEventResult>;
|
|
6
|
+
getCalendarsAsync?(entityType: string | null): Promise<ICalendar[]>;
|
|
7
|
+
saveCalendarAsync?(details: Record<string, unknown>): Promise<string>;
|
|
8
|
+
deleteCalendarAsync?(id: string): Promise<void>;
|
|
9
|
+
getEventsAsync?(startDate: string | Date, endDate: string | Date, calendarIds: string[]): Promise<IEvent[]>;
|
|
10
|
+
getEventByIdAsync?(id: string, instanceStartDate?: string | Date): Promise<IEvent>;
|
|
11
|
+
saveEventAsync?(details: Record<string, unknown>, options: {
|
|
12
|
+
futureEvents?: boolean;
|
|
13
|
+
}): Promise<string>;
|
|
14
|
+
deleteEventAsync?(params: {
|
|
15
|
+
id: string;
|
|
16
|
+
instanceStartDate?: string | Date;
|
|
17
|
+
}, options: {
|
|
18
|
+
futureEvents?: boolean;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
getAttendeesForEventAsync?(params: {
|
|
21
|
+
id: string;
|
|
22
|
+
instanceStartDate?: string | Date;
|
|
23
|
+
} | string): Promise<IAttendee[]>;
|
|
24
|
+
saveAttendeeForEventAsync?(details: Record<string, unknown>, eventId: string | null): Promise<string>;
|
|
25
|
+
deleteAttendeeAsync?(id: string): Promise<void>;
|
|
26
|
+
getDefaultCalendarAsync?(): Promise<ICalendar>;
|
|
27
|
+
getRemindersAsync?(startDate: string | Date | null, endDate: string | Date | null, calendarIds: (string | null)[], status: string | null): Promise<IReminder[]>;
|
|
28
|
+
getReminderByIdAsync?(id: string): Promise<IReminder>;
|
|
29
|
+
saveReminderAsync?(details: Record<string, unknown>): Promise<string>;
|
|
30
|
+
deleteReminderAsync?(id: string): Promise<void>;
|
|
31
|
+
getSourcesAsync?(): Promise<ISource[]>;
|
|
32
|
+
getSourceByIdAsync?(id: string): Promise<ISource>;
|
|
33
|
+
openEventInCalendar?(id: string): void;
|
|
34
|
+
getCalendarPermissionsAsync?(): Promise<PermissionResponse>;
|
|
35
|
+
requestCalendarPermissionsAsync?(): Promise<PermissionResponse>;
|
|
36
|
+
getRemindersPermissionsAsync?(): Promise<PermissionResponse>;
|
|
37
|
+
requestRemindersPermissionsAsync?(): Promise<PermissionResponse>;
|
|
38
|
+
};
|
|
39
|
+
export declare const expoCalendar: INativeCalendarModule;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PermissionResponse } from './types';
|
|
2
|
+
export declare function getCalendarPermissionsAsync(): Promise<PermissionResponse>;
|
|
3
|
+
/** @platform ios */
|
|
4
|
+
export declare function getRemindersPermissionsAsync(): Promise<PermissionResponse>;
|
|
5
|
+
export declare function requestCalendarPermissionsAsync(): Promise<PermissionResponse>;
|
|
6
|
+
/** @deprecated Use `requestCalendarPermissionsAsync` instead */
|
|
7
|
+
export declare function requestPermissionsAsync(): Promise<PermissionResponse>;
|
|
8
|
+
/** @platform ios */
|
|
9
|
+
export declare function requestRemindersPermissionsAsync(): Promise<PermissionResponse>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { UnavailabilityError } from 'expo-modules-core';
|
|
2
|
+
import { expoCalendar } from './native-module.js';
|
|
3
|
+
export async function getCalendarPermissionsAsync() {
|
|
4
|
+
if (!expoCalendar.getCalendarPermissionsAsync) {
|
|
5
|
+
throw new UnavailabilityError('Calendar', 'getCalendarPermissionsAsync');
|
|
6
|
+
}
|
|
7
|
+
return expoCalendar.getCalendarPermissionsAsync();
|
|
8
|
+
}
|
|
9
|
+
/** @platform ios */
|
|
10
|
+
export async function getRemindersPermissionsAsync() {
|
|
11
|
+
if (!expoCalendar.getRemindersPermissionsAsync) {
|
|
12
|
+
throw new UnavailabilityError('Calendar', 'getRemindersPermissionsAsync');
|
|
13
|
+
}
|
|
14
|
+
return expoCalendar.getRemindersPermissionsAsync();
|
|
15
|
+
}
|
|
16
|
+
export async function requestCalendarPermissionsAsync() {
|
|
17
|
+
if (!expoCalendar.requestCalendarPermissionsAsync) {
|
|
18
|
+
throw new UnavailabilityError('Calendar', 'requestCalendarPermissionsAsync');
|
|
19
|
+
}
|
|
20
|
+
return expoCalendar.requestCalendarPermissionsAsync();
|
|
21
|
+
}
|
|
22
|
+
/** @deprecated Use `requestCalendarPermissionsAsync` instead */
|
|
23
|
+
export async function requestPermissionsAsync() {
|
|
24
|
+
console.warn('requestPermissionsAsync is deprecated. Use requestCalendarPermissionsAsync instead.');
|
|
25
|
+
return requestCalendarPermissionsAsync();
|
|
26
|
+
}
|
|
27
|
+
/** @platform ios */
|
|
28
|
+
export async function requestRemindersPermissionsAsync() {
|
|
29
|
+
if (!expoCalendar.requestRemindersPermissionsAsync) {
|
|
30
|
+
throw new UnavailabilityError('Calendar', 'requestRemindersPermissionsAsync');
|
|
31
|
+
}
|
|
32
|
+
return expoCalendar.requestRemindersPermissionsAsync();
|
|
33
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { IReminder } from './types';
|
|
2
|
+
export declare function getRemindersAsync(calendarIds: (string | null)[], status: string | null, startDate: Date | null, endDate: Date | null): Promise<IReminder[]>;
|
|
3
|
+
export declare function getReminderAsync(id: string): Promise<IReminder>;
|
|
4
|
+
export declare function createReminderAsync(calendarId: string | null, reminder?: IReminder): Promise<string>;
|
|
5
|
+
export declare function updateReminderAsync(id: string, details?: IReminder): Promise<string>;
|
|
6
|
+
export declare function deleteReminderAsync(id: string): Promise<void>;
|