@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.
Files changed (141) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +189 -0
  3. package/build/angular/index.d.ts +3 -0
  4. package/build/angular/index.js +3 -0
  5. package/build/angular/services/calendar-permissions.service/index.d.ts +5 -0
  6. package/build/angular/services/calendar-permissions.service/index.js +60 -0
  7. package/build/angular/services/reminders-permissions.service/index.d.ts +5 -0
  8. package/build/angular/services/reminders-permissions.service/index.js +60 -0
  9. package/build/core/attendee.d.ts +9 -0
  10. package/build/core/attendee.js +28 -0
  11. package/build/core/calendar-permission-api.d.ts +9 -0
  12. package/build/core/calendar-permission-api.js +9 -0
  13. package/build/core/calendar.d.ts +34 -0
  14. package/build/core/calendar.js +118 -0
  15. package/build/core/enums.d.ts +141 -0
  16. package/build/core/enums.js +157 -0
  17. package/build/core/event.d.ts +14 -0
  18. package/build/core/event.js +40 -0
  19. package/build/core/index.d.ts +6 -0
  20. package/build/core/index.js +6 -0
  21. package/build/core/native-module.d.ts +154 -0
  22. package/build/core/native-module.js +3 -0
  23. package/build/core/reminder.d.ts +10 -0
  24. package/build/core/reminder.js +34 -0
  25. package/build/core/types.d.ts +184 -0
  26. package/build/core/types.js +1 -0
  27. package/build/core/utils.d.ts +7 -0
  28. package/build/core/utils.js +29 -0
  29. package/build/legacy/calendar.d.ts +23 -0
  30. package/build/legacy/calendar.js +261 -0
  31. package/build/legacy/enums.d.ts +1 -0
  32. package/build/legacy/enums.js +2 -0
  33. package/build/legacy/index.d.ts +5 -0
  34. package/build/legacy/index.js +5 -0
  35. package/build/legacy/native-module.d.ts +39 -0
  36. package/build/legacy/native-module.js +3 -0
  37. package/build/legacy/permissions.d.ts +9 -0
  38. package/build/legacy/permissions.js +33 -0
  39. package/build/legacy/reminders.d.ts +6 -0
  40. package/build/legacy/reminders.js +56 -0
  41. package/build/legacy/types.d.ts +147 -0
  42. package/build/legacy/types.js +1 -0
  43. package/build/react/index.d.ts +3 -0
  44. package/build/react/index.js +3 -0
  45. package/build/react/use-calendar-permissions.d.ts +10 -0
  46. package/build/react/use-calendar-permissions.js +7 -0
  47. package/build/react/use-reminders-permissions.d.ts +8 -0
  48. package/build/react/use-reminders-permissions.js +10 -0
  49. package/build/solid/index.d.ts +3 -0
  50. package/build/solid/index.js +3 -0
  51. package/build/solid/use-calendar-permissions.d.ts +11 -0
  52. package/build/solid/use-calendar-permissions.js +7 -0
  53. package/build/solid/use-reminders-permissions.d.ts +9 -0
  54. package/build/solid/use-reminders-permissions.js +10 -0
  55. package/build/svelte/index.d.ts +3 -0
  56. package/build/svelte/index.js +3 -0
  57. package/build/svelte/use-calendar-permissions.svelte.d.ts +10 -0
  58. package/build/svelte/use-calendar-permissions.svelte.js +7 -0
  59. package/build/svelte/use-reminders-permissions.svelte.d.ts +8 -0
  60. package/build/svelte/use-reminders-permissions.svelte.js +10 -0
  61. package/build/vue/index.d.ts +3 -0
  62. package/build/vue/index.js +3 -0
  63. package/build/vue/use-calendar-permissions.d.ts +11 -0
  64. package/build/vue/use-calendar-permissions.js +7 -0
  65. package/build/vue/use-reminders-permissions.d.ts +9 -0
  66. package/build/vue/use-reminders-permissions.js +10 -0
  67. package/build-ngc/angular/index.d.ts +3 -0
  68. package/build-ngc/angular/index.js +4 -0
  69. package/build-ngc/angular/index.js.map +1 -0
  70. package/build-ngc/angular/services/calendar-permissions.service/index.d.ts +8 -0
  71. package/build-ngc/angular/services/calendar-permissions.service/index.js +17 -0
  72. package/build-ngc/angular/services/calendar-permissions.service/index.js.map +1 -0
  73. package/build-ngc/angular/services/reminders-permissions.service/index.d.ts +8 -0
  74. package/build-ngc/angular/services/reminders-permissions.service/index.js +17 -0
  75. package/build-ngc/angular/services/reminders-permissions.service/index.js.map +1 -0
  76. package/build-ngc/core/attendee.d.ts +9 -0
  77. package/build-ngc/core/attendee.js +29 -0
  78. package/build-ngc/core/attendee.js.map +1 -0
  79. package/build-ngc/core/calendar-permission-api.d.ts +9 -0
  80. package/build-ngc/core/calendar-permission-api.js +10 -0
  81. package/build-ngc/core/calendar-permission-api.js.map +1 -0
  82. package/build-ngc/core/calendar.d.ts +34 -0
  83. package/build-ngc/core/calendar.js +119 -0
  84. package/build-ngc/core/calendar.js.map +1 -0
  85. package/build-ngc/core/enums.d.ts +141 -0
  86. package/build-ngc/core/enums.js +158 -0
  87. package/build-ngc/core/enums.js.map +1 -0
  88. package/build-ngc/core/event.d.ts +14 -0
  89. package/build-ngc/core/event.js +41 -0
  90. package/build-ngc/core/event.js.map +1 -0
  91. package/build-ngc/core/index.d.ts +6 -0
  92. package/build-ngc/core/index.js +7 -0
  93. package/build-ngc/core/index.js.map +1 -0
  94. package/build-ngc/core/native-module.d.ts +154 -0
  95. package/build-ngc/core/native-module.js +4 -0
  96. package/build-ngc/core/native-module.js.map +1 -0
  97. package/build-ngc/core/reminder.d.ts +10 -0
  98. package/build-ngc/core/reminder.js +35 -0
  99. package/build-ngc/core/reminder.js.map +1 -0
  100. package/build-ngc/core/types.d.ts +184 -0
  101. package/build-ngc/core/types.js +2 -0
  102. package/build-ngc/core/types.js.map +1 -0
  103. package/build-ngc/core/utils.d.ts +7 -0
  104. package/build-ngc/core/utils.js +30 -0
  105. package/build-ngc/core/utils.js.map +1 -0
  106. package/native-link.json +29 -0
  107. package/package.json +155 -0
  108. package/src/angular/index.ts +3 -0
  109. package/src/angular/services/calendar-permissions.service/index.ts +19 -0
  110. package/src/angular/services/reminders-permissions.service/index.ts +16 -0
  111. package/src/core/attendee.ts +43 -0
  112. package/src/core/calendar-permission-api.ts +16 -0
  113. package/src/core/calendar.ts +197 -0
  114. package/src/core/enums.ts +156 -0
  115. package/src/core/event.ts +70 -0
  116. package/src/core/index.ts +18 -0
  117. package/src/core/native-module.ts +212 -0
  118. package/src/core/reminder.ts +52 -0
  119. package/src/core/types.ts +209 -0
  120. package/src/core/utils.ts +39 -0
  121. package/src/legacy/calendar.ts +401 -0
  122. package/src/legacy/enums.ts +2 -0
  123. package/src/legacy/index.ts +5 -0
  124. package/src/legacy/native-module.ts +77 -0
  125. package/src/legacy/permissions.ts +47 -0
  126. package/src/legacy/reminders.ts +98 -0
  127. package/src/legacy/types.ts +183 -0
  128. package/src/react/index.ts +3 -0
  129. package/src/react/use-calendar-permissions.ts +25 -0
  130. package/src/react/use-reminders-permissions.ts +25 -0
  131. package/src/solid/index.ts +3 -0
  132. package/src/solid/use-calendar-permissions.ts +26 -0
  133. package/src/solid/use-reminders-permissions.ts +26 -0
  134. package/src/svelte/index.ts +3 -0
  135. package/src/svelte/svelte-ambient.d.ts +3 -0
  136. package/src/svelte/svelte-compile.test-helper.ts +7 -0
  137. package/src/svelte/use-calendar-permissions.svelte.ts +25 -0
  138. package/src/svelte/use-reminders-permissions.svelte.ts +25 -0
  139. package/src/vue/index.ts +3 -0
  140. package/src/vue/use-calendar-permissions.ts +26 -0
  141. package/src/vue/use-reminders-permissions.ts +26 -0
