@acms-subir/client 0.1.13 → 0.1.15

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 CHANGED
@@ -45,14 +45,16 @@ site before shipping an app build with a newer client.
45
45
  | `calendars()` | Public calendars |
46
46
  | `resources(opts)`, `resource(slug, opts)` | Public resources; slug lookup scans list pages |
47
47
  | `availability(opts)` | Required `resource`, `link`; optional `from`, `days`, `minutes` |
48
- | `book(opts)` | Resource booking or RSVP input, optional `idempotencyKey` |
48
+ | `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 |
49
+ | `book(opts)` | Resource booking or RSVP input (`RsvpInput` for an RSVP), optional `idempotencyKey` |
49
50
  | `openapi()` | Raw OpenAPI document |
50
- | `registerDevice({ token, platform, locale?, topics? })` | Register or refresh an Expo push token (call on every app start); `{ created, device }` |
51
- | `updateDevice(token, { topics?, locale? })` | Change a device's topics or language |
51
+ | `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']`) |
52
+ | `updateDevice(token, { topics?, locale?, channels? })` | Change a device's topics, language or channels |
52
53
  | `unregisterDevice(token)` | Opt out (idempotent) |
53
54
  | `pushTopics()` | Topics to offer as notification toggles, named in the client's language (built-in and the site's own, `kind: 'site'`) |
54
55
  | `links()` | The links page: profile, socials and visible blocks (`link`, `email`, `phone`, `contact`, `heading`, `text`, `spacer`, `live`, `embed`) |
55
56
  | `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 |
57
+ | `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 |
56
58
  | `form(id)`, `submitForm(id, { answers, version?, idempotencyKey? })` | A published form's questions; send answers (checkbox groups as arrays). Each call makes one key; retries reuse it |
57
59
  | `manageBooking(token)`, `cancelBooking(token)` | The booker's own booking from its `manageToken`, and cancelling it; `can` says what is allowed |
58
60
  | `rescheduleAvailability(token, { from?, days?, minutes? })`, `rescheduleBooking(token, { start, minutes? })` | Open times for moving it (its own time counts as free), then the move |
@@ -86,6 +88,8 @@ server results or provide snapshot consistency; deduplicate IDs in your app.
86
88
  ## Bookings, errors and cancellation
87
89
 
