@peektravel/app-utilities 0.2.9 → 0.3.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
@@ -44,7 +44,8 @@ declare class GraphQLClient {
44
44
  constructor(options: GraphQLClientOptions);
45
45
  /**
46
46
  * Executes a GraphQL query against the named endpoint and returns the raw
47
- * response body. Retries on HTTP 429 per the configured backoff.
47
+ * response body. Retries on HTTP 429 per the configured backoff (via the
48
+ * shared {@link requestWithRetry} loop).
48
49
  */
49
50
  request<T>(endpointName: string, query: string, variables: object): Promise<GraphQLBody<T>>;
50
51
  private endpoint;
@@ -395,6 +396,11 @@ interface Booking {
395
396
  resellerName: string | null;
396
397
  /** The order id this booking belongs to. `""` if absent. */
397
398
  orderId: string;
399
+ /**
400
+ * Deep link into the Peek Pro app for this booking, derived from the order id
401
+ * and booking id. `""` when either id is absent.
402
+ */
403
+ peekProBookingDeepLink: string;
398
404
  /** Custom question answers captured at the booking level. */
399
405
  customQuestionAnswers: CustomQuestionAnswer[];
400
406
  /** Custom question answers captured per guest/ticket. */
@@ -1188,6 +1194,40 @@ declare class DailyNoteService {
1188
1194
  update(note: string): Promise<DailyNote | null>;
1189
1195
  }
1190
1196
 
1197
+ /**
1198
+ * Config shared by every access service in this package (Peek, CNG, …).
1199
+ *
1200
+ * Each gateway's access service extends {@link BaseAccessServiceConfig} with its
1201
+ * own extras (e.g. Peek adds `gatewayKey`/`mode`), so the only real difference
1202
+ * between accessors is the transport they build and the services they expose.
1203
+ * The shared defaults and the token-manager builder live here too, so that
1204
+ * plumbing is written once.
1205
+ */
1206
+
1207
+ /** Fields common to every access service's config. */
1208
+ interface BaseAccessServiceConfig {
1209
+ /** Install ID. Becomes the JWT subject. */
1210
+ installId: string;
1211
+ /** HMAC secret used to sign the JWT. */
1212
+ jwtSecret: string;
1213
+ /** JWT issuer — the app name / app ID. */
1214
+ issuer: string;
1215
+ /** App ID, used in the gateway endpoint path. */
1216
+ appId: string;
1217
+ /** Override the gateway base URL. Default: per-service. */
1218
+ baseUrl?: string;
1219
+ /** JWT lifetime in seconds. Default: 3600. */
1220
+ tokenTtlSeconds?: number;
1221
+ /** Re-mint the cached token this many seconds before expiry. Default: 60. */
1222
+ tokenRefreshLeewaySeconds?: number;
1223
+ /** Backoff delays (ms) for HTTP 429 retries. Default: [1000, 2000, 4000]. */
1224
+ retryDelaysMs?: number[];
1225
+ /** Optional logger. Default: no-op (silent). */
1226
+ logger?: Logger;
1227
+ /** Custom `fetch` implementation. Default: the global `fetch`. */
1228
+ fetch?: typeof fetch;
1229
+ }
1230
+
1191
1231
  declare class MembershipService {
1192
1232
  private readonly client;
1193
1233
  constructor(client: GraphQLClient);
@@ -1409,16 +1449,12 @@ interface PeekAuthTokenClaims {
1409
1449
  user: PeekAuthTokenUser;
1410
1450
  }
1411
1451
 
1412
- /** Configuration for a {@link PeekAccessService} instance. */
1413
- interface PeekAccessServiceConfig {
1414
- /** Peek install ID. Becomes the JWT subject. */
1415
- installId: string;
1416
- /** HMAC secret used to sign the JWT (the Peek internal secret). */
1417
- jwtSecret: string;
1418
- /** JWT issuer — the app name. */
1419
- issuer: string;
1420
- /** Peek app ID, used in the gateway endpoint path. */
1421
- appId: string;
1452
+ /**
1453
+ * Configuration for a {@link PeekAccessService} instance. Extends the shared
1454
+ * {@link BaseAccessServiceConfig} (install/auth/transport fields) with the
1455
+ * Peek-specific extras below.
1456
+ */
1457
+ interface PeekAccessServiceConfig extends BaseAccessServiceConfig {
1422
1458
  /** API gateway key, sent as the `pk-api-key` header. Required in v1 mode; not used in v2. */
1423
1459
  gatewayKey?: string;
1424
1460
  /**
@@ -1428,18 +1464,6 @@ interface PeekAccessServiceConfig {
1428
1464
  * GraphQL gateway.
1429
1465
  */
1430
1466
  mode?: "v2";
1431
- /** Override the gateway base URL. Default: Peek production gateway (v1) or app-registry sandbox (v2). */
1432
- baseUrl?: string;
1433
- /** JWT lifetime in seconds. Default: 3600. */
1434
- tokenTtlSeconds?: number;
1435
- /** Re-mint the cached token this many seconds before expiry. Default: 60. */
1436
- tokenRefreshLeewaySeconds?: number;
1437
- /** Backoff delays (ms) for HTTP 429 retries. Default: [1000, 2000, 4000]. */
1438
- retryDelaysMs?: number[];
1439
- /** Optional logger. Default: no-op (silent). */
1440
- logger?: Logger;
1441
- /** Custom `fetch` implementation. Default: the global `fetch`. */
1442
- fetch?: typeof fetch;
1443
1467
  /** Page size for cursor-paginated item options. Default: 50. */
1444
1468
  itemOptionsPageSize?: number;
1445
1469
  }
@@ -1635,6 +1659,135 @@ declare class PeekAccessService {
1635
1659
  getReviews(productId: string, reviewCount?: number, reviewOffset?: number): Promise<Review[]>;
1636
1660
  }
1637
1661
 
1662
+ interface RestClientOptions {
1663
+ /** Base URL of the backoffice gateway (no trailing slash). */
1664
+ baseUrl: string;
1665
+ /** App ID, used in the endpoint path. */
1666
+ appId: string;
1667
+ /** Fixed extendable slug inserted between `appId` and the REST path. */
1668
+ extendableSlug: string;
1669
+ /** Supplies a valid bearer token for each request. */
1670
+ getToken: () => string;
1671
+ /** Backoff delays (ms) applied on successive HTTP 429 responses. */
1672
+ retryDelaysMs: number[];
1673
+ /** Diagnostics sink. */
1674
+ logger: Logger;
1675
+ /** `fetch` implementation to use. */
1676
+ fetchFn: typeof fetch;
1677
+ }
1678
+ declare class RestClient {
1679
+ private readonly options;
1680
+ constructor(options: RestClientOptions);
1681
+ /**
1682
+ * Issues a GET against the named REST path and returns the parsed JSON body.
1683
+ * Retries on HTTP 429 per the configured backoff (via the shared
1684
+ * {@link requestWithRetry} loop).
1685
+ *
1686
+ * @throws {AdminAccountRequiredError} on HTTP 418
1687
+ * @throws {RateLimitError} on HTTP 429 after retries are exhausted
1688
+ * @throws {CngApiError} on any other non-2xx response
1689
+ */
1690
+ get<T>(path: string): Promise<T>;
1691
+ /** Reads the response body as JSON, falling back to raw text when unparseable. */
1692
+ private parseBody;
1693
+ private endpoint;
1694
+ private buildHeaders;
1695
+ }
1696
+
1697
+ /**
1698
+ * The clean, transport-agnostic data model for a CNG product.
1699
+ *
1700
+ * The CNG sibling of `../peek/product.ts`. Kept as a separate model because the
1701
+ * CNG gateway is a distinct backoffice, but the shape deliberately mirrors the
1702
+ * Peek `Product` so consumers can treat both brands uniformly. The raw CNG REST
1703
+ * response types and the conversion logic live inside the package and are never
1704
+ * exposed here.
1705
+ */
1706
+ /**
1707
+ * A bookable activity in a CNG account.
1708
+ *
1709
+ * `CngAccessService.getAllActivities()` returns these as a flat list.
1710
+ *
1711
+ * NOTE: field mapping is a best-guess placeholder until the real
1712
+ * `commerce-config/products` response shape is confirmed — see
1713
+ * `internal/cng/products/product-queries.ts`.
1714
+ */
1715
+ interface Activity {
1716
+ /** Stable unique identifier for the activity. */
1717
+ productId: string;
1718
+ /** Human-readable display name. */
1719
+ name: string;
1720
+ /** Product type reported by CNG (e.g. `"ACTIVITY"`). */
1721
+ type: string;
1722
+ /**
1723
+ * Display color as a hex string (e.g. `"#1A2B3C"`). Empty string when no
1724
+ * color is set.
1725
+ */
1726
+ color: string;
1727
+ /** The bookable sub-options (tickets) of this activity. */
1728
+ tickets: ActivityTicket[];
1729
+ }
1730
+ /** A single bookable sub-option (ticket) of an {@link Activity}. */
1731
+ interface ActivityTicket {
1732
+ /** Unique identifier of the ticket. */
1733
+ id: string;
1734
+ /** Human-readable name of the ticket. */
1735
+ name: string;
1736
+ }
1737
+
1738
+ declare class CngProductService {
1739
+ private readonly client;
1740
+ constructor(client: RestClient);
1741
+ /**
1742
+ * Returns every activity as a single flat list.
1743
+ *
1744
+ * @example
1745
+ * ```ts
1746
+ * const activities = await cng.getProductService().getAllActivities();
1747
+ * ```
1748
+ */
1749
+ getAllActivities(): Promise<Activity[]>;
1750
+ }
1751
+
1752
+ /**
1753
+ * Configuration for a {@link CngAccessService} instance. CNG adds no fields
1754
+ * beyond {@link BaseAccessServiceConfig} — it authenticates on the app JWT
1755
+ * alone (no `pk-api-key`, so no `gatewayKey`).
1756
+ */
1757
+ type CngAccessServiceConfig = BaseAccessServiceConfig;
1758
+ /**
1759
+ * Authenticated root entry point to the CNG backoffice REST gateway.
1760
+ *
1761
+ * @example
1762
+ * ```ts
1763
+ * import { CngAccessService, type Activity } from "@peektravel/app-utilities";
1764
+ *
1765
+ * const cng = new CngAccessService({
1766
+ * installId: "install-123",
1767
+ * jwtSecret: process.env.PEEK_APP_SECRET!,
1768
+ * issuer: process.env.PEEK_APP_ID!,
1769
+ * appId: process.env.PEEK_APP_ID!,
1770
+ * });
1771
+ *
1772
+ * const activities: Activity[] = await cng.getAllActivities();
1773
+ * ```
1774
+ *
1775
+ * @throws {Error} from the constructor when any required config field
1776
+ * (`installId`, `jwtSecret`, `issuer`, `appId`) is empty.
1777
+ */
1778
+ declare class CngAccessService {
1779
+ private readonly client;
1780
+ private productService?;
1781
+ constructor(config: CngAccessServiceConfig);
1782
+ /**
1783
+ * Returns the {@link CngProductService} for this install, bound to the shared
1784
+ * authenticated transport. The instance is created lazily and reused.
1785
+ */
1786
+ getProductService(): CngProductService;
1787
+ /** All activities. Delegates to {@link CngProductService.getAllActivities}. */
1788
+ getAllActivities(): Promise<Activity[]>;
1789
+ }
1790
+
1638
1791
  /**
1639
1792
  * Public webhook surface for bookings.
1640
1793
  *
@@ -1717,8 +1870,11 @@ declare function parseWaiverWebhook(payload: unknown): Waiver;
1717
1870
 
1718
1871
  /**
1719
1872
  * Typed errors thrown by the package. Each mirrors a failure mode of the Peek
1720
- * GraphQL gateway so callers can branch on the error type rather than parsing
1721
- * messages.
1873
+ * GraphQL gateway (or the CNG REST gateway) so callers can branch on the error
1874
+ * type rather than parsing messages.
1875
+ *
1876
+ * `AdminAccountRequiredError` and `RateLimitError` are shared by both gateways.
1877
+ * `PeekGraphQLError` is Peek-only; `CngApiError` is CNG-only.
1722
1878
  */
1723
1879
  /**
1724
1880
  * Thrown when the gateway responds with HTTP 418, indicating the install is not
@@ -1747,5 +1903,18 @@ declare class PeekGraphQLError extends Error {
1747
1903
  readonly graphqlErrors: unknown[];
1748
1904
  constructor(graphqlErrors: unknown[], message?: string);
1749
1905
  }
1906
+ /**
1907
+ * Thrown when the CNG REST gateway returns a non-2xx response that is not one
1908
+ * of the specifically-handled statuses (418/429). The offending status is
1909
+ * preserved on {@link CngApiError.statusCode}, and the raw response body (parsed
1910
+ * JSON when possible, otherwise the raw text) on {@link CngApiError.body}.
1911
+ */
1912
+ declare class CngApiError extends Error {
1913
+ /** The HTTP status that triggered this error. */
1914
+ readonly statusCode: number;
1915
+ /** The raw response body (parsed JSON when possible, otherwise text). */
1916
+ readonly body: unknown;
1917
+ constructor(statusCode: number, body: unknown, message?: string);
1918
+ }
1750
1919
 
1751
- export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccountUser, AccountUserService, type AccountUserServiceOptions, 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 CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreatePromoCodeInput, type CreatedBooking, type CreatedPromoCode, type CustomQuestionAnswer, type DailyNote, DailyNoteService, type Duration, type Guest, type GuestMetadata, type Guide, type GuideAssignment, type InvoiceLinkResult, type Logger, type MakePaymentInput, type MakePaymentResult, type Membership, type MembershipPurchaseInput, MembershipService, type NoteMode, type Payment, type PaymentSource, PeekAccessService, type PeekAccessServiceConfig, type PeekAuthTokenClaims, type PeekAuthTokenUser, PeekGraphQLError, type Price, type Product, ProductService, type ProductServiceOptions, type ProductTicket, type PromoCode, type PromoCodeFixedAmount, PromoCodeService, type PromoCodeServiceOptions, type PurchasedMembership, RENTAL_PRODUCT_TYPE, RateLimitError, type RefundInput, type RefundResult, ResellerService, type Resource, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateTimeslotResult, type Waiver, noopLogger, parseBookingWebhook, parseWaiverWebhook };
1920
+ export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccountUser, AccountUserService, type AccountUserServiceOptions, type Activity, 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, CngAccessService, type CngAccessServiceConfig, CngApiError, CngProductService, type CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreatePromoCodeInput, type CreatedBooking, type CreatedPromoCode, type CustomQuestionAnswer, type DailyNote, DailyNoteService, type Duration, type Guest, type GuestMetadata, type Guide, type GuideAssignment, type InvoiceLinkResult, type Logger, type MakePaymentInput, type MakePaymentResult, type Membership, type MembershipPurchaseInput, MembershipService, type NoteMode, type Payment, type PaymentSource, PeekAccessService, type PeekAccessServiceConfig, type PeekAuthTokenClaims, type PeekAuthTokenUser, PeekGraphQLError, type Price, type Product, ProductService, type ProductServiceOptions, type ProductTicket, type PromoCode, type PromoCodeFixedAmount, PromoCodeService, type PromoCodeServiceOptions, type PurchasedMembership, RENTAL_PRODUCT_TYPE, RateLimitError, type RefundInput, type RefundResult, ResellerService, type Resource, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateTimeslotResult, type Waiver, noopLogger, parseBookingWebhook, parseWaiverWebhook };
package/dist/index.d.ts CHANGED
@@ -44,7 +44,8 @@ declare class GraphQLClient {
44
44
  constructor(options: GraphQLClientOptions);
45
45
  /**
46
46
  * Executes a GraphQL query against the named endpoint and returns the raw
47
- * response body. Retries on HTTP 429 per the configured backoff.
47
+ * response body. Retries on HTTP 429 per the configured backoff (via the
48
+ * shared {@link requestWithRetry} loop).
48
49
  */
49
50
  request<T>(endpointName: string, query: string, variables: object): Promise<GraphQLBody<T>>;
50
51
  private endpoint;
@@ -395,6 +396,11 @@ interface Booking {
395
396
  resellerName: string | null;
396
397
  /** The order id this booking belongs to. `""` if absent. */
397
398
  orderId: string;
399
+ /**
400
+ * Deep link into the Peek Pro app for this booking, derived from the order id
401
+ * and booking id. `""` when either id is absent.
402
+ */
403
+ peekProBookingDeepLink: string;
398
404
  /** Custom question answers captured at the booking level. */
399
405
  customQuestionAnswers: CustomQuestionAnswer[];
400
406
  /** Custom question answers captured per guest/ticket. */
@@ -1188,6 +1194,40 @@ declare class DailyNoteService {
1188
1194
  update(note: string): Promise<DailyNote | null>;
1189
1195
  }
1190
1196
 
1197
+ /**
1198
+ * Config shared by every access service in this package (Peek, CNG, …).
1199
+ *
1200
+ * Each gateway's access service extends {@link BaseAccessServiceConfig} with its
1201
+ * own extras (e.g. Peek adds `gatewayKey`/`mode`), so the only real difference
1202
+ * between accessors is the transport they build and the services they expose.
1203
+ * The shared defaults and the token-manager builder live here too, so that
1204
+ * plumbing is written once.
1205
+ */
1206
+
1207
+ /** Fields common to every access service's config. */
1208
+ interface BaseAccessServiceConfig {
1209
+ /** Install ID. Becomes the JWT subject. */
1210
+ installId: string;
1211
+ /** HMAC secret used to sign the JWT. */
1212
+ jwtSecret: string;
1213
+ /** JWT issuer — the app name / app ID. */
1214
+ issuer: string;
1215
+ /** App ID, used in the gateway endpoint path. */
1216
+ appId: string;
1217
+ /** Override the gateway base URL. Default: per-service. */
1218
+ baseUrl?: string;
1219
+ /** JWT lifetime in seconds. Default: 3600. */
1220
+ tokenTtlSeconds?: number;
1221
+ /** Re-mint the cached token this many seconds before expiry. Default: 60. */
1222
+ tokenRefreshLeewaySeconds?: number;
1223
+ /** Backoff delays (ms) for HTTP 429 retries. Default: [1000, 2000, 4000]. */
1224
+ retryDelaysMs?: number[];
1225
+ /** Optional logger. Default: no-op (silent). */
1226
+ logger?: Logger;
1227
+ /** Custom `fetch` implementation. Default: the global `fetch`. */
1228
+ fetch?: typeof fetch;
1229
+ }
1230
+
1191
1231
  declare class MembershipService {
1192
1232
  private readonly client;
1193
1233
  constructor(client: GraphQLClient);
@@ -1409,16 +1449,12 @@ interface PeekAuthTokenClaims {
1409
1449
  user: PeekAuthTokenUser;
1410
1450
  }
1411
1451
 
1412
- /** Configuration for a {@link PeekAccessService} instance. */
1413
- interface PeekAccessServiceConfig {
1414
- /** Peek install ID. Becomes the JWT subject. */
1415
- installId: string;
1416
- /** HMAC secret used to sign the JWT (the Peek internal secret). */
1417
- jwtSecret: string;
1418
- /** JWT issuer — the app name. */
1419
- issuer: string;
1420
- /** Peek app ID, used in the gateway endpoint path. */
1421
- appId: string;
1452
+ /**
1453
+ * Configuration for a {@link PeekAccessService} instance. Extends the shared
1454
+ * {@link BaseAccessServiceConfig} (install/auth/transport fields) with the
1455
+ * Peek-specific extras below.
1456
+ */
1457
+ interface PeekAccessServiceConfig extends BaseAccessServiceConfig {
1422
1458
  /** API gateway key, sent as the `pk-api-key` header. Required in v1 mode; not used in v2. */
1423
1459
  gatewayKey?: string;
1424
1460
  /**
@@ -1428,18 +1464,6 @@ interface PeekAccessServiceConfig {
1428
1464
  * GraphQL gateway.
1429
1465
  */
1430
1466
  mode?: "v2";
1431
- /** Override the gateway base URL. Default: Peek production gateway (v1) or app-registry sandbox (v2). */
1432
- baseUrl?: string;
1433
- /** JWT lifetime in seconds. Default: 3600. */
1434
- tokenTtlSeconds?: number;
1435
- /** Re-mint the cached token this many seconds before expiry. Default: 60. */
1436
- tokenRefreshLeewaySeconds?: number;
1437
- /** Backoff delays (ms) for HTTP 429 retries. Default: [1000, 2000, 4000]. */
1438
- retryDelaysMs?: number[];
1439
- /** Optional logger. Default: no-op (silent). */
1440
- logger?: Logger;
1441
- /** Custom `fetch` implementation. Default: the global `fetch`. */
1442
- fetch?: typeof fetch;
1443
1467
  /** Page size for cursor-paginated item options. Default: 50. */
1444
1468
  itemOptionsPageSize?: number;
1445
1469
  }
@@ -1635,6 +1659,135 @@ declare class PeekAccessService {
1635
1659
  getReviews(productId: string, reviewCount?: number, reviewOffset?: number): Promise<Review[]>;
1636
1660
  }
1637
1661
 
1662
+ interface RestClientOptions {
1663
+ /** Base URL of the backoffice gateway (no trailing slash). */
1664
+ baseUrl: string;
1665
+ /** App ID, used in the endpoint path. */
1666
+ appId: string;
1667
+ /** Fixed extendable slug inserted between `appId` and the REST path. */
1668
+ extendableSlug: string;
1669
+ /** Supplies a valid bearer token for each request. */
1670
+ getToken: () => string;
1671
+ /** Backoff delays (ms) applied on successive HTTP 429 responses. */
1672
+ retryDelaysMs: number[];
1673
+ /** Diagnostics sink. */
1674
+ logger: Logger;
1675
+ /** `fetch` implementation to use. */
1676
+ fetchFn: typeof fetch;
1677
+ }
1678
+ declare class RestClient {
1679
+ private readonly options;
1680
+ constructor(options: RestClientOptions);
1681
+ /**
1682
+ * Issues a GET against the named REST path and returns the parsed JSON body.
1683
+ * Retries on HTTP 429 per the configured backoff (via the shared
1684
+ * {@link requestWithRetry} loop).
1685
+ *
1686
+ * @throws {AdminAccountRequiredError} on HTTP 418
1687
+ * @throws {RateLimitError} on HTTP 429 after retries are exhausted
1688
+ * @throws {CngApiError} on any other non-2xx response
1689
+ */
1690
+ get<T>(path: string): Promise<T>;
1691
+ /** Reads the response body as JSON, falling back to raw text when unparseable. */
1692
+ private parseBody;
1693
+ private endpoint;
1694
+ private buildHeaders;
1695
+ }
1696
+
1697
+ /**
1698
+ * The clean, transport-agnostic data model for a CNG product.
1699
+ *
1700
+ * The CNG sibling of `../peek/product.ts`. Kept as a separate model because the
1701
+ * CNG gateway is a distinct backoffice, but the shape deliberately mirrors the
1702
+ * Peek `Product` so consumers can treat both brands uniformly. The raw CNG REST
1703
+ * response types and the conversion logic live inside the package and are never
1704
+ * exposed here.
1705
+ */
1706
+ /**
1707
+ * A bookable activity in a CNG account.
1708
+ *
1709
+ * `CngAccessService.getAllActivities()` returns these as a flat list.
1710
+ *
1711
+ * NOTE: field mapping is a best-guess placeholder until the real
1712
+ * `commerce-config/products` response shape is confirmed — see
1713
+ * `internal/cng/products/product-queries.ts`.
1714
+ */
1715
+ interface Activity {
1716
+ /** Stable unique identifier for the activity. */
1717
+ productId: string;
1718
+ /** Human-readable display name. */
1719
+ name: string;
1720
+ /** Product type reported by CNG (e.g. `"ACTIVITY"`). */
1721
+ type: string;
1722
+ /**
1723
+ * Display color as a hex string (e.g. `"#1A2B3C"`). Empty string when no
1724
+ * color is set.
1725
+ */
1726
+ color: string;
1727
+ /** The bookable sub-options (tickets) of this activity. */
1728
+ tickets: ActivityTicket[];
1729
+ }
1730
+ /** A single bookable sub-option (ticket) of an {@link Activity}. */
1731
+ interface ActivityTicket {
1732
+ /** Unique identifier of the ticket. */
1733
+ id: string;
1734
+ /** Human-readable name of the ticket. */
1735
+ name: string;
1736
+ }
1737
+
1738
+ declare class CngProductService {
1739
+ private readonly client;
1740
+ constructor(client: RestClient);
1741
+ /**
1742
+ * Returns every activity as a single flat list.
1743
+ *
1744
+ * @example
1745
+ * ```ts
1746
+ * const activities = await cng.getProductService().getAllActivities();
1747
+ * ```
1748
+ */
1749
+ getAllActivities(): Promise<Activity[]>;
1750
+ }
1751
+
1752
+ /**
1753
+ * Configuration for a {@link CngAccessService} instance. CNG adds no fields
1754
+ * beyond {@link BaseAccessServiceConfig} — it authenticates on the app JWT
1755
+ * alone (no `pk-api-key`, so no `gatewayKey`).
1756
+ */
1757
+ type CngAccessServiceConfig = BaseAccessServiceConfig;
1758
+ /**
1759
+ * Authenticated root entry point to the CNG backoffice REST gateway.
1760
+ *
1761
+ * @example
1762
+ * ```ts
1763
+ * import { CngAccessService, type Activity } from "@peektravel/app-utilities";
1764
+ *
1765
+ * const cng = new CngAccessService({
1766
+ * installId: "install-123",
1767
+ * jwtSecret: process.env.PEEK_APP_SECRET!,
1768
+ * issuer: process.env.PEEK_APP_ID!,
1769
+ * appId: process.env.PEEK_APP_ID!,
1770
+ * });
1771
+ *
1772
+ * const activities: Activity[] = await cng.getAllActivities();
1773
+ * ```
1774
+ *
1775
+ * @throws {Error} from the constructor when any required config field
1776
+ * (`installId`, `jwtSecret`, `issuer`, `appId`) is empty.
1777
+ */
1778
+ declare class CngAccessService {
1779
+ private readonly client;
1780
+ private productService?;
1781
+ constructor(config: CngAccessServiceConfig);
1782
+ /**
1783
+ * Returns the {@link CngProductService} for this install, bound to the shared
1784
+ * authenticated transport. The instance is created lazily and reused.
1785
+ */
1786
+ getProductService(): CngProductService;
1787
+ /** All activities. Delegates to {@link CngProductService.getAllActivities}. */
1788
+ getAllActivities(): Promise<Activity[]>;
1789
+ }
1790
+
1638
1791
  /**
1639
1792
  * Public webhook surface for bookings.
1640
1793
  *
@@ -1717,8 +1870,11 @@ declare function parseWaiverWebhook(payload: unknown): Waiver;
1717
1870
 
1718
1871
  /**
1719
1872
  * Typed errors thrown by the package. Each mirrors a failure mode of the Peek
1720
- * GraphQL gateway so callers can branch on the error type rather than parsing
1721
- * messages.
1873
+ * GraphQL gateway (or the CNG REST gateway) so callers can branch on the error
1874
+ * type rather than parsing messages.
1875
+ *
1876
+ * `AdminAccountRequiredError` and `RateLimitError` are shared by both gateways.
1877
+ * `PeekGraphQLError` is Peek-only; `CngApiError` is CNG-only.
1722
1878
  */
1723
1879
  /**
1724
1880
  * Thrown when the gateway responds with HTTP 418, indicating the install is not
@@ -1747,5 +1903,18 @@ declare class PeekGraphQLError extends Error {
1747
1903
  readonly graphqlErrors: unknown[];
1748
1904
  constructor(graphqlErrors: unknown[], message?: string);
1749
1905
  }
1906
+ /**
1907
+ * Thrown when the CNG REST gateway returns a non-2xx response that is not one
1908
+ * of the specifically-handled statuses (418/429). The offending status is
1909
+ * preserved on {@link CngApiError.statusCode}, and the raw response body (parsed
1910
+ * JSON when possible, otherwise the raw text) on {@link CngApiError.body}.
1911
+ */
1912
+ declare class CngApiError extends Error {
1913
+ /** The HTTP status that triggered this error. */
1914
+ readonly statusCode: number;
1915
+ /** The raw response body (parsed JSON when possible, otherwise text). */
1916
+ readonly body: unknown;
1917
+ constructor(statusCode: number, body: unknown, message?: string);
1918
+ }
1750
1919
 
1751
- export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccountUser, AccountUserService, type AccountUserServiceOptions, 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 CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreatePromoCodeInput, type CreatedBooking, type CreatedPromoCode, type CustomQuestionAnswer, type DailyNote, DailyNoteService, type Duration, type Guest, type GuestMetadata, type Guide, type GuideAssignment, type InvoiceLinkResult, type Logger, type MakePaymentInput, type MakePaymentResult, type Membership, type MembershipPurchaseInput, MembershipService, type NoteMode, type Payment, type PaymentSource, PeekAccessService, type PeekAccessServiceConfig, type PeekAuthTokenClaims, type PeekAuthTokenUser, PeekGraphQLError, type Price, type Product, ProductService, type ProductServiceOptions, type ProductTicket, type PromoCode, type PromoCodeFixedAmount, PromoCodeService, type PromoCodeServiceOptions, type PurchasedMembership, RENTAL_PRODUCT_TYPE, RateLimitError, type RefundInput, type RefundResult, ResellerService, type Resource, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateTimeslotResult, type Waiver, noopLogger, parseBookingWebhook, parseWaiverWebhook };
1920
+ export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccountUser, AccountUserService, type AccountUserServiceOptions, type Activity, 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, CngAccessService, type CngAccessServiceConfig, CngApiError, CngProductService, type CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreatePromoCodeInput, type CreatedBooking, type CreatedPromoCode, type CustomQuestionAnswer, type DailyNote, DailyNoteService, type Duration, type Guest, type GuestMetadata, type Guide, type GuideAssignment, type InvoiceLinkResult, type Logger, type MakePaymentInput, type MakePaymentResult, type Membership, type MembershipPurchaseInput, MembershipService, type NoteMode, type Payment, type PaymentSource, PeekAccessService, type PeekAccessServiceConfig, type PeekAuthTokenClaims, type PeekAuthTokenUser, PeekGraphQLError, type Price, type Product, ProductService, type ProductServiceOptions, type ProductTicket, type PromoCode, type PromoCodeFixedAmount, PromoCodeService, type PromoCodeServiceOptions, type PurchasedMembership, RENTAL_PRODUCT_TYPE, RateLimitError, type RefundInput, type RefundResult, ResellerService, type Resource, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateTimeslotResult, type Waiver, noopLogger, parseBookingWebhook, parseWaiverWebhook };