@@ -0,0 +1,212 @@
1
+ import { requireNativeModule } from 'expo-modules-core';
2
+ import type { PermissionResponse } from 'expo-modules-core';
3
+ import type {
4
+ IDialogEventResult,
5
+ IOpenEventPresentationOptions,
6
+ IPresentationOptions,
7
+ IRecurringEventOptions,
8
+ ISource,
9
+ } from './types';
10
+
11
+ const EXPO_CALENDAR_NEXT_MODULE_NAME = 'CalendarNext';
12
+
13
+ // Each class is a real native SharedObject (Kotlin/Swift `Class(...)` registration) - `declare
14
+ // class`, matching @symbiote-native/file-system's next/native-module.ts (see its own comment
15
+ // for why a plain object type with a `new(...)` signature does not work the same way).
16
+ export declare class NativeExpoCalendar {
17
+ readonly id: string;
18
+ readonly title: string;
19
+ /** @platform android */
20
+ readonly name?: string | null;
21
+ readonly source?: ISource;
22
+ /** @platform ios */
23
+ readonly sourceId?: string;
24
+ /** @platform ios */
25
+ readonly type?: string;
26
+ readonly color?: string;
27
+ /** @platform ios */
28
+ readonly entityType?: string;
29
+ readonly allowsModifications: boolean;
30
+ readonly allowedAvailabilities: string[];
31
+ /** @platform android */
32
+ readonly isVisible?: boolean;
33
+ /** @platform android */
34
+ readonly isSynced?: boolean;
35
+ /** @platform android */
36
+ readonly timeZone?: string;
37
+ /** @platform android */
38
+ readonly isPrimary?: boolean;
39
+ /** @platform android */
40
+ readonly allowedReminders?: string[];
41
+ /** @platform android */
42
+ readonly allowedAttendeeTypes?: string[];
43
+ /** @platform android */
44
+ readonly ownerAccount?: string;
45
+ /** @platform android */
46
+ readonly accessLevel?: string;
47
+
48
+ listEvents(
49
+ startDate: string | Date,
50
+ endDate: string | Date,
51
+ ): Promise<NativeExpoCalendarEvent[]>;
52
+ /** @platform ios - typed as always-present, guarded at runtime. */
53
+ listReminders(
54
+ startDate: string | Date | null,
55
+ endDate: string | Date | null,
56
+ status: string | null,
57
+ ): Promise<NativeExpoCalendarReminder[]>;
58
+ createEvent(
59
+ record: Record<string, unknown>,
60
+ ): Promise<NativeExpoCalendarEvent>;
61
+ /** @platform ios - typed as always-present, guarded at runtime. */
62
+ createReminder(
63
+ record: Record<string, unknown>,
64
+ ): Promise<NativeExpoCalendarReminder>;
65
+ addEventWithForm(
66
+ options?: Record<string, unknown>,
67
+ ): Promise<IDialogEventResult>;
68
+ update(patch: Record<string, unknown>): Promise<void>;
69
+ delete(): Promise<void>;
70
+ }
71
+
72
+ export declare class NativeExpoCalendarEvent {
73
+ readonly id: string;
74
+ readonly calendarId?: string;
75
+ readonly title?: string;
76
+ readonly location?: string;
77
+ /** @platform ios */
78
+ readonly creationDate?: string;
79
+ /** @platform ios */
80
+ readonly lastModifiedDate?: string;
81
+ readonly timeZone?: string;
82
+ /** @platform android */
83
+ readonly endTimeZone?: string;
84
+ /** @platform ios */
85
+ readonly url?: string;
86
+ readonly notes?: string;
87
+ readonly alarms?: unknown[];
88
+ readonly recurrenceRule?: Record<string, unknown> | null;
89
+ readonly startDate?: string;
90
+ readonly endDate?: string;
91
+ /** @platform ios */
92
+ readonly originalStartDate?: string;
93
+ /** @platform ios */
94
+ readonly isDetached?: boolean;
95
+ readonly allDay: boolean;
96
+ readonly availability?: string;
97
+ readonly status?: string;
98
+ /** @platform ios */
99
+ readonly organizer?: Record<string, unknown>;
100
+ /** @platform android */
101
+ readonly organizerEmail?: string;
102
+ /** @platform android */
103
+ readonly accessLevel?: string;
104
+ /** @platform android */
105
+ readonly guestsCanModify?: boolean;
106
+ /** @platform android */
107
+ readonly guestsCanInviteOthers?: boolean;
108
+ /** @platform android */
109
+ readonly guestsCanSeeGuests?: boolean;
110
+ /** @platform android */
111
+ readonly originalId?: string;
112
+ /** @platform android */
113
+ readonly instanceId?: string;
114
+
115
+ /** @platform android - typed as always-present, guarded at runtime. */
116
+ createAttendee(
117
+ record: Record<string, unknown>,
118
+ ): Promise<NativeExpoCalendarAttendee>;
119
+ openInCalendar(
120
+ options?: IOpenEventPresentationOptions | null,
121
+ ): Promise<IDialogEventResult>;
122
+ editInCalendar(
123
+ options?: IPresentationOptions | null,
124
+ ): Promise<IDialogEventResult>;
125
+ getOccurrenceSync(options?: IRecurringEventOptions): NativeExpoCalendarEvent;
126
+ getAttendees(): Promise<NativeExpoCalendarAttendee[]>;
127
+ update(
128
+ patch: Record<string, unknown>,
129
+ nullableFields: string[],
130
+ ): Promise<void>;
131
+ delete(): Promise<void>;
132
+ }
133
+
134
+ /** @platform android - iOS registers this class with no properties or methods. */
135
+ export declare class NativeExpoCalendarAttendee {
136
+ constructor(record: Record<string, unknown>);
137
+ readonly id?: string;
138
+ readonly name?: string;
139
+ readonly role?: string;
140
+ readonly status?: string;
141
+ readonly type?: string;
142
+ readonly email?: string;
143
+
144
+ update(
145
+ patch: Record<string, unknown>,
146
+ nullableFields: string[],
147
+ ): Promise<void>;
148
+ delete(): Promise<void>;
149
+ }
150
+
151
+ /** @platform ios - Android registers this class with no properties or methods. */
152
+ export declare class NativeExpoCalendarReminder {
153
+ constructor(id: string);
154
+ readonly id?: string;
155
+ readonly calendarId?: string;
156
+ readonly title?: string;
157
+ readonly location?: string;
158
+ readonly creationDate?: string;
159
+ readonly lastModifiedDate?: string;
160
+ readonly timeZone?: string;
161
+ readonly url?: string;
162
+ readonly notes?: string;
163
+ readonly alarms?: unknown[];
164
+ readonly recurrenceRule?: Record<string, unknown> | null;
165
+ readonly allDay: boolean;
166
+ readonly startDate?: string;
167
+ readonly dueDate?: string;
168
+ readonly completed: boolean;
169
+ readonly completionDate?: string;
170
+
171
+ update(
172
+ patch: Record<string, unknown>,
173
+ nullableFields: string[],
174
+ ): Promise<void>;
175
+ delete(): Promise<void>;
176
+ }
177
+
178
+ export type INativeCalendarNextModule = {
179
+ ExpoCalendar: typeof NativeExpoCalendar;
180
+ ExpoCalendarEvent: typeof NativeExpoCalendarEvent;
181
+ ExpoCalendarAttendee: typeof NativeExpoCalendarAttendee;
182
+ ExpoCalendarReminder: typeof NativeExpoCalendarReminder;
183
+
184
+ getCalendars(type: string | null): Promise<NativeExpoCalendar[]>;
185
+ getCalendarById(id: string): Promise<NativeExpoCalendar>;
186
+ createCalendar(record: Record<string, unknown>): Promise<NativeExpoCalendar>;
187
+ listEvents(
188
+ calendarIds: string[],
189
+ startDate: string,
190
+ endDate: string,
191
+ ): Promise<NativeExpoCalendarEvent[]>;
192
+ getEventById(id: string): Promise<NativeExpoCalendarEvent>;
193
+ getCalendarPermissions(writeOnly?: boolean): Promise<PermissionResponse>;
194
+ requestCalendarPermissions(writeOnly?: boolean): Promise<PermissionResponse>;
195
+
196
+ /** @platform ios */
197
+ getDefaultCalendarSync?(): NativeExpoCalendar;
198
+ /** @platform ios */
199
+ presentPicker?(): Promise<NativeExpoCalendar | null>;
200
+ /** @platform ios */
201
+ getReminderById?(id: string): Promise<NativeExpoCalendarReminder>;
202
+ /** @platform ios */
203
+ getRemindersPermissions?(): Promise<PermissionResponse>;
204
+ /** @platform ios */
205
+ requestRemindersPermissions?(): Promise<PermissionResponse>;
206
+ /** @platform ios */
207
+ getSourcesSync?(): ISource[];
208
+ };
209
+
210
+ export const expoCalendarNext = requireNativeModule<INativeCalendarNextModule>(
211
+ EXPO_CALENDAR_NEXT_MODULE_NAME,
212
+ );
@@ -0,0 +1,52 @@
1
+ import { Platform, UnavailabilityError } from 'expo-modules-core';
2
+ import { expoCalendarNext } from './native-module';
3
+ import type { NativeExpoCalendarReminder } from './native-module';
4
+ import type { IReminderPatch } from './types';
5
+ import { getNullableDetailsFields, stringifyDateValues } from './utils';
6
+
7
+ /** @platform ios - Android registers this class with no properties or methods. */
8
+ export class ExpoCalendarReminder
9
+ extends expoCalendarNext.ExpoCalendarReminder
10
+ {
11
+ override async update(details: IReminderPatch): Promise<void> {
12
+ if (Platform.OS !== 'ios') {
13
+ throw new UnavailabilityError('ExpoCalendarReminder', 'update');
14
+ }
15
+ return super.update(
16
+ stringifyDateValues(details),
17
+ getNullableDetailsFields(details),
18
+ );
19
+ }
20
+
21
+ override async delete(): Promise<void> {
22
+ if (Platform.OS !== 'ios') {
23
+ throw new UnavailabilityError('ExpoCalendarReminder', 'delete');
24
+ }
25
+ return super.delete();
26
+ }
27
+
28
+ static async get(reminderId: string): Promise<ExpoCalendarReminder> {
29
+ if (Platform.OS !== 'ios' || !expoCalendarNext.getReminderById) {
30
+ throw new UnavailabilityError('ExpoCalendarReminder', 'get');
31
+ }
32
+ return upgradeToExpoCalendarReminder(
33
+ await expoCalendarNext.getReminderById(reminderId),
34
+ );
35
+ }
36
+ }
37
+
38
+ function isExpoCalendarReminder(value: unknown): value is ExpoCalendarReminder {
39
+ return value instanceof ExpoCalendarReminder;
40
+ }
41
+
42
+ export function upgradeToExpoCalendarReminder(
43
+ native: NativeExpoCalendarReminder,
44
+ ): ExpoCalendarReminder {
45
+ Object.setPrototypeOf(native, ExpoCalendarReminder.prototype);
46
+ if (!isExpoCalendarReminder(native)) {
47
+ throw new Error(
48
+ 'unreachable - just reassigned the prototype to ExpoCalendarReminder',
49
+ );
50
+ }
51
+ return native;
52
+ }
@@ -0,0 +1,209 @@
1
+ import type {
2
+ AlarmMethod,
3
+ AttendeeRole,
4
+ AttendeeStatus,
5
+ AttendeeType,
6
+ CalendarAccessLevel,
7
+ CalendarDialogResultActions,
8
+ DayOfTheWeek,
9
+ Frequency,
10
+ MonthOfTheYear,
11
+ } from './enums';
12
+
13
+ export type ISource = {
14
+ id?: string;
15
+ type?: string;
16
+ name?: string;
17
+ isLocalAccount?: boolean;
18
+ };
19
+
20
+ export type IDaysOfTheWeek = {
21
+ dayOfTheWeek: DayOfTheWeek;
22
+ /** `-53` to `53`; `0` ignores this field. */
23
+ weekNumber?: number;
24
+ };
25
+
26
+ export type IRecurrenceRule = {
27
+ frequency: Frequency;
28
+ /** @default 1 */
29
+ interval?: number;
30
+ endDate?: string | Date | null;
31
+ occurrence?: number | null;
32
+ /** @platform ios */
33
+ daysOfTheWeek?: IDaysOfTheWeek[] | null;
34
+ /** @platform ios */
35
+ daysOfTheMonth?: number[] | null;
36
+ /** @platform ios */
37
+ monthsOfTheYear?: MonthOfTheYear[] | null;
38
+ /** @platform ios */
39
+ weeksOfTheYear?: number[] | null;
40
+ /** @platform ios */
41
+ daysOfTheYear?: number[] | null;
42
+ /** @platform ios */
43
+ setPositions?: number[] | null;
44
+ };
45
+
46
+ export type IAlarmLocation = {
47
+ title?: string;
48
+ proximity?: string;
49
+ radius?: number;
50
+ coords?: { latitude?: number; longitude?: number };
51
+ };
52
+
53
+ export type IAlarm = {
54
+ /** @platform ios */
55
+ absoluteDate?: string;
56
+ relativeOffset?: number;
57
+ structuredLocation?: IAlarmLocation;
58
+ /** @platform android */
59
+ method?: AlarmMethod;
60
+ };
61
+
62
+ /** Fields for `createCalendar()` - all optional, matches upstream's `Partial<Calendar>`. */
63
+ export type ICalendarInput = {
64
+ title?: string;
65
+ /** @platform android */
66
+ name?: string;
67
+ source?: ISource;
68
+ color?: string;
69
+ /** @platform android */
70
+ isVisible?: boolean;
71
+ /** @platform android */
72
+ isSynced?: boolean;
73
+ /** @platform android */
74
+ timeZone?: string;
75
+ /** @platform android */
76
+ isPrimary?: boolean;
77
+ allowedAvailabilities?: string[];
78
+ /** @platform android */
79
+ allowedReminders?: AlarmMethod[];
80
+ /** @platform android */
81
+ allowedAttendeeTypes?: AttendeeType[];
82
+ /** @platform android */
83
+ ownerAccount?: string;
84
+ /** @platform android */
85
+ accessLevel?: CalendarAccessLevel;
86
+ /** @platform ios */
87
+ sourceId?: string;
88
+ };
89
+
90
+ /** Fields for `calendar.update()`; a field set to `null` clears it natively. */
91
+ export type ICalendarPatch = {
92
+ title?: string | null;
93
+ /** @platform android */
94
+ name?: string | null;
95
+ color?: string | null;
96
+ /** @platform android */
97
+ isVisible?: boolean | null;
98
+ /** @platform android */
99
+ isSynced?: boolean | null;
100
+ /** @platform android */
101
+ timeZone?: string | null;
102
+ };
103
+
104
+ /** Fields for `calendar.createEvent()` - all optional, matches upstream's `Omit<Partial<...>>`. */
105
+ export type IEventInput = {
106
+ startDate?: string | Date;
107
+ endDate?: string | Date;
108
+ title?: string;
109
+ location?: string;
110
+ timeZone?: string;
111
+ /** @platform android */
112
+ endTimeZone?: string;
113
+ notes?: string;
114
+ alarms?: IAlarm[];
115
+ recurrenceRule?: IRecurrenceRule;
116
+ allDay?: boolean;
117
+ availability?: string;
118
+ /** @platform android */
119
+ status?: string;
120
+ /** @platform android */
121
+ organizerEmail?: string;
122
+ /** @platform android */
123
+ accessLevel?: string;
124
+ /** @platform android */
125
+ guestsCanModify?: boolean;
126
+ /** @platform android */
127
+ guestsCanInviteOthers?: boolean;
128
+ /** @platform android */
129
+ guestsCanSeeGuests?: boolean;
130
+ };
131
+
132
+ /** Fields for `event.update()`; a field set to `null` clears it natively. */
133
+ export type IEventPatch = Partial<{
134
+ [K in keyof IEventInput]: IEventInput[K] | null;
135
+ }>;
136
+
137
+ /** Fields for `event.createAttendee()`. @platform android */
138
+ export type IAttendeeInput = {
139
+ name: string;
140
+ role: AttendeeRole;
141
+ status: AttendeeStatus;
142
+ type: AttendeeType;
143
+ email: string;
144
+ };
145
+
146
+ /** Fields for `attendee.update()`. @platform android */
147
+ export type IAttendeePatch = Partial<{
148
+ [K in keyof IAttendeeInput]: IAttendeeInput[K] | null;
149
+ }>;
150
+
151
+ /** Fields for `calendar.createReminder()`. @platform ios */
152
+ export type IReminderInput = {
153
+ title?: string;
154
+ location?: string;
155
+ notes?: string;
156
+ startDate?: string | Date;
157
+ dueDate?: string | Date;
158
+ completionDate?: string | Date;
159
+ timeZone?: string;
160
+ alarms?: IAlarm[];
161
+ recurrenceRule?: IRecurrenceRule;
162
+ url?: string;
163
+ allDay?: boolean;
164
+ completed?: boolean;
165
+ };
166
+
167
+ /** Fields for `reminder.update()`; a field set to `null` clears it natively. @platform ios */
168
+ export type IReminderPatch = Partial<{
169
+ [K in keyof IReminderInput]: IReminderInput[K] | null;
170
+ }>;
171
+
172
+ export type IRecurringEventOptions = {
173
+ /** Applies to `instanceStartDate` and every future occurrence when `true`. */
174
+ futureEvents?: boolean;
175
+ instanceStartDate?: string | Date;
176
+ };
177
+
178
+ export type IPresentationOptions = {
179
+ /** `true` resolves `'done'` right after opening. @default true @platform android */
180
+ startNewActivityTask?: boolean;
181
+ };
182
+
183
+ export type IOpenEventPresentationOptions = IPresentationOptions & {
184
+ /** @default false @platform ios */
185
+ allowsEditing?: boolean;
186
+ /** @default false @platform ios */
187
+ allowsCalendarPreview?: boolean;
188
+ };
189
+
190
+ /** Fields for `calendar.addEventWithForm()`. */
191
+ export type IAddEventWithFormOptions = {
192
+ title?: string;
193
+ location?: string;
194
+ notes?: string;
195
+ url?: string;
196
+ /** @platform android */
197
+ timeZone?: string;
198
+ availability?: string;
199
+ allDay?: boolean;
200
+ startDate?: string | Date;
201
+ endDate?: string | Date;
202
+ recurrenceRule?: IRecurrenceRule;
203
+ alarms?: IAlarm[];
204
+ } & IPresentationOptions;
205
+
206
+ export type IDialogEventResult = {
207
+ action: CalendarDialogResultActions;
208
+ id?: string | null;
209
+ };
@@ -0,0 +1,39 @@
1
+ export function stringifyIfDate(value: Date): string;
2
+ export function stringifyIfDate(value: unknown): unknown;
3
+ export function stringifyIfDate(value: unknown): unknown {
4
+ return value instanceof Date ? value.toISOString() : value;
5
+ }
6
+
7
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
8
+ return (
9
+ typeof value === 'object' &&
10
+ value !== null &&
11
+ !Array.isArray(value) &&
12
+ !(value instanceof Date)
13
+ );
14
+ }
15
+
16
+ function stringifyValue(value: unknown): unknown {
17
+ if (Array.isArray(value)) return value.map(stringifyValue);
18
+ if (isPlainObject(value)) return stringifyDateValues(value);
19
+ return stringifyIfDate(value);
20
+ }
21
+
22
+ /** Recursively converts every `Date` field of `obj` to an ISO string for the native bridge. */
23
+ export function stringifyDateValues(
24
+ obj: Record<string, unknown>,
25
+ ): Record<string, unknown> {
26
+ const result: Record<string, unknown> = {};
27
+ for (const [key, value] of Object.entries(obj)) {
28
+ result[key] = stringifyValue(value);
29
+ }
30
+ return result;
31
+ }
32
+
33
+ /** `null` in a patch means "clear natively" - the native `update()` needs the field named
34
+ * separately, in addition to staying in the stringified record with its `null` value. */
35
+ export function getNullableDetailsFields(
36
+ details: Record<string, unknown>,
37
+ ): string[] {
38
+ return Object.keys(details).filter(key => details[key] === null);
39
+ }