@peektravel/app-utilities 0.3.1 → 0.4.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
@@ -1668,7 +1668,7 @@ declare class PeekAccessService {
1668
1668
  getReviews(productId: string, reviewCount?: number, reviewOffset?: number): Promise<Review[]>;
1669
1669
  }
1670
1670
 
1671
- interface RestClientOptions {
1671
+ interface RestClientOptions$1 {
1672
1672
  /** Base URL of the backoffice gateway (no trailing slash). */
1673
1673
  baseUrl: string;
1674
1674
  /** App ID, used in the endpoint path. */
@@ -1684,9 +1684,9 @@ interface RestClientOptions {
1684
1684
  /** `fetch` implementation to use. */
1685
1685
  fetchFn: typeof fetch;
1686
1686
  }
1687
- declare class RestClient {
1687
+ declare class RestClient$1 {
1688
1688
  private readonly options;
1689
- constructor(options: RestClientOptions);
1689
+ constructor(options: RestClientOptions$1);
1690
1690
  /**
1691
1691
  * Issues a GET against the named REST path and returns the parsed JSON body.
1692
1692
  * Retries on HTTP 429 per the configured backoff (via the shared
@@ -1746,7 +1746,7 @@ interface ActivityTicket {
1746
1746
 
1747
1747
  declare class CngProductService {
1748
1748
  private readonly client;
1749
- constructor(client: RestClient);
1749
+ constructor(client: RestClient$1);
1750
1750
  /**
1751
1751
  * Returns every activity as a single flat list.
1752
1752
  *
@@ -1797,6 +1797,133 @@ declare class CngAccessService {
1797
1797
  getAllActivities(): Promise<Activity[]>;
1798
1798
  }
1799
1799
 
1800
+ interface RestClientOptions {
1801
+ /** Base URL of the backoffice gateway (no trailing slash). */
1802
+ baseUrl: string;
1803
+ /** App ID, used in the endpoint path. */
1804
+ appId: string;
1805
+ /** Fixed extendable slug inserted between `appId` and the REST path. */
1806
+ extendableSlug: string;
1807
+ /** Supplies a valid bearer token for each request. */
1808
+ getToken: () => string;
1809
+ /** Backoff delays (ms) applied on successive HTTP 429 responses. */
1810
+ retryDelaysMs: number[];
1811
+ /** Diagnostics sink. */
1812
+ logger: Logger;
1813
+ /** `fetch` implementation to use. */
1814
+ fetchFn: typeof fetch;
1815
+ }
1816
+ declare class RestClient {
1817
+ private readonly options;
1818
+ constructor(options: RestClientOptions);
1819
+ /**
1820
+ * Issues a GET against the named REST path and returns the parsed JSON body.
1821
+ * Retries on HTTP 429 per the configured backoff (via the shared
1822
+ * {@link requestWithRetry} loop).
1823
+ *
1824
+ * @throws {AdminAccountRequiredError} on HTTP 418
1825
+ * @throws {RateLimitError} on HTTP 429 after retries are exhausted
1826
+ * @throws {AcmeApiError} on any other non-2xx response
1827
+ */
1828
+ get<T>(path: string): Promise<T>;
1829
+ /** Reads the response body as JSON, falling back to raw text when unparseable. */
1830
+ private parseBody;
1831
+ private endpoint;
1832
+ private buildHeaders;
1833
+ }
1834
+
1835
+ /**
1836
+ * The clean, transport-agnostic data model for an ACME event template.
1837
+ *
1838
+ * The ACME sibling of `../cng/product.ts`. Kept as a separate model because the
1839
+ * ACME gateway is a distinct backoffice, but the shape deliberately mirrors the
1840
+ * CNG `Activity` so consumers can treat every brand uniformly. The raw ACME
1841
+ * REST response types and the conversion logic live inside the package and are
1842
+ * never exposed here.
1843
+ */
1844
+ /**
1845
+ * A bookable activity in an ACME account (an event template).
1846
+ *
1847
+ * `AcmeAccessService.getAllActivities()` returns these as a flat list, filtered
1848
+ * to published templates only. ACME does not expose tickets today, so
1849
+ * {@link AcmeActivity.tickets} is always an empty list.
1850
+ */
1851
+ interface AcmeActivity {
1852
+ /** Stable unique identifier for the activity. */
1853
+ productId: string;
1854
+ /** Human-readable display name. */
1855
+ name: string;
1856
+ /** Product type reported by ACME (e.g. `"standard"`). */
1857
+ type: string;
1858
+ /**
1859
+ * Display color as a hex string (e.g. `"#00695c"`). Falls back to a neutral
1860
+ * gray (`"#d1d1d1"`) when no color is set.
1861
+ */
1862
+ color: string;
1863
+ /** The bookable sub-options (tickets) of this activity. Always empty today. */
1864
+ tickets: AcmeActivityTicket[];
1865
+ }
1866
+ /** A single bookable sub-option (ticket) of an {@link AcmeActivity}. */
1867
+ interface AcmeActivityTicket {
1868
+ /** Unique identifier of the ticket. */
1869
+ id: string;
1870
+ /** Human-readable name of the ticket. */
1871
+ name: string;
1872
+ }
1873
+
1874
+ declare class AcmeProductService {
1875
+ private readonly client;
1876
+ constructor(client: RestClient);
1877
+ /**
1878
+ * Returns every published event template as a single flat list of activities.
1879
+ *
1880
+ * @example
1881
+ * ```ts
1882
+ * const activities = await acme.getProductService().getAllActivities();
1883
+ * ```
1884
+ */
1885
+ getAllActivities(): Promise<AcmeActivity[]>;
1886
+ }
1887
+
1888
+ /**
1889
+ * Configuration for an {@link AcmeAccessService} instance. ACME adds no fields
1890
+ * beyond {@link BaseAccessServiceConfig} — it authenticates on the app JWT
1891
+ * alone (no `pk-api-key`, so no `gatewayKey`).
1892
+ */
1893
+ type AcmeAccessServiceConfig = BaseAccessServiceConfig;
1894
+ /**
1895
+ * Authenticated root entry point to the ACME backoffice REST gateway.
1896
+ *
1897
+ * @example
1898
+ * ```ts
1899
+ * import { AcmeAccessService, type AcmeActivity } from "@peektravel/app-utilities";
1900
+ *
1901
+ * const acme = new AcmeAccessService({
1902
+ * installId: "install-123",
1903
+ * jwtSecret: process.env.PEEK_APP_SECRET!,
1904
+ * issuer: process.env.PEEK_APP_ID!,
1905
+ * appId: process.env.PEEK_APP_ID!,
1906
+ * });
1907
+ *
1908
+ * const activities: AcmeActivity[] = await acme.getAllActivities();
1909
+ * ```
1910
+ *
1911
+ * @throws {Error} from the constructor when any required config field
1912
+ * (`installId`, `jwtSecret`, `issuer`, `appId`) is empty.
1913
+ */
1914
+ declare class AcmeAccessService {
1915
+ private readonly client;
1916
+ private productService?;
1917
+ constructor(config: AcmeAccessServiceConfig);
1918
+ /**
1919
+ * Returns the {@link AcmeProductService} for this install, bound to the shared
1920
+ * authenticated transport. The instance is created lazily and reused.
1921
+ */
1922
+ getProductService(): AcmeProductService;
1923
+ /** All activities. Delegates to {@link AcmeProductService.getAllActivities}. */
1924
+ getAllActivities(): Promise<AcmeActivity[]>;
1925
+ }
1926
+
1800
1927
  /**
1801
1928
  * Public webhook surface for bookings.
1802
1929
  *
@@ -1882,8 +2009,9 @@ declare function parseWaiverWebhook(payload: unknown): Waiver;
1882
2009
  * GraphQL gateway (or the CNG REST gateway) so callers can branch on the error
1883
2010
  * type rather than parsing messages.
1884
2011
  *
1885
- * `AdminAccountRequiredError` and `RateLimitError` are shared by both gateways.
1886
- * `PeekGraphQLError` is Peek-only; `CngApiError` is CNG-only.
2012
+ * `AdminAccountRequiredError` and `RateLimitError` are shared by all gateways.
2013
+ * `PeekGraphQLError` is Peek-only; `CngApiError` is CNG-only; `AcmeApiError` is
2014
+ * ACME-only.
1887
2015
  */
1888
2016
  /**
1889
2017
  * Thrown when the gateway responds with HTTP 418, indicating the install is not
@@ -1925,5 +2053,19 @@ declare class CngApiError extends Error {
1925
2053
  readonly body: unknown;
1926
2054
  constructor(statusCode: number, body: unknown, message?: string);
1927
2055
  }
2056
+ /**
2057
+ * Thrown when the ACME REST gateway returns a non-2xx response that is not one
2058
+ * of the specifically-handled statuses (418/429). The offending status is
2059
+ * preserved on {@link AcmeApiError.statusCode}, and the raw response body
2060
+ * (parsed JSON when possible, otherwise the raw text) on
2061
+ * {@link AcmeApiError.body}.
2062
+ */
2063
+ declare class AcmeApiError extends Error {
2064
+ /** The HTTP status that triggered this error. */
2065
+ readonly statusCode: number;
2066
+ /** The raw response body (parsed JSON when possible, otherwise text). */
2067
+ readonly body: unknown;
2068
+ constructor(statusCode: number, body: unknown, message?: string);
2069
+ }
1928
2070
 
1929
- 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 PeekPlatform, 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 };
2071
+ export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccountUser, AccountUserService, type AccountUserServiceOptions, AcmeAccessService, type AcmeAccessServiceConfig, type AcmeActivity, type AcmeActivityTicket, AcmeApiError, AcmeProductService, 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 PeekPlatform, 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
@@ -1668,7 +1668,7 @@ declare class PeekAccessService {
1668
1668
  getReviews(productId: string, reviewCount?: number, reviewOffset?: number): Promise<Review[]>;
1669
1669
  }
1670
1670
 
1671
- interface RestClientOptions {
1671
+ interface RestClientOptions$1 {
1672
1672
  /** Base URL of the backoffice gateway (no trailing slash). */
1673
1673
  baseUrl: string;
1674
1674
  /** App ID, used in the endpoint path. */
@@ -1684,9 +1684,9 @@ interface RestClientOptions {
1684
1684
  /** `fetch` implementation to use. */
1685
1685
  fetchFn: typeof fetch;
1686
1686
  }
1687
- declare class RestClient {
1687
+ declare class RestClient$1 {
1688
1688
  private readonly options;
1689
- constructor(options: RestClientOptions);
1689
+ constructor(options: RestClientOptions$1);
1690
1690
  /**
1691
1691
  * Issues a GET against the named REST path and returns the parsed JSON body.
1692
1692
  * Retries on HTTP 429 per the configured backoff (via the shared
@@ -1746,7 +1746,7 @@ interface ActivityTicket {
1746
1746
 
1747
1747
  declare class CngProductService {
1748
1748
  private readonly client;
1749
- constructor(client: RestClient);
1749
+ constructor(client: RestClient$1);
1750
1750
  /**
1751
1751
  * Returns every activity as a single flat list.
1752
1752
  *
@@ -1797,6 +1797,133 @@ declare class CngAccessService {
1797
1797
  getAllActivities(): Promise<Activity[]>;
1798
1798
  }
1799
1799
 
1800
+ interface RestClientOptions {
1801
+ /** Base URL of the backoffice gateway (no trailing slash). */
1802
+ baseUrl: string;
1803
+ /** App ID, used in the endpoint path. */
1804
+ appId: string;
1805
+ /** Fixed extendable slug inserted between `appId` and the REST path. */
1806
+ extendableSlug: string;
1807
+ /** Supplies a valid bearer token for each request. */
1808
+ getToken: () => string;
1809
+ /** Backoff delays (ms) applied on successive HTTP 429 responses. */
1810
+ retryDelaysMs: number[];
1811
+ /** Diagnostics sink. */
1812
+ logger: Logger;
1813
+ /** `fetch` implementation to use. */
1814
+ fetchFn: typeof fetch;
1815
+ }
1816
+ declare class RestClient {
1817
+ private readonly options;
1818
+ constructor(options: RestClientOptions);
1819
+ /**
1820
+ * Issues a GET against the named REST path and returns the parsed JSON body.
1821
+ * Retries on HTTP 429 per the configured backoff (via the shared
1822
+ * {@link requestWithRetry} loop).
1823
+ *
1824
+ * @throws {AdminAccountRequiredError} on HTTP 418
1825
+ * @throws {RateLimitError} on HTTP 429 after retries are exhausted
1826
+ * @throws {AcmeApiError} on any other non-2xx response
1827
+ */
1828
+ get<T>(path: string): Promise<T>;
1829
+ /** Reads the response body as JSON, falling back to raw text when unparseable. */
1830
+ private parseBody;
1831
+ private endpoint;
1832
+ private buildHeaders;
1833
+ }
1834
+
1835
+ /**
1836
+ * The clean, transport-agnostic data model for an ACME event template.
1837
+ *
1838
+ * The ACME sibling of `../cng/product.ts`. Kept as a separate model because the
1839
+ * ACME gateway is a distinct backoffice, but the shape deliberately mirrors the
1840
+ * CNG `Activity` so consumers can treat every brand uniformly. The raw ACME
1841
+ * REST response types and the conversion logic live inside the package and are
1842
+ * never exposed here.
1843
+ */
1844
+ /**
1845
+ * A bookable activity in an ACME account (an event template).
1846
+ *
1847
+ * `AcmeAccessService.getAllActivities()` returns these as a flat list, filtered
1848
+ * to published templates only. ACME does not expose tickets today, so
1849
+ * {@link AcmeActivity.tickets} is always an empty list.
1850
+ */
1851
+ interface AcmeActivity {
1852
+ /** Stable unique identifier for the activity. */
1853
+ productId: string;
1854
+ /** Human-readable display name. */
1855
+ name: string;
1856
+ /** Product type reported by ACME (e.g. `"standard"`). */
1857
+ type: string;
1858
+ /**
1859
+ * Display color as a hex string (e.g. `"#00695c"`). Falls back to a neutral
1860
+ * gray (`"#d1d1d1"`) when no color is set.
1861
+ */
1862
+ color: string;
1863
+ /** The bookable sub-options (tickets) of this activity. Always empty today. */
1864
+ tickets: AcmeActivityTicket[];
1865
+ }
1866
+ /** A single bookable sub-option (ticket) of an {@link AcmeActivity}. */
1867
+ interface AcmeActivityTicket {
1868
+ /** Unique identifier of the ticket. */
1869
+ id: string;
1870
+ /** Human-readable name of the ticket. */
1871
+ name: string;
1872
+ }
1873
+
1874
+ declare class AcmeProductService {
1875
+ private readonly client;
1876
+ constructor(client: RestClient);
1877
+ /**
1878
+ * Returns every published event template as a single flat list of activities.
1879
+ *
1880
+ * @example
1881
+ * ```ts
1882
+ * const activities = await acme.getProductService().getAllActivities();
1883
+ * ```
1884
+ */
1885
+ getAllActivities(): Promise<AcmeActivity[]>;
1886
+ }
1887
+
1888
+ /**
1889
+ * Configuration for an {@link AcmeAccessService} instance. ACME adds no fields
1890
+ * beyond {@link BaseAccessServiceConfig} — it authenticates on the app JWT
1891
+ * alone (no `pk-api-key`, so no `gatewayKey`).
1892
+ */
1893
+ type AcmeAccessServiceConfig = BaseAccessServiceConfig;
1894
+ /**
1895
+ * Authenticated root entry point to the ACME backoffice REST gateway.
1896
+ *
1897
+ * @example
1898
+ * ```ts
1899
+ * import { AcmeAccessService, type AcmeActivity } from "@peektravel/app-utilities";
1900
+ *
1901
+ * const acme = new AcmeAccessService({
1902
+ * installId: "install-123",
1903
+ * jwtSecret: process.env.PEEK_APP_SECRET!,
1904
+ * issuer: process.env.PEEK_APP_ID!,
1905
+ * appId: process.env.PEEK_APP_ID!,
1906
+ * });
1907
+ *
1908
+ * const activities: AcmeActivity[] = await acme.getAllActivities();
1909
+ * ```
1910
+ *
1911
+ * @throws {Error} from the constructor when any required config field
1912
+ * (`installId`, `jwtSecret`, `issuer`, `appId`) is empty.
1913
+ */
1914
+ declare class AcmeAccessService {
1915
+ private readonly client;
1916
+ private productService?;
1917
+ constructor(config: AcmeAccessServiceConfig);
1918
+ /**
1919
+ * Returns the {@link AcmeProductService} for this install, bound to the shared
1920
+ * authenticated transport. The instance is created lazily and reused.
1921
+ */
1922
+ getProductService(): AcmeProductService;
1923
+ /** All activities. Delegates to {@link AcmeProductService.getAllActivities}. */
1924
+ getAllActivities(): Promise<AcmeActivity[]>;
1925
+ }
1926
+
1800
1927
  /**
1801
1928
  * Public webhook surface for bookings.
1802
1929
  *
@@ -1882,8 +2009,9 @@ declare function parseWaiverWebhook(payload: unknown): Waiver;
1882
2009
  * GraphQL gateway (or the CNG REST gateway) so callers can branch on the error
1883
2010
  * type rather than parsing messages.
1884
2011
  *
1885
- * `AdminAccountRequiredError` and `RateLimitError` are shared by both gateways.
1886
- * `PeekGraphQLError` is Peek-only; `CngApiError` is CNG-only.
2012
+ * `AdminAccountRequiredError` and `RateLimitError` are shared by all gateways.
2013
+ * `PeekGraphQLError` is Peek-only; `CngApiError` is CNG-only; `AcmeApiError` is
2014
+ * ACME-only.
1887
2015
  */
1888
2016
  /**
1889
2017
  * Thrown when the gateway responds with HTTP 418, indicating the install is not
@@ -1925,5 +2053,19 @@ declare class CngApiError extends Error {
1925
2053
  readonly body: unknown;
1926
2054
  constructor(statusCode: number, body: unknown, message?: string);
1927
2055
  }
2056
+ /**
2057
+ * Thrown when the ACME REST gateway returns a non-2xx response that is not one
2058
+ * of the specifically-handled statuses (418/429). The offending status is
2059
+ * preserved on {@link AcmeApiError.statusCode}, and the raw response body
2060
+ * (parsed JSON when possible, otherwise the raw text) on
2061
+ * {@link AcmeApiError.body}.
2062
+ */
2063
+ declare class AcmeApiError extends Error {
2064
+ /** The HTTP status that triggered this error. */
2065
+ readonly statusCode: number;
2066
+ /** The raw response body (parsed JSON when possible, otherwise text). */
2067
+ readonly body: unknown;
2068
+ constructor(statusCode: number, body: unknown, message?: string);
2069
+ }
1928
2070
 
1929
- 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 PeekPlatform, 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 };
2071
+ export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, type AccountUser, AccountUserService, type AccountUserServiceOptions, AcmeAccessService, type AcmeAccessServiceConfig, type AcmeActivity, type AcmeActivityTicket, AcmeApiError, AcmeProductService, 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 PeekPlatform, 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.js CHANGED
@@ -1858,6 +1858,18 @@ var CngApiError = class extends Error {
1858
1858
  this.body = body;
1859
1859
  }
1860
1860
  };
1861
+ var AcmeApiError = class extends Error {
1862
+ /** The HTTP status that triggered this error. */
1863
+ statusCode;
1864
+ /** The raw response body (parsed JSON when possible, otherwise text). */
1865
+ body;
1866
+ constructor(statusCode, body, message) {
1867
+ super(message ?? `ACME request failed with HTTP ${statusCode}`);
1868
+ this.name = "AcmeApiError";
1869
+ this.statusCode = statusCode;
1870
+ this.body = body;
1871
+ }
1872
+ };
1861
1873
 
1862
1874
  // src/internal/http-transport.ts
1863
1875
  var RATE_LIMIT_STATUS = 429;
@@ -3484,6 +3496,146 @@ var CngAccessService = class {
3484
3496
  }
3485
3497
  };
3486
3498
 
3499
+ // src/internal/acme/endpoints.ts
3500
+ var ACME_EXTENDABLE_SLUG = "acme_backoffice_api@v1";
3501
+ var TEMPLATES_PATH = "v2/b2b/event/templates/names?pageSize=-1&page=1";
3502
+
3503
+ // src/models/acme/product.ts
3504
+ var ACME_ACTIVITY_TYPE = "standard";
3505
+
3506
+ // src/internal/acme/products/product-queries.ts
3507
+ var PUBLISHED_REVIEW_STATE = "published";
3508
+
3509
+ // src/internal/acme/products/product-converter.ts
3510
+ function fromTemplateNodes(nodes) {
3511
+ return nodes.filter((node) => node.reviewState === PUBLISHED_REVIEW_STATE).map(fromTemplateNode);
3512
+ }
3513
+ function fromTemplateNode(node) {
3514
+ return {
3515
+ productId: node.id || "",
3516
+ name: node.name || "",
3517
+ type: node.type || ACME_ACTIVITY_TYPE,
3518
+ color: node.colorCategory?.backgroundColor || "#d1d1d1",
3519
+ tickets: []
3520
+ };
3521
+ }
3522
+
3523
+ // src/internal/acme/products/product-service.ts
3524
+ var AcmeProductService = class {
3525
+ constructor(client) {
3526
+ this.client = client;
3527
+ }
3528
+ client;
3529
+ /**
3530
+ * Returns every published event template as a single flat list of activities.
3531
+ *
3532
+ * @example
3533
+ * ```ts
3534
+ * const activities = await acme.getProductService().getAllActivities();
3535
+ * ```
3536
+ */
3537
+ async getAllActivities() {
3538
+ const body = await this.client.get(
3539
+ TEMPLATES_PATH
3540
+ );
3541
+ const nodes = Array.isArray(body) ? body : body?.list ?? [];
3542
+ return fromTemplateNodes(nodes ?? []);
3543
+ }
3544
+ };
3545
+
3546
+ // src/internal/acme/rest-client.ts
3547
+ var RestClient2 = class {
3548
+ constructor(options) {
3549
+ this.options = options;
3550
+ }
3551
+ options;
3552
+ /**
3553
+ * Issues a GET against the named REST path and returns the parsed JSON body.
3554
+ * Retries on HTTP 429 per the configured backoff (via the shared
3555
+ * {@link requestWithRetry} loop).
3556
+ *
3557
+ * @throws {AdminAccountRequiredError} on HTTP 418
3558
+ * @throws {RateLimitError} on HTTP 429 after retries are exhausted
3559
+ * @throws {AcmeApiError} on any other non-2xx response
3560
+ */
3561
+ async get(path) {
3562
+ const { logger } = this.options;
3563
+ const url = this.endpoint(path);
3564
+ logger.info("Making ACME request", { url, path });
3565
+ return requestWithRetry(
3566
+ this.options,
3567
+ url,
3568
+ { method: "GET", headers: this.buildHeaders() },
3569
+ path,
3570
+ async (response) => {
3571
+ const body = await this.parseBody(response);
3572
+ if (!response.ok) {
3573
+ logger.error(`ACME request failed with HTTP ${response.status}`, { url });
3574
+ throw new AcmeApiError(response.status, body);
3575
+ }
3576
+ return body;
3577
+ }
3578
+ );
3579
+ }
3580
+ /** Reads the response body as JSON, falling back to raw text when unparseable. */
3581
+ async parseBody(response) {
3582
+ const text = await response.text();
3583
+ try {
3584
+ return JSON.parse(text);
3585
+ } catch {
3586
+ return text;
3587
+ }
3588
+ }
3589
+ endpoint(path) {
3590
+ const { baseUrl, appId, extendableSlug } = this.options;
3591
+ return `${baseUrl}/${appId}/${extendableSlug}/${path}`;
3592
+ }
3593
+ buildHeaders() {
3594
+ return {
3595
+ "X-Peek-Auth": `Bearer ${this.options.getToken()}`,
3596
+ "Content-Type": "application/json"
3597
+ };
3598
+ }
3599
+ };
3600
+
3601
+ // src/acme-access-service.ts
3602
+ var DEFAULT_BASE_URL3 = "https://app-registry.peeklabs.com/installations-api";
3603
+ var AcmeAccessService = class {
3604
+ client;
3605
+ productService;
3606
+ constructor(config) {
3607
+ requireNonEmpty(config.installId, "installId", "AcmeAccessService");
3608
+ requireNonEmpty(config.jwtSecret, "jwtSecret", "AcmeAccessService");
3609
+ requireNonEmpty(config.issuer, "issuer", "AcmeAccessService");
3610
+ requireNonEmpty(config.appId, "appId", "AcmeAccessService");
3611
+ const logger = config.logger ?? noopLogger;
3612
+ const tokens = createTokenManager(config);
3613
+ this.client = new RestClient2({
3614
+ baseUrl: config.baseUrl ?? DEFAULT_BASE_URL3,
3615
+ appId: config.appId,
3616
+ extendableSlug: ACME_EXTENDABLE_SLUG,
3617
+ getToken: () => tokens.getToken(),
3618
+ retryDelaysMs: config.retryDelaysMs ?? DEFAULT_RETRY_DELAYS_MS,
3619
+ logger,
3620
+ fetchFn: config.fetch ?? globalThis.fetch
3621
+ });
3622
+ }
3623
+ /**
3624
+ * Returns the {@link AcmeProductService} for this install, bound to the shared
3625
+ * authenticated transport. The instance is created lazily and reused.
3626
+ */
3627
+ getProductService() {
3628
+ if (!this.productService) {
3629
+ this.productService = new AcmeProductService(this.client);
3630
+ }
3631
+ return this.productService;
3632
+ }
3633
+ /** All activities. Delegates to {@link AcmeProductService.getAllActivities}. */
3634
+ getAllActivities() {
3635
+ return this.getProductService().getAllActivities();
3636
+ }
3637
+ };
3638
+
3487
3639
  // src/internal/peek/bookings/booking-webhook.ts
3488
3640
  var PAYLOAD_BOOKING_KEY = "booking";
3489
3641
  var VALUE_OPEN_TOKEN = "value {";
@@ -3569,6 +3721,6 @@ function extractWaiverNode(payload) {
3569
3721
  return record;
3570
3722
  }
3571
3723
 
3572
- export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, AccountUserService, AdminAccountRequiredError, AvailabilityService, BookingService, CngAccessService, CngApiError, CngProductService, DailyNoteService, MembershipService, PeekAccessService, PeekGraphQLError, ProductService, PromoCodeService, RENTAL_PRODUCT_TYPE, RateLimitError, ResellerService, ResourcePoolService, ReviewService, TimeslotService, noopLogger, parseBookingWebhook, parseWaiverWebhook };
3724
+ export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, AccountUserService, AcmeAccessService, AcmeApiError, AcmeProductService, AdminAccountRequiredError, AvailabilityService, BookingService, CngAccessService, CngApiError, CngProductService, DailyNoteService, MembershipService, PeekAccessService, PeekGraphQLError, ProductService, PromoCodeService, RENTAL_PRODUCT_TYPE, RateLimitError, ResellerService, ResourcePoolService, ReviewService, TimeslotService, noopLogger, parseBookingWebhook, parseWaiverWebhook };
3573
3725
  //# sourceMappingURL=index.js.map
3574
3726
  //# sourceMappingURL=index.js.map