@acms-subir/client 0.1.13 → 0.1.14

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
@@ -47,12 +47,13 @@ site before shipping an app build with a newer client.
47
47
  | `availability(opts)` | Required `resource`, `link`; optional `from`, `days`, `minutes` |
48
48
  | `book(opts)` | Resource booking or RSVP input, optional `idempotencyKey` |
49
49
  | `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 |
50
+ | `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']`) |
51
+ | `updateDevice(token, { topics?, locale?, channels? })` | Change a device's topics, language or channels |
52
52
  | `unregisterDevice(token)` | Opt out (idempotent) |
53
53
  | `pushTopics()` | Topics to offer as notification toggles, named in the client's language (built-in and the site's own, `kind: 'site'`) |
54
54
  | `links()` | The links page: profile, socials and visible blocks (`link`, `email`, `phone`, `contact`, `heading`, `text`, `spacer`, `live`, `embed`) |
55
55
  | `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 |
56
+ | `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
57
  | `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
58
  | `manageBooking(token)`, `cancelBooking(token)` | The booker's own booking from its `manageToken`, and cancelling it; `can` says what is allowed |
58
59
  | `rescheduleAvailability(token, { from?, days?, minutes? })`, `rescheduleBooking(token, { start, minutes? })` | Open times for moving it (its own time counts as free), then the move |
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, 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;
@@ -168,6 +173,14 @@ export declare const endpoints: {
168
173
  readonly method: "GET";
169
174
  readonly path: "/live";
170
175
  };
176
+ readonly announcements: {
177
+ readonly method: "GET";
178
+ readonly path: "/announcements";
179
+ };
180
+ readonly announcement: {
181
+ readonly method: "GET";
182
+ readonly path: "/announcements/{id}";
183
+ };
171
184
  readonly manageBooking: {
172
185
  readonly method: "GET";
173
186
  readonly path: "/bookings/manage";
@@ -246,6 +259,10 @@ export interface AcmsClient {
246
259
  * clock, even if later requests fail. Requires `site.features.live`.
247
260
  */
248
261
  live(o?: RequestOptions): Promise<LiveStatus>;
262
+ /** Announcements up right now, newest first (`pinned: true`: only the banners, urgent first). Requires `site.features.announcements`. */
263
+ announcements(o?: AnnouncementOptions): Promise<Announcements>;
264
+ /** One announcement that is up; 404 once it came down. */
265
+ announcement(id: string, o?: RequestOptions): Promise<AnnouncementDetail>;
249
266
  /** A published form's questions. 410 when it stopped accepting responses. Requires `site.features.forms`. */
250
267
  form(id: string, o?: RequestOptions): Promise<Form>;
251
268
  /** Send answers (checkbox groups as arrays). Retries reuse the same Idempotency-Key, so they never duplicate. */
@@ -278,5 +295,6 @@ export interface AcmsClient {
278
295
  pages(o?: ListOptions): AsyncGenerator<ContentList['items'][number]>;
279
296
  events(o?: EventOptions): AsyncGenerator<Events['occurrences'][number]>;
280
297
  resources(o?: ListOptions): AsyncGenerator<Resource>;
298
+ announcements(o?: AnnouncementOptions): AsyncGenerator<Announcements['announcements'][number]>;
281
299
  };
282
300
  }
package/dist/index.js CHANGED
@@ -17,6 +17,8 @@ export const endpoints = {
17
17
  links: { method: 'GET', path: '/links' }, form: { method: 'GET', path: '/forms/{id}' }, submitForm: { method: 'POST', path: '/forms/{id}/responses' },
18
18
  // live video status (404 while the site's live video is off)
19
19
  live: { method: 'GET', path: '/live' },
20
+ // announcements (404 unless the site turns them on)
21
+ announcements: { method: 'GET', path: '/announcements' }, announcement: { method: 'GET', path: '/announcements/{id}' },
20
22
  // the booker's own booking: its private token goes in the Booking-Token header
21
23
  manageBooking: { method: 'GET', path: '/bookings/manage' }, cancelBooking: { method: 'POST', path: '/bookings/manage/cancel' },
22
24
  rescheduleAvailability: { method: 'GET', path: '/bookings/manage/availability' }, rescheduleBooking: { method: 'POST', path: '/bookings/manage/reschedule' },
@@ -26,7 +28,7 @@ export const endpoints = {
26
28
  guestBookings: { method: 'GET', path: '/guest/bookings' }, guestSignOut: { method: 'POST', path: '/guest/revoke' },
27
29
  };
28
30
  // site: its legal links; pushTopics: topic names
29
- const localized = new Set(['home', 'page', 'content', 'contentById', 'search', 'events', 'site', 'pushTopics']);
31
+ const localized = new Set(['home', 'page', 'content', 'contentById', 'search', 'events', 'site', 'pushTopics', 'announcements', 'announcement']);
30
32
  // localized since core 0.3.32; older sites answer ?locale= with a 400, so ask them again without it
31
33
  const lateLocalized = new Set(['site', 'pushTopics']);
32
34
  function uuid() {
@@ -230,19 +232,22 @@ export function createClient(options) {
230
232
  const pages = (o = {}) => content({ ...o, kind: 'page' });
231
233
  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
234
  const resources = (o = {}) => request('resources', o, paging(o));
235
+ const announcements = (o = {}) => request('announcements', o, { ...paging(o), kind: o.kind, pinned: o.pinned ? 'true' : undefined });
233
236
  const paginate = {
234
237
  content: (o = {}) => iterate(content, 'items', o),
235
238
  posts: (o = {}) => iterate(posts, 'items', o),
236
239
  pages: (o = {}) => iterate(pages, 'items', o),
237
240
  events: (o = {}) => iterate(events, 'occurrences', o),
238
241
  resources: (o = {}) => iterate(resources, 'resources', o),
242
+ announcements: (o = {}) => iterate(announcements, 'announcements', o),
239
243
  };
240
244
  return {
241
245
  site: (o = {}) => request('site', o),
242
246
  theme: (o = {}) => request('theme', o),
243
247
  home: (o = {}) => request('home', o),
244
248
  page: (slug, o = {}) => request('page', o, {}, slug),
245
- content, posts, pages, events, resources, paginate,
249
+ content, posts, pages, events, resources, announcements, paginate,
250
+ announcement: (id, o = {}) => request('announcement', o, {}, id),
246
251
  async search(q, o = {}) {
247
252
  const query = q.trim();
248
253
  // blank input (an emptied search box) needs no round trip
package/dist/types.d.ts CHANGED
@@ -35,6 +35,7 @@ export type Site = {
35
35
  "forms": boolean;
36
36
  "links": boolean;
37
37
  "live": boolean;
38
+ "announcements": boolean;
38
39
  };
39
40
  "legal": {
40
41
  "privacy": string | null;
@@ -787,6 +788,7 @@ export type Device = {
787
788
  "platform": "ios" | "android";
788
789
  "locale": string | null;
789
790
  "topics": Array<string>;
791
+ "channels": Array<string>;
790
792
  "registeredAt": string;
791
793
  "lastSeenAt": string;
792
794
  };
@@ -797,6 +799,7 @@ export type DeviceRegistration = {
797
799
  "platform": "ios" | "android";
798
800
  "locale": string | null;
799
801
  "topics": Array<string>;
802
+ "channels": Array<string>;
800
803
  "registeredAt": string;
801
804
  "lastSeenAt": string;
802
805
  };
@@ -814,6 +817,69 @@ export type PushTopics = {
814
817
  "description"?: string;
815
818
  }>;
816
819
  };
820
+ export type Announcement = {
821
+ "id": string;
822
+ "kind": "event" | "registration" | "help" | "info" | "urgent";
823
+ "kindLabel": string;
824
+ "title": string;
825
+ "message": string;
826
+ "details": string;
827
+ "button": ({
828
+ "label": string;
829
+ "url": string;
830
+ }) | (null);
831
+ "url": string | null;
832
+ "pinned": boolean;
833
+ "urgent": boolean;
834
+ "publishedAt": string;
835
+ "showUntil": (string) | (null);
836
+ "translated": boolean;
837
+ };
838
+ export type Announcements = {
839
+ "locale": string | null;
840
+ "announcements": Array<{
841
+ "id": string;
842
+ "kind": "event" | "registration" | "help" | "info" | "urgent";
843
+ "kindLabel": string;
844
+ "title": string;
845
+ "message": string;
846
+ "details": string;
847
+ "button": ({
848
+ "label": string;
849
+ "url": string;
850
+ }) | (null);
851
+ "url": string | null;
852
+ "pinned": boolean;
853
+ "urgent": boolean;
854
+ "publishedAt": string;
855
+ "showUntil": (string) | (null);
856
+ "translated": boolean;
857
+ }>;
858
+ "pagination": {
859
+ "page": number;
860
+ "limit": number;
861
+ "nextPage": (number) | (null);
862
+ };
863
+ };
864
+ export type AnnouncementDetail = {
865
+ "id": string;
866
+ "kind": "event" | "registration" | "help" | "info" | "urgent";
867
+ "kindLabel": string;
868
+ "title": string;
869
+ "message": string;
870
+ "details": string;
871
+ "button": ({
872
+ "label": string;
873
+ "url": string;
874
+ }) | (null);
875
+ "url": string | null;
876
+ "pinned": boolean;
877
+ "urgent": boolean;
878
+ "publishedAt": string;
879
+ "showUntil": (string) | (null);
880
+ "translated": boolean;
881
+ "locale": string | null;
882
+ };
817
883
  export type LiveSnapshot = {
818
884
  "status": "live" | "upcoming" | "offline" | "unknown";
819
885
  "source": "automatic" | "manual";
@@ -1881,10 +1947,12 @@ export type DeviceInput = {
1881
1947
  "platform": "ios" | "android";
1882
1948
  "locale"?: string;
1883
1949
  "topics"?: Array<string>;
1950
+ "channels"?: Array<string>;
1884
1951
  };
1885
1952
  export type DeviceUpdate = {
1886
1953
  "locale"?: string;
1887
1954
  "topics"?: Array<string>;
1955
+ "channels"?: Array<string>;
1888
1956
  };
1889
1957
  export type EditorCreateInput = ({
1890
1958
  "kind": "post";
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.14",
4
4
  "description": "Typed, dependency-free client for the ACMS public mobile API.",
5
5
  "type": "module",
6
6
  "license": "MIT",