88
90
  ```ts
91
+ import type { RsvpInput } from '@acms-subir/client';
92
+
89
93
  // Persist a UUID v4 with this booking intent before submitting; reuse it until
90
94
  // the outcome is known. Use your platform's secure UUID/storage facilities.
91
95
  const idempotencyKey = crypto.randomUUID();
@@ -102,6 +106,25 @@ try {
102
106
  }
103
107
  }
104
108
 
109
+ // RSVP to one date of an event (needs only the calendar: site.features.rsvp)
110
+ const { occurrences } = await client.events({ q: 'supper' });
111
+ const date = occurrences[0];
112
+ const status = await client.rsvpStatus(date.event.slug, { start: date.start });
113
+ if (status.open) {
114
+ const rsvp: RsvpInput = {
115
+ event: date.event.slug, start: date.start, seats: 2, name: 'Example Guest', email: 'guest@example.com',
116
+ // field id → answer; checkbox groups send a list
117
+ answers: { meal: 'Vegetarian', help: ['Setup', 'Music'] },
118
+ // required when the event asks questions: a changed form answers 409, so read the status again
119
+ ...(status.form ? { formVersion: status.form.version } : {}),
120
+ };
121
+ const result = await client.book({ ...rsvp, idempotencyKey: crypto.randomUUID() });
122
+ // pending when the organiser approves RSVPs; status.form?.confirmation is the thank-you text.
123
+ // result.manageToken changes or cancels it later (manageBooking, cancelBooking), like the email's link:
124
+ // keep it in secure storage only.
125
+ console.log(result.booking.status);
126
+ }
127
+
105
128
  const controller = new AbortController();
106
129
  const pending = client.home({ signal: controller.signal });
107
130
  controller.abort();
@@ -171,7 +194,7 @@ if (current?.status === 'live') console.log(`Live: ${current.title} → ${curren
171
194
  ETag revalidation defaults to an in-memory URL-keyed cache. Each read contacts
172
195
  the server with `If-None-Match`; a 304 reuses the saved data. This is not an
173
196
  offline fallback. Treat returned cached objects as immutable. Use `cache: false`
174
- to disable it. Availability, live status, booking results and errors are never cached.
197
+ to disable it. Availability, live status, RSVP status, booking results and errors are never cached.
175
198
  Responses without an ETag or with `no-store` invalidate an older entry.
176
199
 
177
200
  ```ts
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, Device, DeviceInput, DeviceUpdate, DeviceRegistration, DeviceRemoved, PushTopics, LiveStatus } 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 } from './types.js';
2
2
  export { AcmsError, isAcmsError } from './errors.js';
3
3
  export type * from './types.js';
4
4
  export * from './editor.js';
@@ -44,6 +44,11 @@ export interface SearchOptions extends RequestOptions {
44
44
  /** Matches per group, 1–20; default 5. */
45
45
  limit?: number;
46
46
  }
47
+ export interface AnnouncementOptions extends ListOptions {
48
+ kind?: 'event' | 'registration' | 'help' | 'info' | 'urgent';
49
+ /** Only the banners (pinned), urgent first. */
50
+ pinned?: boolean;
51
+ }
47
52
  export interface AvailabilityOptions extends RequestOptions {
48
53
  resource: string;
49
54
  link: string;
@@ -51,6 +56,10 @@ export interface AvailabilityOptions extends RequestOptions {
51
56
  days?: number;
52
57
  minutes?: number;
53
58
  }
59
+ /** `start`: the occurrence's start exactly as `events()` returns it, a UTC ISO string such as `'2026-10-05T14:00:00.000Z'`. */
60
+ export interface RsvpStatusOptions extends RequestOptions {
61
+ start: string;
62
+ }
54
63
  export type BookOptions = BookingInput & RequestOptions & {
55
64
  idempotencyKey?: string;
56
65
  };
@@ -120,6 +129,10 @@ export declare const endpoints: {
120
129
  readonly method: "GET";
121
130
  readonly path: "/calendars";
122
131
  };
132
+ readonly rsvpStatus: {
133
+ readonly method: "GET";
134
+ readonly path: "/events/{slug}/rsvp";
135
+ };
123
136
  readonly resources: {
124
137
  readonly method: "GET";
125
138
  readonly path: "/resources";
@@ -168,6 +181,14 @@ export declare const endpoints: {
168
181
  readonly method: "GET";
169
182
  readonly path: "/live";
170
183
  };
184
+ readonly announcements: {
185
+ readonly method: "GET";
186
+ readonly path: "/announcements";
187
+ };
188
+ readonly announcement: {
189
+ readonly method: "GET";
190
+ readonly path: "/announcements/{id}";
191
+ };
171
192
  readonly manageBooking: {
172
193
  readonly method: "GET";
173
194
  readonly path: "/bookings/manage";
@@ -228,6 +249,12 @@ export interface AcmsClient {
228
249
  resources(o?: ListOptions): Promise<Resources>;
229
250
  resource(slug: string, o?: RequestOptions): Promise<Resource>;
230
251
  availability(o: AvailabilityOptions): Promise<Availability>;
252
+ /**
253
+ * One date's RSVP status: `open` (or `reason`: disabled, ended, cancelled, full), live `going`/`left`,
254
+ * `maxSeats` for one RSVP right now, and `form` (questions and `version`, or null). Never cached.
255
+ * RSVP with `book({ event, start, seats, name, email, answers, formVersion: form.version })`.
256
+ */
257
+ rsvpStatus(slug: string, o: RsvpStatusOptions): Promise<RsvpStatus>;
231
258
  book(o: BookOptions): Promise<BookingResult>;
232
259
  openapi(o?: RequestOptions): Promise<OpenApiDocument>;
233
260
  /** Register or refresh this device's Expo push token. Call on every app start. Requires push on the site. */
@@ -246,6 +273,10 @@ export interface AcmsClient {
246
273
  * clock, even if later requests fail. Requires `site.features.live`.
247
274
  */
248
275
  live(o?: RequestOptions): Promise<LiveStatus>;
276
+ /** Announcements up right now, newest first (`pinned: true`: only the banners, urgent first). Requires `site.features.announcements`. */
277
+ announcements(o?: AnnouncementOptions): Promise<Announcements>;
278
+ /** One announcement that is up; 404 once it came down. */
279
+ announcement(id: string, o?: RequestOptions): Promise<AnnouncementDetail>;
249
280
  /** A published form's questions. 410 when it stopped accepting responses. Requires `site.features.forms`. */
250
281
  form(id: string, o?: RequestOptions): Promise<Form>;
251
282
  /** Send answers (checkbox groups as arrays). Retries reuse the same Idempotency-Key, so they never duplicate. */
@@ -278,5 +309,6 @@ export interface AcmsClient {
278
309
  pages(o?: ListOptions): AsyncGenerator<ContentList['items'][number]>;
279
310
  events(o?: EventOptions): AsyncGenerator<Events['occurrences'][number]>;
280
311
  resources(o?: ListOptions): AsyncGenerator<Resource>;
312
+ announcements(o?: AnnouncementOptions): AsyncGenerator<Announcements['announcements'][number]>;
281
313
  };
282
314
  }
package/dist/index.js CHANGED
@@ -8,6 +8,8 @@ export const endpoints = {
8
8
  content: { method: 'GET', path: '/content' }, contentById: { method: 'GET', path: '/content/{id}' },
9
9
  search: { method: 'GET', path: '/search' },
10
10
  events: { method: 'GET', path: '/events' }, calendars: { method: 'GET', path: '/calendars' },
11
+ // an event date's RSVP status: live seats and questions (never cached); RSVP with book()
12
+ rsvpStatus: { method: 'GET', path: '/events/{slug}/rsvp' },
11
13
  resources: { method: 'GET', path: '/resources' }, availability: { method: 'GET', path: '/availability' },
12
14
  book: { method: 'POST', path: '/bookings' }, openapi: { method: 'GET', path: '/openapi.json' },
13
15
  // push notifications (only when the site enables push; 404 otherwise)
@@ -17,6 +19,8 @@ export const endpoints = {
17
19
  links: { method: 'GET', path: '/links' }, form: { method: 'GET', path: '/forms/{id}' }, submitForm: { method: 'POST', path: '/forms/{id}/responses' },
18
20
  // live video status (404 while the site's live video is off)
19
21
  live: { method: 'GET', path: '/live' },
22
+ // announcements (404 unless the site turns them on)
23
+ announcements: { method: 'GET', path: '/announcements' }, announcement: { method: 'GET', path: '/announcements/{id}' },
20
24
  // the booker's own booking: its private token goes in the Booking-Token header
21
25
  manageBooking: { method: 'GET', path: '/bookings/manage' }, cancelBooking: { method: 'POST', path: '/bookings/manage/cancel' },
22
26
  rescheduleAvailability: { method: 'GET', path: '/bookings/manage/availability' }, rescheduleBooking: { method: 'POST', path: '/bookings/manage/reschedule' },
@@ -26,7 +30,7 @@ export const endpoints = {
26
30
  guestBookings: { method: 'GET', path: '/guest/bookings' }, guestSignOut: { method: 'POST', path: '/guest/revoke' },
27
31
  };
28
32
  // site: its legal links; pushTopics: topic names
29
- const localized = new Set(['home', 'page', 'content', 'contentById', 'search', 'events', 'site', 'pushTopics']);
33
+ const localized = new Set(['home', 'page', 'content', 'contentById', 'search', 'events', 'rsvpStatus', 'site', 'pushTopics', 'announcements', 'announcement']);
30
34
  // localized since core 0.3.32; older sites answer ?locale= with a 400, so ask them again without it
31
35
  const lateLocalized = new Set(['site', 'pushTopics']);
32
36
  function uuid() {
@@ -110,8 +114,8 @@ export function createClient(options) {
110
114
  opts.signal?.addEventListener('abort', abort, { once: true });
111
115
  const timer = setTimeout(() => controller.abort(new AcmsError(0, 'timeout', 'Request timed out.', undefined, undefined, key)), timeoutMs);
112
116
  const signal = controller.signal;
113
- // availability and live status are never served from the cache
114
- const cacheable = endpoint.method === 'GET' && name !== 'availability' && name !== 'live' && !extra.headers && cache;
117
+ // availability, live status and RSVP seats are never served from the cache
118
+ const cacheable = endpoint.method === 'GET' && name !== 'availability' && name !== 'live' && name !== 'rsvpStatus' && !extra.headers && cache;
115
119
  // only replay what the server treats as repeatable: a lost reply to a code
116
120
  // exchange or a move must not run it twice
117
121
  const replayable = endpoint.method !== 'POST' || !!key || name === 'registerDevice';
@@ -230,19 +234,22 @@ export function createClient(options) {
230
234
  const pages = (o = {}) => content({ ...o, kind: 'page' });
231
235
  const events = (o = {}) => request('events', o, { ...paging(o), from: o.from, to: o.to, calendar: o.calendar, tag: o.tag, excludeTag: o.excludeTag, q: o.q });
232
236
  const resources = (o = {}) => request('resources', o, paging(o));
237
+ const announcements = (o = {}) => request('announcements', o, { ...paging(o), kind: o.kind, pinned: o.pinned ? 'true' : undefined });
233
238
  const paginate = {
234
239
  content: (o = {}) => iterate(content, 'items', o),
235
240
  posts: (o = {}) => iterate(posts, 'items', o),
236
241
  pages: (o = {}) => iterate(pages, 'items', o),
237
242
  events: (o = {}) => iterate(events, 'occurrences', o),
238
243
  resources: (o = {}) => iterate(resources, 'resources', o),
244
+ announcements: (o = {}) => iterate(announcements, 'announcements', o),
239
245
  };
240
246
  return {
241
247
  site: (o = {}) => request('site', o),
242
248
  theme: (o = {}) => request('theme', o),
243
249
  home: (o = {}) => request('home', o),
244
250
  page: (slug, o = {}) => request('page', o, {}, slug),
245
- content, posts, pages, events, resources, paginate,
251
+ content, posts, pages, events, resources, announcements, paginate,
252
+ announcement: (id, o = {}) => request('announcement', o, {}, id),
246
253
  async search(q, o = {}) {
247
254
  const query = q.trim();
248
255
  // blank input (an emptied search box) needs no round trip
@@ -272,6 +279,7 @@ export function createClient(options) {
272
279
  },
273
280
  calendars: (o = {}) => request('calendars', o),
274
281
  availability: (o) => request('availability', o, { resource: o.resource, link: o.link, from: o.from, days: o.days, minutes: o.minutes }),
282
+ rsvpStatus: (slug, o) => request('rsvpStatus', o, { start: o.start }, slug),
275
283
  book: (o) => {
276
284
  const { locale, signal, idempotencyKey, ...body } = o;
277
285
  const key = idempotencyKey ?? defaultHeaders.get('Idempotency-Key') ?? uuid();
package/dist/types.d.ts CHANGED
@@ -29,12 +29,14 @@ export type Site = {
29
29
  }>;
30
30
  "calendar": boolean;
31
31
  "bookings": boolean;
32
+ "rsvp": boolean;
32
33
  "search": boolean;
33
34
  "bookingChanges": boolean;
34
35
  "guestSignIn": boolean;
35
36
  "forms": boolean;
36
37
  "links": boolean;
37
38
  "live": boolean;
39
+ "announcements": boolean;
38
40
  };
39
41
  "legal": {
40
42
  "privacy": string | null;
@@ -590,6 +592,40 @@ export type FormReceipt = {
590
592
  "received": true;
591
593
  "confirmation": string;
592
594
  };
595
+ export type RsvpStatus = {
596
+ "event": {
597
+ "id": string;
598
+ "slug": string;
599
+ "title": string;
600
+ };
601
+ "start": string;
602
+ "end": string;
603
+ "open": boolean;
604
+ "reason": ("disabled" | "ended" | "cancelled" | "full") | (null);
605
+ "going": number;
606
+ "left": (number) | (null);
607
+ "capacity": number;
608
+ "maxSeats": number;
609
+ "autoConfirm": boolean;
610
+ "form": ({
611
+ "version": string;
612
+ "title": string;
613
+ "intro": string;
614
+ "submitLabel": string;
615
+ "confirmation": string;
616
+ "fields": Array<{
617
+ "id": string;
618
+ "type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
619
+ "label": string;
620
+ "required": boolean;
621
+ "help": string;
622
+ "options": Array<string>;
623
+ "placeholder": string;
624
+ "width": "full" | "half";
625
+ "allowOther": boolean;
626
+ }>;
627
+ }) | (null);
628
+ };
593
629
  export type ManagedBooking = {
594
630
  "booking": {
595
631
  "id": string;
@@ -633,6 +669,7 @@ export type ManagedBooking = {
633
669
  "cutoffHours": number;
634
670
  "closed": boolean;
635
671
  };
672
+ "confirmation": string | null;
636
673
  };
637
674
  export type GuestCodeSent = {
638
675
  "sent": true;
@@ -773,7 +810,7 @@ export type BookingResult = {
773
810
  [key: string]: string;
774
811
  };
775
812
  };
776
- "source": "web" | "admin" | "api" | "agent";
813
+ "source": "web" | "app" | "admin" | "api" | "agent";
777
814
  "start": string;
778
815
  "end": string;
779
816
  "resourceId": string | null;
@@ -787,6 +824,7 @@ export type Device = {
787
824
  "platform": "ios" | "android";
788
825
  "locale": string | null;
789
826
  "topics": Array<string>;
827
+ "channels": Array<string>;
790
828
  "registeredAt": string;
791
829
  "lastSeenAt": string;
792
830
  };
@@ -797,6 +835,7 @@ export type DeviceRegistration = {
797
835
  "platform": "ios" | "android";
798
836
  "locale": string | null;
799
837
  "topics": Array<string>;
838
+ "channels": Array<string>;
800
839
  "registeredAt": string;
801
840
  "lastSeenAt": string;
802
841
  };
@@ -814,6 +853,69 @@ export type PushTopics = {
814
853
  "description"?: string;
815
854
  }>;
816
855
  };
856
+ export type Announcement = {
857
+ "id": string;
858
+ "kind": "event" | "registration" | "help" | "info" | "urgent";
859
+ "kindLabel": string;
860
+ "title": string;
861
+ "message": string;
862
+ "details": string;
863
+ "button": ({
864
+ "label": string;
865
+ "url": string;
866
+ }) | (null);
867
+ "url": string | null;
868
+ "pinned": boolean;
869
+ "urgent": boolean;
870
+ "publishedAt": string;
871
+ "showUntil": (string) | (null);
872
+ "translated": boolean;
873
+ };
874
+ export type Announcements = {
875
+ "locale": string | null;
876
+ "announcements": Array<{
877
+ "id": string;
878
+ "kind": "event" | "registration" | "help" | "info" | "urgent";
879
+ "kindLabel": string;
880
+ "title": string;
881
+ "message": string;
882
+ "details": string;
883
+ "button": ({
884
+ "label": string;
885
+ "url": string;
886
+ }) | (null);
887
+ "url": string | null;
888
+ "pinned": boolean;
889
+ "urgent": boolean;
890
+ "publishedAt": string;
891
+ "showUntil": (string) | (null);
892
+ "translated": boolean;
893
+ }>;
894
+ "pagination": {
895
+ "page": number;
896
+ "limit": number;
897
+ "nextPage": (number) | (null);
898
+ };
899
+ };
900
+ export type AnnouncementDetail = {
901
+ "id": string;
902
+ "kind": "event" | "registration" | "help" | "info" | "urgent";
903
+ "kindLabel": string;
904
+ "title": string;
905
+ "message": string;
906
+ "details": string;
907
+ "button": ({
908
+ "label": string;
909
+ "url": string;
910
+ }) | (null);
911
+ "url": string | null;
912
+ "pinned": boolean;
913
+ "urgent": boolean;
914
+ "publishedAt": string;
915
+ "showUntil": (string) | (null);
916
+ "translated": boolean;
917
+ "locale": string | null;
918
+ };
817
919
  export type LiveSnapshot = {
818
920
  "status": "live" | "upcoming" | "offline" | "unknown";
819
921
  "source": "automatic" | "manual";
@@ -1266,7 +1368,7 @@ export type EditorBooking = {
1266
1368
  [key: string]: string;
1267
1369
  };
1268
1370
  };
1269
- "source": "web" | "admin" | "api" | "agent";
1371
+ "source": "web" | "app" | "admin" | "api" | "agent";
1270
1372
  "notes": string;
1271
1373
  "start": string;
1272
1374
  "end": string;
@@ -1313,7 +1415,7 @@ export type EditorBookingList = {
1313
1415
  [key: string]: string;
1314
1416
  };
1315
1417
  };
1316
- "source": "web" | "admin" | "api" | "agent";
1418
+ "source": "web" | "app" | "admin" | "api" | "agent";
1317
1419
  "notes": string;
1318
1420
  "start": string;
1319
1421
  "end": string;
@@ -1858,22 +1960,22 @@ export type BookingInput = ({
1858
1960
  "name": string;
1859
1961
  "email": string;
1860
1962
  "phone"?: string;
1963
+ "answers"?: {
1964
+ [key: string]: (string) | (Array<string>);
1965
+ };
1861
1966
  "resource": string;
1862
1967
  "link": string;
1863
1968
  "minutes"?: number;
1864
- "answers"?: {
1865
- [key: string]: string;
1866
- };
1867
1969
  }) | ({
1868
1970
  "start": string;
1869
1971
  "name": string;
1870
1972
  "email": string;
1871
1973
  "phone"?: string;
1872
- "event": string;
1873
- "seats"?: number;
1874
1974
  "answers"?: {
1875
- [key: string]: string;
1975
+ [key: string]: (string) | (Array<string>);
1876
1976
  };
1977
+ "event": string;
1978
+ "seats"?: number;
1877
1979
  "formVersion"?: string;
1878
1980
  });
1879
1981
  export type DeviceInput = {
@@ -1881,10 +1983,12 @@ export type DeviceInput = {
1881
1983
  "platform": "ios" | "android";
1882
1984
  "locale"?: string;
1883
1985
  "topics"?: Array<string>;
1986
+ "channels"?: Array<string>;
1884
1987
  };
1885
1988
  export type DeviceUpdate = {
1886
1989
  "locale"?: string;
1887
1990
  "topics"?: Array<string>;
1991
+ "channels"?: Array<string>;
1888
1992
  };
1889
1993
  export type EditorCreateInput = ({
1890
1994
  "kind": "post";
@@ -2361,4 +2465,8 @@ export type SearchEventHit = SearchResults["events"][number];
2361
2465
  export type LinkItem = Links["items"][number];
2362
2466
  export type FormField = Form["fields"][number];
2363
2467
  export type GuestBooking = GuestBookings["items"][number];
2468
+ export type RsvpInput = Extract<BookingInput, {
2469
+ "event": string;
2470
+ }>;
2471
+ export type RsvpForm = NonNullable<RsvpStatus["form"]>;
2364
2472
  export type LiveDisplay = LiveStatus["display"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acms-subir/client",
3
- "version": "0.1.13",
3
+ "version": "0.1.15",
4
4
  "description": "Typed, dependency-free client for the ACMS public mobile API.",
5
5
  "type": "module",
6
6
  "license": "MIT",