@proteos/sdk 0.53.0 → 0.54.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.
@@ -0,0 +1,576 @@
1
+ import type { ProteosClient } from '../client.js'
2
+ import type {
3
+ AvailabilityConstraint,
4
+ BookSchedulingLinkRequest,
5
+ BookSchedulingLinkResponse,
6
+ Calendar,
7
+ CalendarConnection,
8
+ CalendarEvent,
9
+ CalendarEventType,
10
+ CalendarEventsResponse,
11
+ CreateAvailabilityConstraintRequest,
12
+ CreateCalendarConnectionRequest,
13
+ CreateCalendarEventRequest,
14
+ CreateSchedulingLinkRequest,
15
+ CancelPublicCalendarEventRequest,
16
+ GetPublicSlotsQuery,
17
+ GetSlotsRequest,
18
+ GetSlotsResponse,
19
+ ListAvailabilityConstraintsQuery,
20
+ ListCalendarConnectionsQuery,
21
+ ListCalendarEventTypesQuery,
22
+ ListCalendarEventsQuery,
23
+ ListCalendarsQuery,
24
+ ListResponse,
25
+ ListSchedulingLinksQuery,
26
+ PublicBookSchedulingLinkResponse,
27
+ PublicCalendarEvent,
28
+ PublicSchedulingLink,
29
+ PutCalendarEventTypeRequest,
30
+ PutSchedulingProfileRequest,
31
+ RecurrenceScope,
32
+ ReschedulePublicCalendarEventRequest,
33
+ RespondCalendarEventRequest,
34
+ SchedulingLink,
35
+ SchedulingProfile,
36
+ UpdateCalendarSyncRequest,
37
+ UpdateAvailabilityConstraintRequest,
38
+ UpdateCalendarConnectionRequest,
39
+ UpdateCalendarEventRequest,
40
+ UpdateCalendarEventTypeRequest,
41
+ UpdateCalendarRequest,
42
+ UpdateSchedulingLinkRequest,
43
+ } from './types.js'
44
+
45
+ export * from './types.js'
46
+
47
+ const SCHEDULING_BASE_PATH = '/scheduling/v1'
48
+
49
+ const encode = encodeURIComponent
50
+
51
+ /**
52
+ * Facade for scheduling-service: calendar connections (bindings to
53
+ * connector-service google-calendar / microsoft-calendar grants), the
54
+ * calendars under them with their platform roles, per-user scheduling
55
+ * profiles, and the two-way calendar_event mirror.
56
+ *
57
+ * `*Mine` methods act on the caller's own rows (`/me/...`); `*ForUser`
58
+ * methods are the admin path (`/users/:userId/...`).
59
+ *
60
+ * ```ts
61
+ * const scheduling = new SchedulingClient(client)
62
+ * const connection = await scheduling.calendarConnections.connect({ connection_id })
63
+ * const { data: calendars } = await scheduling.calendars.listMine()
64
+ * await scheduling.calendars.updateMine(calendars[0].id, { is_synced: true })
65
+ * const { data: events } = await scheduling.calendarEvents.list({ from, to })
66
+ * ```
67
+ */
68
+ export class SchedulingClient {
69
+ readonly calendarConnections: CalendarConnectionService
70
+ readonly calendars: CalendarService
71
+ readonly schedulingProfiles: SchedulingProfileService
72
+ readonly calendarEvents: CalendarEventService
73
+ readonly calendarEventTypes: CalendarEventTypeService
74
+ readonly availabilityConstraints: AvailabilityConstraintService
75
+ readonly slots: SlotService
76
+ readonly schedulingLinks: SchedulingLinkService
77
+ /** The unauthenticated scheduling page + manage page (no Authorization header). */
78
+ readonly public: PublicSchedulingService
79
+
80
+ constructor(client: ProteosClient) {
81
+ this.schedulingLinks = new SchedulingLinkServiceImpl(client)
82
+ this.public = new PublicSchedulingServiceImpl(client)
83
+ this.calendarConnections = new CalendarConnectionServiceImpl(client)
84
+ this.calendars = new CalendarServiceImpl(client)
85
+ this.schedulingProfiles = new SchedulingProfileServiceImpl(client)
86
+ this.calendarEvents = new CalendarEventServiceImpl(client)
87
+ this.calendarEventTypes = new CalendarEventTypeServiceImpl(client)
88
+ this.availabilityConstraints = new AvailabilityConstraintServiceImpl(client)
89
+ this.slots = new SlotServiceImpl(client)
90
+ }
91
+ }
92
+
93
+ /** Bindings to connector-service calendar grants. */
94
+ export interface CalendarConnectionService {
95
+ listMine(query?: ListCalendarConnectionsQuery): Promise<ListResponse<CalendarConnection>>
96
+ /** Bind one of the caller's user-scope calendar connector connections; discovers its calendars. */
97
+ connect(request: CreateCalendarConnectionRequest): Promise<CalendarConnection>
98
+ updateMine(id: string, request: UpdateCalendarConnectionRequest): Promise<CalendarConnection>
99
+ disconnectMine(id: string): Promise<void>
100
+ /** Enqueue a sync of every synced calendar under the connection. */
101
+ syncMine(id: string, request?: UpdateCalendarSyncRequest): Promise<CalendarConnection>
102
+ listForUser(
103
+ userId: string,
104
+ query?: ListCalendarConnectionsQuery,
105
+ ): Promise<ListResponse<CalendarConnection>>
106
+ updateForUser(
107
+ userId: string,
108
+ id: string,
109
+ request: UpdateCalendarConnectionRequest,
110
+ ): Promise<CalendarConnection>
111
+ disconnectForUser(userId: string, id: string): Promise<void>
112
+ }
113
+
114
+ class CalendarConnectionServiceImpl implements CalendarConnectionService {
115
+ constructor(private readonly client: ProteosClient) {}
116
+
117
+ listMine(query: ListCalendarConnectionsQuery = {}): Promise<ListResponse<CalendarConnection>> {
118
+ return this.client.requestWithQuery(
119
+ 'GET',
120
+ `${SCHEDULING_BASE_PATH}/me/calendar-connections`,
121
+ query,
122
+ )
123
+ }
124
+
125
+ connect(request: CreateCalendarConnectionRequest): Promise<CalendarConnection> {
126
+ return this.client.request('POST', `${SCHEDULING_BASE_PATH}/me/calendar-connections`, request)
127
+ }
128
+
129
+ updateMine(id: string, request: UpdateCalendarConnectionRequest): Promise<CalendarConnection> {
130
+ return this.client.request(
131
+ 'PATCH',
132
+ `${SCHEDULING_BASE_PATH}/me/calendar-connections/${encode(id)}`,
133
+ request,
134
+ )
135
+ }
136
+
137
+ async disconnectMine(id: string): Promise<void> {
138
+ await this.client.request(
139
+ 'DELETE',
140
+ `${SCHEDULING_BASE_PATH}/me/calendar-connections/${encode(id)}`,
141
+ )
142
+ }
143
+
144
+ syncMine(id: string, request: UpdateCalendarSyncRequest = {}): Promise<CalendarConnection> {
145
+ return this.client.request<CalendarConnection>(
146
+ 'POST',
147
+ `${SCHEDULING_BASE_PATH}/me/calendar-connections/${encode(id)}/sync`,
148
+ request,
149
+ )
150
+ }
151
+
152
+ listForUser(
153
+ userId: string,
154
+ query: ListCalendarConnectionsQuery = {},
155
+ ): Promise<ListResponse<CalendarConnection>> {
156
+ return this.client.requestWithQuery(
157
+ 'GET',
158
+ `${SCHEDULING_BASE_PATH}/users/${encode(userId)}/calendar-connections`,
159
+ query,
160
+ )
161
+ }
162
+
163
+ updateForUser(
164
+ userId: string,
165
+ id: string,
166
+ request: UpdateCalendarConnectionRequest,
167
+ ): Promise<CalendarConnection> {
168
+ return this.client.request(
169
+ 'PATCH',
170
+ `${SCHEDULING_BASE_PATH}/users/${encode(userId)}/calendar-connections/${encode(id)}`,
171
+ request,
172
+ )
173
+ }
174
+
175
+ async disconnectForUser(userId: string, id: string): Promise<void> {
176
+ await this.client.request(
177
+ 'DELETE',
178
+ `${SCHEDULING_BASE_PATH}/users/${encode(userId)}/calendar-connections/${encode(id)}`,
179
+ )
180
+ }
181
+ }
182
+
183
+ /** Provider calendars under a connection + their platform roles. */
184
+ export interface CalendarService {
185
+ listMine(query?: ListCalendarsQuery): Promise<ListResponse<Calendar>>
186
+ getMine(id: string): Promise<Calendar>
187
+ updateMine(id: string, request: UpdateCalendarRequest): Promise<Calendar>
188
+ listForUser(userId: string, query?: ListCalendarsQuery): Promise<ListResponse<Calendar>>
189
+ getForUser(userId: string, id: string): Promise<Calendar>
190
+ updateForUser(userId: string, id: string, request: UpdateCalendarRequest): Promise<Calendar>
191
+ }
192
+
193
+ class CalendarServiceImpl implements CalendarService {
194
+ constructor(private readonly client: ProteosClient) {}
195
+
196
+ listMine(query: ListCalendarsQuery = {}): Promise<ListResponse<Calendar>> {
197
+ return this.client.requestWithQuery('GET', `${SCHEDULING_BASE_PATH}/me/calendars`, query)
198
+ }
199
+
200
+ getMine(id: string): Promise<Calendar> {
201
+ return this.client.request('GET', `${SCHEDULING_BASE_PATH}/me/calendars/${encode(id)}`)
202
+ }
203
+
204
+ updateMine(id: string, request: UpdateCalendarRequest): Promise<Calendar> {
205
+ return this.client.request(
206
+ 'PATCH',
207
+ `${SCHEDULING_BASE_PATH}/me/calendars/${encode(id)}`,
208
+ request,
209
+ )
210
+ }
211
+
212
+ listForUser(userId: string, query: ListCalendarsQuery = {}): Promise<ListResponse<Calendar>> {
213
+ return this.client.requestWithQuery(
214
+ 'GET',
215
+ `${SCHEDULING_BASE_PATH}/users/${encode(userId)}/calendars`,
216
+ query,
217
+ )
218
+ }
219
+
220
+ getForUser(userId: string, id: string): Promise<Calendar> {
221
+ return this.client.request(
222
+ 'GET',
223
+ `${SCHEDULING_BASE_PATH}/users/${encode(userId)}/calendars/${encode(id)}`,
224
+ )
225
+ }
226
+
227
+ updateForUser(userId: string, id: string, request: UpdateCalendarRequest): Promise<Calendar> {
228
+ return this.client.request(
229
+ 'PATCH',
230
+ `${SCHEDULING_BASE_PATH}/users/${encode(userId)}/calendars/${encode(id)}`,
231
+ request,
232
+ )
233
+ }
234
+ }
235
+
236
+ /** Per-user scheduling settings (one per org + user; defaults when absent). */
237
+ export interface SchedulingProfileService {
238
+ getMine(): Promise<SchedulingProfile>
239
+ putMine(request: PutSchedulingProfileRequest): Promise<SchedulingProfile>
240
+ getForUser(userId: string): Promise<SchedulingProfile>
241
+ putForUser(userId: string, request: PutSchedulingProfileRequest): Promise<SchedulingProfile>
242
+ }
243
+
244
+ class SchedulingProfileServiceImpl implements SchedulingProfileService {
245
+ constructor(private readonly client: ProteosClient) {}
246
+
247
+ getMine(): Promise<SchedulingProfile> {
248
+ return this.client.request('GET', `${SCHEDULING_BASE_PATH}/me/scheduling-profile`)
249
+ }
250
+
251
+ putMine(request: PutSchedulingProfileRequest): Promise<SchedulingProfile> {
252
+ return this.client.request('PUT', `${SCHEDULING_BASE_PATH}/me/scheduling-profile`, request)
253
+ }
254
+
255
+ getForUser(userId: string): Promise<SchedulingProfile> {
256
+ return this.client.request(
257
+ 'GET',
258
+ `${SCHEDULING_BASE_PATH}/users/${encode(userId)}/scheduling-profile`,
259
+ )
260
+ }
261
+
262
+ putForUser(userId: string, request: PutSchedulingProfileRequest): Promise<SchedulingProfile> {
263
+ return this.client.request(
264
+ 'PUT',
265
+ `${SCHEDULING_BASE_PATH}/users/${encode(userId)}/scheduling-profile`,
266
+ request,
267
+ )
268
+ }
269
+ }
270
+
271
+ /** The two-way calendar_event mirror. */
272
+ export interface CalendarEventService {
273
+ /** A window of events (from/to required, ≤ 93 days); colleagues' events come back projected. */
274
+ list(query: ListCalendarEventsQuery): Promise<CalendarEventsResponse>
275
+ get(id: string): Promise<CalendarEvent>
276
+ /** Write an event through to the provider (calendar_id = own calendar, or hosts). */
277
+ create(request: CreateCalendarEventRequest): Promise<CalendarEvent>
278
+ /** Partial update; `scope` picks the instance or the whole series on recurring events. */
279
+ update(
280
+ id: string,
281
+ request: UpdateCalendarEventRequest,
282
+ scope?: RecurrenceScope,
283
+ ): Promise<CalendarEvent>
284
+ delete(id: string, scope?: RecurrenceScope): Promise<void>
285
+ /** Record the caller's RSVP. */
286
+ respond(id: string, request: RespondCalendarEventRequest): Promise<CalendarEvent>
287
+ }
288
+
289
+ class CalendarEventServiceImpl implements CalendarEventService {
290
+ constructor(private readonly client: ProteosClient) {}
291
+
292
+ list(query: ListCalendarEventsQuery): Promise<CalendarEventsResponse> {
293
+ return this.client.requestWithQuery('GET', `${SCHEDULING_BASE_PATH}/calendar-events`, query)
294
+ }
295
+
296
+ get(id: string): Promise<CalendarEvent> {
297
+ return this.client.request('GET', `${SCHEDULING_BASE_PATH}/calendar-events/${encode(id)}`)
298
+ }
299
+
300
+ create(request: CreateCalendarEventRequest): Promise<CalendarEvent> {
301
+ return this.client.request('POST', `${SCHEDULING_BASE_PATH}/calendar-events`, request)
302
+ }
303
+
304
+ update(
305
+ id: string,
306
+ request: UpdateCalendarEventRequest,
307
+ scope?: RecurrenceScope,
308
+ ): Promise<CalendarEvent> {
309
+ return this.client.requestWithQuery(
310
+ 'PATCH',
311
+ `${SCHEDULING_BASE_PATH}/calendar-events/${encode(id)}`,
312
+ scope ? { scope } : undefined,
313
+ request,
314
+ )
315
+ }
316
+
317
+ async delete(id: string, scope?: RecurrenceScope): Promise<void> {
318
+ await this.client.requestWithQuery(
319
+ 'DELETE',
320
+ `${SCHEDULING_BASE_PATH}/calendar-events/${encode(id)}`,
321
+ scope ? { scope } : undefined,
322
+ )
323
+ }
324
+
325
+ respond(id: string, request: RespondCalendarEventRequest): Promise<CalendarEvent> {
326
+ return this.client.request(
327
+ 'POST',
328
+ `${SCHEDULING_BASE_PATH}/calendar-events/${encode(id)}/respond`,
329
+ request,
330
+ )
331
+ }
332
+ }
333
+
334
+ /** The slot-rules catalog: calendar event types, keyed by (org, key). */
335
+ export interface CalendarEventTypeService {
336
+ list(query?: ListCalendarEventTypesQuery): Promise<ListResponse<CalendarEventType>>
337
+ get(key: string): Promise<CalendarEventType>
338
+ /** Create or replace (PUT semantics: every field is the new value). */
339
+ put(key: string, request: PutCalendarEventTypeRequest): Promise<CalendarEventType>
340
+ update(key: string, request: UpdateCalendarEventTypeRequest): Promise<CalendarEventType>
341
+ delete(key: string): Promise<void>
342
+ }
343
+
344
+ class CalendarEventTypeServiceImpl implements CalendarEventTypeService {
345
+ constructor(private readonly client: ProteosClient) {}
346
+
347
+ list(query: ListCalendarEventTypesQuery = {}): Promise<ListResponse<CalendarEventType>> {
348
+ return this.client.requestWithQuery('GET', `${SCHEDULING_BASE_PATH}/calendar-event-types`, query)
349
+ }
350
+
351
+ get(key: string): Promise<CalendarEventType> {
352
+ return this.client.request('GET', `${SCHEDULING_BASE_PATH}/calendar-event-types/${encode(key)}`)
353
+ }
354
+
355
+ put(key: string, request: PutCalendarEventTypeRequest): Promise<CalendarEventType> {
356
+ return this.client.request(
357
+ 'PUT',
358
+ `${SCHEDULING_BASE_PATH}/calendar-event-types/${encode(key)}`,
359
+ request,
360
+ )
361
+ }
362
+
363
+ update(key: string, request: UpdateCalendarEventTypeRequest): Promise<CalendarEventType> {
364
+ return this.client.request(
365
+ 'PATCH',
366
+ `${SCHEDULING_BASE_PATH}/calendar-event-types/${encode(key)}`,
367
+ request,
368
+ )
369
+ }
370
+
371
+ async delete(key: string): Promise<void> {
372
+ await this.client.request(
373
+ 'DELETE',
374
+ `${SCHEDULING_BASE_PATH}/calendar-event-types/${encode(key)}`,
375
+ )
376
+ }
377
+ }
378
+
379
+ /** A user's hours and blocks. `*Mine` = the caller's own; `*ForUser` = admin path. */
380
+ export interface AvailabilityConstraintService {
381
+ listMine(query?: ListAvailabilityConstraintsQuery): Promise<ListResponse<AvailabilityConstraint>>
382
+ getMine(id: string): Promise<AvailabilityConstraint>
383
+ createMine(request: CreateAvailabilityConstraintRequest): Promise<AvailabilityConstraint>
384
+ updateMine(id: string, request: UpdateAvailabilityConstraintRequest): Promise<AvailabilityConstraint>
385
+ deleteMine(id: string): Promise<void>
386
+ listForUser(
387
+ userId: string,
388
+ query?: ListAvailabilityConstraintsQuery,
389
+ ): Promise<ListResponse<AvailabilityConstraint>>
390
+ getForUser(userId: string, id: string): Promise<AvailabilityConstraint>
391
+ createForUser(
392
+ userId: string,
393
+ request: CreateAvailabilityConstraintRequest,
394
+ ): Promise<AvailabilityConstraint>
395
+ updateForUser(
396
+ userId: string,
397
+ id: string,
398
+ request: UpdateAvailabilityConstraintRequest,
399
+ ): Promise<AvailabilityConstraint>
400
+ deleteForUser(userId: string, id: string): Promise<void>
401
+ }
402
+
403
+ class AvailabilityConstraintServiceImpl implements AvailabilityConstraintService {
404
+ constructor(private readonly client: ProteosClient) {}
405
+
406
+ private base(userId?: string): string {
407
+ return userId
408
+ ? `${SCHEDULING_BASE_PATH}/users/${encode(userId)}/availability-constraints`
409
+ : `${SCHEDULING_BASE_PATH}/me/availability-constraints`
410
+ }
411
+
412
+ listMine(query: ListAvailabilityConstraintsQuery = {}): Promise<ListResponse<AvailabilityConstraint>> {
413
+ return this.client.requestWithQuery('GET', this.base(), query)
414
+ }
415
+
416
+ getMine(id: string): Promise<AvailabilityConstraint> {
417
+ return this.client.request('GET', `${this.base()}/${encode(id)}`)
418
+ }
419
+
420
+ createMine(request: CreateAvailabilityConstraintRequest): Promise<AvailabilityConstraint> {
421
+ return this.client.request('POST', this.base(), request)
422
+ }
423
+
424
+ updateMine(id: string, request: UpdateAvailabilityConstraintRequest): Promise<AvailabilityConstraint> {
425
+ return this.client.request('PATCH', `${this.base()}/${encode(id)}`, request)
426
+ }
427
+
428
+ async deleteMine(id: string): Promise<void> {
429
+ await this.client.request('DELETE', `${this.base()}/${encode(id)}`)
430
+ }
431
+
432
+ listForUser(
433
+ userId: string,
434
+ query: ListAvailabilityConstraintsQuery = {},
435
+ ): Promise<ListResponse<AvailabilityConstraint>> {
436
+ return this.client.requestWithQuery('GET', this.base(userId), query)
437
+ }
438
+
439
+ getForUser(userId: string, id: string): Promise<AvailabilityConstraint> {
440
+ return this.client.request('GET', `${this.base(userId)}/${encode(id)}`)
441
+ }
442
+
443
+ createForUser(
444
+ userId: string,
445
+ request: CreateAvailabilityConstraintRequest,
446
+ ): Promise<AvailabilityConstraint> {
447
+ return this.client.request('POST', this.base(userId), request)
448
+ }
449
+
450
+ updateForUser(
451
+ userId: string,
452
+ id: string,
453
+ request: UpdateAvailabilityConstraintRequest,
454
+ ): Promise<AvailabilityConstraint> {
455
+ return this.client.request('PATCH', `${this.base(userId)}/${encode(id)}`, request)
456
+ }
457
+
458
+ async deleteForUser(userId: string, id: string): Promise<void> {
459
+ await this.client.request('DELETE', `${this.base(userId)}/${encode(id)}`)
460
+ }
461
+ }
462
+
463
+ /** The slot engine: bookable starts of some hosts under a type's / explicit rules. */
464
+ export interface SlotService {
465
+ get(request: GetSlotsRequest): Promise<GetSlotsResponse>
466
+ }
467
+
468
+ class SlotServiceImpl implements SlotService {
469
+ constructor(private readonly client: ProteosClient) {}
470
+
471
+ get(request: GetSlotsRequest): Promise<GetSlotsResponse> {
472
+ return this.client.request('POST', `${SCHEDULING_BASE_PATH}/slots`, request)
473
+ }
474
+ }
475
+
476
+ /** Scheduling links: the entry points for taking a slot, plus booking through one. */
477
+ export interface SchedulingLinkService {
478
+ list(query?: ListSchedulingLinksQuery): Promise<ListResponse<SchedulingLink>>
479
+ get(key: string): Promise<SchedulingLink>
480
+ create(request: CreateSchedulingLinkRequest): Promise<SchedulingLink>
481
+ update(key: string, request: UpdateSchedulingLinkRequest): Promise<SchedulingLink>
482
+ delete(key: string): Promise<void>
483
+ /** The link as an embedded scheduling picker renders it (types, hosts, policy) — private links included. */
484
+ getPage(key: string, contactId?: string): Promise<PublicSchedulingLink>
485
+ /** The link's slots (its hosts + assignment, its type's rules). */
486
+ getSlots(key: string, query: GetPublicSlotsQuery): Promise<GetSlotsResponse>
487
+ /** Take a slot through the link (scheduling-links:read); an empty contact books for the caller. */
488
+ book(key: string, request: BookSchedulingLinkRequest): Promise<BookSchedulingLinkResponse>
489
+ }
490
+
491
+ class SchedulingLinkServiceImpl implements SchedulingLinkService {
492
+ constructor(private readonly client: ProteosClient) {}
493
+
494
+ list(query: ListSchedulingLinksQuery = {}): Promise<ListResponse<SchedulingLink>> {
495
+ return this.client.requestWithQuery('GET', `${SCHEDULING_BASE_PATH}/scheduling-links`, query)
496
+ }
497
+
498
+ get(key: string): Promise<SchedulingLink> {
499
+ return this.client.request('GET', `${SCHEDULING_BASE_PATH}/scheduling-links/${encode(key)}`)
500
+ }
501
+
502
+ create(request: CreateSchedulingLinkRequest): Promise<SchedulingLink> {
503
+ return this.client.request('POST', `${SCHEDULING_BASE_PATH}/scheduling-links`, request)
504
+ }
505
+
506
+ update(key: string, request: UpdateSchedulingLinkRequest): Promise<SchedulingLink> {
507
+ return this.client.request('PATCH', `${SCHEDULING_BASE_PATH}/scheduling-links/${encode(key)}`, request)
508
+ }
509
+
510
+ async delete(key: string): Promise<void> {
511
+ await this.client.request('DELETE', `${SCHEDULING_BASE_PATH}/scheduling-links/${encode(key)}`)
512
+ }
513
+
514
+ getPage(key: string, contactId?: string): Promise<PublicSchedulingLink> {
515
+ const suffix = contactId ? `?contact_id=${encode(contactId)}` : ''
516
+ return this.client.request('GET', `${SCHEDULING_BASE_PATH}/scheduling-links/${encode(key)}/page${suffix}`)
517
+ }
518
+
519
+ getSlots(key: string, query: GetPublicSlotsQuery): Promise<GetSlotsResponse> {
520
+ return this.client.requestWithQuery('GET', `${SCHEDULING_BASE_PATH}/scheduling-links/${encode(key)}/slots`, query)
521
+ }
522
+
523
+ book(key: string, request: BookSchedulingLinkRequest): Promise<BookSchedulingLinkResponse> {
524
+ return this.client.request('POST', `${SCHEDULING_BASE_PATH}/scheduling-links/${encode(key)}/calendar-events`, request)
525
+ }
526
+ }
527
+
528
+ /**
529
+ * The unauthenticated scheduling surface: every call sends NO Authorization
530
+ * header (skipAuth), so it is safe on the anonymous /s/ routes. Links answer
531
+ * only when public + enabled; events only with their manage token.
532
+ */
533
+ export interface PublicSchedulingService {
534
+ getLink(orgId: string, key: string, contactId?: string): Promise<PublicSchedulingLink>
535
+ getSlots(orgId: string, key: string, query: GetPublicSlotsQuery): Promise<GetSlotsResponse>
536
+ book(orgId: string, key: string, request: BookSchedulingLinkRequest): Promise<PublicBookSchedulingLinkResponse>
537
+ getEvent(orgId: string, id: string, token: string): Promise<PublicCalendarEvent>
538
+ cancel(orgId: string, id: string, request: CancelPublicCalendarEventRequest): Promise<PublicCalendarEvent>
539
+ reschedule(orgId: string, id: string, request: ReschedulePublicCalendarEventRequest): Promise<PublicBookSchedulingLinkResponse>
540
+ }
541
+
542
+ class PublicSchedulingServiceImpl implements PublicSchedulingService {
543
+ constructor(private readonly client: ProteosClient) {}
544
+
545
+ private base(orgId: string): string {
546
+ return `${SCHEDULING_BASE_PATH}/public/orgs/${encode(orgId)}`
547
+ }
548
+
549
+ getLink(orgId: string, key: string, contactId?: string): Promise<PublicSchedulingLink> {
550
+ const suffix = contactId ? `?contact_id=${encode(contactId)}` : ''
551
+ return this.client.request('GET', `${this.base(orgId)}/links/${encode(key)}${suffix}`, undefined, { skipAuth: true })
552
+ }
553
+
554
+ getSlots(orgId: string, key: string, query: GetPublicSlotsQuery): Promise<GetSlotsResponse> {
555
+ const params = new URLSearchParams({ from: query.from, to: query.to, timezone: query.timezone })
556
+ if (query.host_user_id) params.set('host_user_id', query.host_user_id)
557
+ if (query.type_key) params.set('type_key', query.type_key)
558
+ return this.client.request('GET', `${this.base(orgId)}/links/${encode(key)}/slots?${params.toString()}`, undefined, { skipAuth: true })
559
+ }
560
+
561
+ book(orgId: string, key: string, request: BookSchedulingLinkRequest): Promise<PublicBookSchedulingLinkResponse> {
562
+ return this.client.request('POST', `${this.base(orgId)}/links/${encode(key)}/calendar-events`, request, { skipAuth: true })
563
+ }
564
+
565
+ getEvent(orgId: string, id: string, token: string): Promise<PublicCalendarEvent> {
566
+ return this.client.request('GET', `${this.base(orgId)}/calendar-events/${encode(id)}?token=${encode(token)}`, undefined, { skipAuth: true })
567
+ }
568
+
569
+ cancel(orgId: string, id: string, request: CancelPublicCalendarEventRequest): Promise<PublicCalendarEvent> {
570
+ return this.client.request('POST', `${this.base(orgId)}/calendar-events/${encode(id)}/cancel`, request, { skipAuth: true })
571
+ }
572
+
573
+ reschedule(orgId: string, id: string, request: ReschedulePublicCalendarEventRequest): Promise<PublicBookSchedulingLinkResponse> {
574
+ return this.client.request('POST', `${this.base(orgId)}/calendar-events/${encode(id)}/reschedule`, request, { skipAuth: true })
575
+ }
576
+ }