@acms-subir/client 0.1.11 → 0.1.13

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
@@ -25,7 +25,10 @@ const english = client.withLocale('en');
25
25
  hosting prefix. All methods return **unwrapped `data`**; `openapi()` returns the
26
26
  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
- the cache and transport configuration with the original client.
28
+ the cache and transport configuration with the original client. `site()` and
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. Update the
31
+ site before shipping an app build with a newer client.
29
32
 
30
33
  | Method | Options / behavior |
31
34
  | --- | --- |
@@ -47,7 +50,7 @@ the cache and transport configuration with the original client.
47
50
  | `registerDevice({ token, platform, locale?, topics? })` | Register or refresh an Expo push token (call on every app start); `{ created, device }` |
48
51
  | `updateDevice(token, { topics?, locale? })` | Change a device's topics or language |
49
52
  | `unregisterDevice(token)` | Opt out (idempotent) |
50
- | `pushTopics()` | Topics to offer as notification toggles |
53
+ | `pushTopics()` | Topics to offer as notification toggles, named in the client's language (built-in and the site's own, `kind: 'site'`) |
51
54
  | `links()` | The links page: profile, socials and visible blocks (`link`, `email`, `phone`, `contact`, `heading`, `text`, `spacer`, `live`, `embed`) |
52
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 |
53
56
  | `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 |
package/dist/index.js CHANGED
@@ -25,7 +25,10 @@ export const endpoints = {
25
25
  requestGuestCode: { method: 'POST', path: '/guest/code' }, guestSignIn: { method: 'POST', path: '/guest/token' },
26
26
  guestBookings: { method: 'GET', path: '/guest/bookings' }, guestSignOut: { method: 'POST', path: '/guest/revoke' },
27
27
  };
28
- const localized = new Set(['home', 'page', 'content', 'contentById', 'search', 'events']);
28
+ // site: its legal links; pushTopics: topic names
29
+ const localized = new Set(['home', 'page', 'content', 'contentById', 'search', 'events', 'site', 'pushTopics']);
30
+ // localized since core 0.3.32; older sites answer ?locale= with a 400, so ask them again without it
31
+ const lateLocalized = new Set(['site', 'pushTopics']);
29
32
  function uuid() {
30
33
  if (globalThis.crypto?.randomUUID)
31
34
  return globalThis.crypto.randomUUID();
@@ -97,7 +100,7 @@ export function createClient(options) {
97
100
  if (v !== undefined)
98
101
  url.searchParams.set(k, String(v));
99
102
  const locale = opts.locale ?? options.locale;
100
- if (localized.has(name) && locale !== undefined)
103
+ if (localized.has(name) && locale !== undefined && !extra.noLocale)
101
104
  url.searchParams.set('locale', locale);
102
105
  const controller = new AbortController();
103
106
  const abort = () => controller.abort(new AcmsError(0, 'aborted', 'Request aborted.', undefined, undefined, key));
@@ -177,6 +180,9 @@ export function createClient(options) {
177
180
  }
178
181
  throw new AcmsError(res.status, res.ok ? 'invalid_response' : 'http_error', `HTTP ${res.status}: expected a JSON response.`, retryAfter, undefined, key);
179
182
  }
183
+ // a site older than the client: unlocalized words beat no site info at all
184
+ if (res.status === 400 && lateLocalized.has(name) && url.searchParams.has('locale') && /locale/i.test(JSON.stringify(json?.error ?? '')))
185
+ return await request(name, opts, query, param, payload, key, { ...extra, noLocale: true });
180
186
  if (!res.ok)
181
187
  throw new AcmsError(res.status, json?.error?.code ?? 'http_error', json?.error?.message ?? `HTTP ${res.status}`, retryAfter, json?.error?.issues, key);
182
188
  if (name !== 'openapi' && (json?.version !== 1 || !Object.prototype.hasOwnProperty.call(json, 'data')))
package/dist/types.d.ts CHANGED
@@ -806,10 +806,12 @@ export type DeviceRemoved = {
806
806
  "deleted": true;
807
807
  };
808
808
  export type PushTopics = {
809
+ "locale": string | null;
809
810
  "topics": Array<{
810
811
  "id": string;
811
812
  "label": string;
812
- "kind": "general" | "collection" | "calendar";
813
+ "kind": "general" | "collection" | "calendar" | "site";
814
+ "description"?: string;
813
815
  }>;
814
816
  };
815
817
  export type LiveSnapshot = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@acms-subir/client",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "Typed, dependency-free client for the ACMS public mobile API.",
5
5
  "type": "module",
6
6
  "license": "MIT",