@peektravel/app-utilities 0.9.4 → 1.0.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.d.cts CHANGED
@@ -1932,6 +1932,37 @@ declare class AvailabilityService {
1932
1932
  getAvailabilityTimes(query: AvailabilityTimesQuery): Promise<AvailabilityTime[]>;
1933
1933
  }
1934
1934
 
1935
+ /**
1936
+ * Reads custom questions defined on the account.
1937
+ *
1938
+ * Obtain an instance via {@link PeekAccessService.getCustomQuestionService}.
1939
+ */
1940
+ declare class CustomQuestionService {
1941
+ private readonly client;
1942
+ constructor(client: GraphQLClient);
1943
+ /**
1944
+ * Returns every custom question defined on the account, across all
1945
+ * activities. Choice-style questions (`SELECT_ONE`, `LOCATION`, …) carry their
1946
+ * selectable {@link CustomQuestion.options}; free-text/checkbox questions
1947
+ * return an empty option list.
1948
+ *
1949
+ * These are account-wide question **definitions**, not customer answers — no
1950
+ * PII is involved, so the result is unaffected by `fullCustomerAccess`. Unlike
1951
+ * {@link ProductService.getCustomQuestions}, the catalog carries no
1952
+ * per-activity configuration, so {@link CustomQuestion.order} is `0` and
1953
+ * {@link CustomQuestion.isRequired} is `false` on every entry.
1954
+ *
1955
+ * @returns Every custom question on the account, or an empty list when none
1956
+ * are defined.
1957
+ *
1958
+ * @example
1959
+ * ```ts
1960
+ * const questions = await peek.getCustomQuestionService().getAll();
1961
+ * ```
1962
+ */
1963
+ getAll(): Promise<CustomQuestion[]>;
1964
+ }
1965
+
1935
1966
  /**
1936
1967
  * The clean data model for a Peek Pro daily (dashboard) note.
1937
1968
  */
