@acms-subir/client 0.1.16 → 0.1.18
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 +4 -2
- package/dist/index.d.ts +10 -1
- package/dist/index.js +12 -3
- package/dist/types.d.ts +101 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,11 +44,12 @@ language. Update the site before shipping an app build with a newer client.
|
|
|
44
44
|
| `pages(opts)` | Page **summaries**, with pagination; use `page()` for sections |
|
|
45
45
|
| `search(text, opts)` | Top matches in `posts`, `pages` and `events`, plus `more` per group; `types`, `collection`, `limit` (1–20, default 5). Blank text resolves empty without a request |
|
|
46
46
|
| `events(opts)` | Occurrences with `from`, `to`, `calendar`, `tag`, `excludeTag`, `q`, pagination |
|
|
47
|
-
| `event(slug, opts)` |
|
|
47
|
+
| `event(slug, opts)` | One event by slug, whatever its date (`GET /events/{slug}`; on sites older than core 0.3.40, the first match in the requested window) |
|
|
48
|
+
| `eventDetail(slug, { on? })` | The event and its next occurrence, or the one on `on` (`YYYY-MM-DD`) |
|
|
48
49
|
| `calendars()` | Public calendars |
|
|
49
50
|
| `resources(opts)`, `resource(slug, opts)` | Public resources; slug lookup scans list pages |
|
|
50
51
|
| `availability(opts)` | Required `resource`, `link`; optional `from`, `days`, `minutes` |
|
|
51
|
-
| `rsvpStatus(slug, { start })` | One event date's RSVP status: `open` or `reason` (`disabled`, `ended`, `cancelled`, `full`), live `going`/`left`, `maxSeats` for one RSVP right now, `autoConfirm`, 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 |
|
|
52
|
+
| `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`, `maxSeats` for one RSVP right now, `autoConfirm`, 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 |
|
|
52
53
|
| `book(opts)` | Resource booking or RSVP input (`RsvpInput` for an RSVP), optional `idempotencyKey`; sends the client's `locale` (or `opts.locale`) for its emails |
|
|
53
54
|
| `openapi()` | Raw OpenAPI document |
|
|
54
55
|
| `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']`) |
|
|
@@ -121,6 +122,7 @@ if (status.open) {
|
|
|
121
122
|
// required when the event asks questions: a changed form answers 409, so read the status again
|
|
122
123
|
...(status.form ? { formVersion: status.form.version } : {}),
|
|
123
124
|
};
|
|
125
|
+
// an email that already has an RSVP for this date: AcmsError 409 with code 'duplicate' (its link is emailed again)
|
|
124
126
|
const result = await client.book({ ...rsvp, idempotencyKey: crypto.randomUUID() });
|
|
125
127
|
// pending when the organiser approves RSVPs; status.form?.confirmation is the thank-you text.
|
|
126
128
|
// result.manageToken changes or cancels it later (manageBooking, cancelBooking), like the email's link:
|
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 } 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, PushTopics, LiveStatus, Announcements, AnnouncementDetail, EventDetail } from './types.js';
|
|
2
2
|
export { AcmsError, isAcmsError } from './errors.js';
|
|
3
3
|
export type * from './types.js';
|
|
4
4
|
export * from './editor.js';
|
|
@@ -125,6 +125,10 @@ export declare const endpoints: {
|
|
|
125
125
|
readonly method: "GET";
|
|
126
126
|
readonly path: "/events";
|
|
127
127
|
};
|
|
128
|
+
readonly eventDetail: {
|
|
129
|
+
readonly method: "GET";
|
|
130
|
+
readonly path: "/events/{slug}";
|
|
131
|
+
};
|
|
128
132
|
readonly calendars: {
|
|
129
133
|
readonly method: "GET";
|
|
130
134
|
readonly path: "/calendars";
|
|
@@ -244,7 +248,12 @@ export interface AcmsClient {
|
|
|
244
248
|
/** Ranked matches across posts, pages and events, the top few per group. Requires `site.features.search`. */
|
|
245
249
|
search(q: string, o?: SearchOptions): Promise<SearchResults>;
|
|
246
250
|
events(o?: EventOptions): Promise<Events>;
|
|
251
|
+
/** One event by slug, whatever its date (older sites: searched in the window). */
|
|
247
252
|
event(slug: string, o?: EventOptions): Promise<Event>;
|
|
253
|
+
/** One event by slug or id with its next occurrence, or the one on `on` (YYYY-MM-DD, like the website's ?on=). */
|
|
254
|
+
eventDetail(slug: string, o?: RequestOptions & {
|
|
255
|
+
on?: string;
|
|
256
|
+
}): Promise<EventDetail>;
|
|
248
257
|
calendars(o?: RequestOptions): Promise<Calendars>;
|
|
249
258
|
resources(o?: ListOptions): Promise<Resources>;
|
|
250
259
|
resource(slug: string, o?: RequestOptions): Promise<Resource>;
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ export const endpoints = {
|
|
|
7
7
|
home: { method: 'GET', path: '/pages/home' }, page: { method: 'GET', path: '/pages/{slug}' },
|
|
8
8
|
content: { method: 'GET', path: '/content' }, contentById: { method: 'GET', path: '/content/{id}' },
|
|
9
9
|
search: { method: 'GET', path: '/search' },
|
|
10
|
-
events: { method: 'GET', path: '/events' }, calendars: { method: 'GET', path: '/calendars' },
|
|
10
|
+
events: { method: 'GET', path: '/events' }, eventDetail: { method: 'GET', path: '/events/{slug}' }, calendars: { method: 'GET', path: '/calendars' },
|
|
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' },
|
|
@@ -30,7 +30,7 @@ export const endpoints = {
|
|
|
30
30
|
guestBookings: { method: 'GET', path: '/guest/bookings' }, guestSignOut: { method: 'POST', path: '/guest/revoke' },
|
|
31
31
|
};
|
|
32
32
|
// site: its legal links; pushTopics: topic names
|
|
33
|
-
const localized = new Set(['home', 'page', 'content', 'contentById', 'search', 'events', 'rsvpStatus', 'site', 'pushTopics', 'announcements', 'announcement']);
|
|
33
|
+
const localized = new Set(['home', 'page', 'content', 'contentById', 'search', 'events', 'rsvpStatus', 'site', 'pushTopics', 'announcements', 'announcement', 'eventDetail']);
|
|
34
34
|
// localized since core 0.3.32; older sites answer ?locale= with a 400, so ask them again without it
|
|
35
35
|
const lateLocalized = new Set(['site', 'pushTopics']);
|
|
36
36
|
function uuid() {
|
|
@@ -264,8 +264,17 @@ export function createClient(options) {
|
|
|
264
264
|
return request('contentById', o, { kind: 'post' }, item.id);
|
|
265
265
|
throw new AcmsError(404, 'not_found', 'Post not found.');
|
|
266
266
|
},
|
|
267
|
-
|
|
267
|
+
eventDetail: (slug, o = {}) => request('eventDetail', o, { on: o.on }, slug),
|
|
268
|
+
/** One event by slug, whatever its date. Sites older than core 0.3.40 have no such route: then it searches occurrences in the window (default: next 30 days). */
|
|
268
269
|
async event(slug, o = {}) {
|
|
270
|
+
try {
|
|
271
|
+
return (await request('eventDetail', o, {}, slug)).event;
|
|
272
|
+
}
|
|
273
|
+
catch (e) {
|
|
274
|
+
// a real "not found" comes as JSON with code not_found; an older site answers its HTML 404 page
|
|
275
|
+
if (!(e instanceof AcmsError) || e.status !== 404 || e.code === 'not_found')
|
|
276
|
+
throw e;
|
|
277
|
+
}
|
|
269
278
|
for await (const item of paginate.events(o))
|
|
270
279
|
if (item.event.slug === slug)
|
|
271
280
|
return item.event;
|
package/dist/types.d.ts
CHANGED
|
@@ -221,6 +221,8 @@ export type Event = {
|
|
|
221
221
|
"capacity": number;
|
|
222
222
|
"autoConfirm": boolean;
|
|
223
223
|
"maxSeats": number;
|
|
224
|
+
"closesAt": string | null;
|
|
225
|
+
"closeBefore": number;
|
|
224
226
|
"form"?: {
|
|
225
227
|
"title": string;
|
|
226
228
|
"intro": string;
|
|
@@ -311,6 +313,8 @@ export type Events = {
|
|
|
311
313
|
"capacity": number;
|
|
312
314
|
"autoConfirm": boolean;
|
|
313
315
|
"maxSeats": number;
|
|
316
|
+
"closesAt": string | null;
|
|
317
|
+
"closeBefore": number;
|
|
314
318
|
"form"?: {
|
|
315
319
|
"title": string;
|
|
316
320
|
"intro": string;
|
|
@@ -347,6 +351,92 @@ export type Events = {
|
|
|
347
351
|
};
|
|
348
352
|
}>;
|
|
349
353
|
};
|
|
354
|
+
export type EventDetail = {
|
|
355
|
+
"locale": string | null;
|
|
356
|
+
"occurrence": ({
|
|
357
|
+
"id": string;
|
|
358
|
+
"start": string;
|
|
359
|
+
"end": string;
|
|
360
|
+
"allDay": boolean;
|
|
361
|
+
"cancelled": boolean;
|
|
362
|
+
}) | (null);
|
|
363
|
+
"event": {
|
|
364
|
+
"id": string;
|
|
365
|
+
"slug": string;
|
|
366
|
+
"title": string;
|
|
367
|
+
"excerpt": string;
|
|
368
|
+
"status": "draft" | "scheduled" | "published" | "archived";
|
|
369
|
+
"cancelled": boolean;
|
|
370
|
+
"featured": boolean;
|
|
371
|
+
"start": string;
|
|
372
|
+
"end": string;
|
|
373
|
+
"allDay": boolean;
|
|
374
|
+
"timezone": string;
|
|
375
|
+
"rrule": string;
|
|
376
|
+
"exdates": Array<string>;
|
|
377
|
+
"cancelledDates": Array<string>;
|
|
378
|
+
"location": {
|
|
379
|
+
"name": string;
|
|
380
|
+
"address": string;
|
|
381
|
+
"url": string;
|
|
382
|
+
"lat": number | null;
|
|
383
|
+
"lng": number | null;
|
|
384
|
+
"placeId": string;
|
|
385
|
+
"showMap": boolean;
|
|
386
|
+
"mapImage": string;
|
|
387
|
+
"mapImageDark": string;
|
|
388
|
+
};
|
|
389
|
+
"cta": {
|
|
390
|
+
"label": string;
|
|
391
|
+
"href": string;
|
|
392
|
+
"style": "primary" | "outline";
|
|
393
|
+
};
|
|
394
|
+
"tags": Array<string>;
|
|
395
|
+
"fields": {
|
|
396
|
+
[key: string]: string;
|
|
397
|
+
};
|
|
398
|
+
"rsvp": {
|
|
399
|
+
"enabled": boolean;
|
|
400
|
+
"capacity": number;
|
|
401
|
+
"autoConfirm": boolean;
|
|
402
|
+
"maxSeats": number;
|
|
403
|
+
"closesAt": string | null;
|
|
404
|
+
"closeBefore": number;
|
|
405
|
+
"form"?: {
|
|
406
|
+
"title": string;
|
|
407
|
+
"intro": string;
|
|
408
|
+
"submitLabel": string;
|
|
409
|
+
"confirmation": string;
|
|
410
|
+
"fields": Array<{
|
|
411
|
+
"id": string;
|
|
412
|
+
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
|
|
413
|
+
"label": string;
|
|
414
|
+
"required": boolean;
|
|
415
|
+
"help": string;
|
|
416
|
+
"options": Array<string>;
|
|
417
|
+
"placeholder"?: string;
|
|
418
|
+
"width"?: "full" | "half";
|
|
419
|
+
"allowOther"?: boolean;
|
|
420
|
+
}>;
|
|
421
|
+
};
|
|
422
|
+
};
|
|
423
|
+
"url": string;
|
|
424
|
+
"icsUrl": string;
|
|
425
|
+
"repeats": string;
|
|
426
|
+
"image": string;
|
|
427
|
+
"imageAlt": string;
|
|
428
|
+
"updatedAt": string;
|
|
429
|
+
"calendars": Array<{
|
|
430
|
+
"id": string;
|
|
431
|
+
"slug": string;
|
|
432
|
+
"name": string;
|
|
433
|
+
"color": string;
|
|
434
|
+
}>;
|
|
435
|
+
"notify": {
|
|
436
|
+
"changes": Array<string>;
|
|
437
|
+
};
|
|
438
|
+
};
|
|
439
|
+
};
|
|
350
440
|
export type SearchResults = {
|
|
351
441
|
"locale": string | null;
|
|
352
442
|
"query": string;
|
|
@@ -450,6 +540,8 @@ export type SearchResults = {
|
|
|
450
540
|
"capacity": number;
|
|
451
541
|
"autoConfirm": boolean;
|
|
452
542
|
"maxSeats": number;
|
|
543
|
+
"closesAt": string | null;
|
|
544
|
+
"closeBefore": number;
|
|
453
545
|
"form"?: {
|
|
454
546
|
"title": string;
|
|
455
547
|
"intro": string;
|
|
@@ -610,12 +702,13 @@ export type RsvpStatus = {
|
|
|
610
702
|
"start": string;
|
|
611
703
|
"end": string;
|
|
612
704
|
"open": boolean;
|
|
613
|
-
"reason": ("disabled" | "ended" | "cancelled" | "full") | (null);
|
|
705
|
+
"reason": ("disabled" | "ended" | "closed" | "cancelled" | "full") | (null);
|
|
614
706
|
"going": number;
|
|
615
707
|
"left": (number) | (null);
|
|
616
708
|
"capacity": number;
|
|
617
709
|
"maxSeats": number;
|
|
618
710
|
"autoConfirm": boolean;
|
|
711
|
+
"closesAt": (string) | (null);
|
|
619
712
|
"form": ({
|
|
620
713
|
"version": string;
|
|
621
714
|
"title": string;
|
|
@@ -967,7 +1060,7 @@ export type LiveStatus = {
|
|
|
967
1060
|
export type ApiErrorResponse = {
|
|
968
1061
|
"version": 1;
|
|
969
1062
|
"error": {
|
|
970
|
-
"code": "invalid_request" | "unauthorized" | "forbidden" | "not_found" | "method_not_allowed" | "conflict" | "gone" | "payload_too_large" | "unsupported_media_type" | "rate_limited" | "upstream_error" | "internal_error";
|
|
1063
|
+
"code": "invalid_request" | "unauthorized" | "forbidden" | "not_found" | "method_not_allowed" | "conflict" | "duplicate" | "gone" | "payload_too_large" | "unsupported_media_type" | "rate_limited" | "upstream_error" | "internal_error";
|
|
971
1064
|
"message": string;
|
|
972
1065
|
"issues"?: Array<{
|
|
973
1066
|
"path": Array<string | number>;
|
|
@@ -1153,6 +1246,9 @@ export type EditorDocument = {
|
|
|
1153
1246
|
"capacity": number;
|
|
1154
1247
|
"autoConfirm": boolean;
|
|
1155
1248
|
"maxSeats": number;
|
|
1249
|
+
"closesAt": string | null;
|
|
1250
|
+
"closeBefore": number;
|
|
1251
|
+
"notifyStaff": boolean;
|
|
1156
1252
|
"form"?: {
|
|
1157
1253
|
"title": string;
|
|
1158
1254
|
"intro": string;
|
|
@@ -2083,6 +2179,9 @@ export type EditorSaveInput = {
|
|
|
2083
2179
|
"capacity": number;
|
|
2084
2180
|
"autoConfirm": boolean;
|
|
2085
2181
|
"maxSeats": number;
|
|
2182
|
+
"closesAt"?: (string) | (null);
|
|
2183
|
+
"closeBefore"?: number;
|
|
2184
|
+
"notifyStaff"?: boolean;
|
|
2086
2185
|
"form"?: {
|
|
2087
2186
|
"title"?: string;
|
|
2088
2187
|
"intro"?: string;
|