@playaos/api-client 0.58.0 → 0.59.0

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/dist/index.js CHANGED
@@ -12,6 +12,26 @@ var ApiClientError = class extends Error {
12
12
  }
13
13
  };
14
14
  /**
15
+ * Error codes a caller may branch on. `ApiClientError.code` stays a plain `string`, since the API
16
+ * can add codes; compare against these constants rather than string literals.
17
+ */
18
+ const ApiErrorCode = {
19
+ /** 403: the request writes to an archived event, which is read-only (ADR-128/132). */
20
+ EVENT_READ_ONLY: "EVENT_READ_ONLY",
21
+ /** 409: a year-only request matches more than one event; resend with `eventId` (ADR-132). */
22
+ EVENT_REQUIRED: "EVENT_REQUIRED"
23
+ };
24
+ /** The embed API spells the read-only code in lower_snake; methods that fall back to embed see it. */
25
+ const EMBED_EVENT_READ_ONLY = "event_read_only";
26
+ /**
27
+ * True when a write was refused because its event is archived and read-only: 403 with code
28
+ * `EVENT_READ_ONLY` (or embed's `event_read_only`). Reads of an archived event still succeed. Plain
29
+ * 403 FORBIDDEN (scope or role) is not this error.
30
+ */
31
+ function isEventReadOnlyError(error) {
32
+ return error instanceof ApiClientError && error.status === 403 && (error.code === ApiErrorCode.EVENT_READ_ONLY || error.code === EMBED_EVENT_READ_ONLY);
33
+ }
34
+ /**
15
35
  * Parse the `Retry-After` header into integer seconds. Only the delta-seconds
16
36
  * form is honored; the HTTP-date form is ignored (returns undefined) since
17
37
  * callers expect a seconds hint.
@@ -232,24 +252,50 @@ var PlayaOSClient = class PlayaOSClient {
232
252
  book: (token, payload, opts) => post(buildUrl(this.baseUrl, `/public/booking/${encodeURIComponent(token)}/book`), this.auth, payload, opts?.signal),
233
253
  cancel: (token, payload, opts) => post(buildUrl(this.baseUrl, `/public/booking/${encodeURIComponent(token)}/cancel`), this.auth, payload, opts?.signal)
234
254
  };
255
+ /**
256
+ * Finance configuration (ADR-129) is scoped by `eventId` or `year` (ADR-132): reads default to the
257
+ * configured active camp year; `fee_tier`, widget `upsert` and `set_active_tier` write into the scope
258
+ * sent. Other operations are organization-wide.
259
+ */
235
260
  campSettings = {
236
- catalog: (opts) => request(buildUrl(this.baseUrl, "/admin/givebutter-catalog"), this.auth, opts?.signal),
261
+ catalog: (params, opts) => {
262
+ const { signal, ...scope } = params ?? {};
263
+ return request(buildUrl(this.baseUrl, "/admin/givebutter-catalog", scope), this.auth, opts?.signal ?? signal);
264
+ },
237
265
  catalogOperation: (payload, opts) => post(buildUrl(this.baseUrl, "/admin/givebutter-catalog"), this.auth, payload, opts?.signal),
238
- widgets: (opts) => request(buildUrl(this.baseUrl, "/admin/givebutter-widgets"), this.auth, opts?.signal),
266
+ widgets: (params, opts) => {
267
+ const { signal, ...scope } = params ?? {};
268
+ return request(buildUrl(this.baseUrl, "/admin/givebutter-widgets", scope), this.auth, opts?.signal ?? signal);
269
+ },
239
270
  widgetOperation: (payload, opts) => post(buildUrl(this.baseUrl, "/admin/givebutter-widgets"), this.auth, payload, opts?.signal),
240
- admin: (opts) => request(buildUrl(this.baseUrl, "/admin/camp-settings"), this.auth, opts?.signal),
271
+ admin: (params, opts) => {
272
+ const { signal, ...scope } = params ?? {};
273
+ return request(buildUrl(this.baseUrl, "/admin/camp-settings", scope), this.auth, opts?.signal ?? signal);
274
+ },
241
275
  update: (payload, opts) => post(buildUrl(this.baseUrl, "/admin/camp-settings"), this.auth, payload, opts?.signal)
242
276
  };
243
277
  scheduling = {
244
278
  booking: (id, opts) => request(buildUrl(this.baseUrl, `/admin/scheduling/bookings/${encodeURIComponent(id)}`), this.auth, opts?.signal),
245
279
  adminSettings: (opts) => request(buildUrl(this.baseUrl, "/admin/scheduling/settings"), this.auth, opts?.signal),
246
280
  adminOperation: (payload, opts) => post(buildUrl(this.baseUrl, "/admin/scheduling/settings"), this.auth, payload, opts?.signal),
247
- feed: (interviewerId, token, opts) => request(buildUrl(this.baseUrl, `/scheduling/feed/${encodeURIComponent(interviewerId)}`, { token }), this.auth, opts?.signal)
281
+ /**
282
+ * Calendar subscription read. Scope with `eventId` or `year` (ADR-132); with neither, the
283
+ * active camp year. A year matching several events fails with 409 EVENT_REQUIRED.
284
+ */
285
+ feed: (interviewerId, token, params, opts) => {
286
+ const { signal, ...scope } = params ?? {};
287
+ return request(buildUrl(this.baseUrl, `/scheduling/feed/${encodeURIComponent(interviewerId)}`, {
288
+ token,
289
+ ...scope
290
+ }), this.auth, opts?.signal ?? signal);
291
+ }
248
292
  };
