@acms-subir/client 0.1.23 → 0.1.25
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 +48 -1
- package/dist/index.d.ts +67 -3
- package/dist/index.js +18 -6
- package/dist/types.d.ts +201 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -63,6 +63,7 @@ language. Update the site before shipping an app build with a newer client.
|
|
|
63
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 |
|
|
64
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 |
|
|
65
65
|
| `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 |
|
|
66
|
+
| `requestOptions()`, `submitRequest(input, { idempotencyKey? })` | Event requests without an account: what the form offers (`open`, `types`, `rooms`, `replyTime`, `notice`, `phone`, `timezone`; never cached), and asking for a new event or a change (`{ id }`). 404 while `site.features.requests` is false. See Event requests below |
|
|
66
67
|
| `manageBooking(token)`, `cancelBooking(token)` | The booker's own booking from its `manageToken`, and cancelling it (or leaving a waitlist, or releasing a held spot); `can` says what is allowed. A waitlisted RSVP has `booking.position` (its place in line), an offered one `booking.holdUntil` |
|
|
67
68
|
| `confirmBooking(token)` | Take a spot the waitlist offered (`can.confirm`): `confirmed`, or `pending` when RSVPs need approval. 410 once `holdUntil` passed. Core 0.3.40 or later |
|
|
68
69
|
| `rescheduleAvailability(token, { from?, days?, minutes? })`, `rescheduleBooking(token, { start, minutes? })` | Open times for moving it (its own time counts as free), then the move |
|
|
@@ -149,7 +150,7 @@ await pending.catch(() => {});
|
|
|
149
150
|
```
|
|
150
151
|
|
|
151
152
|
Requests that are safe to repeat (GET, PUT, DELETE, device registration, and
|
|
152
|
-
POSTs with an Idempotency-Key: bookings and
|
|
153
|
+
POSTs with an Idempotency-Key: bookings, form responses and event requests) retry network
|
|
153
154
|
failures, 5xx and 429 responses at most twice (three attempts total), with
|
|
154
155
|
250/500ms backoff and at least the server's `Retry-After` delay (seconds or HTTP
|
|
155
156
|
date). A wait that would outlast `timeoutMs` throws the 429 straight away, with
|
|
@@ -170,6 +171,52 @@ booking must be retried with its existing key. `AcmsError` exposes `status`,
|
|
|
170
171
|
`aborted`, or `invalid_response`; non-JSON HTTP errors use `http_error`.
|
|
171
172
|
Convenience lookups apply the timeout separately to each underlying request.
|
|
172
173
|
|
|
174
|
+
## Event requests
|
|
175
|
+
|
|
176
|
+
A site can take event requests from people
|
|
177
|
+
without an account (`acms({ requests: true })`, so `site.features.requests`
|
|
178
|
+
is true; staff answer them in Calendar → Requests). Someone asks for
|
|
179
|
+
something new, or for a change to an event, and gives a name, an email and
|
|
180
|
+
optionally a phone. Nothing goes on the calendar until staff approve it.
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
import type { RequestInput } from '@acms-subir/client';
|
|
184
|
+
|
|
185
|
+
const options = await client.requestOptions();
|
|
186
|
+
// { open, types: [{ id, label }], rooms: [{ slug, name, color }], replyTime: '3 days', notice, phone, timezone }
|
|
187
|
+
if (!options.open) {
|
|
188
|
+
// say "We aren't taking requests here right now." and show options.phone; keep the screen itself reachable
|
|
189
|
+
}
|
|
190
|
+
const ask: RequestInput = {
|
|
191
|
+
kind: 'new', type: options.types[0]?.id, title: 'Guitar workshop',
|
|
192
|
+
// the site's wall clock (options.timezone), in the future; the end may be just HH:mm on the same day
|
|
193
|
+
start: '2026-11-07T18:00', end: '20:00',
|
|
194
|
+
repeat: 'weekly', // 'once' (default), 'weekly', or 'other' with repeatText
|
|
195
|
+
rooms: ['fellowship-hall'], // slugs from options.rooms, or roomsUnsure: true
|
|
196
|
+
people: 12, message: 'We bring our own chairs.',
|
|
197
|
+
name: 'Example Guest', email: 'guest@example.com', phone: '555 0100',
|
|
198
|
+
};
|
|
199
|
+
const { id } = await client.submitRequest(ask, { idempotencyKey: crypto.randomUUID() });
|
|
200
|
+
|
|
201
|
+
// a change to a public event: one date of it (YYYY-MM-DD, the site's day), or leave date out for every date
|
|
202
|
+
await client.submitRequest({ kind: 'change', event: 'fall-fair', date: '2026-11-08', message: 'Could it start at 10?', name: 'Example Guest', email: 'guest@example.com' });
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
- Check whether a room looks free first with `roomFree({ room, start, end })`
|
|
206
|
+
(needs bookings on the site; the times there take a zone, so convert the
|
|
207
|
+
wall-clock times with `options.timezone`).
|
|
208
|
+
- Keep one Idempotency-Key per request and reuse it for retries: a retry
|
|
209
|
+
answers the same `{ id }`, and the same key with other details is a 409
|
|
210
|
+
`changed`. Each call without `idempotencyKey` makes a new one.
|
|
211
|
+
- The client's `locale` (or `input.locale`) goes in the body, so the emails
|
|
212
|
+
about the request speak the app's language.
|
|
213
|
+
- A refusal is an `AcmsError` whose `code` says why: `closed` (409, requests
|
|
214
|
+
closed meanwhile), a field (400: `title`, `type`, `start`, `end`, `past`,
|
|
215
|
+
`far`, `repeat`, `room`, `people`, `event`, `date`, `what` (the change's
|
|
216
|
+
message), `name`, `email`, `phone`), `changed` (409), or `busy` / `full`
|
|
217
|
+
(429, with `retryAfter`). 10 requests a minute per address, plus the
|
|
218
|
+
site's daily cap.
|
|
219
|
+
|
|
173
220
|
## Push notifications
|
|
174
221
|
|
|
175
222
|
Available when the site enables push (`acms({ mobile: { push: true } })`);
|
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, StaffLink, PushTopics, LiveStatus, Announcements, AnnouncementDetail, EventDetail, RoomFree } 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, EventRequestOptions, RequestReceipt } from './types.js';
|
|
2
2
|
export { AcmsError, isAcmsError } from './errors.js';
|
|
3
3
|
export type * from './types.js';
|
|
4
4
|
export * from './editor.js';
|
|
@@ -72,6 +72,44 @@ export interface RoomFreeOptions extends RequestOptions {
|
|
|
72
72
|
export type BookOptions = BookingInput & RequestOptions & {
|
|
73
73
|
idempotencyKey?: string;
|
|
74
74
|
};
|
|
75
|
+
/** Who's asking. `locale`: the language for the emails about it (default: the client's). */
|
|
76
|
+
interface RequestAsker {
|
|
77
|
+
name: string;
|
|
78
|
+
email: string;
|
|
79
|
+
phone?: string;
|
|
80
|
+
locale?: string;
|
|
81
|
+
}
|
|
82
|
+
/** Ask for a new event. Times are the site's wall clock (`requestOptions().timezone`). */
|
|
83
|
+
export interface NewEventRequest extends RequestAsker {
|
|
84
|
+
kind: 'new';
|
|
85
|
+
/** One of `requestOptions().types` (an `id`); required when the site lists any. */
|
|
86
|
+
type?: string;
|
|
87
|
+
title: string;
|
|
88
|
+
/** `YYYY-MM-DDTHH:mm`, in the future. */
|
|
89
|
+
start: string;
|
|
90
|
+
/** `YYYY-MM-DDTHH:mm`, or `HH:mm`: the start's day, or the next when it's before the start (20:00 → 01:00); within a day. */
|
|
91
|
+
end: string;
|
|
92
|
+
/** Default `once`; `other` needs `repeatText` ("every other Tuesday"). */
|
|
93
|
+
repeat?: 'once' | 'weekly' | 'other';
|
|
94
|
+
repeatText?: string;
|
|
95
|
+
/** Room slugs from `requestOptions().rooms`, or `roomsUnsure: true`. */
|
|
96
|
+
rooms?: string[];
|
|
97
|
+
roomsUnsure?: boolean;
|
|
98
|
+
people?: number | null;
|
|
99
|
+
/** Anything else they want staff to know. */
|
|
100
|
+
message?: string;
|
|
101
|
+
}
|
|
102
|
+
/** Ask for a change to a public event. */
|
|
103
|
+
export interface ChangeRequest extends RequestAsker {
|
|
104
|
+
kind: 'change';
|
|
105
|
+
/** The event's slug. */
|
|
106
|
+
event: string;
|
|
107
|
+
/** One of its dates (`YYYY-MM-DD`, the site's day); leave it out for every date. */
|
|
108
|
+
date?: string;
|
|
109
|
+
/** What should change. */
|
|
110
|
+
message: string;
|
|
111
|
+
}
|
|
112
|
+
export type RequestInput = NewEventRequest | ChangeRequest;
|
|
75
113
|
export interface ApiResponse<T> {
|
|
76
114
|
version: 1;
|
|
77
115
|
data: T;
|
|
@@ -214,6 +252,14 @@ export declare const endpoints: {
|
|
|
214
252
|
readonly method: "GET";
|
|
215
253
|
readonly path: "/announcements/{id}";
|
|
216
254
|
};
|
|
255
|
+
readonly requestOptions: {
|
|
256
|
+
readonly method: "GET";
|
|
257
|
+
readonly path: "/requests/options";
|
|
258
|
+
};
|
|
259
|
+
readonly submitRequest: {
|
|
260
|
+
readonly method: "POST";
|
|
261
|
+
readonly path: "/requests";
|
|
262
|
+
};
|
|
217
263
|
readonly manageBooking: {
|
|
218
264
|
readonly method: "GET";
|
|
219
265
|
readonly path: "/bookings/manage";
|
|
@@ -325,12 +371,30 @@ export interface AcmsClient {
|
|
|
325
371
|
announcements(o?: AnnouncementOptions): Promise<Announcements>;
|
|
326
372
|
/** One announcement that is up; 404 once it came down. */
|
|
327
373
|
announcement(id: string, o?: RequestOptions): Promise<AnnouncementDetail>;
|
|
328
|
-
/**
|
|
374
|
+
/**
|
|
375
|
+
* A published form's questions, in the client's `locale` where the form has
|
|
376
|
+
* its words (older sites: the main language). 410 when it stopped accepting
|
|
377
|
+
* responses. Requires `site.features.forms`. A `time` answer is HH:mm (24-hour).
|
|
378
|
+
*/
|
|
329
379
|
form(id: string, o?: RequestOptions): Promise<Form>;
|
|
330
|
-
/** Send answers (checkbox groups as arrays). Retries reuse the same Idempotency-Key, so they never duplicate. */
|
|
380
|
+
/** Send answers (checkbox groups as arrays; a choice as it was shown). Retries reuse the same Idempotency-Key, so they never duplicate. The receipt's `confirmation` is in the client's `locale`. */
|
|
331
381
|
submitForm(id: string, input: FormResponseInput & {
|
|
332
382
|
idempotencyKey?: string;
|
|
333
383
|
}, o?: RequestOptions): Promise<FormReceipt>;
|
|
384
|
+
/**
|
|
385
|
+
* What the event request form offers (`site.features.requests`): `open` (false: say so, show `phone`, and keep
|
|
386
|
+
* the screen reachable), `types` and `rooms` to choose from, the site's `replyTime` and `notice` in the client's language,
|
|
387
|
+
* and its `timezone` (the times in a request are its wall clock). Never cached; 404 while the site has requests off.
|
|
388
|
+
*/
|
|
389
|
+
requestOptions(o?: RequestOptions): Promise<EventRequestOptions>;
|
|
390
|
+
/**
|
|
391
|
+
* Ask for a new event or a change to one, without an account: `{ id }`. Retries reuse the same Idempotency-Key, so they
|
|
392
|
+
* never send twice; the same key with other details is a 409 `changed`. Refusals carry a `code` (`closed`, `title`,
|
|
393
|
+
* `start`, `email`, `busy`, …). Sends the client's `locale` (or `o.locale`), so the emails about it speak it.
|
|
394
|
+
*/
|
|
395
|
+
submitRequest(input: RequestInput, o?: RequestOptions & {
|
|
396
|
+
idempotencyKey?: string;
|
|
397
|
+
}): Promise<RequestReceipt>;
|
|
334
398
|
/** The booker's own booking, from its private token (`manageToken`). Never cached. Requires `site.features.bookingChanges`. */
|
|
335
399
|
manageBooking(token: string, o?: RequestOptions): Promise<ManagedBooking>;
|
|
336
400
|
/** Cancel it; for an RSVP on a waitlist, leave the line or release a held spot. */
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,8 @@ export const endpoints = {
|
|
|
25
25
|
live: { method: 'GET', path: '/live' },
|
|
26
26
|
// announcements (404 unless the site turns them on)
|
|
27
27
|
announcements: { method: 'GET', path: '/announcements' }, announcement: { method: 'GET', path: '/announcements/{id}' },
|
|
28
|
+
// event requests without an account (404 unless the site turns them on): what the form offers (never cached), and sending one
|
|
29
|
+
requestOptions: { method: 'GET', path: '/requests/options' }, submitRequest: { method: 'POST', path: '/requests' },
|
|
28
30
|
// the booker's own booking: its private token goes in the Booking-Token header
|
|
29
31
|
manageBooking: { method: 'GET', path: '/bookings/manage' }, cancelBooking: { method: 'POST', path: '/bookings/manage/cancel' },
|
|
30
32
|
// take a spot an RSVP's waitlist offered
|
|
@@ -35,10 +37,13 @@ export const endpoints = {
|
|
|
35
37
|
requestGuestCode: { method: 'POST', path: '/guest/code' }, guestSignIn: { method: 'POST', path: '/guest/token' },
|
|
36
38
|
guestBookings: { method: 'GET', path: '/guest/bookings' }, guestSignOut: { method: 'POST', path: '/guest/revoke' },
|
|
37
39
|
};
|
|
38
|
-
// site: its legal links; pushTopics: topic names
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
const
|
|
40
|
+
// site: its legal links; pushTopics: topic names; form: its questions;
|
|
41
|
+
// submitForm: the receipt's thank-you (any site ignores it on that POST);
|
|
42
|
+
// requestOptions: the kinds and the site's words
|
|
43
|
+
const localized = new Set(['home', 'page', 'content', 'contentById', 'search', 'events', 'rsvpStatus', 'site', 'pushTopics', 'announcements', 'announcement', 'eventDetail', 'form', 'submitForm', 'requestOptions']);
|
|
44
|
+
// localized later (site, pushTopics: core 0.3.32; form: with form
|
|
45
|
+
// translations); older sites answer ?locale= with a 400, so ask them again without it
|
|
46
|
+
const lateLocalized = new Set(['site', 'pushTopics', 'form']);
|
|
42
47
|
function uuid() {
|
|
43
48
|
if (globalThis.crypto?.randomUUID)
|
|
44
49
|
return globalThis.crypto.randomUUID();
|
|
@@ -120,8 +125,8 @@ export function createClient(options) {
|
|
|
120
125
|
opts.signal?.addEventListener('abort', abort, { once: true });
|
|
121
126
|
const timer = setTimeout(() => controller.abort(new AcmsError(0, 'timeout', 'Request timed out.', undefined, undefined, key)), timeoutMs);
|
|
122
127
|
const signal = controller.signal;
|
|
123
|
-
// availability, live status
|
|
124
|
-
const cacheable = endpoint.method === 'GET' && name !== 'availability' && name !== 'live' && name !== 'rsvpStatus' && name !== 'roomFree' && !extra.headers && cache;
|
|
128
|
+
// availability, live status, RSVP seats, free rooms and whether requests are open are never served from the cache
|
|
129
|
+
const cacheable = endpoint.method === 'GET' && name !== 'availability' && name !== 'live' && name !== 'rsvpStatus' && name !== 'roomFree' && name !== 'requestOptions' && !extra.headers && cache;
|
|
125
130
|
// only replay what the server treats as repeatable: a lost reply to a code
|
|
126
131
|
// exchange or a move must not run it twice
|
|
127
132
|
const replayable = endpoint.method !== 'POST' || !!key || name === 'registerDevice';
|
|
@@ -329,6 +334,13 @@ export function createClient(options) {
|
|
|
329
334
|
const { idempotencyKey, ...body } = input;
|
|
330
335
|
return request('submitForm', o, {}, id, body, idempotencyKey ?? uuid());
|
|
331
336
|
},
|
|
337
|
+
requestOptions: (o = {}) => request('requestOptions', o),
|
|
338
|
+
submitRequest: (input, o = {}) => {
|
|
339
|
+
const { idempotencyKey, signal } = o;
|
|
340
|
+
// the language rides in the body: the emails about it speak it
|
|
341
|
+
const locale = input.locale ?? o.locale ?? options.locale;
|
|
342
|
+
return request('submitRequest', { signal }, {}, undefined, locale === undefined ? input : { ...input, locale }, idempotencyKey ?? uuid());
|
|
343
|
+
},
|
|
332
344
|
manageBooking: (token, o = {}) => request('manageBooking', o, {}, undefined, undefined, undefined, bookingAuth(token)),
|
|
333
345
|
cancelBooking: (token, o = {}) => request('cancelBooking', o, {}, undefined, undefined, undefined, bookingAuth(token)),
|
|
334
346
|
confirmBooking: (token, o = {}) => request('confirmBooking', o, {}, undefined, undefined, undefined, bookingAuth(token)),
|
package/dist/types.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ export type Site = {
|
|
|
37
37
|
"links": boolean;
|
|
38
38
|
"live": boolean;
|
|
39
39
|
"announcements": boolean;
|
|
40
|
+
"requests": boolean;
|
|
40
41
|
};
|
|
41
42
|
"legal": {
|
|
42
43
|
"privacy": string | null;
|
|
@@ -248,7 +249,7 @@ export type Event = {
|
|
|
248
249
|
"confirmation": string;
|
|
249
250
|
"fields": Array<{
|
|
250
251
|
"id": string;
|
|
251
|
-
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
|
|
252
|
+
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading" | "time";
|
|
252
253
|
"label": string;
|
|
253
254
|
"required": boolean;
|
|
254
255
|
"help": string;
|
|
@@ -256,7 +257,23 @@ export type Event = {
|
|
|
256
257
|
"placeholder"?: string;
|
|
257
258
|
"width"?: "full" | "half";
|
|
258
259
|
"allowOther"?: boolean;
|
|
260
|
+
"translations"?: {
|
|
261
|
+
[key: string]: {
|
|
262
|
+
"label"?: string;
|
|
263
|
+
"help"?: string;
|
|
264
|
+
"placeholder"?: string;
|
|
265
|
+
"options"?: Array<string>;
|
|
266
|
+
};
|
|
267
|
+
};
|
|
259
268
|
}>;
|
|
269
|
+
"translations"?: {
|
|
270
|
+
[key: string]: {
|
|
271
|
+
"title"?: string;
|
|
272
|
+
"intro"?: string;
|
|
273
|
+
"submitLabel"?: string;
|
|
274
|
+
"confirmation"?: string;
|
|
275
|
+
};
|
|
276
|
+
};
|
|
260
277
|
};
|
|
261
278
|
};
|
|
262
279
|
"url": string;
|
|
@@ -370,7 +387,7 @@ export type Events = {
|
|
|
370
387
|
"confirmation": string;
|
|
371
388
|
"fields": Array<{
|
|
372
389
|
"id": string;
|
|
373
|
-
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
|
|
390
|
+
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading" | "time";
|
|
374
391
|
"label": string;
|
|
375
392
|
"required": boolean;
|
|
376
393
|
"help": string;
|
|
@@ -378,7 +395,23 @@ export type Events = {
|
|
|
378
395
|
"placeholder"?: string;
|
|
379
396
|
"width"?: "full" | "half";
|
|
380
397
|
"allowOther"?: boolean;
|
|
398
|
+
"translations"?: {
|
|
399
|
+
[key: string]: {
|
|
400
|
+
"label"?: string;
|
|
401
|
+
"help"?: string;
|
|
402
|
+
"placeholder"?: string;
|
|
403
|
+
"options"?: Array<string>;
|
|
404
|
+
};
|
|
405
|
+
};
|
|
381
406
|
}>;
|
|
407
|
+
"translations"?: {
|
|
408
|
+
[key: string]: {
|
|
409
|
+
"title"?: string;
|
|
410
|
+
"intro"?: string;
|
|
411
|
+
"submitLabel"?: string;
|
|
412
|
+
"confirmation"?: string;
|
|
413
|
+
};
|
|
414
|
+
};
|
|
382
415
|
};
|
|
383
416
|
};
|
|
384
417
|
"url": string;
|
|
@@ -487,7 +520,7 @@ export type EventDetail = {
|
|
|
487
520
|
"confirmation": string;
|
|
488
521
|
"fields": Array<{
|
|
489
522
|
"id": string;
|
|
490
|
-
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
|
|
523
|
+
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading" | "time";
|
|
491
524
|
"label": string;
|
|
492
525
|
"required": boolean;
|
|
493
526
|
"help": string;
|
|
@@ -495,7 +528,23 @@ export type EventDetail = {
|
|
|
495
528
|
"placeholder"?: string;
|
|
496
529
|
"width"?: "full" | "half";
|
|
497
530
|
"allowOther"?: boolean;
|
|
531
|
+
"translations"?: {
|
|
532
|
+
[key: string]: {
|
|
533
|
+
"label"?: string;
|
|
534
|
+
"help"?: string;
|
|
535
|
+
"placeholder"?: string;
|
|
536
|
+
"options"?: Array<string>;
|
|
537
|
+
};
|
|
538
|
+
};
|
|
498
539
|
}>;
|
|
540
|
+
"translations"?: {
|
|
541
|
+
[key: string]: {
|
|
542
|
+
"title"?: string;
|
|
543
|
+
"intro"?: string;
|
|
544
|
+
"submitLabel"?: string;
|
|
545
|
+
"confirmation"?: string;
|
|
546
|
+
};
|
|
547
|
+
};
|
|
499
548
|
};
|
|
500
549
|
};
|
|
501
550
|
"url": string;
|
|
@@ -657,7 +706,7 @@ export type SearchResults = {
|
|
|
657
706
|
"confirmation": string;
|
|
658
707
|
"fields": Array<{
|
|
659
708
|
"id": string;
|
|
660
|
-
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
|
|
709
|
+
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading" | "time";
|
|
661
710
|
"label": string;
|
|
662
711
|
"required": boolean;
|
|
663
712
|
"help": string;
|
|
@@ -665,7 +714,23 @@ export type SearchResults = {
|
|
|
665
714
|
"placeholder"?: string;
|
|
666
715
|
"width"?: "full" | "half";
|
|
667
716
|
"allowOther"?: boolean;
|
|
717
|
+
"translations"?: {
|
|
718
|
+
[key: string]: {
|
|
719
|
+
"label"?: string;
|
|
720
|
+
"help"?: string;
|
|
721
|
+
"placeholder"?: string;
|
|
722
|
+
"options"?: Array<string>;
|
|
723
|
+
};
|
|
724
|
+
};
|
|
668
725
|
}>;
|
|
726
|
+
"translations"?: {
|
|
727
|
+
[key: string]: {
|
|
728
|
+
"title"?: string;
|
|
729
|
+
"intro"?: string;
|
|
730
|
+
"submitLabel"?: string;
|
|
731
|
+
"confirmation"?: string;
|
|
732
|
+
};
|
|
733
|
+
};
|
|
669
734
|
};
|
|
670
735
|
};
|
|
671
736
|
"url": string;
|
|
@@ -799,7 +864,7 @@ export type Form = {
|
|
|
799
864
|
"confirmation": string;
|
|
800
865
|
"fields": Array<{
|
|
801
866
|
"id": string;
|
|
802
|
-
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
|
|
867
|
+
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading" | "time";
|
|
803
868
|
"label": string;
|
|
804
869
|
"required": boolean;
|
|
805
870
|
"help": string;
|
|
@@ -843,7 +908,7 @@ export type RsvpStatus = {
|
|
|
843
908
|
"confirmation": string;
|
|
844
909
|
"fields": Array<{
|
|
845
910
|
"id": string;
|
|
846
|
-
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
|
|
911
|
+
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading" | "time";
|
|
847
912
|
"label": string;
|
|
848
913
|
"required": boolean;
|
|
849
914
|
"help": string;
|
|
@@ -1041,7 +1106,7 @@ export type BookingResult = {
|
|
|
1041
1106
|
"confirmation": string;
|
|
1042
1107
|
"fields": Array<{
|
|
1043
1108
|
"id": string;
|
|
1044
|
-
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
|
|
1109
|
+
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading" | "time";
|
|
1045
1110
|
"label": string;
|
|
1046
1111
|
"required": boolean;
|
|
1047
1112
|
"help": string;
|
|
@@ -1049,7 +1114,23 @@ export type BookingResult = {
|
|
|
1049
1114
|
"placeholder"?: string;
|
|
1050
1115
|
"width"?: "full" | "half";
|
|
1051
1116
|
"allowOther"?: boolean;
|
|
1117
|
+
"translations"?: {
|
|
1118
|
+
[key: string]: {
|
|
1119
|
+
"label"?: string;
|
|
1120
|
+
"help"?: string;
|
|
1121
|
+
"placeholder"?: string;
|
|
1122
|
+
"options"?: Array<string>;
|
|
1123
|
+
};
|
|
1124
|
+
};
|
|
1052
1125
|
}>;
|
|
1126
|
+
"translations"?: {
|
|
1127
|
+
[key: string]: {
|
|
1128
|
+
"title"?: string;
|
|
1129
|
+
"intro"?: string;
|
|
1130
|
+
"submitLabel"?: string;
|
|
1131
|
+
"confirmation"?: string;
|
|
1132
|
+
};
|
|
1133
|
+
};
|
|
1053
1134
|
};
|
|
1054
1135
|
"answers": {
|
|
1055
1136
|
[key: string]: string;
|
|
@@ -1212,10 +1293,34 @@ export type LiveStatus = {
|
|
|
1212
1293
|
"dock": boolean;
|
|
1213
1294
|
};
|
|
1214
1295
|
};
|
|
1296
|
+
export type EventRequestOptions = {
|
|
1297
|
+
"open": boolean;
|
|
1298
|
+
"types": Array<{
|
|
1299
|
+
"id": string;
|
|
1300
|
+
"label": string;
|
|
1301
|
+
}>;
|
|
1302
|
+
"rooms": Array<{
|
|
1303
|
+
"slug": string;
|
|
1304
|
+
"name": string;
|
|
1305
|
+
"color": string;
|
|
1306
|
+
}>;
|
|
1307
|
+
"replyTime": string;
|
|
1308
|
+
"notice": string;
|
|
1309
|
+
"phone": string;
|
|
1310
|
+
"timezone": string;
|
|
1311
|
+
"events": Array<{
|
|
1312
|
+
"slug": string;
|
|
1313
|
+
"title": string;
|
|
1314
|
+
"dates": Array<string>;
|
|
1315
|
+
}>;
|
|
1316
|
+
};
|
|
1317
|
+
export type RequestReceipt = {
|
|
1318
|
+
"id": string;
|
|
1319
|
+
};
|
|
1215
1320
|
export type ApiErrorResponse = {
|
|
1216
1321
|
"version": 1;
|
|
1217
1322
|
"error": {
|
|
1218
|
-
"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";
|
|
1323
|
+
"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" | "closed" | "trap" | "busy" | "full" | "changed" | "title" | "type" | "start" | "end" | "past" | "far" | "repeat" | "room" | "people" | "event" | "date" | "what" | "name" | "email" | "phone";
|
|
1219
1324
|
"message": string;
|
|
1220
1325
|
"issues"?: Array<{
|
|
1221
1326
|
"path": Array<string | number>;
|
|
@@ -1412,7 +1517,7 @@ export type EditorDocument = {
|
|
|
1412
1517
|
"confirmation": string;
|
|
1413
1518
|
"fields": Array<{
|
|
1414
1519
|
"id": string;
|
|
1415
|
-
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
|
|
1520
|
+
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading" | "time";
|
|
1416
1521
|
"label": string;
|
|
1417
1522
|
"required": boolean;
|
|
1418
1523
|
"help": string;
|
|
@@ -1420,7 +1525,23 @@ export type EditorDocument = {
|
|
|
1420
1525
|
"placeholder"?: string;
|
|
1421
1526
|
"width"?: "full" | "half";
|
|
1422
1527
|
"allowOther"?: boolean;
|
|
1528
|
+
"translations"?: {
|
|
1529
|
+
[key: string]: {
|
|
1530
|
+
"label"?: string;
|
|
1531
|
+
"help"?: string;
|
|
1532
|
+
"placeholder"?: string;
|
|
1533
|
+
"options"?: Array<string>;
|
|
1534
|
+
};
|
|
1535
|
+
};
|
|
1423
1536
|
}>;
|
|
1537
|
+
"translations"?: {
|
|
1538
|
+
[key: string]: {
|
|
1539
|
+
"title"?: string;
|
|
1540
|
+
"intro"?: string;
|
|
1541
|
+
"submitLabel"?: string;
|
|
1542
|
+
"confirmation"?: string;
|
|
1543
|
+
};
|
|
1544
|
+
};
|
|
1424
1545
|
};
|
|
1425
1546
|
};
|
|
1426
1547
|
}) | (null);
|
|
@@ -1615,7 +1736,7 @@ export type EditorBooking = {
|
|
|
1615
1736
|
"confirmation": string;
|
|
1616
1737
|
"fields": Array<{
|
|
1617
1738
|
"id": string;
|
|
1618
|
-
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
|
|
1739
|
+
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading" | "time";
|
|
1619
1740
|
"label": string;
|
|
1620
1741
|
"required": boolean;
|
|
1621
1742
|
"help": string;
|
|
@@ -1623,7 +1744,23 @@ export type EditorBooking = {
|
|
|
1623
1744
|
"placeholder"?: string;
|
|
1624
1745
|
"width"?: "full" | "half";
|
|
1625
1746
|
"allowOther"?: boolean;
|
|
1747
|
+
"translations"?: {
|
|
1748
|
+
[key: string]: {
|
|
1749
|
+
"label"?: string;
|
|
1750
|
+
"help"?: string;
|
|
1751
|
+
"placeholder"?: string;
|
|
1752
|
+
"options"?: Array<string>;
|
|
1753
|
+
};
|
|
1754
|
+
};
|
|
1626
1755
|
}>;
|
|
1756
|
+
"translations"?: {
|
|
1757
|
+
[key: string]: {
|
|
1758
|
+
"title"?: string;
|
|
1759
|
+
"intro"?: string;
|
|
1760
|
+
"submitLabel"?: string;
|
|
1761
|
+
"confirmation"?: string;
|
|
1762
|
+
};
|
|
1763
|
+
};
|
|
1627
1764
|
};
|
|
1628
1765
|
"answers": {
|
|
1629
1766
|
[key: string]: string;
|
|
@@ -1662,7 +1799,7 @@ export type EditorBookingList = {
|
|
|
1662
1799
|
"confirmation": string;
|
|
1663
1800
|
"fields": Array<{
|
|
1664
1801
|
"id": string;
|
|
1665
|
-
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
|
|
1802
|
+
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading" | "time";
|
|
1666
1803
|
"label": string;
|
|
1667
1804
|
"required": boolean;
|
|
1668
1805
|
"help": string;
|
|
@@ -1670,7 +1807,23 @@ export type EditorBookingList = {
|
|
|
1670
1807
|
"placeholder"?: string;
|
|
1671
1808
|
"width"?: "full" | "half";
|
|
1672
1809
|
"allowOther"?: boolean;
|
|
1810
|
+
"translations"?: {
|
|
1811
|
+
[key: string]: {
|
|
1812
|
+
"label"?: string;
|
|
1813
|
+
"help"?: string;
|
|
1814
|
+
"placeholder"?: string;
|
|
1815
|
+
"options"?: Array<string>;
|
|
1816
|
+
};
|
|
1817
|
+
};
|
|
1673
1818
|
}>;
|
|
1819
|
+
"translations"?: {
|
|
1820
|
+
[key: string]: {
|
|
1821
|
+
"title"?: string;
|
|
1822
|
+
"intro"?: string;
|
|
1823
|
+
"submitLabel"?: string;
|
|
1824
|
+
"confirmation"?: string;
|
|
1825
|
+
};
|
|
1826
|
+
};
|
|
1674
1827
|
};
|
|
1675
1828
|
"answers": {
|
|
1676
1829
|
[key: string]: string;
|
|
@@ -2353,7 +2506,7 @@ export type EditorSaveInput = {
|
|
|
2353
2506
|
"confirmation"?: string;
|
|
2354
2507
|
"fields"?: Array<{
|
|
2355
2508
|
"id": string;
|
|
2356
|
-
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading";
|
|
2509
|
+
"type": "text" | "textarea" | "email" | "phone" | "number" | "select" | "checkbox" | "date" | "radio" | "checkboxes" | "url" | "consent" | "heading" | "time";
|
|
2357
2510
|
"label": string;
|
|
2358
2511
|
"required"?: boolean;
|
|
2359
2512
|
"help"?: string;
|
|
@@ -2361,7 +2514,23 @@ export type EditorSaveInput = {
|
|
|
2361
2514
|
"placeholder"?: string;
|
|
2362
2515
|
"width"?: "full" | "half";
|
|
2363
2516
|
"allowOther"?: boolean;
|
|
2517
|
+
"translations"?: {
|
|
2518
|
+
[key: string]: {
|
|
2519
|
+
"label"?: string;
|
|
2520
|
+
"help"?: string;
|
|
2521
|
+
"placeholder"?: string;
|
|
2522
|
+
"options"?: Array<string>;
|
|
2523
|
+
};
|
|
2524
|
+
};
|
|
2364
2525
|
}>;
|
|
2526
|
+
"translations"?: {
|
|
2527
|
+
[key: string]: {
|
|
2528
|
+
"title"?: string;
|
|
2529
|
+
"intro"?: string;
|
|
2530
|
+
"submitLabel"?: string;
|
|
2531
|
+
"confirmation"?: string;
|
|
2532
|
+
};
|
|
2533
|
+
};
|
|
2365
2534
|
};
|
|
2366
2535
|
};
|
|
2367
2536
|
});
|
|
@@ -2720,6 +2889,26 @@ export type FormResponseInput = {
|
|
|
2720
2889
|
"version"?: string;
|
|
2721
2890
|
"website"?: string;
|
|
2722
2891
|
};
|
|
2892
|
+
export type RequestFields = {
|
|
2893
|
+
"kind": "new" | "change";
|
|
2894
|
+
"type"?: string;
|
|
2895
|
+
"title"?: string;
|
|
2896
|
+
"start"?: string;
|
|
2897
|
+
"end"?: string;
|
|
2898
|
+
"repeat"?: "once" | "weekly" | "other";
|
|
2899
|
+
"repeatText"?: string;
|
|
2900
|
+
"rooms"?: Array<string>;
|
|
2901
|
+
"roomsUnsure"?: boolean;
|
|
2902
|
+
"people"?: (number) | (null);
|
|
2903
|
+
"event"?: string;
|
|
2904
|
+
"date"?: string;
|
|
2905
|
+
"message"?: string;
|
|
2906
|
+
"name": string;
|
|
2907
|
+
"email": string;
|
|
2908
|
+
"phone"?: string;
|
|
2909
|
+
"locale"?: string;
|
|
2910
|
+
"website"?: string;
|
|
2911
|
+
};
|
|
2723
2912
|
export type RescheduleInput = {
|
|
2724
2913
|
"start": string;
|
|
2725
2914
|
"minutes"?: number;
|