@proveanything/smartlinks 2.0.69 → 2.0.71

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.
@@ -101,6 +101,11 @@ export declare namespace asset {
101
101
  * Restore a soft-deleted asset (clears `deletedAt`).
102
102
  */
103
103
  function restoreAdmin(collectionId: string, assetId: string): Promise<Asset>;
104
+ /**
105
+ * Give an existing asset its own address (`assetUrl`). New and replaced assets get one automatically;
106
+ * this is for assets made before asset addresses existed. Safe to call again. → the asset, with `assetUrl`.
107
+ */
108
+ function ensureAssetUrl(collectionId: string, assetId: string): Promise<Asset>;
104
109
  /**
105
110
  * Soft-delete multiple assets in one request.
106
111
  */
package/dist/api/asset.js CHANGED
@@ -424,6 +424,15 @@ export var asset;
424
424
  return post(path, {});
425
425
  }
426
426
  asset.restoreAdmin = restoreAdmin;
427
+ /**
428
+ * Give an existing asset its own address (`assetUrl`). New and replaced assets get one automatically;
429
+ * this is for assets made before asset addresses existed. Safe to call again. → the asset, with `assetUrl`.
430
+ */
431
+ async function ensureAssetUrl(collectionId, assetId) {
432
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/asset/${encodeURIComponent(assetId)}/asset-url`;
433
+ return post(path, {});
434
+ }
435
+ asset.ensureAssetUrl = ensureAssetUrl;
427
436
  /**
428
437
  * Soft-delete multiple assets in one request.
429
438
  */
@@ -673,6 +682,8 @@ export var asset;
673
682
  startBody.productId = scope.productId;
674
683
  if (scope.type === 'proof')
675
684
  startBody.proofId = scope.proofId;
685
+ if (options.replaceAssetId)
686
+ startBody.replaceAssetId = options.replaceAssetId;
676
687
  const started = await post(base, startBody, token ? { 'X-Upload-Token': token } : undefined);
677
688
  const finalizePath = `${base}/${encodeURIComponent(started.uploadId)}/complete`;
678
689
  const finalizeBody = {};
@@ -1,4 +1,4 @@
1
- import type { AuthLoginResponse, AppleLoginOptions, RefreshResponse, LogoutResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, AuthKitConfig, AuthKitConfigInput, AuthKitSetIdentityResponse, MagicLinkSendResponse, MagicLinkVerifyResponse, UserProfile, UpdateProfileResponse, ProfileUpdateData, SuccessResponse, SendWhatsAppRequest, SendWhatsAppResponse, ExchangeWhatsAppSessionResponse, VerifyWhatsAppResponse, WhatsAppStatusResponse, SendSmsVerifyRequest, SendSmsVerifyResponse, VerifySmsResponse, UpsertContactRequest, UpsertContactResponse, MfaChallengeSendResponse, MfaFinalizeResponse, MfaEnrollSendResponse, MfaEnrolledResponse, MfaFactorsResponse, TrustedDevice } from "../types/authKit.js";
1
+ import type { AuthLoginResponse, AppleLoginOptions, RefreshResponse, LogoutResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, AuthKitConfig, AuthKitConfigInput, AuthKitSetIdentityResponse, AuthKitInviteRequest, AuthKitInviteResponse, MagicLinkSendResponse, MagicLinkVerifyResponse, UserProfile, UpdateProfileResponse, ProfileUpdateData, SuccessResponse, SendWhatsAppRequest, SendWhatsAppResponse, ExchangeWhatsAppSessionResponse, VerifyWhatsAppResponse, WhatsAppStatusResponse, SendSmsVerifyRequest, SendSmsVerifyResponse, VerifySmsResponse, UpsertContactRequest, UpsertContactResponse, MfaChallengeSendResponse, MfaFinalizeResponse, MfaEnrollSendResponse, MfaTotpEnrollResponse, MfaEnrolledResponse, MfaFactor, MfaFactorsResponse, TrustedDevice } from "../types/authKit.js";
2
2
  /**
3
3
  * Namespace containing helper functions for the new AuthKit API.
4
4
  * Legacy collection-based authKit helpers retained (marked as *Legacy*).
@@ -208,8 +208,11 @@ export declare namespace authKit {
208
208
  function verifyEmailChange(clientId: string, token: string): Promise<SuccessResponse>;
209
209
  function updatePhone(clientId: string, phoneNumber: string, verificationCode: string): Promise<SuccessResponse>;
210
210
  function deleteAccount(clientId: string, password: string, confirmText: string): Promise<SuccessResponse>;
211
- /** Send (or resend) an MFA challenge code to the given factor (public). */
212
- function mfaChallengeSend(clientId: string, mfaSessionToken: string, factor: 'email' | 'sms'): Promise<MfaChallengeSendResponse>;
211
+ /**
212
+ * Send (or resend) an MFA challenge code to the given factor (public). For `totp` nothing is sent —
213
+ * it tells the server the code will come from their authenticator app; then {@link mfaChallengeVerify}.
214
+ */
215
+ function mfaChallengeSend(clientId: string, mfaSessionToken: string, factor: MfaFactor): Promise<MfaChallengeSendResponse>;
213
216
  /**
214
217
  * Verify an MFA challenge code and finalize the login (public). On success this behaves
215
218
  * like {@link login} — the bearer token is adopted and the cache invalidated.
@@ -233,6 +236,15 @@ export declare namespace authKit {
233
236
  function enrollSmsMfa(clientId: string, phoneNumber: string): Promise<MfaEnrollSendResponse>;
234
237
  /** Confirm SMS-factor enrollment with the code sent by {@link enrollSmsMfa} (authenticated). */
235
238
  function confirmSmsMfa(clientId: string, mfaSessionToken: string, code: string): Promise<MfaEnrolledResponse>;
239
+ /**
240
+ * Begin authenticator-app enrollment (authenticated): a new secret for Google Authenticator,
241
+ * Microsoft Authenticator, 1Password and the like. Show `otpauthUri` as a QR code (and `secret` for
242
+ * typing in), then {@link confirmTotpMfa} with the code the app shows. Nothing is kept until then;
243
+ * setting up again replaces the previous app once confirmed.
244
+ */
245
+ function enrollTotpMfa(clientId: string): Promise<MfaTotpEnrollResponse>;
246
+ /** Confirm authenticator-app enrollment with the 6-digit code the app shows (authenticated). */
247
+ function confirmTotpMfa(clientId: string, mfaSessionToken: string, code: string): Promise<MfaEnrolledResponse>;
236
248
  /**
237
249
  * Generate a fresh set of recovery codes, invalidating any previous set (authenticated).
238
250
  * Returned **in plaintext, exactly once** — nothing else in the API ever returns them
@@ -242,7 +254,7 @@ export declare namespace authKit {
242
254
  recoveryCodes: string[];
243
255
  }>;
244
256
  /** Remove an enrolled MFA factor (authenticated). Server route is DELETE with a body. */
245
- function removeMfaFactor(clientId: string, factor: 'email' | 'sms', password: string): Promise<SuccessResponse>;
257
+ function removeMfaFactor(clientId: string, factor: MfaFactor, password: string): Promise<SuccessResponse>;
246
258
  /** List devices trusted to skip MFA challenges for the current user (authenticated). */
247
259
  function listTrustedDevices(clientId: string): Promise<{
248
260
  devices: TrustedDevice[];
@@ -281,5 +293,17 @@ export declare namespace authKit {
281
293
  function setIdentity(collectionId: string, authKitId: string, body: {
282
294
  mode: 'own';
283
295
  }): Promise<AuthKitSetIdentityResponse>;
296
+ /**
297
+ * Invite someone to be a member of a site with its own logins (admin). Makes their account if they have
298
+ * none (the only way in when the site is invitation only — `signUp: 'invite'`), finds or creates their
299
+ * contact in this collection with the `customFields` you pass (their level), links the two, and emails
300
+ * them a sign-in link to the site (`redirectUrl`, default the kit's) that works once for 7 days. The page
301
+ * it opens handles it like any magic link: `mode=magicLink&token=…` → {@link verifyMagicLink}.
302
+ * Inviting someone again sends a fresh link.
303
+ *
304
+ * Errors: `OWN_LOGINS_REQUIRED` (409), `INVALID_EMAIL` (400), `INVALID_REDIRECT_URL` (400, not one of
305
+ * this site's addresses), `TOO_MANY_INVITES` (429, 5 an hour per address).
306
+ */
307
+ function invite(collectionId: string, authKitId: string, body: AuthKitInviteRequest): Promise<AuthKitInviteResponse>;
284
308
  function remove(collectionId: string, authKitId: string): Promise<void>;
285
309
  }
@@ -380,7 +380,10 @@ export var authKit;
380
380
  * challenge/send can be called again on the same token (while unexpired/unburned) to
381
381
  * switch factors or resend.
382
382
  * =================================== */
383
- /** Send (or resend) an MFA challenge code to the given factor (public). */
383
+ /**
384
+ * Send (or resend) an MFA challenge code to the given factor (public). For `totp` nothing is sent —
385
+ * it tells the server the code will come from their authenticator app; then {@link mfaChallengeVerify}.
386
+ */
384
387
  async function mfaChallengeSend(clientId, mfaSessionToken, factor) {
385
388
  return post(`/authkit/${encodeURIComponent(clientId)}/mfa/challenge/send`, { mfaSessionToken, factor });
386
389
  }
@@ -442,6 +445,21 @@ export var authKit;
442
445
  return post(`/authkit/${encodeURIComponent(clientId)}/mfa/factors/sms/confirm`, { mfaSessionToken, code });
443
446
  }
444
447
  authKit.confirmSmsMfa = confirmSmsMfa;
448
+ /**
449
+ * Begin authenticator-app enrollment (authenticated): a new secret for Google Authenticator,
450
+ * Microsoft Authenticator, 1Password and the like. Show `otpauthUri` as a QR code (and `secret` for
451
+ * typing in), then {@link confirmTotpMfa} with the code the app shows. Nothing is kept until then;
452
+ * setting up again replaces the previous app once confirmed.
453
+ */
454
+ async function enrollTotpMfa(clientId) {
455
+ return post(`/authkit/${encodeURIComponent(clientId)}/mfa/factors/totp/enroll`, {});
456
+ }
457
+ authKit.enrollTotpMfa = enrollTotpMfa;
458
+ /** Confirm authenticator-app enrollment with the 6-digit code the app shows (authenticated). */
459
+ async function confirmTotpMfa(clientId, mfaSessionToken, code) {
460
+ return post(`/authkit/${encodeURIComponent(clientId)}/mfa/factors/totp/confirm`, { mfaSessionToken, code });
461
+ }
462
+ authKit.confirmTotpMfa = confirmTotpMfa;
445
463
  /**
446
464
  * Generate a fresh set of recovery codes, invalidating any previous set (authenticated).
447
465
  * Returned **in plaintext, exactly once** — nothing else in the API ever returns them
@@ -525,6 +543,22 @@ export var authKit;
525
543
  return post(path, body);
526
544
  }
527
545
  authKit.setIdentity = setIdentity;
546
+ /**
547
+ * Invite someone to be a member of a site with its own logins (admin). Makes their account if they have
548
+ * none (the only way in when the site is invitation only — `signUp: 'invite'`), finds or creates their
549
+ * contact in this collection with the `customFields` you pass (their level), links the two, and emails
550
+ * them a sign-in link to the site (`redirectUrl`, default the kit's) that works once for 7 days. The page
551
+ * it opens handles it like any magic link: `mode=magicLink&token=…` → {@link verifyMagicLink}.
552
+ * Inviting someone again sends a fresh link.
553
+ *
554
+ * Errors: `OWN_LOGINS_REQUIRED` (409), `INVALID_EMAIL` (400), `INVALID_REDIRECT_URL` (400, not one of
555
+ * this site's addresses), `TOO_MANY_INVITES` (429, 5 an hour per address).
556
+ */
557
+ async function invite(collectionId, authKitId, body) {
558
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/authKit/${encodeURIComponent(authKitId)}/invite`;
559
+ return post(path, body);
560
+ }
561
+ authKit.invite = invite;
528
562
  async function remove(collectionId, authKitId) {
529
563
  const path = `/admin/collection/${encodeURIComponent(collectionId)}/authKit/${encodeURIComponent(authKitId)}`;
530
564
  return del(path);
@@ -0,0 +1,89 @@
1
+ import type { Booking, BookingSlot, BookingAllocation, CreateBookingInput, UpdateBookingInput, MoveBookingInput, BookingListQueryParams, CreateSlotInput, UpdateSlotInput, SlotListQueryParams, CreateBlockInput, BlockListQueryParams, FreeBusyQuery, FreeBusyResponse, BookingAccessOptions } from '../types/bookings.js';
2
+ import type { PaginatedResponse } from '../types/appObjects.js';
3
+ export declare namespace bookings {
4
+ /**
5
+ * Book. All claims succeed together or nothing is written; a clash fails with 409
6
+ * (`SLOT_FULL`, `RESOURCE_TAKEN`, `PER_CONTACT_LIMIT`, …). Pass `idempotencyKey` so a retry never
7
+ * books twice.
8
+ *
9
+ * Public (admin = false): the app's `publicCreate.bookings` rules decide the status and limits; an
10
+ * anonymous guest may get `editToken` back (once) to manage the booking later.
11
+ *
12
+ * POST /bookings
13
+ */
14
+ function create(collectionId: string, appId: string, input: CreateBookingInput, admin?: boolean): Promise<Booking>;
15
+ /** List bookings (admin). GET /bookings */
16
+ function list(collectionId: string, appId: string, params?: BookingListQueryParams, admin?: boolean): Promise<PaginatedResponse<Booking>>;
17
+ /** The signed-in caller's own bookings (public). GET /bookings/mine */
18
+ function mine(collectionId: string, appId: string, params?: BookingListQueryParams): Promise<PaginatedResponse<Booking>>;
19
+ /**
20
+ * Get one booking. Public: the signed-in booker, or a guest passing `{ editToken }`.
21
+ * GET /bookings/:bookingId
22
+ */
23
+ function get(collectionId: string, appId: string, bookingId: string, admin?: boolean, opts?: BookingAccessOptions): Promise<Booking>;
24
+ /** Update zones and descriptive fields (admin). PATCH /bookings/:bookingId */
25
+ function update(collectionId: string, appId: string, bookingId: string, input: UpdateBookingInput, admin?: boolean): Promise<Booking>;
26
+ /**
27
+ * held / pending / waitlisted → confirmed (idempotent). A held booking whose hold has run out fails
28
+ * with HOLD_EXPIRED. Public: only the booker's own hold, when `ownerActions.bookings.confirm` allows.
29
+ * POST /bookings/:bookingId/confirm
30
+ */
31
+ function confirm(collectionId: string, appId: string, bookingId: string, admin?: boolean, opts?: BookingAccessOptions): Promise<Booking>;
32
+ /**
33
+ * Cancel and give the places back (idempotent). Public: per `ownerActions.bookings.cancel` and its
34
+ * cutoff. `reason` is admin-only (public cancels record 'owner').
35
+ * POST /bookings/:bookingId/cancel
36
+ */
37
+ function cancel(collectionId: string, appId: string, bookingId: string, admin?: boolean, opts?: BookingAccessOptions & {
38
+ reason?: string;
39
+ }): Promise<Booking>;
40
+ /**
41
+ * Move to a new slot / time, all-or-nothing (a failed move leaves the booking as it was).
42
+ * Public: per `ownerActions.bookings.move`; the create rules are re-checked for the new time.
43
+ * POST /bookings/:bookingId/move
44
+ */
45
+ function move(collectionId: string, appId: string, bookingId: string, input: MoveBookingInput, admin?: boolean, opts?: BookingAccessOptions): Promise<Booking>;
46
+ /** Extend a hold by `holdMinutes` from now (admin; capped at 24h after the booking was made). */
47
+ function extendHold(collectionId: string, appId: string, bookingId: string, holdMinutes: number): Promise<Booking>;
48
+ /** confirmed → completed (admin). */
49
+ function complete(collectionId: string, appId: string, bookingId: string): Promise<Booking>;
50
+ /** confirmed → no_show (admin). */
51
+ function noShow(collectionId: string, appId: string, bookingId: string): Promise<Booking>;
52
+ /**
53
+ * Busy intervals per resource (bookings, blocks, slots' own blocks) — never booking details.
54
+ * Public only when the app sets `publicRead.bookings.freebusy: true`.
55
+ * GET /bookings/freebusy
56
+ */
57
+ function freebusy(collectionId: string, appId: string, q: FreeBusyQuery, admin?: boolean): Promise<FreeBusyResponse>;
58
+ namespace slots {
59
+ /** Create a slot (admin). POST /bookings/slots */
60
+ function create(collectionId: string, appId: string, input: CreateSlotInput): Promise<BookingSlot>;
61
+ /** Create many slots at once — a series — all-or-nothing (admin, max 500). POST /bookings/slots/batch */
62
+ function createMany(collectionId: string, appId: string, slots: CreateSlotInput[], opts?: {
63
+ seriesId?: string;
64
+ }): Promise<{
65
+ data: BookingSlot[];
66
+ }>;
67
+ /** List slots. Public: open, public slots only, each with `remaining`. GET /bookings/slots */
68
+ function list(collectionId: string, appId: string, params?: SlotListQueryParams, admin?: boolean): Promise<PaginatedResponse<BookingSlot>>;
69
+ /** GET /bookings/slots/:slotId */
70
+ function get(collectionId: string, appId: string, slotId: string, admin?: boolean): Promise<BookingSlot>;
71
+ /**
72
+ * Update a slot (admin). Capacity can't drop below what's booked (SLOT_OVERBOOKED); times can't
73
+ * change once anything is booked (SLOT_HAS_BOOKINGS).
74
+ */
75
+ function update(collectionId: string, appId: string, slotId: string, input: UpdateSlotInput): Promise<BookingSlot>;
76
+ /** Delete a slot (admin; refused while places are booked). */
77
+ function remove(collectionId: string, appId: string, slotId: string): Promise<{
78
+ success: boolean;
79
+ }>;
80
+ }
81
+ /** Blocked time on a resource with no booking — time off, a closure, maintenance (admin). */
82
+ namespace blocks {
83
+ function create(collectionId: string, appId: string, input: CreateBlockInput): Promise<BookingAllocation>;
84
+ function list(collectionId: string, appId: string, params?: BlockListQueryParams): Promise<PaginatedResponse<BookingAllocation>>;
85
+ function remove(collectionId: string, appId: string, blockId: string): Promise<{
86
+ success: boolean;
87
+ }>;
88
+ }
89
+ }
@@ -0,0 +1,179 @@
1
+ // src/api/bookings.ts
2
+ // Generic booking objects — see docs/bookings.md.
3
+ //
4
+ // Every function takes `admin` last (default false), like app.cases / app.records:
5
+ // admin = true → /admin/... — unconditional (Studio users, your app's own server functions)
6
+ // admin = false → /public/... — governed by the app's config: publicCreate.bookings (who may book,
7
+ // as what status, limits, time rules), ownerActions.bookings (cancel / move /
8
+ // confirm afterwards) and publicRead.bookings.freebusy.
9
+ import { request, post, patch, del, requestWithOptions } from '../http.js';
10
+ function basePath(collectionId, appId, admin) {
11
+ const zone = admin ? 'admin' : 'public';
12
+ return `/${zone}/collection/${encodeURIComponent(collectionId)}/app/${encodeURIComponent(appId)}/bookings`;
13
+ }
14
+ function query(params) {
15
+ if (!params)
16
+ return '';
17
+ const parts = [];
18
+ for (const [key, value] of Object.entries(params)) {
19
+ if (value === undefined || value === null)
20
+ continue;
21
+ const v = value instanceof Date ? value.toISOString() : Array.isArray(value) ? value.join(',') : String(value);
22
+ parts.push(`${encodeURIComponent(key)}=${encodeURIComponent(v)}`);
23
+ }
24
+ return parts.length ? `?${parts.join('&')}` : '';
25
+ }
26
+ function tokenHeaders(opts) {
27
+ return (opts === null || opts === void 0 ? void 0 : opts.editToken) ? { 'X-Edit-Token': opts.editToken } : undefined;
28
+ }
29
+ function refString(r) {
30
+ return typeof r === 'string' ? r : `${r.type}:${r.id}`;
31
+ }
32
+ export var bookings;
33
+ (function (bookings) {
34
+ /**
35
+ * Book. All claims succeed together or nothing is written; a clash fails with 409
36
+ * (`SLOT_FULL`, `RESOURCE_TAKEN`, `PER_CONTACT_LIMIT`, …). Pass `idempotencyKey` so a retry never
37
+ * books twice.
38
+ *
39
+ * Public (admin = false): the app's `publicCreate.bookings` rules decide the status and limits; an
40
+ * anonymous guest may get `editToken` back (once) to manage the booking later.
41
+ *
42
+ * POST /bookings
43
+ */
44
+ async function create(collectionId, appId, input, admin = false) {
45
+ return post(basePath(collectionId, appId, admin), input);
46
+ }
47
+ bookings.create = create;
48
+ /** List bookings (admin). GET /bookings */
49
+ async function list(collectionId, appId, params, admin = true) {
50
+ return request(`${basePath(collectionId, appId, admin)}${query(params)}`);
51
+ }
52
+ bookings.list = list;
53
+ /** The signed-in caller's own bookings (public). GET /bookings/mine */
54
+ async function mine(collectionId, appId, params) {
55
+ return request(`${basePath(collectionId, appId, false)}/mine${query(params)}`);
56
+ }
57
+ bookings.mine = mine;
58
+ /**
59
+ * Get one booking. Public: the signed-in booker, or a guest passing `{ editToken }`.
60
+ * GET /bookings/:bookingId
61
+ */
62
+ async function get(collectionId, appId, bookingId, admin = false, opts) {
63
+ const path = `${basePath(collectionId, appId, admin)}/${encodeURIComponent(bookingId)}`;
64
+ const headers = tokenHeaders(opts);
65
+ return headers ? requestWithOptions(path, { method: 'GET', headers }) : request(path);
66
+ }
67
+ bookings.get = get;
68
+ /** Update zones and descriptive fields (admin). PATCH /bookings/:bookingId */
69
+ async function update(collectionId, appId, bookingId, input, admin = true) {
70
+ return patch(`${basePath(collectionId, appId, admin)}/${encodeURIComponent(bookingId)}`, input);
71
+ }
72
+ bookings.update = update;
73
+ /**
74
+ * held / pending / waitlisted → confirmed (idempotent). A held booking whose hold has run out fails
75
+ * with HOLD_EXPIRED. Public: only the booker's own hold, when `ownerActions.bookings.confirm` allows.
76
+ * POST /bookings/:bookingId/confirm
77
+ */
78
+ async function confirm(collectionId, appId, bookingId, admin = false, opts) {
79
+ return post(`${basePath(collectionId, appId, admin)}/${encodeURIComponent(bookingId)}/confirm`, {}, tokenHeaders(opts));
80
+ }
81
+ bookings.confirm = confirm;
82
+ /**
83
+ * Cancel and give the places back (idempotent). Public: per `ownerActions.bookings.cancel` and its
84
+ * cutoff. `reason` is admin-only (public cancels record 'owner').
85
+ * POST /bookings/:bookingId/cancel
86
+ */
87
+ async function cancel(collectionId, appId, bookingId, admin = false, opts) {
88
+ return post(`${basePath(collectionId, appId, admin)}/${encodeURIComponent(bookingId)}/cancel`, (opts === null || opts === void 0 ? void 0 : opts.reason) ? { reason: opts.reason } : {}, tokenHeaders(opts));
89
+ }
90
+ bookings.cancel = cancel;
91
+ /**
92
+ * Move to a new slot / time, all-or-nothing (a failed move leaves the booking as it was).
93
+ * Public: per `ownerActions.bookings.move`; the create rules are re-checked for the new time.
94
+ * POST /bookings/:bookingId/move
95
+ */
96
+ async function move(collectionId, appId, bookingId, input, admin = false, opts) {
97
+ return post(`${basePath(collectionId, appId, admin)}/${encodeURIComponent(bookingId)}/move`, input, tokenHeaders(opts));
98
+ }
99
+ bookings.move = move;
100
+ /** Extend a hold by `holdMinutes` from now (admin; capped at 24h after the booking was made). */
101
+ async function extendHold(collectionId, appId, bookingId, holdMinutes) {
102
+ return post(`${basePath(collectionId, appId, true)}/${encodeURIComponent(bookingId)}/extend-hold`, { holdMinutes });
103
+ }
104
+ bookings.extendHold = extendHold;
105
+ /** confirmed → completed (admin). */
106
+ async function complete(collectionId, appId, bookingId) {
107
+ return post(`${basePath(collectionId, appId, true)}/${encodeURIComponent(bookingId)}/complete`, {});
108
+ }
109
+ bookings.complete = complete;
110
+ /** confirmed → no_show (admin). */
111
+ async function noShow(collectionId, appId, bookingId) {
112
+ return post(`${basePath(collectionId, appId, true)}/${encodeURIComponent(bookingId)}/no-show`, {});
113
+ }
114
+ bookings.noShow = noShow;
115
+ /**
116
+ * Busy intervals per resource (bookings, blocks, slots' own blocks) — never booking details.
117
+ * Public only when the app sets `publicRead.bookings.freebusy: true`.
118
+ * GET /bookings/freebusy
119
+ */
120
+ async function freebusy(collectionId, appId, q, admin = false) {
121
+ const params = { resources: q.resources.map(refString).join(','), from: q.from, to: q.to };
122
+ return request(`${basePath(collectionId, appId, admin)}/freebusy${query(params)}`);
123
+ }
124
+ bookings.freebusy = freebusy;
125
+ // ==================== SLOTS ====================
126
+ let slots;
127
+ (function (slots_1) {
128
+ /** Create a slot (admin). POST /bookings/slots */
129
+ async function create(collectionId, appId, input) {
130
+ return post(`${basePath(collectionId, appId, true)}/slots`, input);
131
+ }
132
+ slots_1.create = create;
133
+ /** Create many slots at once — a series — all-or-nothing (admin, max 500). POST /bookings/slots/batch */
134
+ async function createMany(collectionId, appId, slots, opts) {
135
+ return post(`${basePath(collectionId, appId, true)}/slots/batch`, { slots, seriesId: opts === null || opts === void 0 ? void 0 : opts.seriesId });
136
+ }
137
+ slots_1.createMany = createMany;
138
+ /** List slots. Public: open, public slots only, each with `remaining`. GET /bookings/slots */
139
+ async function list(collectionId, appId, params, admin = false) {
140
+ return request(`${basePath(collectionId, appId, admin)}/slots${query(params)}`);
141
+ }
142
+ slots_1.list = list;
143
+ /** GET /bookings/slots/:slotId */
144
+ async function get(collectionId, appId, slotId, admin = false) {
145
+ return request(`${basePath(collectionId, appId, admin)}/slots/${encodeURIComponent(slotId)}`);
146
+ }
147
+ slots_1.get = get;
148
+ /**
149
+ * Update a slot (admin). Capacity can't drop below what's booked (SLOT_OVERBOOKED); times can't
150
+ * change once anything is booked (SLOT_HAS_BOOKINGS).
151
+ */
152
+ async function update(collectionId, appId, slotId, input) {
153
+ return patch(`${basePath(collectionId, appId, true)}/slots/${encodeURIComponent(slotId)}`, input);
154
+ }
155
+ slots_1.update = update;
156
+ /** Delete a slot (admin; refused while places are booked). */
157
+ async function remove(collectionId, appId, slotId) {
158
+ return del(`${basePath(collectionId, appId, true)}/slots/${encodeURIComponent(slotId)}`);
159
+ }
160
+ slots_1.remove = remove;
161
+ })(slots = bookings.slots || (bookings.slots = {}));
162
+ // ==================== BLOCKS ====================
163
+ /** Blocked time on a resource with no booking — time off, a closure, maintenance (admin). */
164
+ let blocks;
165
+ (function (blocks) {
166
+ async function create(collectionId, appId, input) {
167
+ return post(`${basePath(collectionId, appId, true)}/blocks`, input);
168
+ }
169
+ blocks.create = create;
170
+ async function list(collectionId, appId, params) {
171
+ return request(`${basePath(collectionId, appId, true)}/blocks${query(params)}`);
172
+ }
173
+ blocks.list = list;
174
+ async function remove(collectionId, appId, blockId) {
175
+ return del(`${basePath(collectionId, appId, true)}/blocks/${encodeURIComponent(blockId)}`);
176
+ }
177
+ blocks.remove = remove;
178
+ })(blocks = bookings.blocks || (bookings.blocks = {}));
179
+ })(bookings || (bookings = {}));
@@ -34,6 +34,7 @@ export { adminCards } from "./adminCards.js";
34
34
  export { tags } from "./tags.js";
35
35
  export { order } from "./order.js";
36
36
  export { app } from "./appObjects.js";
37
+ export { bookings } from "./bookings.js";
37
38
  export { attestations } from "./attestations.js";
38
39
  export { containers } from "./containers.js";
39
40
  export { lots } from "./lots.js";
package/dist/api/index.js CHANGED
@@ -37,6 +37,7 @@ export { adminCards } from "./adminCards.js";
37
37
  export { tags } from "./tags.js";
38
38
  export { order } from "./order.js";
39
39
  export { app } from "./appObjects.js";
40
+ export { bookings } from "./bookings.js";
40
41
  export { attestations } from "./attestations.js";
41
42
  export { containers } from "./containers.js";
42
43
  export { lots } from "./lots.js";