249
293
  members = {
294
+ /** Exports one event, or a year with one event (ADR-132); with neither, the active camp year. */
250
295
  adminExport: (params, opts) => request(buildUrl(this.baseUrl, "/members/admin/export", params), this.auth, opts?.signal),
251
296
  adminOperation: (payload, opts) => post(buildUrl(this.baseUrl, "/members/admin/operation"), this.auth, payload, opts?.signal),
252
297
  adminImportOperation: (payload, opts) => post(buildUrl(this.baseUrl, "/members/admin/import-operation"), this.auth, payload, opts?.signal),
298
+ /** On an event, `campYear` holds that event's participation (ADR-132). */
253
299
  adminDetail: (id, params, opts) => request(buildUrl(this.baseUrl, `/members/admin/${encodeURIComponent(id)}/detail`, params), this.auth, opts?.signal),
254
300
  adminHistory: (id, opts) => request(buildUrl(this.baseUrl, `/members/admin/${encodeURIComponent(id)}/history`), this.auth, opts?.signal),
255
301
  selfProfile: (params, opts) => request(buildUrl(this.baseUrl, "/members/me/profile", params), this.auth, opts?.signal),
@@ -266,8 +312,14 @@ var PlayaOSClient = class PlayaOSClient {
266
312
  bootstrap: (opts) => request(buildUrl(this.baseUrl, "/members/me/bootstrap"), this.auth, opts?.signal, "no-store"),
267
313
  gates: (opts) => request(buildUrl(this.baseUrl, "/members/me/gates"), this.auth, opts?.signal, "no-store"),
268
314
  dashboard: (opts) => request(buildUrl(this.baseUrl, "/members/me/dashboard"), this.auth, opts?.signal),
269
- /** Always the acting member, including admins; requires a member token and members:read scope. */
270
- paymentOverview: (opts) => request(buildUrl(this.baseUrl, "/members/me/payment-overview"), this.auth, opts?.signal, "no-store"),
315
+ /**
316
+ * Always the acting member, including admins; requires a member token and members:read scope.
317
+ * Without a scope, the configured active camp year (ADR-132).
318
+ */
319
+ paymentOverview: (params, opts) => {
320
+ const { signal, ...scope } = params ?? {};
321
+ return request(buildUrl(this.baseUrl, "/members/me/payment-overview", scope), this.auth, opts?.signal ?? signal, "no-store");
322
+ },
271
323
  /** Acting member's original photo only; missing originals return 404, never an avatar fallback. */
272
324
  selfPhotoDownloadUrl: (opts) => request(buildUrl(this.baseUrl, "/members/me/photo/download-url"), this.auth, opts?.signal, "no-store"),
273
325
  /** Presigned profile-photo upload (PLA-1263). PUT the bytes, then setPhoto. */
@@ -347,13 +399,21 @@ var PlayaOSClient = class PlayaOSClient {
347
399
  dues = { list: (params, opts) => request(buildUrl(this.baseUrl, "/dues", params), this.auth, opts?.signal) };
348
400
  shifts = {
349
401
  memberAction: (payload, opts) => post(buildUrl(this.baseUrl, "/members/shifts/actions"), this.auth, payload, opts?.signal),
402
+ /** Without a scope, the configured active camp year (ADR-132). */
350
403
  mobile: (params, opts) => request(buildUrl(this.baseUrl, "/members/shifts/mobile", params), this.auth, opts?.signal),
351
- memberView: (opts) => request(buildUrl(this.baseUrl, "/members/shifts/view"), this.auth, opts?.signal),
404
+ /** Without a scope, the configured active camp year (ADR-132). */
405
+ memberView: (params, opts) => {
406
+ const { signal, ...scope } = params ?? {};
407
+ return request(buildUrl(this.baseUrl, "/members/shifts/view", scope), this.auth, opts?.signal ?? signal);
408
+ },
352
409
  adminWorkflow: (payload, opts) => post(buildUrl(this.baseUrl, "/admin/shifts/workflow"), this.auth, payload, opts?.signal),
410
+ /** Without a scope, the configured active camp year (ADR-132). */
353
411
  planner: (params, opts) => request(buildUrl(this.baseUrl, "/admin/shifts/planner", params), this.auth, opts?.signal),
354
412
  adminOperation: (payload, opts) => post(buildUrl(this.baseUrl, "/admin/shifts/operations"), this.auth, payload, opts?.signal),
355
413
  adminTypes: (opts) => request(buildUrl(this.baseUrl, "/shifts/types"), this.auth, opts?.signal),
414
+ /** With neither `year` nor `eventId`, every shift in the org (documented ADR-132 exception). */
356
415
  adminList: (params, opts) => request(buildUrl(this.baseUrl, "/shifts/admin", params), this.auth, opts?.signal),
416
+ /** With neither `year` nor `eventId`, every shift in the org (documented ADR-132 exception). */
357
417
  list: (params, opts) => request(buildUrl(this.baseUrl, "/shifts", params), this.auth, opts?.signal)
358
418
  };
359
419
  org = { get: (opts) => request(buildUrl(this.baseUrl, "/org"), this.auth, opts?.signal) };
@@ -363,7 +423,10 @@ var PlayaOSClient = class PlayaOSClient {
363
423
  adminOperation: (payload, opts) => post(buildUrl(this.baseUrl, "/admin/payments/operations"), this.auth, payload, opts?.signal),
364
424
  unmatchedRefunds: (opts) => request(buildUrl(this.baseUrl, "/admin/payments/unmatched-refunds"), this.auth, opts?.signal),
365
425
  memberPayments: (id, opts) => request(buildUrl(this.baseUrl, `/admin/payments/member/${encodeURIComponent(id)}`), this.auth, opts?.signal),
366
- adminSummary: (opts) => request(buildUrl(this.baseUrl, "/admin/payments/summary"), this.auth, opts?.signal),
426
+ adminSummary: (params, opts) => {
427
+ const { signal, ...scope } = params ?? {};
428
+ return request(buildUrl(this.baseUrl, "/admin/payments/summary", scope), this.auth, opts?.signal ?? signal);
429
+ },
367
430
  exportMonarch: (params, opts) => request(buildUrl(this.baseUrl, "/admin/payments/export", params), this.auth, opts?.signal),
368
431
  list: (params, opts) => request(buildUrl(this.baseUrl, "/payments", params), this.auth, opts?.signal),
369
432
  /** Requires a member token. `memberId` may be omitted by a non-admin (defaults to themselves); admins must pass it. */
@@ -376,21 +439,37 @@ var PlayaOSClient = class PlayaOSClient {
376
439
  contacts = { list: (params, opts) => request(buildUrl(this.baseUrl, "/contacts", params), this.auth, opts?.signal) };
377
440
  /** Logistics dashboard reads (PLA-1342): rollup, daily headcount, unsure dates, area breakdowns. */
378
441
  logistics = {
442
+ /** Requires `eventId` or `year` (ADR-132); an ambiguous year rejects with EVENT_REQUIRED. */
379
443
  summary: (params, opts) => request(buildUrl(this.baseUrl, "/logistics/summary", params), this.auth, opts?.signal),
444
+ /** Without a scope, the org's active camp year. */
380
445
  headcount: (params, opts) => request(buildUrl(this.baseUrl, "/logistics/headcount", params), this.auth, opts?.signal),
446
+ /** Without a scope, every camp year. */
381
447
  unsureDates: (params, opts) => request(buildUrl(this.baseUrl, "/logistics/unsure-dates", params), this.auth, opts?.signal),
382
- breakdowns: (opts) => request(buildUrl(this.baseUrl, "/logistics/breakdowns"), this.auth, opts?.signal)
448
+ /** Without a scope, the org's active camp year. */
449
+ breakdowns: (params, opts) => {
450
+ const { signal, ...scope } = params ?? {};
451
+ return request(buildUrl(this.baseUrl, "/logistics/breakdowns", scope), this.auth, opts?.signal ?? signal);
452
+ }
383
453
  };
384
454
  /** Admin reports (PLA-1343): dashboard rollup + build/strike availability. */
385
455
  reports = {
456
+ /** Requires `eventId` or `year` (ADR-132); an ambiguous year rejects with EVENT_REQUIRED. */
386
457
  dashboard: (params, opts) => request(buildUrl(this.baseUrl, "/reports/dashboard", params), this.auth, opts?.signal),
458
+ /** Requires `eventId` or `year` (ADR-132); an ambiguous year rejects with EVENT_REQUIRED. */
387
459
  buildStrike: (params, opts) => request(buildUrl(this.baseUrl, "/reports/build-strike", params), this.auth, opts?.signal).then((r) => r.data)
388
460
  };
389
461
  /** Bookkeeping reads (PLA-1345): camp-year list + ops-binder export preview. */
390
462
  bookkeeping = {
391
- syncGoogleSheets: (opts) => post(buildUrl(this.baseUrl, "/admin/bookkeeping/sheets/sync"), this.auth, void 0, opts?.signal),
463
+ /** Without a scope, the camp's active year (ADR-132). */
464
+ syncGoogleSheets: (params, opts) => {
465
+ const { signal, ...scope } = params ?? {};
466
+ return post(buildUrl(this.baseUrl, "/admin/bookkeeping/sheets/sync", scope), this.auth, void 0, opts?.signal ?? signal);
467
+ },
392
468
  adminOperation: (payload, opts) => post(buildUrl(this.baseUrl, "/admin/bookkeeping/operations"), this.auth, payload, opts?.signal),
393
469
  years: (opts) => request(buildUrl(this.baseUrl, "/bookkeeping/years"), this.auth, opts?.signal).then((r) => r.data),
470
+ /** Requires `eventId` or `year` (ADR-132); an ambiguous year rejects with EVENT_REQUIRED. */
471
+ summary: (params, opts) => request(buildUrl(this.baseUrl, "/bookkeeping/summary", params), this.auth, opts?.signal),
472
+ /** Without a scope, the org's operational year. */
394
473
  exportPreview: (params, opts) => request(buildUrl(this.baseUrl, "/bookkeeping/export-preview", params), this.auth, opts?.signal)
395
474
  };
396
475
  /** Operational audit logs (PLA-1338): outbound email sends and inbound webhooks. */
@@ -407,7 +486,9 @@ var PlayaOSClient = class PlayaOSClient {
407
486
  list: (params, opts) => request(buildUrl(this.baseUrl, "/notifications", params), this.auth, opts?.signal)
408
487
  };
409
488
  documents = {
489
+ /** Scope with `eventId` or `year` (ADR-132); with neither, the active camp year. */
410
490
  memberPage: (params, opts) => request(buildUrl(this.baseUrl, "/members/documents/page", params), this.auth, opts?.signal),
491
+ /** `eventId` attaches the document to that event (ADR-132); with neither scope, the active camp year. */
411
492
  create: (payload, opts) => post(buildUrl(this.baseUrl, "/documents"), this.auth, payload, opts?.signal),
412
493
  update: (id, payload, opts) => sendV1("PATCH", buildUrl(this.baseUrl, `/documents/${encodeURIComponent(id)}`), this.auth, payload, opts?.signal),
413
494
  delete: (id, opts) => sendV1("DELETE", buildUrl(this.baseUrl, `/documents/${encodeURIComponent(id)}`), this.auth, {}, opts?.signal),
@@ -418,6 +499,7 @@ var PlayaOSClient = class PlayaOSClient {
418
499
  renderContract: (id, opts) => request(buildUrl(this.baseUrl, `/documents/${encodeURIComponent(id)}/render`), this.auth, opts?.signal),
419
500
  signatureDownloadUrl: (id, opts) => request(buildUrl(this.baseUrl, `/documents/signatures/${encodeURIComponent(id)}/download-url`), this.auth, opts?.signal),
420
501
  deleteSignature: (id, opts) => sendV1("DELETE", buildUrl(this.baseUrl, `/documents/signatures/${encodeURIComponent(id)}`), this.auth, {}, opts?.signal),
502
+ /** With `eventId`, only that event's documents (ADR-132); with no scope, every document. */
421
503
  list: (params, opts) => request(buildUrl(this.baseUrl, "/documents", params), this.auth, opts?.signal),
422
504
  get: (id, opts) => request(buildUrl(this.baseUrl, `/documents/${encodeURIComponent(id)}`), this.auth, opts?.signal),
423
505
  /** Admin member signature rows, optionally filtered to one document. */
@@ -431,6 +513,7 @@ var PlayaOSClient = class PlayaOSClient {
431
513
  /** Save the acting member's response; the date option must belong to this meeting. */
432
514
  rsvp: (id, payload, opts) => sendV1("PUT", buildUrl(this.baseUrl, `/meetings/${encodeURIComponent(id)}/rsvp`), this.auth, payload, opts?.signal),
433
515
  cancelRsvp: (id, opts) => sendV1("DELETE", buildUrl(this.baseUrl, `/meetings/${encodeURIComponent(id)}/rsvp`), this.auth, void 0, opts?.signal),
516
+ /** With `eventId`, only that event's meetings (ADR-132); with no scope, every meeting. */
434
517
  list: (params, opts) => request(buildUrl(this.baseUrl, "/meetings", params), this.auth, opts?.signal),
435
518
  get: (id, opts) => request(buildUrl(this.baseUrl, `/meetings/${encodeURIComponent(id)}`), this.auth, opts?.signal),
436
519
  /** Create a meeting (PLA-1266). Admin-only; requires a member token. */
@@ -439,10 +522,20 @@ var PlayaOSClient = class PlayaOSClient {
439
522
  archive: (id, opts) => sendV1("DELETE", buildUrl(this.baseUrl, `/meetings/${encodeURIComponent(id)}`), this.auth, void 0, opts?.signal)
440
523
  };
441
524
  scholarships = {
525
+ /**
526
+ * Scholarship dashboard for an event or year (ADR-132). A year with one event reads that event;
527
+ * a year with none reads the annual rows; a year with several fails with 409 `EVENT_REQUIRED`.
528
+ * With no params, the camp's configured active year (400 when none).
529
+ */
442
530
  adminPage: (params, opts) => request(buildUrl(this.baseUrl, "/scholarships/admin-page", params), this.auth, opts?.signal),
443
531
  refresh: (id, opts) => post(buildUrl(this.baseUrl, `/scholarships/${encodeURIComponent(id)}/refresh`), this.auth, {}, opts?.signal),
532
+ /** Scholarship totals for an event or year; same scope rules and 409 `EVENT_REQUIRED` as `adminPage`. */
444
533
  stats: (params, opts) => request(buildUrl(this.baseUrl, "/scholarships/stats", params), this.auth, opts?.signal),
445
- /** Create a scholarship (code + Givebutter sync). Admin-only (PLA-1266). */
534
+ /**
535
+ * Create a scholarship (code + Givebutter sync). Admin-only (PLA-1266). A year-only create on a
536
+ * single-event year writes an event scholarship; an ambiguous year is 409 `EVENT_REQUIRED`
537
+ * (ADR-132).
538
+ */
446
539
  create: (payload, opts) => post(buildUrl(this.baseUrl, "/scholarships"), this.auth, payload, opts?.signal),
447
540
  /** Move a scholarship between assigned/used/expired. Admin-only (PLA-1266). */
448
541
  updateStatus: (id, status, opts) => sendV1("PATCH", buildUrl(this.baseUrl, `/scholarships/${encodeURIComponent(id)}`), this.auth, {
@@ -456,7 +549,17 @@ var PlayaOSClient = class PlayaOSClient {
456
549
  tickets = {
457
550
  /** Admin upsert by member and camp year, including members with no existing tracking row. */
458
551
  upsert: (memberId, year, payload, opts) => sendV1("PUT", buildUrl(this.baseUrl, `/members/${encodeURIComponent(memberId)}/tickets/${year}`), this.auth, payload, opts?.signal),
459
- /** Admin ticket-page projection; requires ticket, vehicle-pass, and member read scopes. */
552
+ /**
553
+ * Admin upsert for one event (ADR-132). Never creates a participation: a member with none in
554
+ * the event fails with 404 `PARTICIPATION_NOT_FOUND`. Pass `year` to label an event with no
555
+ * start date (400 without one); a `year` that disagrees with a dated event is 400.
556
+ */
557
+ upsertForEvent: (memberId, eventId, payload, opts) => sendV1("PUT", buildUrl(this.baseUrl, `/members/${encodeURIComponent(memberId)}/events/${encodeURIComponent(eventId)}/tickets`, { year: opts?.year }), this.auth, payload, opts?.signal),
558
+ /**
559
+ * Admin ticket-page projection; requires ticket, vehicle-pass, and member read scopes. Pass
560
+ * `eventId` for one event's participations; a year with several events fails with
561
+ * `EVENT_REQUIRED` (ADR-132).
562
+ */
460
563
  adminList: (params, opts) => request(buildUrl(this.baseUrl, "/tickets/admin", params), this.auth, opts?.signal),
461
564
  /** Update a member's ticket status/confirmation. Admin-only (PLA-1266). */
462
565
  update: (id, payload, opts) => sendV1("PATCH", buildUrl(this.baseUrl, `/tickets/${encodeURIComponent(id)}`), this.auth, payload, opts?.signal)
@@ -464,35 +567,80 @@ var PlayaOSClient = class PlayaOSClient {
464
567
  vehiclePasses = {
465
568
  /** Admin upsert by member and camp year, including members with no existing tracking row. */
466
569
  upsert: (memberId, year, payload, opts) => sendV1("PUT", buildUrl(this.baseUrl, `/members/${encodeURIComponent(memberId)}/vehicle-passes/${year}`), this.auth, payload, opts?.signal),
570
+ /**
571
+ * Admin upsert for one event (ADR-132). Never creates a participation: a member with none in
572
+ * the event fails with 404 `PARTICIPATION_NOT_FOUND`. Pass `year` to label an event with no
573
+ * start date (400 without one); a `year` that disagrees with a dated event is 400.
574
+ */
575
+ upsertForEvent: (memberId, eventId, payload, opts) => sendV1("PUT", buildUrl(this.baseUrl, `/members/${encodeURIComponent(memberId)}/events/${encodeURIComponent(eventId)}/vehicle-passes`, { year: opts?.year }), this.auth, payload, opts?.signal),
467
576
  /** Update a member's vehicle-pass status. Admin-only (PLA-1266). */
468
577
  update: (id, payload, opts) => sendV1("PATCH", buildUrl(this.baseUrl, `/vehicle-passes/${encodeURIComponent(id)}`), this.auth, payload, opts?.signal)
469
578
  };
470
579
  shelters = {
471
580
  adminOperation: (payload, opts) => post(buildUrl(this.baseUrl, "/admin/shelters/operations"), this.auth, payload, opts?.signal),
581
+ /** With an event scope, the acting member and any mates must be confirmed, attending participants. */
472
582
  createForMember: (payload, opts) => post(buildUrl(this.baseUrl, "/members/me/shelters"), this.auth, payload, opts?.signal),
473
- updateForMember: (id, payload, opts) => sendV1("PATCH", buildUrl(this.baseUrl, `/members/me/shelters/${encodeURIComponent(id)}`), this.auth, payload, opts?.signal),
474
- deleteForMember: (id, opts) => sendV1("DELETE", buildUrl(this.baseUrl, `/members/me/shelters/${encodeURIComponent(id)}`), this.auth, {}, opts?.signal),
583
+ /** A scope, when sent, must match the shelter's own event; without one, annual shelters only. */
584
+ updateForMember: (id, payload, params, opts) => {
585
+ const { signal, ...scope } = params ?? {};
586
+ return sendV1("PATCH", buildUrl(this.baseUrl, `/members/me/shelters/${encodeURIComponent(id)}`, scope), this.auth, payload, opts?.signal ?? signal);
587
+ },
588
+ deleteForMember: (id, params, opts) => {
589
+ const { signal, ...scope } = params ?? {};
590
+ return sendV1("DELETE", buildUrl(this.baseUrl, `/members/me/shelters/${encodeURIComponent(id)}`, scope), this.auth, {}, opts?.signal ?? signal);
591
+ },
475
592
  memberPage: (params, opts) => request(buildUrl(this.baseUrl, "/members/me/shelters", params), this.auth, opts?.signal),
476
593
  searchMembers: (params, opts) => request(buildUrl(this.baseUrl, "/shelters/member-search", params), this.auth, opts?.signal),
477
- requestJoin: (id, opts) => post(buildUrl(this.baseUrl, `/shelters/${encodeURIComponent(id)}/request-join`), this.auth, {}, opts?.signal),
478
- inviteCandidates: (id, opts) => request(buildUrl(this.baseUrl, `/shelters/${encodeURIComponent(id)}/invite-candidates`), this.auth, opts?.signal),
594
+ requestJoin: (id, params, opts) => {
595
+ const { signal, ...scope } = params ?? {};
596
+ return post(buildUrl(this.baseUrl, `/shelters/${encodeURIComponent(id)}/request-join`, scope), this.auth, {}, opts?.signal ?? signal);
597
+ },
598
+ inviteCandidates: (id, params, opts) => {
599
+ const { signal, ...scope } = params ?? {};
600
+ return request(buildUrl(this.baseUrl, `/shelters/${encodeURIComponent(id)}/invite-candidates`, scope), this.auth, opts?.signal ?? signal);
601
+ },
479
602
  previewJoinRequest: (token, opts) => request(buildUrl(this.baseUrl, "/shelters/join-requests/preview", { token }), this.auth, opts?.signal),
480
603
  decideJoinRequest: (payload, opts) => post(buildUrl(this.baseUrl, "/shelters/join-requests/decision"), this.auth, payload, opts?.signal),
481
604
  requestPayer: (payload, opts) => post(buildUrl(this.baseUrl, "/shelters/payer-requests"), this.auth, payload, opts?.signal),
482
605
  pendingPayerRequests: (params, opts) => request(buildUrl(this.baseUrl, "/shelters/payer-requests", params), this.auth, opts?.signal),
483
606
  resolvePayerRequests: (payload, opts) => post(buildUrl(this.baseUrl, "/shelters/payer-requests/resolve"), this.auth, payload, opts?.signal),
484
- /** Admin-only shelter table/map projection; requires members:read and a member token. */
607
+ /**
608
+ * Admin-only shelter table/map projection; requires members:read and a member token. Send
609
+ * `eventId` or `year` (ADR-132); a year matching several events is 409 EVENT_REQUIRED.
610
+ */
485
611
  adminList: (params, opts) => request(buildUrl(this.baseUrl, "/shelters/admin", params), this.auth, opts?.signal),
486
612
  list: (params, opts) => request(buildUrl(this.baseUrl, "/shelters", params), this.auth, opts?.signal),
487
- get: (id, opts) => request(buildUrl(this.baseUrl, `/shelters/${encodeURIComponent(id)}`), this.auth, opts?.signal),
488
- /** Request to join a shelter (member). PLA-1260. */
489
- join: (shelterId, opts) => post(buildUrl(this.baseUrl, `/shelters/${encodeURIComponent(shelterId)}/join`), this.auth, {}, opts?.signal),
490
- /** Invite a member to a shelter the acting member owns. PLA-1260. */
491
- invite: (shelterId, inviteeUserId, opts) => post(buildUrl(this.baseUrl, `/shelters/${encodeURIComponent(shelterId)}/invites`), this.auth, { inviteeUserId }, opts?.signal),
613
+ /** Without a scope only annual shelters match; send `eventId` to read an event's shelter. */
614
+ get: (id, params, opts) => {
615
+ const { signal, ...scope } = params ?? {};
616
+ return request(buildUrl(this.baseUrl, `/shelters/${encodeURIComponent(id)}`, scope), this.auth, opts?.signal ?? signal);
617
+ },
618
+ /** Request to join a shelter (member). PLA-1260. A scope must match the shelter's event. */
619
+ join: (shelterId, params, opts) => {
620
+ const { signal, ...scope } = params ?? {};
621
+ return post(buildUrl(this.baseUrl, `/shelters/${encodeURIComponent(shelterId)}/join`, scope), this.auth, {}, opts?.signal ?? signal);
622
+ },
623
+ /** Invite a member to a shelter the acting member owns. PLA-1260. A scope must match the shelter's event. */
624
+ invite: (shelterId, inviteeUserId, params, opts) => {
625
+ const { signal, ...scope } = params ?? {};
626
+ return post(buildUrl(this.baseUrl, `/shelters/${encodeURIComponent(shelterId)}/invites`), this.auth, {
627
+ inviteeUserId,
628
+ ...scope
629
+ }, opts?.signal ?? signal);
630
+ },
492
631
  /** Leave a shelter (deletes the acting member's own assignment). PLA-1260. */
493
- leave: (assignmentId, opts) => sendV1("DELETE", buildUrl(this.baseUrl, `/shelter-assignments/${encodeURIComponent(assignmentId)}`), this.auth, void 0, opts?.signal),
632
+ leave: (assignmentId, params, opts) => {
633
+ const { signal, ...scope } = params ?? {};
634
+ return sendV1("DELETE", buildUrl(this.baseUrl, `/shelter-assignments/${encodeURIComponent(assignmentId)}`, scope), this.auth, void 0, opts?.signal ?? signal);
635
+ },
494
636
  /** Accept or decline a shelter invitation. PLA-1260. */
495
- respond: (assignmentId, accept, opts) => sendV1("PUT", buildUrl(this.baseUrl, `/shelter-assignments/${encodeURIComponent(assignmentId)}/response`), this.auth, { accept }, opts?.signal)
637
+ respond: (assignmentId, accept, params, opts) => {
638
+ const { signal, ...scope } = params ?? {};
639
+ return sendV1("PUT", buildUrl(this.baseUrl, `/shelter-assignments/${encodeURIComponent(assignmentId)}/response`), this.auth, {
640
+ accept,
641
+ ...scope
642
+ }, opts?.signal ?? signal);
643
+ }
496
644
  };
497
645
  bikes = {
498
646
  adminInterest: (params, opts) => request(buildUrl(this.baseUrl, "/admin/bikes/interest", params), this.auth, opts?.signal),
@@ -610,40 +758,74 @@ var PlayaOSClient = class PlayaOSClient {
610
758
  * Admin/super_admin only; there is no member-facing SAP surface. Year is
611
759
  * the selected year when supplied, otherwise the org's active camp year.
612
760
  */
761
+ /** SAP reads and writes take an ADR-132 scope; without one, the configured active camp year. */
613
762
  sap = {
763
+ /** With an event scope, the event's participants instead of the year's roster. */
614
764
  roster: (params, opts) => request(buildUrl(this.baseUrl, "/sap/roster", params), this.auth, opts?.signal),
615
765
  allocation: {
616
- get: (opts) => request(buildUrl(this.baseUrl, "/sap/allocation", { year: opts?.year }), this.auth, opts?.signal),
766
+ get: (params, opts) => {
767
+ const { signal, ...scope } = params ?? {};
768
+ return request(buildUrl(this.baseUrl, "/sap/allocation", scope), this.auth, opts?.signal ?? signal);
769
+ },
617
770
  update: (payload, opts) => sendV1("PUT", buildUrl(this.baseUrl, "/sap/allocation"), this.auth, payload, opts?.signal)
618
771
  },
619
772
  dayAllocations: {
620
773
  update: (id, payload, opts) => sendV1("PATCH", buildUrl(this.baseUrl, `/sap/day-allocations/${encodeURIComponent(id)}`), this.auth, payload, opts?.signal),
621
- remove: (id, opts) => sendV1("DELETE", buildUrl(this.baseUrl, `/sap/day-allocations/${encodeURIComponent(id)}`), this.auth, {}, opts?.signal),
622
- list: (opts) => request(buildUrl(this.baseUrl, "/sap/day-allocations", { year: opts?.year }), this.auth, opts?.signal),
623
- /** Upserts by (active year, accessDate); 409 on a cross-org date collision. */
774
+ /** A scope, when sent, must match the row's own event or year. */
775
+ remove: (id, params, opts) => {
776
+ const { signal, ...scope } = params ?? {};
777
+ return sendV1("DELETE", buildUrl(this.baseUrl, `/sap/day-allocations/${encodeURIComponent(id)}`, scope), this.auth, {}, opts?.signal ?? signal);
778
+ },
779
+ list: (params, opts) => {
780
+ const { signal, ...scope } = params ?? {};
781
+ return request(buildUrl(this.baseUrl, "/sap/day-allocations", scope), this.auth, opts?.signal ?? signal);
782
+ },
783
+ /** Upserts by (scope, accessDate); 409 on a date collision or an ambiguous year. */
624
784
  upsert: (payload, opts) => sendV1("PUT", buildUrl(this.baseUrl, "/sap/day-allocations"), this.auth, payload, opts?.signal)
625
785
  },
626
786
  assignments: {
627
- list: (opts) => request(buildUrl(this.baseUrl, "/sap/assignments", { year: opts?.year }), this.auth, opts?.signal),
787
+ list: (params, opts) => {
788
+ const { signal, ...scope } = params ?? {};
789
+ return request(buildUrl(this.baseUrl, "/sap/assignments", scope), this.auth, opts?.signal ?? signal);
790
+ },
628
791
  create: (payload, opts) => post(buildUrl(this.baseUrl, "/sap/assignments"), this.auth, payload, opts?.signal),
629
792
  update: (payload, opts) => sendV1("PATCH", buildUrl(this.baseUrl, "/sap/assignments"), this.auth, payload, opts?.signal),
630
- remove: (assignmentId, opts) => sendV1("DELETE", buildUrl(this.baseUrl, "/sap/assignments"), this.auth, { assignmentId }, opts?.signal)
793
+ remove: (assignmentId, params, opts) => {
794
+ const { signal, ...scope } = params ?? {};
795
+ return sendV1("DELETE", buildUrl(this.baseUrl, "/sap/assignments"), this.auth, {
796
+ assignmentId,
797
+ ...scope
798
+ }, opts?.signal ?? signal);
799
+ }
631
800
  }
632
801
  };
633
802
  importantDates = {
634
- adminList: (opts) => request(buildUrl(this.baseUrl, "/admin/important-dates"), this.auth, opts?.signal),
803
+ /** Scope with `eventId` or `year` (ADR-132); with neither, the active camp year (409 when none). */
804
+ adminList: (params, opts) => {
805
+ const { signal, ...scope } = params ?? {};
806
+ return request(buildUrl(this.baseUrl, "/admin/important-dates", scope), this.auth, opts?.signal ?? signal);
807
+ },
635
808
  adminOperation: (payload, opts) => post(buildUrl(this.baseUrl, "/admin/important-dates"), this.auth, payload, opts?.signal),
636
- /** Visible camp dates (PLA-1268), optionally pinned to a year. */
809
+ /** Visible camp dates (PLA-1268), optionally pinned to an event or year (ADR-132). */
637
810
  list: (params, opts) => request(buildUrl(this.baseUrl, "/important-dates", params), this.auth, opts?.signal)
638
811
  };
639
812
  events = {
640
813
  /** The camp's events with the given status (default `published`), earliest first. */
641
814
  list: (params, opts) => request(buildUrl(this.baseUrl, "/events", params), this.auth, opts?.signal) };
642
815
  emails = {
816
+ /** Payment, attendance and build-week filters follow `eventId` or `year` (ADR-132). */
643
817
  recipients: (payload, opts) => post(buildUrl(this.baseUrl, "/email/recipients"), this.auth, payload, opts?.signal),
818
+ /** Year-dependent segment counts follow `eventId` or `year`; null when unscoped with no camp year. */
644
819
  composerOptions: (params, opts) => request(buildUrl(this.baseUrl, "/email/composer-options", params), this.auth, opts?.signal),
645
820
  broadcast: (payload, opts) => post(buildUrl(this.baseUrl, "/email/broadcasts"), this.auth, payload, opts?.signal),
646
- history: (opts) => request(buildUrl(this.baseUrl, "/email/history"), this.auth, opts?.signal),
821
+ /**
822
+ * Broadcast history scoped with `eventId` or `year` (ADR-132); with neither, the configured
823
+ * active camp year. An event lists its own broadcasts plus the year's camp-wide ones.
824
+ */
825
+ history: (params, opts) => {
826
+ const { signal, ...scope } = params ?? {};
827
+ return request(buildUrl(this.baseUrl, "/email/history", scope), this.auth, opts?.signal ?? signal);
828
+ },
647
829
  deliveryPage: (params, opts) => request(buildUrl(this.baseUrl, "/email/delivery", params), this.auth, opts?.signal),
648
830
  /**
649
831
  * Make one failed retry row due now; the retry executor sends it (nothing is sent by this call).
@@ -718,9 +900,10 @@ list: (params, opts) => request(buildUrl(this.baseUrl, "/events", params), this.
718
900
  return request(buildUrl(this.baseUrl, "/admin/applications", params), this.auth, opts?.signal);
719
901
  },
720
902
  /**
721
- * Application capacity for a camp year (PLA-1328): the approved count
722
- * against the camp cap, defaulting to the org's active camp year. v1-only
723
- * — requires a member token (`withMember`).
903
+ * Application capacity (PLA-1328): the approved count against the camp
904
+ * cap for one event, or a year with no event (ADR-132), defaulting to the
905
+ * org's configured active camp year. v1-only — requires a member token
906
+ * (`withMember`).
724
907
  */
725
908
  capacity: (params, opts) => {
726
909
  if (!this.memberToken) throw new Error("applications.capacity requires withMember(token)");
@@ -976,6 +1159,6 @@ function createPublicMarketplaceClient(opts) {
976
1159
  };
977
1160
  }
978
1161
  //#endregion
979
- export { ApiClientError, MAX_IMAGE_POSITION, PlayaOSClient, createClient, createPublicMarketplaceClient, exchangeCode };
1162
+ export { ApiClientError, ApiErrorCode, MAX_IMAGE_POSITION, PlayaOSClient, createClient, createPublicMarketplaceClient, exchangeCode, isEventReadOnlyError };
980
1163
 
981
1164
  //# sourceMappingURL=index.js.map