@acms-subir/client 0.1.19 → 0.1.21
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/README.md +16 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.js +8 -1
- package/dist/types.d.ts +77 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,13 +49,16 @@ language. Update the site before shipping an app build with a newer client.
|
|
|
49
49
|
| `calendars()` | Public calendars |
|
|
50
50
|
| `resources(opts)`, `resource(slug, opts)` | Public resources; slug lookup scans list pages |
|
|
51
51
|
| `availability(opts)` | Required `resource`, `link`; optional `from`, `days`, `minutes` |
|
|
52
|
+
| `roomFree({ room, start, end })` | Free or busy for a room the site lets people check, with the busy times and no names; never cached (core 0.3.45+) |
|
|
52
53
|
| `rsvpStatus(slug, { start })` | One event date's RSVP status: `open` or `reason` (`disabled`, `ended`, `closed` past the event's deadline, `cancelled`, `full`), `closesAt` (when RSVPs to the date close, or `null`: open until it ends), live `going`/`left` (held waitlist spots count as taken), `maxSeats` for one RSVP right now, `autoConfirm`, `waitlist` (`enabled`: a full date takes places in line; `waiting` people for `seats` seats; `maxSeats` for one place in line), and `form` (questions and `version`, or `null`). `start` is the occurrence's start exactly as `events()` returns it (a UTC ISO string such as `2026-10-05T14:00:00.000Z`). Never cached |
|
|
53
54
|
| `book(opts)` | Resource booking or RSVP input (`RsvpInput` for an RSVP; `waitlist: true` joins a full date's waitlist, status `waitlisted`), optional `idempotencyKey`; sends the client's `locale` (or `opts.locale`) for its emails |
|
|
54
55
|
| `openapi()` | Raw OpenAPI document |
|
|
55
56
|
| `registerDevice({ token, platform, locale?, topics?, channels? })` | Register or refresh an Expo push token (call on every app start); `{ created, device }`. `channels`: Android channels the app created (e.g. `['urgent']`) |
|
|
56
57
|
| `updateDevice(token, { topics?, locale?, channels? })` | Change a device's topics, language or channels |
|
|
57
|
-
| `unregisterDevice(token)` | Opt out (idempotent) |
|
|
58
|
+
| `unregisterDevice(token)` | Opt out (idempotent); also unlinks a staff test phone |
|
|
58
59
|
| `pushTopics()` | Topics to offer as notification toggles, named in the client's language (built-in and the site's own, `kind: 'site'`) |
|
|
60
|
+
| `linkStaffPhone(token, code)` | Staff only: link this registered device with the 6-digit code from the admin's Test phones, so it gets that person's test notifications; `{ linked, staff: { name } }`. A wrong, used or expired code is a 400, too many tries a 429; never retried |
|
|
61
|
+
| `unlinkStaffPhone(token)` | Unlink it (idempotent); `{ linked: false, staff: null }` |
|
|
59
62
|
| `links()` | The links page: profile, socials and visible blocks (`link`, `email`, `phone`, `contact`, `heading`, `text`, `spacer`, `live`, `embed`) |
|
|
60
63
|
| `live()` | Live video: the current broadcast (`snapshot` or `null`), `serverNow` and the owner's `display` choices. Never cached; 404 while `site.features.live` is false |
|
|
61
64
|
| `announcements({ kind?, pinned?, page?, limit? })`, `announcement(id)`, `paginate.announcements()` | Announcements up right now in the client's language, newest first (`pinned: true`: the banners, urgent first); 404 while `site.features.announcements` is false |
|
|
@@ -181,6 +184,18 @@ await client.updateDevice(token, { topics: ['events'] });
|
|
|
181
184
|
await client.unregisterDevice(token);
|
|
182
185
|
```
|
|
183
186
|
|
|
187
|
+
Staff can link their own phone for test notifications ("Send test to my
|
|
188
|
+
phone" in the admin): the admin's Test phones panel shows a one-time 6-digit
|
|
189
|
+
code (10 minutes, single use) that the app sends with this phone's token.
|
|
190
|
+
`device.staff` (from `registerDevice` and `updateDevice`) and the link
|
|
191
|
+
response name who it's linked to (their name only), or `null`. Test pushes
|
|
192
|
+
carry `data.test: true`.
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
const { staff } = await client.linkStaffPhone(token, '123456'); // { name: 'Ana López' }; 400 for a wrong, used or expired code
|
|
196
|
+
await client.unlinkStaffPhone(token); // turning notifications off unlinks it too
|
|
197
|
+
```
|
|
198
|
+
|
|
184
199
|
## Live video
|
|
185
200
|
|
|
186
201
|
`site.features.live` is true while the site's live video (Integrations → Live
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Site, Theme, Page, Content, Post, ContentList, SearchResults, Links, Form, FormReceipt, FormResponseInput, ManagedBooking, RescheduleInput, ManageAvailabilityQuery, GuestCodeSent, GuestToken, GuestBookings, GuestBookingsQuery, GuestSignedOut, Events, Event, Calendars, Resources, Resource, Availability, BookingInput, BookingResult, RsvpStatus, Device, DeviceInput, DeviceUpdate, DeviceRegistration, DeviceRemoved, PushTopics, LiveStatus, Announcements, AnnouncementDetail, EventDetail } from './types.js';
|
|
1
|
+
import type { Site, Theme, Page, Content, Post, ContentList, SearchResults, Links, Form, FormReceipt, FormResponseInput, ManagedBooking, RescheduleInput, ManageAvailabilityQuery, GuestCodeSent, GuestToken, GuestBookings, GuestBookingsQuery, GuestSignedOut, Events, Event, Calendars, Resources, Resource, Availability, BookingInput, BookingResult, RsvpStatus, Device, DeviceInput, DeviceUpdate, DeviceRegistration, DeviceRemoved, StaffLink, PushTopics, LiveStatus, Announcements, AnnouncementDetail, EventDetail, RoomFree } from './types.js';
|
|
2
2
|
export { AcmsError, isAcmsError } from './errors.js';
|
|
3
3
|
export type * from './types.js';
|
|
4
4
|
export * from './editor.js';
|
|
@@ -60,6 +60,12 @@ export interface AvailabilityOptions extends RequestOptions {
|
|
|
60
60
|
export interface RsvpStatusOptions extends RequestOptions {
|
|
61
61
|
start: string;
|
|
62
62
|
}
|
|
63
|
+
/** A room's slug and a span: each bound a site-local day (its midnight) or an ISO date-time with a zone; at most 31 days. */
|
|
64
|
+
export interface RoomFreeOptions extends RequestOptions {
|
|
65
|
+
room: string;
|
|
66
|
+
start: EventBound | (string & {});
|
|
67
|
+
end: EventBound | (string & {});
|
|
68
|
+
}
|
|
63
69
|
export type BookOptions = BookingInput & RequestOptions & {
|
|
64
70
|
idempotencyKey?: string;
|
|
65
71
|
};
|
|
@@ -145,6 +151,10 @@ export declare const endpoints: {
|
|
|
145
151
|
readonly method: "GET";
|
|
146
152
|
readonly path: "/availability";
|
|
147
153
|
};
|
|
154
|
+
readonly roomFree: {
|
|
155
|
+
readonly method: "GET";
|
|
156
|
+
readonly path: "/rooms/free";
|
|
157
|
+
};
|
|
148
158
|
readonly book: {
|
|
149
159
|
readonly method: "POST";
|
|
150
160
|
readonly path: "/bookings";
|
|
@@ -169,6 +179,14 @@ export declare const endpoints: {
|
|
|
169
179
|
readonly method: "GET";
|
|
170
180
|
readonly path: "/push/topics";
|
|
171
181
|
};
|
|
182
|
+
readonly linkStaffPhone: {
|
|
183
|
+
readonly method: "POST";
|
|
184
|
+
readonly path: "/devices/{token}/staff-link";
|
|
185
|
+
};
|
|
186
|
+
readonly unlinkStaffPhone: {
|
|
187
|
+
readonly method: "DELETE";
|
|
188
|
+
readonly path: "/devices/{token}/staff-link";
|
|
189
|
+
};
|
|
172
190
|
readonly links: {
|
|
173
191
|
readonly method: "GET";
|
|
174
192
|
readonly path: "/links";
|
|
@@ -268,6 +286,11 @@ export interface AcmsClient {
|
|
|
268
286
|
* RSVP with `book({ event, start, seats, name, email, answers, formVersion: form.version })`.
|
|
269
287
|
*/
|
|
270
288
|
rsvpStatus(slug: string, o: RsvpStatusOptions): Promise<RsvpStatus>;
|
|
289
|
+
/**
|
|
290
|
+
* Whether a room is free over a span (`free`), and its taken times (`busy`), never what or who. Only rooms the site
|
|
291
|
+
* lets people check answer; others are a 404. Never cached; 30 checks a minute. Requires bookings and core 0.3.45.
|
|
292
|
+
*/
|
|
293
|
+
roomFree(o: RoomFreeOptions): Promise<RoomFree>;
|
|
271
294
|
/** A room booking or an RSVP. Sends the client's `locale` (or `o.locale`), so its emails and links speak it. */
|
|
272
295
|
book(o: BookOptions): Promise<BookingResult>;
|
|
273
296
|
openapi(o?: RequestOptions): Promise<OpenApiDocument>;
|
|
@@ -279,6 +302,14 @@ export interface AcmsClient {
|
|
|
279
302
|
unregisterDevice(token: string, o?: RequestOptions): Promise<DeviceRemoved>;
|
|
280
303
|
/** Topics the app can offer as notification toggles. */
|
|
281
304
|
pushTopics(o?: RequestOptions): Promise<PushTopics>;
|
|
305
|
+
/**
|
|
306
|
+
* Staff only: link this registered device to the staff member whose one-time code (Admin → Test phones) it sends,
|
|
307
|
+
* so it gets their test notifications. `{ linked: true, staff: { name } }`. A wrong, used or expired code is a 400;
|
|
308
|
+
* too many tries a 429 (never retried). Sites without it (or with push off) answer 404.
|
|
309
|
+
*/
|
|
310
|
+
linkStaffPhone(token: string, code: string, o?: RequestOptions): Promise<StaffLink>;
|
|
311
|
+
/** Unlink it (idempotent). Turning notifications off (`unregisterDevice`) unlinks it too. */
|
|
312
|
+
unlinkStaffPhone(token: string, o?: RequestOptions): Promise<StaffLink>;
|
|
282
313
|
/** The links page: profile, socials and visible blocks. Requires `site.features.links`. */
|
|
283
314
|
links(o?: RequestOptions): Promise<Links>;
|
|
284
315
|
/**
|
package/dist/index.js
CHANGED
|
@@ -11,10 +11,14 @@ export const endpoints = {
|
|
|
11
11
|
// an event date's RSVP status: live seats and questions (never cached); RSVP with book()
|
|
12
12
|
rsvpStatus: { method: 'GET', path: '/events/{slug}/rsvp' },
|
|
13
13
|
resources: { method: 'GET', path: '/resources' }, availability: { method: 'GET', path: '/availability' },
|
|
14
|
+
// free or busy for a room people may request (no names; never cached)
|
|
15
|
+
roomFree: { method: 'GET', path: '/rooms/free' },
|
|
14
16
|
book: { method: 'POST', path: '/bookings' }, openapi: { method: 'GET', path: '/openapi.json' },
|
|
15
17
|
// push notifications (only when the site enables push; 404 otherwise)
|
|
16
18
|
registerDevice: { method: 'POST', path: '/devices' }, updateDevice: { method: 'PUT', path: '/devices/{token}' },
|
|
17
19
|
unregisterDevice: { method: 'DELETE', path: '/devices/{token}' }, pushTopics: { method: 'GET', path: '/push/topics' },
|
|
20
|
+
// a staff member's own test phone (a one-time code from the admin's Test phones)
|
|
21
|
+
linkStaffPhone: { method: 'POST', path: '/devices/{token}/staff-link' }, unlinkStaffPhone: { method: 'DELETE', path: '/devices/{token}/staff-link' },
|
|
18
22
|
// links page and forms (owner switches in Admin → Mobile app)
|
|
19
23
|
links: { method: 'GET', path: '/links' }, form: { method: 'GET', path: '/forms/{id}' }, submitForm: { method: 'POST', path: '/forms/{id}/responses' },
|
|
20
24
|
// live video status (404 while the site's live video is off)
|
|
@@ -117,7 +121,7 @@ export function createClient(options) {
|
|
|
117
121
|
const timer = setTimeout(() => controller.abort(new AcmsError(0, 'timeout', 'Request timed out.', undefined, undefined, key)), timeoutMs);
|
|
118
122
|
const signal = controller.signal;
|
|
119
123
|
// availability, live status and RSVP seats are never served from the cache
|
|
120
|
-
const cacheable = endpoint.method === 'GET' && name !== 'availability' && name !== 'live' && name !== 'rsvpStatus' && !extra.headers && cache;
|
|
124
|
+
const cacheable = endpoint.method === 'GET' && name !== 'availability' && name !== 'live' && name !== 'rsvpStatus' && name !== 'roomFree' && !extra.headers && cache;
|
|
121
125
|
// only replay what the server treats as repeatable: a lost reply to a code
|
|
122
126
|
// exchange or a move must not run it twice
|
|
123
127
|
const replayable = endpoint.method !== 'POST' || !!key || name === 'registerDevice';
|
|
@@ -291,6 +295,7 @@ export function createClient(options) {
|
|
|
291
295
|
calendars: (o = {}) => request('calendars', o),
|
|
292
296
|
availability: (o) => request('availability', o, { resource: o.resource, link: o.link, from: o.from, days: o.days, minutes: o.minutes }),
|
|
293
297
|
rsvpStatus: (slug, o) => request('rsvpStatus', o, { start: o.start }, slug),
|
|
298
|
+
roomFree: (o) => request('roomFree', o, { room: o.room, start: o.start, end: o.end }),
|
|
294
299
|
async book(o) {
|
|
295
300
|
const { locale = options.locale, signal, idempotencyKey, ...body } = o;
|
|
296
301
|
const key = idempotencyKey ?? defaultHeaders.get('Idempotency-Key') ?? uuid();
|
|
@@ -313,6 +318,8 @@ export function createClient(options) {
|
|
|
313
318
|
updateDevice: (token, input, o = {}) => request('updateDevice', o, {}, token, input),
|
|
314
319
|
unregisterDevice: (token, o = {}) => request('unregisterDevice', o, {}, token),
|
|
315
320
|
pushTopics: (o = {}) => request('pushTopics', o),
|
|
321
|
+
linkStaffPhone: (token, code, o = {}) => request('linkStaffPhone', o, {}, token, { code }),
|
|
322
|
+
unlinkStaffPhone: (token, o = {}) => request('unlinkStaffPhone', o, {}, token),
|
|
316
323
|
links: (o = {}) => request('links', o),
|
|
317
324
|
live: (o = {}) => request('live', o),
|
|
318
325
|
form: (id, o = {}) => request('form', o, {}, id),
|
package/dist/types.d.ts
CHANGED
|
@@ -181,6 +181,11 @@ export type Page = {
|
|
|
181
181
|
};
|
|
182
182
|
}>;
|
|
183
183
|
};
|
|
184
|
+
export type EventRoom = {
|
|
185
|
+
"slug": string;
|
|
186
|
+
"name": string;
|
|
187
|
+
"color": string | null;
|
|
188
|
+
};
|
|
184
189
|
export type Event = {
|
|
185
190
|
"id": string;
|
|
186
191
|
"slug": string;
|
|
@@ -254,6 +259,11 @@ export type Event = {
|
|
|
254
259
|
"name": string;
|
|
255
260
|
"color": string;
|
|
256
261
|
}>;
|
|
262
|
+
"rooms": Array<{
|
|
263
|
+
"slug": string;
|
|
264
|
+
"name": string;
|
|
265
|
+
"color": string | null;
|
|
266
|
+
}>;
|
|
257
267
|
"notify": {
|
|
258
268
|
"changes": Array<string>;
|
|
259
269
|
};
|
|
@@ -274,6 +284,11 @@ export type Events = {
|
|
|
274
284
|
"end": string;
|
|
275
285
|
"allDay": boolean;
|
|
276
286
|
"cancelled": boolean;
|
|
287
|
+
"rooms": Array<{
|
|
288
|
+
"slug": string;
|
|
289
|
+
"name": string;
|
|
290
|
+
"color": string | null;
|
|
291
|
+
}>;
|
|
277
292
|
"event": {
|
|
278
293
|
"id": string;
|
|
279
294
|
"slug": string;
|
|
@@ -347,6 +362,11 @@ export type Events = {
|
|
|
347
362
|
"name": string;
|
|
348
363
|
"color": string;
|
|
349
364
|
}>;
|
|
365
|
+
"rooms": Array<{
|
|
366
|
+
"slug": string;
|
|
367
|
+
"name": string;
|
|
368
|
+
"color": string | null;
|
|
369
|
+
}>;
|
|
350
370
|
"notify": {
|
|
351
371
|
"changes": Array<string>;
|
|
352
372
|
};
|
|
@@ -361,6 +381,11 @@ export type EventDetail = {
|
|
|
361
381
|
"end": string;
|
|
362
382
|
"allDay": boolean;
|
|
363
383
|
"cancelled": boolean;
|
|
384
|
+
"rooms": Array<{
|
|
385
|
+
"slug": string;
|
|
386
|
+
"name": string;
|
|
387
|
+
"color": string | null;
|
|
388
|
+
}>;
|
|
364
389
|
}) | (null);
|
|
365
390
|
"event": {
|
|
366
391
|
"id": string;
|
|
@@ -435,6 +460,11 @@ export type EventDetail = {
|
|
|
435
460
|
"name": string;
|
|
436
461
|
"color": string;
|
|
437
462
|
}>;
|
|
463
|
+
"rooms": Array<{
|
|
464
|
+
"slug": string;
|
|
465
|
+
"name": string;
|
|
466
|
+
"color": string | null;
|
|
467
|
+
}>;
|
|
438
468
|
"notify": {
|
|
439
469
|
"changes": Array<string>;
|
|
440
470
|
};
|
|
@@ -502,6 +532,11 @@ export type SearchResults = {
|
|
|
502
532
|
"end": string;
|
|
503
533
|
"allDay": boolean;
|
|
504
534
|
"cancelled": boolean;
|
|
535
|
+
"rooms": Array<{
|
|
536
|
+
"slug": string;
|
|
537
|
+
"name": string;
|
|
538
|
+
"color": string | null;
|
|
539
|
+
}>;
|
|
505
540
|
}) | (null);
|
|
506
541
|
"event": {
|
|
507
542
|
"id": string;
|
|
@@ -576,6 +611,11 @@ export type SearchResults = {
|
|
|
576
611
|
"name": string;
|
|
577
612
|
"color": string;
|
|
578
613
|
}>;
|
|
614
|
+
"rooms": Array<{
|
|
615
|
+
"slug": string;
|
|
616
|
+
"name": string;
|
|
617
|
+
"color": string | null;
|
|
618
|
+
}>;
|
|
579
619
|
"notify": {
|
|
580
620
|
"changes": Array<string>;
|
|
581
621
|
};
|
|
@@ -876,6 +916,19 @@ export type Resources = {
|
|
|
876
916
|
}>;
|
|
877
917
|
}>;
|
|
878
918
|
};
|
|
919
|
+
export type RoomFree = {
|
|
920
|
+
"room": {
|
|
921
|
+
"slug": string;
|
|
922
|
+
"name": string;
|
|
923
|
+
};
|
|
924
|
+
"start": string;
|
|
925
|
+
"end": string;
|
|
926
|
+
"free": boolean;
|
|
927
|
+
"busy": Array<{
|
|
928
|
+
"start": string;
|
|
929
|
+
"end": string;
|
|
930
|
+
}>;
|
|
931
|
+
};
|
|
879
932
|
export type Availability = {
|
|
880
933
|
"timezone": string;
|
|
881
934
|
"mode": "slots" | "day" | "range";
|
|
@@ -943,6 +996,9 @@ export type Device = {
|
|
|
943
996
|
"channels": Array<string>;
|
|
944
997
|
"registeredAt": string;
|
|
945
998
|
"lastSeenAt": string;
|
|
999
|
+
"staff": ({
|
|
1000
|
+
"name": string;
|
|
1001
|
+
}) | (null);
|
|
946
1002
|
};
|
|
947
1003
|
export type DeviceRegistration = {
|
|
948
1004
|
"created": boolean;
|
|
@@ -954,12 +1010,21 @@ export type DeviceRegistration = {
|
|
|
954
1010
|
"channels": Array<string>;
|
|
955
1011
|
"registeredAt": string;
|
|
956
1012
|
"lastSeenAt": string;
|
|
1013
|
+
"staff": ({
|
|
1014
|
+
"name": string;
|
|
1015
|
+
}) | (null);
|
|
957
1016
|
};
|
|
958
1017
|
};
|
|
959
1018
|
export type DeviceRemoved = {
|
|
960
1019
|
"token": string;
|
|
961
1020
|
"deleted": true;
|
|
962
1021
|
};
|
|
1022
|
+
export type StaffLink = {
|
|
1023
|
+
"linked": boolean;
|
|
1024
|
+
"staff": ({
|
|
1025
|
+
"name": string;
|
|
1026
|
+
}) | (null);
|
|
1027
|
+
};
|
|
963
1028
|
export type PushTopics = {
|
|
964
1029
|
"locale": string | null;
|
|
965
1030
|
"topics": Array<{
|
|
@@ -1727,6 +1792,9 @@ export type EditorResource = {
|
|
|
1727
1792
|
"notifyEmails": Array<string>;
|
|
1728
1793
|
"visibility": "public" | "unlisted";
|
|
1729
1794
|
"showOnCalendar": boolean;
|
|
1795
|
+
"color": string;
|
|
1796
|
+
"showOnEvents": boolean;
|
|
1797
|
+
"requestable": boolean;
|
|
1730
1798
|
"placeId": string;
|
|
1731
1799
|
"order": number;
|
|
1732
1800
|
"createdAt": string;
|
|
@@ -1861,6 +1929,9 @@ export type EditorResourceList = {
|
|
|
1861
1929
|
"notifyEmails": Array<string>;
|
|
1862
1930
|
"visibility": "public" | "unlisted";
|
|
1863
1931
|
"showOnCalendar": boolean;
|
|
1932
|
+
"color": string;
|
|
1933
|
+
"showOnEvents": boolean;
|
|
1934
|
+
"requestable": boolean;
|
|
1864
1935
|
"placeId": string;
|
|
1865
1936
|
"order": number;
|
|
1866
1937
|
"createdAt": string;
|
|
@@ -2324,6 +2395,9 @@ export type EditorResourceInput = {
|
|
|
2324
2395
|
"visibility"?: "public" | "unlisted";
|
|
2325
2396
|
"showOnCalendar"?: boolean;
|
|
2326
2397
|
"placeId"?: string;
|
|
2398
|
+
"color"?: ("") | (string);
|
|
2399
|
+
"showOnEvents"?: boolean;
|
|
2400
|
+
"requestable"?: boolean;
|
|
2327
2401
|
"busyFeeds"?: Array<string>;
|
|
2328
2402
|
"notifyEmails"?: Array<string>;
|
|
2329
2403
|
};
|
|
@@ -2378,6 +2452,9 @@ export type EditorResourcePatch = {
|
|
|
2378
2452
|
"visibility"?: "public" | "unlisted";
|
|
2379
2453
|
"showOnCalendar"?: boolean;
|
|
2380
2454
|
"placeId"?: string;
|
|
2455
|
+
"color"?: ("") | (string);
|
|
2456
|
+
"showOnEvents"?: boolean;
|
|
2457
|
+
"requestable"?: boolean;
|
|
2381
2458
|
"busyFeeds"?: Array<string>;
|
|
2382
2459
|
"notifyEmails"?: Array<string>;
|
|
2383
2460
|
};
|