@acms-subir/client 0.1.15 → 0.1.17
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 +8 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +15 -3
- package/dist/types.d.ts +24 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,8 +27,11 @@ raw document. Every method accepts `locale` and `signal` in its options object.
|
|
|
27
27
|
Locale is sent only for routes that support translations. `withLocale` shares
|
|
28
28
|
the cache and transport configuration with the original client. `site()` and
|
|
29
29
|
`pushTopics()` take a language since core 0.3.32; an older site rejects it, so
|
|
30
|
-
the client asks once more without it and gets the main language.
|
|
31
|
-
|
|
30
|
+
the client asks once more without it and gets the main language. `book()`
|
|
31
|
+
sends the client's `locale` in its body, so the booking's emails (and the links
|
|
32
|
+
in them) speak the app's language; a site before core 0.3.38 refuses that field,
|
|
33
|
+
so the client books once more without it, with the same key, in the site's main
|
|
34
|
+
language. Update the site before shipping an app build with a newer client.
|
|
32
35
|
|
|
33
36
|
| Method | Options / behavior |
|
|
34
37
|
| --- | --- |
|
|
@@ -45,8 +48,8 @@ site before shipping an app build with a newer client.
|
|
|
45
48
|
| `calendars()` | Public calendars |
|
|
46
49
|
| `resources(opts)`, `resource(slug, opts)` | Public resources; slug lookup scans list pages |
|
|
47
50
|
| `availability(opts)` | Required `resource`, `link`; optional `from`, `days`, `minutes` |
|
|
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` |
|
|
51
|
+
| `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
|
+
| `book(opts)` | Resource booking or RSVP input (`RsvpInput` for an RSVP), optional `idempotencyKey`; sends the client's `locale` (or `opts.locale`) for its emails |
|
|
50
53
|
| `openapi()` | Raw OpenAPI document |
|
|
51
54
|
| `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
55
|
| `updateDevice(token, { topics?, locale?, channels? })` | Change a device's topics, language or channels |
|
|
@@ -118,6 +121,7 @@ if (status.open) {
|
|
|
118
121
|
// required when the event asks questions: a changed form answers 409, so read the status again
|
|
119
122
|
...(status.form ? { formVersion: status.form.version } : {}),
|
|
120
123
|
};
|
|
124
|
+
// an email that already has an RSVP for this date: AcmsError 409 with code 'duplicate' (its link is emailed again)
|
|
121
125
|
const result = await client.book({ ...rsvp, idempotencyKey: crypto.randomUUID() });
|
|
122
126
|
// pending when the organiser approves RSVPs; status.form?.confirmation is the thank-you text.
|
|
123
127
|
// result.manageToken changes or cancels it later (manageBooking, cancelBooking), like the email's link:
|
package/dist/index.d.ts
CHANGED
|
@@ -255,6 +255,7 @@ export interface AcmsClient {
|
|
|
255
255
|
* RSVP with `book({ event, start, seats, name, email, answers, formVersion: form.version })`.
|
|
256
256
|
*/
|
|
257
257
|
rsvpStatus(slug: string, o: RsvpStatusOptions): Promise<RsvpStatus>;
|
|
258
|
+
/** A room booking or an RSVP. Sends the client's `locale` (or `o.locale`), so its emails and links speak it. */
|
|
258
259
|
book(o: BookOptions): Promise<BookingResult>;
|
|
259
260
|
openapi(o?: RequestOptions): Promise<OpenApiDocument>;
|
|
260
261
|
/** Register or refresh this device's Expo push token. Call on every app start. Requires push on the site. */
|
package/dist/index.js
CHANGED
|
@@ -280,10 +280,22 @@ export function createClient(options) {
|
|
|
280
280
|
calendars: (o = {}) => request('calendars', o),
|
|
281
281
|
availability: (o) => request('availability', o, { resource: o.resource, link: o.link, from: o.from, days: o.days, minutes: o.minutes }),
|
|
282
282
|
rsvpStatus: (slug, o) => request('rsvpStatus', o, { start: o.start }, slug),
|
|
283
|
-
book
|
|
284
|
-
const { locale, signal, idempotencyKey, ...body } = o;
|
|
283
|
+
async book(o) {
|
|
284
|
+
const { locale = options.locale, signal, idempotencyKey, ...body } = o;
|
|
285
285
|
const key = idempotencyKey ?? defaultHeaders.get('Idempotency-Key') ?? uuid();
|
|
286
|
-
|
|
286
|
+
// the client's language rides in the body: the booking's emails and links speak it
|
|
287
|
+
if (locale === undefined)
|
|
288
|
+
return request('book', { signal }, {}, undefined, body, key);
|
|
289
|
+
try {
|
|
290
|
+
return await request('book', { signal }, {}, undefined, { ...body, locale }, key);
|
|
291
|
+
}
|
|
292
|
+
catch (error) {
|
|
293
|
+
// sites before core 0.3.38 refuse the field (and one the site doesn't have): book without it, in
|
|
294
|
+
// the site's main language. A refused request doesn't use up the key.
|
|
295
|
+
if (!(error instanceof AcmsError) || error.status !== 400 || !/locale/i.test(JSON.stringify([error.message, error.issues ?? []])))
|
|
296
|
+
throw error;
|
|
297
|
+
return request('book', { signal }, {}, undefined, body, key);
|
|
298
|
+
}
|
|
287
299
|
},
|
|
288
300
|
openapi: (o = {}) => request('openapi', o),
|
|
289
301
|
registerDevice: (input, o = {}) => request('registerDevice', o, {}, undefined, input),
|
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;
|
|
@@ -251,6 +253,9 @@ export type Event = {
|
|
|
251
253
|
"name": string;
|
|
252
254
|
"color": string;
|
|
253
255
|
}>;
|
|
256
|
+
"notify": {
|
|
257
|
+
"changes": Array<string>;
|
|
258
|
+
};
|
|
254
259
|
};
|
|
255
260
|
export type Events = {
|
|
256
261
|
"locale": string | null;
|
|
@@ -308,6 +313,8 @@ export type Events = {
|
|
|
308
313
|
"capacity": number;
|
|
309
314
|
"autoConfirm": boolean;
|
|
310
315
|
"maxSeats": number;
|
|
316
|
+
"closesAt": string | null;
|
|
317
|
+
"closeBefore": number;
|
|
311
318
|
"form"?: {
|
|
312
319
|
"title": string;
|
|
313
320
|
"intro": string;
|
|
@@ -338,6 +345,9 @@ export type Events = {
|
|
|
338
345
|
"name": string;
|
|
339
346
|
"color": string;
|
|
340
347
|
}>;
|
|
348
|
+
"notify": {
|
|
349
|
+
"changes": Array<string>;
|
|
350
|
+
};
|
|
341
351
|
};
|
|
342
352
|
}>;
|
|
343
353
|
};
|
|
@@ -444,6 +454,8 @@ export type SearchResults = {
|
|
|
444
454
|
"capacity": number;
|
|
445
455
|
"autoConfirm": boolean;
|
|
446
456
|
"maxSeats": number;
|
|
457
|
+
"closesAt": string | null;
|
|
458
|
+
"closeBefore": number;
|
|
447
459
|
"form"?: {
|
|
448
460
|
"title": string;
|
|
449
461
|
"intro": string;
|
|
@@ -474,6 +486,9 @@ export type SearchResults = {
|
|
|
474
486
|
"name": string;
|
|
475
487
|
"color": string;
|
|
476
488
|
}>;
|
|
489
|
+
"notify": {
|
|
490
|
+
"changes": Array<string>;
|
|
491
|
+
};
|
|
477
492
|
};
|
|
478
493
|
}>;
|
|
479
494
|
"more": {
|
|
@@ -601,12 +616,13 @@ export type RsvpStatus = {
|
|
|
601
616
|
"start": string;
|
|
602
617
|
"end": string;
|
|
603
618
|
"open": boolean;
|
|
604
|
-
"reason": ("disabled" | "ended" | "cancelled" | "full") | (null);
|
|
619
|
+
"reason": ("disabled" | "ended" | "closed" | "cancelled" | "full") | (null);
|
|
605
620
|
"going": number;
|
|
606
621
|
"left": (number) | (null);
|
|
607
622
|
"capacity": number;
|
|
608
623
|
"maxSeats": number;
|
|
609
624
|
"autoConfirm": boolean;
|
|
625
|
+
"closesAt": (string) | (null);
|
|
610
626
|
"form": ({
|
|
611
627
|
"version": string;
|
|
612
628
|
"title": string;
|
|
@@ -958,7 +974,7 @@ export type LiveStatus = {
|
|
|
958
974
|
export type ApiErrorResponse = {
|
|
959
975
|
"version": 1;
|
|
960
976
|
"error": {
|
|
961
|
-
"code": "invalid_request" | "unauthorized" | "forbidden" | "not_found" | "method_not_allowed" | "conflict" | "gone" | "payload_too_large" | "unsupported_media_type" | "rate_limited" | "upstream_error" | "internal_error";
|
|
977
|
+
"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";
|
|
962
978
|
"message": string;
|
|
963
979
|
"issues"?: Array<{
|
|
964
980
|
"path": Array<string | number>;
|
|
@@ -1144,6 +1160,8 @@ export type EditorDocument = {
|
|
|
1144
1160
|
"capacity": number;
|
|
1145
1161
|
"autoConfirm": boolean;
|
|
1146
1162
|
"maxSeats": number;
|
|
1163
|
+
"closesAt": string | null;
|
|
1164
|
+
"closeBefore": number;
|
|
1147
1165
|
"form"?: {
|
|
1148
1166
|
"title": string;
|
|
1149
1167
|
"intro": string;
|
|
@@ -1963,6 +1981,7 @@ export type BookingInput = ({
|
|
|
1963
1981
|
"answers"?: {
|
|
1964
1982
|
[key: string]: (string) | (Array<string>);
|
|
1965
1983
|
};
|
|
1984
|
+
"locale"?: string;
|
|
1966
1985
|
"resource": string;
|
|
1967
1986
|
"link": string;
|
|
1968
1987
|
"minutes"?: number;
|
|
@@ -1974,6 +1993,7 @@ export type BookingInput = ({
|
|
|
1974
1993
|
"answers"?: {
|
|
1975
1994
|
[key: string]: (string) | (Array<string>);
|
|
1976
1995
|
};
|
|
1996
|
+
"locale"?: string;
|
|
1977
1997
|
"event": string;
|
|
1978
1998
|
"seats"?: number;
|
|
1979
1999
|
"formVersion"?: string;
|
|
@@ -2072,6 +2092,8 @@ export type EditorSaveInput = {
|
|
|
2072
2092
|
"capacity": number;
|
|
2073
2093
|
"autoConfirm": boolean;
|
|
2074
2094
|
"maxSeats": number;
|
|
2095
|
+
"closesAt"?: (string) | (null);
|
|
2096
|
+
"closeBefore"?: number;
|
|
2075
2097
|
"form"?: {
|
|
2076
2098
|
"title"?: string;
|
|
2077
2099
|
"intro"?: string;
|