@@ -1980,6 +2011,15 @@ interface BaseAccessServiceConfig {
1980
2011
  * way to target an install — prefer it over `baseUrl`/`appId`, which are
1981
2012
  * deprecated (the hardcoded base-URL fallbacks will be removed and a URL will
1982
2013
  * become required in a future release).
2014
+ *
2015
+ * For Peek `mode: "v2"` this field is **required** (the constructor throws
2016
+ * without it). If you do not yet have a webhook `apiUrl` — e.g. an install that
2017
+ * predates webhook `apiUrl` delivery, which you don't want to uninstall /
2018
+ * reinstall just to obtain one — build one by appending your **app slug** to
2019
+ * the registry prefix and pass that here:
2020
+ * `https://apps.peek.com/installations-api/<app-slug>` (the trailing app-slug
2021
+ * segment is required — the prefix alone is not a valid URL). Treat that as a
2022
+ * transitional bridge and prefer the `apiUrl` the install webhook delivers.
1983
2023
  */
1984
2024
  apiUrl?: string;
1985
2025
  /**
@@ -2378,15 +2418,35 @@ interface InstallWebhookClaims {
2378
2418
  * Peek-specific extras below.
2379
2419
  */
2380
2420
  interface PeekAccessServiceConfig extends BaseAccessServiceConfig {
2381
- /** API gateway key, sent as the `pk-api-key` header. Required in v1 mode; not used in v2. */
2382
- gatewayKey?: string;
2383
2421
  /**
2384
- * Gateway mode. `"v2"` routes through the app-registry installations API
2385
- * (`baseUrl/appId/peek_backoffice_api-v1/endpointName`) and defaults to the
2386
- * app-registry sandbox base URL. `"v1"` (default) uses the standard backoffice
2387
- * GraphQL gateway.
2422
+ * API gateway key, sent as the `pk-api-key` header. Required in `"v1"` mode
2423
+ * (unless an `apiUrl` is supplied); not used in `"v2"`.
2388
2424
  */
2389
- mode?: "v2";
2425
+ gatewayKey?: string;
2426
+ /**
2427
+ * Which connection generation to use. **Required — choose explicitly.**
2428
+ *
2429
+ * This field used to be optional, and omitting it meant `"v1"`. It is now
2430
+ * mandatory so that updating the package forces a deliberate choice instead of
2431
+ * silently keeping the old behaviour. If your install used the previous
2432
+ * default, the fastest no-behaviour-change update is to pass `mode: "v1"`.
2433
+ *
2434
+ * - `"v2"` — **use this going forward.** Routes through the app-registry
2435
+ * installations API. It **requires** the install's **`apiUrl`**: the
2436
+ * per-install base URL delivered on the install webhook (`api.url`), which you
2437
+ * persist and pass as `apiUrl`. The constructor throws if it is missing —
2438
+ * there is no silent default. If you do not have a webhook `apiUrl` yet, build
2439
+ * one by appending your **app slug** to the registry prefix and pass that
2440
+ * yourself — `https://apps.peek.com/installations-api/<app-slug>` (same shape
2441
+ * as the webhook's `api.url`; the trailing app-slug segment is required, the
2442
+ * prefix alone is not a valid URL). Treat it as a transitional bridge and
2443
+ * prefer the webhook URL. No `gatewayKey` is needed (the registry
2444
+ * authenticates on the JWT alone).
2445
+ * - `"v1"` — **deprecated; will be removed.** The legacy backoffice GraphQL
2446
+ * gateway; requires `gatewayKey`. Retained only so existing installs can
2447
+ * update with no immediate behaviour change. Migrate to `"v2"`.
2448
+ */
2449
+ mode: "v1" | "v2";
2390
2450
  /** Page size for cursor-paginated item options. Default: 50. */
2391
2451
  itemOptionsPageSize?: number;
2392
2452
  }
@@ -2402,20 +2462,28 @@ interface PeekAccessServiceConfig extends BaseAccessServiceConfig {
2402
2462
  * ```ts
2403
2463
  * import { PeekAccessService, type Product } from "@peektravel/app-utilities";
2404
2464
  *
2465
+ * // "v2" (recommended) — registry connection, targeted by the install
2466
+ * // webhook's apiUrl; no gatewayKey needed:
2405
2467
  * const peek = new PeekAccessService({
2406
2468
  * installId: "install-123", // JWT subject
2407
2469
  * jwtSecret: process.env.PEEK_INTERNAL_SECRET!, // signs the JWT
2408
2470
  * issuer: process.env.APP_NAME!, // JWT issuer
2409
- * appId: process.env.PEEK_APP_ID!, // gateway path segment
2410
- * gatewayKey: process.env.PEEK_GATEWAY_KEY!, // pk-api-key header
2471
+ * mode: "v2", // connection generation (required)
2472
+ * apiUrl: install.apiUrl, // persisted from the install webhook
2411
2473
  * });
2412
2474
  *
2475
+ * // "v1" (deprecated) — legacy gateway; the fastest update for installs that
2476
+ * // relied on the old default:
2477
+ * // new PeekAccessService({ installId, jwtSecret, issuer, appId, gatewayKey, mode: "v1" })
2478
+ *
2413
2479
  * const products: Product[] = await peek.getProductService().getAllProducts();
2414
2480
  * const booking = await peek.getBookingService().getById("b_abc123");
2415
2481
  * ```
2416
2482
  *
2417
- * @throws {Error} from the constructor when any required config field
2418
- * (`installId`, `jwtSecret`, `issuer`, `appId`, `gatewayKey`) is empty.
2483
+ * @throws {Error} from the constructor when `mode` is missing or not `"v1"`/
2484
+ * `"v2"`; when `"v2"` is selected without an `apiUrl`; or when any required
2485
+ * config field is empty (`installId`, `jwtSecret`, `issuer`, and — in `"v1"`
2486
+ * mode without an `apiUrl` — `appId` and `gatewayKey`).
2419
2487
  */
2420
2488
  declare class PeekAccessService {
2421
2489
  private readonly client;
@@ -2435,6 +2503,7 @@ declare class PeekAccessService {
2435
2503
  private membershipService?;
2436
2504
  private readonly bookingServices;
2437
2505
  private reviewService?;
2506
+ private customQuestionService?;
2438
2507
  constructor(config: PeekAccessServiceConfig);
2439
2508
  /**
2440
2509
  * Verifies a Peek auth token issued by the app registry and returns the
@@ -2527,6 +2596,11 @@ declare class PeekAccessService {
2527
2596
  * authenticated transport. The instance is created lazily and reused.
2528
2597
  */
2529
2598
  getReviewService(): ReviewService;
2599
+ /**
2600
+ * Returns the {@link CustomQuestionService} for this install, bound to the
2601
+ * shared authenticated transport. The instance is created lazily and reused.
2602
+ */
2603
+ getCustomQuestionService(): CustomQuestionService;
2530
2604
  /** All products (activities + add-ons). @deprecated The access service exposes only its resource-service accessors; call the service directly instead. See {@link ProductService.getAllProducts}. */
2531
2605
  getAllProducts(): Promise<Product[]>;
2532
2606
  /** All activity products (excludes add-ons). @deprecated The access service exposes only its resource-service accessors; call the service directly instead. See {@link ProductService.getAllActivities}. */
@@ -3325,4 +3399,4 @@ declare class AcmeApiError extends Error {
3325
3399
  constructor(statusCode: number, body: unknown, message?: string);
3326
3400
  }
3327
3401
 
3328
- export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccessOptions, type AccountUser, AccountUserService, type AccountUserServiceOptions, AcmeAccessService, type AcmeAccessServiceConfig, type AcmeActivity, type AcmeActivityTicket, AcmeApiError, AcmeProductService, type Activity, type ActivityOverrides, type ActivityTicket, type AddAddonInput, AdminAccountRequiredError, type Agent, type AssignGuideResult, type AssignedActivity, type AssignedResource, type Availability, AvailabilityService, type AvailabilityTime, type AvailabilityTimesQuery, type Booking, type BookingAddon, type BookingAddonMoney, type BookingAddonOption, type BookingAddons, type BookingAddonsMutationResult, type BookingPaymentsOnFile, type BookingReadOptions, type BookingSearchBy, BookingService, type BookingServiceOptions, type BookingTimeRangeSearch, type CancelBookingResult, type Channel, type ClearOverridesInput, CngAccessService, type CngAccessServiceConfig, CngApiError, CngPermissionError, CngProductService, type CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreateEngineInput, type CreatePromoCodeInput, type CreatedBooking, type CreatedPricingEngine, type CreatedPromoCode, type CustomQuestion, type CustomQuestionAnswer, type CustomQuestionAnswerInput, type CustomQuestionOption, type DailyNote, DailyNoteService, type Duration, type Guest, type GuestMetadata, type Guide, type GuideAssignment, INSTALL_STATUSES, type InstallAccessConfig, type InstallAccessService, type InstallAccessTarget, type InstallStatus, type InstallWebhook, type InstallWebhookAccount, type InstallWebhookClaims, type InvoiceLinkResult, type Logger, type MakePaymentInput, type MakePaymentResult, type Membership, type MembershipPurchaseInput, MembershipService, type MetaData, type MetaDataBarcodeType, type MetaDataDurationUnit, type MetaDataValue, type MetaDataVolumeUnit, type MetaDataWeightUnit, type NoteMode, type Payment, type PaymentSource, PeekAccessService, type PeekAccessServiceConfig, type PeekAuthTokenClaims, type PeekAuthTokenUser, PeekGraphQLError, PeekHttpError, type PeekPlatform, PiiAccessDisabledError, type Price, type PricingActivityContext, type PricingEngine, type PricingMoney, type PricingNamedRef, type PricingOverride, type PricingOverrideFilter, PricingService, type Product, type ProductMeetingLocation, type ProductReviewSummary, ProductService, type ProductServiceOptions, type ProductTicket, type PromoCode, type PromoCodeFixedAmount, PromoCodeService, type PromoCodeServiceOptions, type PurchasedMembership, RENTAL_PRODUCT_TYPE, RateLimitError, type RefundInput, type RefundResult, ResellerService, type ResolvedOverride, type ResolvedPricingOverride, type ResolvedResourceOption, type Resource, type ResourceOptionOverride, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type SetMetaDataAttachmentInput, type SetMetaDataGuestInput, type SetMetaDataResult, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateEngineInput, type UpdateTimeslotResult, type UpsertOverridesInput, type UpsertOverridesResult, type Waiver, createAccessServiceForInstall, noopLogger, parseBookingWebhook, parseInstallWebhook, parseWaiverWebhook, verifyInstallWebhook };
3402
+ export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccessOptions, type AccountUser, AccountUserService, type AccountUserServiceOptions, AcmeAccessService, type AcmeAccessServiceConfig, type AcmeActivity, type AcmeActivityTicket, AcmeApiError, AcmeProductService, type Activity, type ActivityOverrides, type ActivityTicket, type AddAddonInput, AdminAccountRequiredError, type Agent, type AssignGuideResult, type AssignedActivity, type AssignedResource, type Availability, AvailabilityService, type AvailabilityTime, type AvailabilityTimesQuery, type Booking, type BookingAddon, type BookingAddonMoney, type BookingAddonOption, type BookingAddons, type BookingAddonsMutationResult, type BookingPaymentsOnFile, type BookingReadOptions, type BookingSearchBy, BookingService, type BookingServiceOptions, type BookingTimeRangeSearch, type CancelBookingResult, type Channel, type ClearOverridesInput, CngAccessService, type CngAccessServiceConfig, CngApiError, CngPermissionError, CngProductService, type CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreateEngineInput, type CreatePromoCodeInput, type CreatedBooking, type CreatedPricingEngine, type CreatedPromoCode, type CustomQuestion, type CustomQuestionAnswer, type CustomQuestionAnswerInput, type CustomQuestionOption, CustomQuestionService, type DailyNote, DailyNoteService, type Duration, type Guest, type GuestMetadata, type Guide, type GuideAssignment, INSTALL_STATUSES, type InstallAccessConfig, type InstallAccessService, type InstallAccessTarget, type InstallStatus, type InstallWebhook, type InstallWebhookAccount, type InstallWebhookClaims, type InvoiceLinkResult, type Logger, type MakePaymentInput, type MakePaymentResult, type Membership, type MembershipPurchaseInput, MembershipService, type MetaData, type MetaDataBarcodeType, type MetaDataDurationUnit, type MetaDataValue, type MetaDataVolumeUnit, type MetaDataWeightUnit, type NoteMode, type Payment, type PaymentSource, PeekAccessService, type PeekAccessServiceConfig, type PeekAuthTokenClaims, type PeekAuthTokenUser, PeekGraphQLError, PeekHttpError, type PeekPlatform, PiiAccessDisabledError, type Price, type PricingActivityContext, type PricingEngine, type PricingMoney, type PricingNamedRef, type PricingOverride, type PricingOverrideFilter, PricingService, type Product, type ProductMeetingLocation, type ProductReviewSummary, ProductService, type ProductServiceOptions, type ProductTicket, type PromoCode, type PromoCodeFixedAmount, PromoCodeService, type PromoCodeServiceOptions, type PurchasedMembership, RENTAL_PRODUCT_TYPE, RateLimitError, type RefundInput, type RefundResult, ResellerService, type ResolvedOverride, type ResolvedPricingOverride, type ResolvedResourceOption, type Resource, type ResourceOptionOverride, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type SetMetaDataAttachmentInput, type SetMetaDataGuestInput, type SetMetaDataResult, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateEngineInput, type UpdateTimeslotResult, type UpsertOverridesInput, type UpsertOverridesResult, type Waiver, createAccessServiceForInstall, noopLogger, parseBookingWebhook, parseInstallWebhook, parseWaiverWebhook, verifyInstallWebhook };
package/dist/index.d.ts CHANGED
@@ -1932,6 +1932,37 @@ declare class AvailabilityService {
1932
1932
  getAvailabilityTimes(query: AvailabilityTimesQuery): Promise<AvailabilityTime[]>;
1933
1933
  }
1934
1934
 
1935
+ /**
1936
+ * Reads custom questions defined on the account.
1937
+ *
1938
+ * Obtain an instance via {@link PeekAccessService.getCustomQuestionService}.
1939
+ */
1940
+ declare class CustomQuestionService {
1941
+ private readonly client;
1942
+ constructor(client: GraphQLClient);
1943
+ /**
1944
+ * Returns every custom question defined on the account, across all
1945
+ * activities. Choice-style questions (`SELECT_ONE`, `LOCATION`, …) carry their
1946
+ * selectable {@link CustomQuestion.options}; free-text/checkbox questions
1947
+ * return an empty option list.
1948
+ *
1949
+ * These are account-wide question **definitions**, not customer answers — no
1950
+ * PII is involved, so the result is unaffected by `fullCustomerAccess`. Unlike
1951
+ * {@link ProductService.getCustomQuestions}, the catalog carries no
1952
+ * per-activity configuration, so {@link CustomQuestion.order} is `0` and
1953
+ * {@link CustomQuestion.isRequired} is `false` on every entry.
1954
+ *
1955
+ * @returns Every custom question on the account, or an empty list when none
1956
+ * are defined.
1957
+ *
1958
+ * @example
1959
+ * ```ts
1960
+ * const questions = await peek.getCustomQuestionService().getAll();
1961
+ * ```
1962
+ */
1963
+ getAll(): Promise<CustomQuestion[]>;
1964
+ }
1965
+
1935
1966
  /**
1936
1967
  * The clean data model for a Peek Pro daily (dashboard) note.
1937
1968
  */
@@ -1980,6 +2011,15 @@ interface BaseAccessServiceConfig {
1980
2011
  * way to target an install — prefer it over `baseUrl`/`appId`, which are
1981
2012
  * deprecated (the hardcoded base-URL fallbacks will be removed and a URL will
1982
2013
  * become required in a future release).
2014
+ *
2015
+ * For Peek `mode: "v2"` this field is **required** (the constructor throws
2016
+ * without it). If you do not yet have a webhook `apiUrl` — e.g. an install that
2017
+ * predates webhook `apiUrl` delivery, which you don't want to uninstall /
2018
+ * reinstall just to obtain one — build one by appending your **app slug** to
2019
+ * the registry prefix and pass that here:
2020
+ * `https://apps.peek.com/installations-api/<app-slug>` (the trailing app-slug
2021
+ * segment is required — the prefix alone is not a valid URL). Treat that as a
2022
+ * transitional bridge and prefer the `apiUrl` the install webhook delivers.
1983
2023
  */
1984
2024
  apiUrl?: string;
1985
2025
  /**
@@ -2378,15 +2418,35 @@ interface InstallWebhookClaims {
2378
2418
  * Peek-specific extras below.
2379
2419
  */
2380
2420
  interface PeekAccessServiceConfig extends BaseAccessServiceConfig {
2381
- /** API gateway key, sent as the `pk-api-key` header. Required in v1 mode; not used in v2. */
2382
- gatewayKey?: string;
2383
2421
  /**
2384
- * Gateway mode. `"v2"` routes through the app-registry installations API
2385
- * (`baseUrl/appId/peek_backoffice_api-v1/endpointName`) and defaults to the
2386
- * app-registry sandbox base URL. `"v1"` (default) uses the standard backoffice
2387
- * GraphQL gateway.
2422
+ * API gateway key, sent as the `pk-api-key` header. Required in `"v1"` mode
2423
+ * (unless an `apiUrl` is supplied); not used in `"v2"`.
2388
2424
  */
2389
- mode?: "v2";
2425
+ gatewayKey?: string;
2426
+ /**
2427
+ * Which connection generation to use. **Required — choose explicitly.**
2428
+ *
2429
+ * This field used to be optional, and omitting it meant `"v1"`. It is now
2430
+ * mandatory so that updating the package forces a deliberate choice instead of
2431
+ * silently keeping the old behaviour. If your install used the previous
2432
+ * default, the fastest no-behaviour-change update is to pass `mode: "v1"`.
2433
+ *
2434
+ * - `"v2"` — **use this going forward.** Routes through the app-registry
2435
+ * installations API. It **requires** the install's **`apiUrl`**: the
2436
+ * per-install base URL delivered on the install webhook (`api.url`), which you
2437
+ * persist and pass as `apiUrl`. The constructor throws if it is missing —
2438
+ * there is no silent default. If you do not have a webhook `apiUrl` yet, build
2439
+ * one by appending your **app slug** to the registry prefix and pass that
2440
+ * yourself — `https://apps.peek.com/installations-api/<app-slug>` (same shape
2441
+ * as the webhook's `api.url`; the trailing app-slug segment is required, the
2442
+ * prefix alone is not a valid URL). Treat it as a transitional bridge and
2443
+ * prefer the webhook URL. No `gatewayKey` is needed (the registry
2444
+ * authenticates on the JWT alone).
2445
+ * - `"v1"` — **deprecated; will be removed.** The legacy backoffice GraphQL
2446
+ * gateway; requires `gatewayKey`. Retained only so existing installs can
2447
+ * update with no immediate behaviour change. Migrate to `"v2"`.
2448
+ */
2449
+ mode: "v1" | "v2";
2390
2450
  /** Page size for cursor-paginated item options. Default: 50. */
2391
2451
  itemOptionsPageSize?: number;
2392
2452
  }
@@ -2402,20 +2462,28 @@ interface PeekAccessServiceConfig extends BaseAccessServiceConfig {
2402
2462
  * ```ts
2403
2463
  * import { PeekAccessService, type Product } from "@peektravel/app-utilities";
2404
2464
  *
2465
+ * // "v2" (recommended) — registry connection, targeted by the install
2466
+ * // webhook's apiUrl; no gatewayKey needed:
2405
2467
  * const peek = new PeekAccessService({
2406
2468
  * installId: "install-123", // JWT subject
2407
2469
  * jwtSecret: process.env.PEEK_INTERNAL_SECRET!, // signs the JWT
2408
2470
  * issuer: process.env.APP_NAME!, // JWT issuer
2409
- * appId: process.env.PEEK_APP_ID!, // gateway path segment
2410
- * gatewayKey: process.env.PEEK_GATEWAY_KEY!, // pk-api-key header
2471
+ * mode: "v2", // connection generation (required)
2472
+ * apiUrl: install.apiUrl, // persisted from the install webhook
2411
2473
  * });
2412
2474
  *
2475
+ * // "v1" (deprecated) — legacy gateway; the fastest update for installs that
2476
+ * // relied on the old default:
2477
+ * // new PeekAccessService({ installId, jwtSecret, issuer, appId, gatewayKey, mode: "v1" })
2478
+ *
2413
2479
  * const products: Product[] = await peek.getProductService().getAllProducts();
2414
2480
  * const booking = await peek.getBookingService().getById("b_abc123");
2415
2481
  * ```
2416
2482
  *
2417
- * @throws {Error} from the constructor when any required config field
2418
- * (`installId`, `jwtSecret`, `issuer`, `appId`, `gatewayKey`) is empty.
2483
+ * @throws {Error} from the constructor when `mode` is missing or not `"v1"`/
2484
+ * `"v2"`; when `"v2"` is selected without an `apiUrl`; or when any required
2485
+ * config field is empty (`installId`, `jwtSecret`, `issuer`, and — in `"v1"`
2486
+ * mode without an `apiUrl` — `appId` and `gatewayKey`).
2419
2487
  */
2420
2488
  declare class PeekAccessService {
2421
2489
  private readonly client;
@@ -2435,6 +2503,7 @@ declare class PeekAccessService {
2435
2503
  private membershipService?;
2436
2504
  private readonly bookingServices;
2437
2505
  private reviewService?;
2506
+ private customQuestionService?;
2438
2507
  constructor(config: PeekAccessServiceConfig);
2439
2508
  /**
2440
2509
  * Verifies a Peek auth token issued by the app registry and returns the
@@ -2527,6 +2596,11 @@ declare class PeekAccessService {
2527
2596
  * authenticated transport. The instance is created lazily and reused.
2528
2597
  */
2529
2598
  getReviewService(): ReviewService;
2599
+ /**
2600
+ * Returns the {@link CustomQuestionService} for this install, bound to the
2601
+ * shared authenticated transport. The instance is created lazily and reused.
2602
+ */
2603
+ getCustomQuestionService(): CustomQuestionService;
2530
2604
  /** All products (activities + add-ons). @deprecated The access service exposes only its resource-service accessors; call the service directly instead. See {@link ProductService.getAllProducts}. */
2531
2605
  getAllProducts(): Promise<Product[]>;
2532
2606
  /** All activity products (excludes add-ons). @deprecated The access service exposes only its resource-service accessors; call the service directly instead. See {@link ProductService.getAllActivities}. */
@@ -3325,4 +3399,4 @@ declare class AcmeApiError extends Error {
3325
3399
  constructor(statusCode: number, body: unknown, message?: string);
3326
3400
  }
3327
3401
 
3328
- export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccessOptions, type AccountUser, AccountUserService, type AccountUserServiceOptions, AcmeAccessService, type AcmeAccessServiceConfig, type AcmeActivity, type AcmeActivityTicket, AcmeApiError, AcmeProductService, type Activity, type ActivityOverrides, type ActivityTicket, type AddAddonInput, AdminAccountRequiredError, type Agent, type AssignGuideResult, type AssignedActivity, type AssignedResource, type Availability, AvailabilityService, type AvailabilityTime, type AvailabilityTimesQuery, type Booking, type BookingAddon, type BookingAddonMoney, type BookingAddonOption, type BookingAddons, type BookingAddonsMutationResult, type BookingPaymentsOnFile, type BookingReadOptions, type BookingSearchBy, BookingService, type BookingServiceOptions, type BookingTimeRangeSearch, type CancelBookingResult, type Channel, type ClearOverridesInput, CngAccessService, type CngAccessServiceConfig, CngApiError, CngPermissionError, CngProductService, type CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreateEngineInput, type CreatePromoCodeInput, type CreatedBooking, type CreatedPricingEngine, type CreatedPromoCode, type CustomQuestion, type CustomQuestionAnswer, type CustomQuestionAnswerInput, type CustomQuestionOption, type DailyNote, DailyNoteService, type Duration, type Guest, type GuestMetadata, type Guide, type GuideAssignment, INSTALL_STATUSES, type InstallAccessConfig, type InstallAccessService, type InstallAccessTarget, type InstallStatus, type InstallWebhook, type InstallWebhookAccount, type InstallWebhookClaims, type InvoiceLinkResult, type Logger, type MakePaymentInput, type MakePaymentResult, type Membership, type MembershipPurchaseInput, MembershipService, type MetaData, type MetaDataBarcodeType, type MetaDataDurationUnit, type MetaDataValue, type MetaDataVolumeUnit, type MetaDataWeightUnit, type NoteMode, type Payment, type PaymentSource, PeekAccessService, type PeekAccessServiceConfig, type PeekAuthTokenClaims, type PeekAuthTokenUser, PeekGraphQLError, PeekHttpError, type PeekPlatform, PiiAccessDisabledError, type Price, type PricingActivityContext, type PricingEngine, type PricingMoney, type PricingNamedRef, type PricingOverride, type PricingOverrideFilter, PricingService, type Product, type ProductMeetingLocation, type ProductReviewSummary, ProductService, type ProductServiceOptions, type ProductTicket, type PromoCode, type PromoCodeFixedAmount, PromoCodeService, type PromoCodeServiceOptions, type PurchasedMembership, RENTAL_PRODUCT_TYPE, RateLimitError, type RefundInput, type RefundResult, ResellerService, type ResolvedOverride, type ResolvedPricingOverride, type ResolvedResourceOption, type Resource, type ResourceOptionOverride, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type SetMetaDataAttachmentInput, type SetMetaDataGuestInput, type SetMetaDataResult, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateEngineInput, type UpdateTimeslotResult, type UpsertOverridesInput, type UpsertOverridesResult, type Waiver, createAccessServiceForInstall, noopLogger, parseBookingWebhook, parseInstallWebhook, parseWaiverWebhook, verifyInstallWebhook };
3402
+ export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccessOptions, type AccountUser, AccountUserService, type AccountUserServiceOptions, AcmeAccessService, type AcmeAccessServiceConfig, type AcmeActivity, type AcmeActivityTicket, AcmeApiError, AcmeProductService, type Activity, type ActivityOverrides, type ActivityTicket, type AddAddonInput, AdminAccountRequiredError, type Agent, type AssignGuideResult, type AssignedActivity, type AssignedResource, type Availability, AvailabilityService, type AvailabilityTime, type AvailabilityTimesQuery, type Booking, type BookingAddon, type BookingAddonMoney, type BookingAddonOption, type BookingAddons, type BookingAddonsMutationResult, type BookingPaymentsOnFile, type BookingReadOptions, type BookingSearchBy, BookingService, type BookingServiceOptions, type BookingTimeRangeSearch, type CancelBookingResult, type Channel, type ClearOverridesInput, CngAccessService, type CngAccessServiceConfig, CngApiError, CngPermissionError, CngProductService, type CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreateEngineInput, type CreatePromoCodeInput, type CreatedBooking, type CreatedPricingEngine, type CreatedPromoCode, type CustomQuestion, type CustomQuestionAnswer, type CustomQuestionAnswerInput, type CustomQuestionOption, CustomQuestionService, type DailyNote, DailyNoteService, type Duration, type Guest, type GuestMetadata, type Guide, type GuideAssignment, INSTALL_STATUSES, type InstallAccessConfig, type InstallAccessService, type InstallAccessTarget, type InstallStatus, type InstallWebhook, type InstallWebhookAccount, type InstallWebhookClaims, type InvoiceLinkResult, type Logger, type MakePaymentInput, type MakePaymentResult, type Membership, type MembershipPurchaseInput, MembershipService, type MetaData, type MetaDataBarcodeType, type MetaDataDurationUnit, type MetaDataValue, type MetaDataVolumeUnit, type MetaDataWeightUnit, type NoteMode, type Payment, type PaymentSource, PeekAccessService, type PeekAccessServiceConfig, type PeekAuthTokenClaims, type PeekAuthTokenUser, PeekGraphQLError, PeekHttpError, type PeekPlatform, PiiAccessDisabledError, type Price, type PricingActivityContext, type PricingEngine, type PricingMoney, type PricingNamedRef, type PricingOverride, type PricingOverrideFilter, PricingService, type Product, type ProductMeetingLocation, type ProductReviewSummary, ProductService, type ProductServiceOptions, type ProductTicket, type PromoCode, type PromoCodeFixedAmount, PromoCodeService, type PromoCodeServiceOptions, type PurchasedMembership, RENTAL_PRODUCT_TYPE, RateLimitError, type RefundInput, type RefundResult, ResellerService, type ResolvedOverride, type ResolvedPricingOverride, type ResolvedResourceOption, type Resource, type ResourceOptionOverride, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type SetMetaDataAttachmentInput, type SetMetaDataGuestInput, type SetMetaDataResult, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateEngineInput, type UpdateTimeslotResult, type UpsertOverridesInput, type UpsertOverridesResult, type Waiver, createAccessServiceForInstall, noopLogger, parseBookingWebhook, parseInstallWebhook, parseWaiverWebhook, verifyInstallWebhook };
package/dist/index.js CHANGED
@@ -2474,6 +2474,123 @@ function buildCancellation(items, addonOptionId, quantity) {
2474
2474
  return { bookingQuotes, canceledCount };
2475
2475
  }
2476
2476
 
2477
+ // src/internal/peek/custom-questions/custom-question-converter.ts
2478
+ function fromQuestionConfigurations(configs) {
2479
+ return configs.map(
2480
+ (config) => fromQuestionNode(config.question, config.order, config.isRequired)
2481
+ );
2482
+ }
2483
+ function fromQuestionNodes(questions) {
2484
+ return questions.map((question) => fromQuestionNode(question));
2485
+ }
2486
+ function fromQuestionNode(question, order, isRequired) {
2487
+ return {
2488
+ id: question.id,
2489
+ order: order ?? 0,
2490
+ isRequired: isRequired ?? false,
2491
+ questionText: question.text,
2492
+ hintText: question.hint ?? null,
2493
+ questionType: question.questionType,
2494
+ internalLabel: question.internalLabel ?? null,
2495
+ perGuest: question.perGuest ?? false,
2496
+ defaultValue: question.answerDefaultValue ?? null,
2497
+ options: (question.options ?? []).map(fromQuestionOption)
2498
+ };
2499
+ }
2500
+ function fromQuestionOption(option) {
2501
+ return {
2502
+ id: option.id,
2503
+ order: option.order,
2504
+ value: option.text
2505
+ };
2506
+ }
2507
+
2508
+ // src/internal/peek/custom-questions/custom-question-queries.ts
2509
+ var ALL_CUSTOM_QUESTIONS_QUERY = `
2510
+ query Sales {
2511
+ questions {
2512
+ id
2513
+ questionType
2514
+ text
2515
+ answerDefaultValue
2516
+ hint
2517
+ internalLabel
2518
+ perGuest
2519
+ ... on ChoiceQuestion {
2520
+ options {
2521
+ id
2522
+ text
2523
+ order
2524
+ }
2525
+ }
2526
+ }
2527
+ }
2528
+ `;
2529
+ var CUSTOM_QUESTIONS_QUERY = `
2530
+ query Sales($id: ID!) {
2531
+ activity(id: $id) {
2532
+ id
2533
+ name
2534
+ questionActivityConfigurations {
2535
+ isRequired
2536
+ order
2537
+ question {
2538
+ id
2539
+ questionType
2540
+ text
2541
+ answerDefaultValue
2542
+ hint
2543
+ internalLabel
2544
+ perGuest
2545
+ ... on ChoiceQuestion {
2546
+ options {
2547
+ id
2548
+ text
2549
+ order
2550
+ }
2551
+ }
2552
+ }
2553
+ }
2554
+ }
2555
+ }
2556
+ `;
2557
+
2558
+ // src/internal/peek/custom-questions/custom-question-service.ts
2559
+ var CustomQuestionService = class {
2560
+ constructor(client) {
2561
+ this.client = client;
2562
+ }
2563
+ client;
2564
+ /**
2565
+ * Returns every custom question defined on the account, across all
2566
+ * activities. Choice-style questions (`SELECT_ONE`, `LOCATION`, …) carry their
2567
+ * selectable {@link CustomQuestion.options}; free-text/checkbox questions
2568
+ * return an empty option list.
2569
+ *
2570
+ * These are account-wide question **definitions**, not customer answers — no
2571
+ * PII is involved, so the result is unaffected by `fullCustomerAccess`. Unlike
2572
+ * {@link ProductService.getCustomQuestions}, the catalog carries no
2573
+ * per-activity configuration, so {@link CustomQuestion.order} is `0` and
2574
+ * {@link CustomQuestion.isRequired} is `false` on every entry.
2575
+ *
2576
+ * @returns Every custom question on the account, or an empty list when none
2577
+ * are defined.
2578
+ *
2579
+ * @example
2580
+ * ```ts
2581
+ * const questions = await peek.getCustomQuestionService().getAll();
2582
+ * ```
2583
+ */
2584
+ async getAll() {
2585
+ const body = await this.client.request(
2586
+ SALES_ENDPOINT,
2587
+ ALL_CUSTOM_QUESTIONS_QUERY,
2588
+ {}
2589
+ );
2590
+ return fromQuestionNodes(body.data?.questions ?? []);
2591
+ }
2592
+ };
2593
+
2477
2594
  // src/internal/peek/daily-notes/daily-note-converter.ts
2478
2595
  function toDailyNote(response) {
2479
2596
  const union = response?.dailyNote;
@@ -2652,7 +2769,7 @@ async function requestWithRetry(http, url, init, label, onResponse) {
2652
2769
  // src/internal/sdk-headers.ts
2653
2770
  var SDK_HEADER_NAME = "x-peek-sdk";
2654
2771
  var SDK_PLATFORM = "js";
2655
- var SDK_VERSION = "0.9.4";
2772
+ var SDK_VERSION = "1.0.0";
2656
2773
  var SDK_HEADER_VALUE = `${SDK_PLATFORM}-${SDK_VERSION}`;
2657
2774
 
2658
2775
  // src/internal/peek/graphql-client.ts
@@ -3678,33 +3795,6 @@ function fromItemOptionNodes(nodes) {
3678
3795
  return Array.from(grouped.values());
3679
3796
  }
3680
3797
 
3681
- // src/internal/peek/products/custom-question-converter.ts
3682
- function fromQuestionConfigurations(configs) {
3683
- return configs.map(fromQuestionConfiguration);
3684
- }
3685
- function fromQuestionConfiguration(config) {
3686
- const question = config.question;
3687
- return {
3688
- id: question.id,
3689
- order: config.order ?? 0,
3690
- isRequired: config.isRequired ?? false,
3691
- questionText: question.text,
3692
- hintText: question.hint ?? null,
3693
- questionType: question.questionType,
3694
- internalLabel: question.internalLabel ?? null,
3695
- perGuest: question.perGuest ?? false,
3696
- defaultValue: question.answerDefaultValue ?? null,
3697
- options: (question.options ?? []).map(fromQuestionOption)
3698
- };
3699
- }
3700
- function fromQuestionOption(option) {
3701
- return {
3702
- id: option.id,
3703
- order: option.order,
3704
- value: option.text
3705
- };
3706
- }
3707
-
3708
3798
  // src/internal/peek/products/product-queries.ts
3709
3799
  var PRODUCTS_QUERY = `
3710
3800
  query Sales {
@@ -3763,36 +3853,6 @@ var ITEM_OPTIONS_QUERY = `
3763
3853
  }
3764
3854
  `;
3765
3855
 
3766
- // src/internal/peek/products/custom-question-queries.ts
3767
- var CUSTOM_QUESTIONS_QUERY = `
3768
- query Sales($id: ID!) {
3769
- activity(id: $id) {
3770
- id
3771
- name
3772
- questionActivityConfigurations {
3773
- isRequired
3774
- order
3775
- question {
3776
- id
3777
- questionType
3778
- text
3779
- answerDefaultValue
3780
- hint
3781
- internalLabel
3782
- perGuest
3783
- ... on ChoiceQuestion {
3784
- options {
3785
- id
3786
- text
3787
- order
3788
- }
3789
- }
3790
- }
3791
- }
3792
- }
3793
- }
3794
- `;
3795
-
3796
3856
  // src/internal/peek/products/product-service.ts
3797
3857
  var ERROR_PRODUCT_ID_REQUIRED2 = "A non-empty product id is required.";
3798
3858
  var DEFAULT_ITEM_OPTIONS_PAGE_SIZE = 50;
@@ -4352,7 +4412,9 @@ var noopLogger = {
4352
4412
 
4353
4413
  // src/peek-access-service.ts
4354
4414
  var DEFAULT_BASE_URL = "https://apps.peekapis.com/backoffice-gql";
4355
- var DEFAULT_V2_BASE_URL = "https://app-registry.peeklabs.com/installations-api";
4415
+ var V2_FALLBACK_URL_PREFIX = "https://apps.peek.com/installations-api";
4416
+ var ERROR_MODE_REQUIRED = `PeekAccessService: "mode" is required and must be "v1" or "v2". Existing installs used the previous default of "v1" \u2014 pass mode: "v1" for the fastest update. Note: "v1" is deprecated and will be removed; migrate to "v2" and pass the install webhook's apiUrl.`;
4417
+ var ERROR_V2_API_URL_REQUIRED = `PeekAccessService: mode "v2" requires an "apiUrl" \u2014 the per-install URL delivered on the install webhook (api.url) and persisted per install. If you do not have one yet, append your app slug to the registry prefix and pass that, e.g. "${V2_FALLBACK_URL_PREFIX}/<app-slug>" (the trailing app-slug segment is required \u2014 the prefix alone is not a valid apiUrl).`;
4356
4418
  var PeekAccessService = class {
4357
4419
  client;
4358
4420
  productServiceOptions;
@@ -4371,21 +4433,27 @@ var PeekAccessService = class {
4371
4433
  membershipService;
4372
4434
  bookingServices = /* @__PURE__ */ new Map();
4373
4435
  reviewService;
4436
+ customQuestionService;
4374
4437
  constructor(config) {
4375
4438
  const hasApiUrl = !!config.apiUrl;
4439
+ if (config.mode !== "v1" && config.mode !== "v2") {
4440
+ throw new Error(ERROR_MODE_REQUIRED);
4441
+ }
4376
4442
  const isV2 = config.mode === "v2";
4377
4443
  requireNonEmpty(config.installId, "installId", "PeekAccessService");
4378
4444
  requireNonEmpty(config.jwtSecret, "jwtSecret", "PeekAccessService");
4379
4445
  requireNonEmpty(config.issuer, "issuer", "PeekAccessService");
4380
- if (!hasApiUrl) requireNonEmpty(config.appId ?? "", "appId", "PeekAccessService");
4381
- if (!hasApiUrl && !isV2) requireNonEmpty(config.gatewayKey ?? "", "gatewayKey", "PeekAccessService");
4446
+ if (isV2 && !hasApiUrl) throw new Error(ERROR_V2_API_URL_REQUIRED);
4447
+ if (!isV2 && !hasApiUrl) {
4448
+ requireNonEmpty(config.appId ?? "", "appId", "PeekAccessService");
4449
+ requireNonEmpty(config.gatewayKey ?? "", "gatewayKey", "PeekAccessService");
4450
+ }
4382
4451
  this.jwtSecret = config.jwtSecret;
4383
4452
  this.issuer = config.issuer;
4384
4453
  const logger = config.logger ?? noopLogger;
4385
4454
  const tokens = createTokenManager(config);
4386
- const useRegistrySlug = hasApiUrl || isV2;
4387
- const defaultBaseUrl = isV2 ? DEFAULT_V2_BASE_URL : DEFAULT_BASE_URL;
4388
- const baseApiUrl = hasApiUrl ? resolveBaseApiUrl(config.apiUrl, V2_EXTENDABLE_SLUG, "PeekAccessService") : `${config.baseUrl ?? defaultBaseUrl}/${config.appId}`;
4455
+ const useRegistrySlug = hasApiUrl;
4456
+ const baseApiUrl = hasApiUrl ? resolveBaseApiUrl(config.apiUrl, V2_EXTENDABLE_SLUG, "PeekAccessService") : `${config.baseUrl ?? DEFAULT_BASE_URL}/${config.appId}`;
4389
4457
  this.client = new GraphQLClient({
4390
4458
  baseApiUrl,
4391
4459
  endpoints: peekApiEndpoints(useRegistrySlug),
@@ -4571,6 +4639,16 @@ var PeekAccessService = class {
4571
4639
  }
4572
4640
  return this.reviewService;
4573
4641
  }
4642
+ /**
4643
+ * Returns the {@link CustomQuestionService} for this install, bound to the
4644
+ * shared authenticated transport. The instance is created lazily and reused.
4645
+ */
4646
+ getCustomQuestionService() {
4647
+ if (!this.customQuestionService) {
4648
+ this.customQuestionService = new CustomQuestionService(this.client);
4649
+ }
4650
+ return this.customQuestionService;
4651
+ }
4574
4652
  // ─── Product short-forms ─────────────────────────────────────────────────
4575
4653
  /** All products (activities + add-ons). @deprecated The access service exposes only its resource-service accessors; call the service directly instead. See {@link ProductService.getAllProducts}. */
4576
4654
  getAllProducts() {
@@ -5040,7 +5118,12 @@ var AcmeAccessService = class {
5040
5118
 
5041
5119
  // src/access-service-factory.ts
5042
5120
  function createAccessServiceForInstall(install, config) {
5043
- const shared = { ...config, installId: install.installId, apiUrl: install.apiUrl };
5121
+ const shared = {
5122
+ ...config,
5123
+ installId: install.installId,
5124
+ apiUrl: install.apiUrl,
5125
+ mode: "v2"
5126
+ };
5044
5127
  switch (install.platform) {
5045
5128
  case "peek":
5046
5129
  return new PeekAccessService(shared);
@@ -5207,6 +5290,6 @@ function verifyInstallWebhook(token, secret) {
5207
5290
  };
5208
5291
  }
5209
5292
 
5210
- export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, AccountUserService, AcmeAccessService, AcmeApiError, AcmeProductService, AdminAccountRequiredError, AvailabilityService, BookingService, CngAccessService, CngApiError, CngPermissionError, CngProductService, DailyNoteService, INSTALL_STATUSES, MembershipService, PeekAccessService, PeekGraphQLError, PeekHttpError, PiiAccessDisabledError, PricingService, ProductService, PromoCodeService, RENTAL_PRODUCT_TYPE, RateLimitError, ResellerService, ResourcePoolService, ReviewService, TimeslotService, createAccessServiceForInstall, noopLogger, parseBookingWebhook, parseInstallWebhook, parseWaiverWebhook, verifyInstallWebhook };
5293
+ export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, AccountUserService, AcmeAccessService, AcmeApiError, AcmeProductService, AdminAccountRequiredError, AvailabilityService, BookingService, CngAccessService, CngApiError, CngPermissionError, CngProductService, CustomQuestionService, DailyNoteService, INSTALL_STATUSES, MembershipService, PeekAccessService, PeekGraphQLError, PeekHttpError, PiiAccessDisabledError, PricingService, ProductService, PromoCodeService, RENTAL_PRODUCT_TYPE, RateLimitError, ResellerService, ResourcePoolService, ReviewService, TimeslotService, createAccessServiceForInstall, noopLogger, parseBookingWebhook, parseInstallWebhook, parseWaiverWebhook, verifyInstallWebhook };
5211
5294
  //# sourceMappingURL=index.js.map
5212
5295
  //# sourceMappingURL=index.js.map