@peektravel/app-utilities 0.5.0 → 0.5.2

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.ts CHANGED
@@ -52,6 +52,247 @@ declare class GraphQLClient {
52
52
  private buildHeaders;
53
53
  }
54
54
 
55
+ /**
56
+ * The clean data model for Peek Pro pricing engines and pricing overrides.
57
+ *
58
+ * A **pricing engine** is a named container Peek Pro applies at checkout. A
59
+ * caller creates one lazily, stores its id, then repeatedly **upserts pricing
60
+ * overrides** onto it for a given date range. Overrides adjust ticket prices
61
+ * (fixed replacement or percentage adjustment) for an activity, optionally
62
+ * gated by how many spots are already taken and/or a start-time window.
63
+ *
64
+ * Scope note: this package is a thin wrapper over the Peek GraphQL primitives.
65
+ * It does **not** own the domain logic that decides *what* the overrides should
66
+ * be — segmenting an activity across time windows, ordering overrides by tier,
67
+ * or computing the `spotsTaken` bounds. The caller builds an
68
+ * {@link UpsertOverridesInput} and the service sends it faithfully; the service
69
+ * only maps between these clean shapes and the raw GraphQL payload.
70
+ */
71
+ /**
72
+ * A monetary value on a pricing override.
73
+ *
74
+ * `amount` is intentionally a **string** (e.g. `"50.00"`), never a number — the
75
+ * Peek API rejects floats here, and stringly-typed money avoids precision loss.
76
+ */
77
+ interface PricingMoney {
78
+ /** Numeric amount as a decimal string (e.g. `"50.00"`). */
79
+ amount: string;
80
+ /** ISO 4217 currency code (e.g. `"USD"`). */
81
+ currency: string;
82
+ /**
83
+ * Human-formatted display string for the amount (e.g. `"$50.00"`), as
84
+ * rendered by the Peek gateway.
85
+ *
86
+ * Populated on values **read back** from the gateway (resolved overrides,
87
+ * product ticket price ranges). It is optional and purely informational —
88
+ * omit it when *building* an override input; the gateway derives it from
89
+ * `amount`/`currency`.
90
+ */
91
+ displayPrice?: string;
92
+ }
93
+ /** An `{ id, name }` reference to a Peek entity echoed back in a response. */
94
+ interface PricingNamedRef {
95
+ /** Stable Peek identifier. */
96
+ id: string;
97
+ /** Human-readable display name. */
98
+ name: string;
99
+ }
100
+ /** Input for creating a pricing engine. */
101
+ interface CreateEngineInput {
102
+ /** Display name for the engine. */
103
+ name: string;
104
+ /**
105
+ * Optional list of activity ids the engine is scoped to. Omit (or pass an
106
+ * empty array) to create an unfiltered engine that applies to all activities.
107
+ */
108
+ activityIds?: string[];
109
+ }
110
+ /**
111
+ * The result of creating a pricing engine.
112
+ *
113
+ * The create mutation returns only the new engine's id; store it as the
114
+ * schedule's `source_refid` for subsequent override upserts.
115
+ */
116
+ interface CreatedPricingEngine {
117
+ /** The new engine's id. */
118
+ id: string;
119
+ }
120
+ /** Input for updating a pricing engine's name and/or activity scope. */
121
+ interface UpdateEngineInput {
122
+ /** The engine to update. */
123
+ engineId: string;
124
+ /** New display name. */
125
+ name: string;
126
+ /**
127
+ * Activity ids the engine should be scoped to. An empty array (or omitting
128
+ * the field) **clears** the filter so the engine applies to all activities.
129
+ */
130
+ activityIds?: string[];
131
+ }
132
+ /** A pricing engine reference as echoed back by the API. */
133
+ interface PricingEngine {
134
+ /** Engine id. */
135
+ id: string;
136
+ /** Engine display name. */
137
+ name: string;
138
+ }
139
+ /**
140
+ * A single ticket (resourceOption) price override, discriminated by `mode`.
141
+ *
142
+ * - `fixed` — replace the ticket price outright with {@link PricingMoney}.
143
+ * - `percentage` — adjust the ticket price by a percentage. The adjustment is a
144
+ * decimal **string** (e.g. `"-25"` for 25% off) and must be greater than
145
+ * `-100`.
146
+ */
147
+ type ResourceOptionOverride = {
148
+ /** The Peek resourceOption (ticket) id being overridden. */
149
+ id: string;
150
+ mode: "fixed";
151
+ /** The replacement price. */
152
+ price: PricingMoney;
153
+ } | {
154
+ /** The Peek resourceOption (ticket) id being overridden. */
155
+ id: string;
156
+ mode: "percentage";
157
+ /** Percentage adjustment as a decimal string, e.g. `"-25"`. Must be > -100. */
158
+ percentageAdjustment: string;
159
+ };
160
+ /**
161
+ * A filter gating when an override applies. Both variants are optional and an
162
+ * override may carry zero, one, or both.
163
+ */
164
+ type PricingOverrideFilter = {
165
+ /**
166
+ * Restricts the override by how many spots are already taken.
167
+ *
168
+ * `minSpots`/`maxSpots` are **zero-indexed spots-taken counts**, not
169
+ * ticket counts — e.g. "applies from the 5th ticket onward" is
170
+ * `{ minSpots: 4 }`. The caller is responsible for this off-by-one
171
+ * conversion from ticket-count ranges.
172
+ */
173
+ spotsTaken: {
174
+ /** Lower bound (inclusive) on spots already taken. Omit for no lower bound. */
175
+ minSpots?: number;
176
+ /** Upper bound (inclusive) on spots already taken. Omit for no upper bound. */
177
+ maxSpots?: number;
178
+ };
179
+ } | {
180
+ /**
181
+ * Restricts the override to a start-time window, as a PostgreSQL-style
182
+ * inclusive range string `"[HH:MM:SS,HH:MM:SS]"`.
183
+ */
184
+ startTimeRange: string;
185
+ };
186
+ /**
187
+ * One override entry for an activity: which tickets it adjusts, in what order,
188
+ * under which filters.
189
+ */
190
+ interface PricingOverride {
191
+ /**
192
+ * The override's precedence index (0-based). The caller assigns this — Peek
193
+ * evaluates lower `order` values first, so higher-discount / more-specific
194
+ * tiers should get lower numbers.
195
+ */
196
+ order: number;
197
+ /** The per-ticket price overrides applied by this entry. */
198
+ resourceOptions: ResourceOptionOverride[];
199
+ /** Zero or more filters gating when this entry applies. */
200
+ filters: PricingOverrideFilter[];
201
+ }
202
+ /** The set of overrides to apply for a single activity. */
203
+ interface ActivityOverrides {
204
+ /** The Peek activity id these overrides apply to. */
205
+ activityId: string;
206
+ /**
207
+ * The overrides for this activity. Pass an **empty array to clear** all
208
+ * overrides for the activity — never omit the activity to clear it.
209
+ */
210
+ overrides: PricingOverride[];
211
+ }
212
+ /**
213
+ * The full input for upserting pricing overrides onto an engine.
214
+ *
215
+ * Mirrors the Peek `upsertPricingOverridesActivityContexts` input verbatim. The
216
+ * caller owns all segmentation and ordering; the service sends this as-is.
217
+ */
218
+ interface UpsertOverridesInput {
219
+ /** The engine to write overrides to (its {@link CreatedPricingEngine.id}). */
220
+ engineId: string;
221
+ /**
222
+ * The date range the overrides apply to, as a PostgreSQL-style inclusive
223
+ * range string. For a single day, both ends are the same: `"[2025-07-04,2025-07-04]"`.
224
+ */
225
+ dateRange: string;
226
+ /** One entry per activity being written (or cleared). */
227
+ activities: ActivityOverrides[];
228
+ }
229
+ /**
230
+ * Convenience input for clearing all overrides across a set of activities for a
231
+ * date range. Equivalent to an {@link UpsertOverridesInput} whose every
232
+ * activity carries `overrides: []`.
233
+ */
234
+ interface ClearOverridesInput {
235
+ /** The engine to clear overrides on. */
236
+ engineId: string;
237
+ /** The date range to clear, same format as {@link UpsertOverridesInput.dateRange}. */
238
+ dateRange: string;
239
+ /** The activity ids to clear. Recover these from a prior sync's payload. */
240
+ activityIds: string[];
241
+ }
242
+ /**
243
+ * A ticket price override as **resolved** by Peek, discriminated by `mode`.
244
+ *
245
+ * This normalizes Peek's GraphQL union (a `price` object vs a bare
246
+ * `percentageAdjustment`) into the same `mode`-tagged shape used on input.
247
+ */
248
+ type ResolvedOverride = {
249
+ mode: "fixed";
250
+ /** The resolved replacement price. */
251
+ price: PricingMoney;
252
+ } | {
253
+ mode: "percentage";
254
+ /** The resolved percentage adjustment as a decimal string. */
255
+ percentageAdjustment: string;
256
+ };
257
+ /** A single ticket's resolved override within a returned context. */
258
+ interface ResolvedResourceOption {
259
+ /** The ticket (resourceOption) this override resolved for. */
260
+ resourceOption: PricingNamedRef;
261
+ /** The resolved fixed or percentage override. */
262
+ override: ResolvedOverride;
263
+ }
264
+ /** A single resolved override entry within a returned activity context. */
265
+ interface ResolvedPricingOverride {
266
+ /** The override's precedence index as stored by Peek. */
267
+ order: number;
268
+ /** The resolved per-ticket overrides. */
269
+ resourceOptions: ResolvedResourceOption[];
270
+ /**
271
+ * The filters gating this override, normalized to the same shape as the
272
+ * {@link PricingOverrideFilter} used on input.
273
+ */
274
+ filters: PricingOverrideFilter[];
275
+ }
276
+ /**
277
+ * The resolved pricing state for one activity on one date, as returned by an
278
+ * upsert or clear. Useful as an audit record of exactly what Peek stored.
279
+ */
280
+ interface PricingActivityContext {
281
+ /** The date the context applies to (ISO `YYYY-MM-DD`). */
282
+ date: string;
283
+ /** The activity the overrides belong to. */
284
+ activity: PricingNamedRef;
285
+ /** The engine the overrides live under. */
286
+ engine: PricingNamedRef;
287
+ /** The resolved overrides (empty when the date was cleared). */
288
+ overrides: ResolvedPricingOverride[];
289
+ }
290
+ /** The result of an upsert or clear: the resolved contexts Peek returned. */
291
+ interface UpsertOverridesResult {
292
+ /** One entry per activity written or cleared in the request. */
293
+ activityContexts: PricingActivityContext[];
294
+ }
295
+
55
296
  /**
56
297
  * The clean, transport-agnostic data model for a Peek Pro product.
57
298
  *
@@ -59,6 +300,7 @@ declare class GraphQLClient {
59
300
  * decoupled from the underlying Peek GraphQL schema — the raw GraphQL types and
60
301
  * the conversion logic live inside the package and are never exposed here.
61
302
  */
303
+
62
304
  /**
63
305
  * A bookable product in a Peek Pro account.
64
306
  *
@@ -95,6 +337,14 @@ interface Product {
95
337
  * Add-ons default to white (`"#FFFFFF"`). Empty string when no color is set.
96
338
  */
97
339
  color: string;
340
+ /**
341
+ * ISO 4217 currency code the activity prices in (e.g. `"USD"`).
342
+ *
343
+ * Populated for activities and rentals; empty string for add-ons (which carry
344
+ * no currency of their own) and when Peek reports none. Consumers building
345
+ * pricing overrides use this to set the currency on fixed-price adjustments.
346
+ */
347
+ currency: string;
98
348
  /**
99
349
  * The bookable sub-options of this product.
100
350
  *
@@ -109,6 +359,20 @@ interface ProductTicket {
109
359
  id: string;
110
360
  /** Human-readable name of the ticket / option. */
111
361
  name: string;
362
+ /**
363
+ * Lowest price this ticket can be sold at, across its price range.
364
+ *
365
+ * Populated for activity/rental resource options that expose a price range;
366
+ * `null` for add-on options (which carry no range) and when Peek reports none.
367
+ */
368
+ minPrice: PricingMoney | null;
369
+ /**
370
+ * Highest price this ticket can be sold at, across its price range.
371
+ *
372
+ * Populated for activity/rental resource options that expose a price range;
373
+ * `null` for add-on options (which carry no range) and when Peek reports none.
374
+ */
375
+ maxPrice: PricingMoney | null;
112
376
  }
113
377
  /** {@link Product.type} for standard bookable activities. */
114
378
  declare const ACTIVITY_PRODUCT_TYPE = "ACTIVITY";
@@ -1469,6 +1733,39 @@ declare class PromoCodeService {
1469
1733
  create(input: CreatePromoCodeInput): Promise<CreatedPromoCode>;
1470
1734
  }
1471
1735
 
1736
+ declare class PricingService {
1737
+ private readonly client;
1738
+ constructor(client: GraphQLClient);
1739
+ /**
1740
+ * Creates a pricing engine. Store the returned id and reuse it on every
1741
+ * subsequent override upsert. Throws on an InvalidDataError from Peek.
1742
+ */
1743
+ createEngine(input: CreateEngineInput): Promise<CreatedPricingEngine>;
1744
+ /**
1745
+ * Updates a pricing engine's name and/or activity scope. Throws on an
1746
+ * InvalidDataError or NotFoundError from Peek.
1747
+ */
1748
+ updateEngine(input: UpdateEngineInput): Promise<PricingEngine>;
1749
+ /**
1750
+ * Deletes a pricing engine. Idempotent — resolves whether the engine existed
1751
+ * or was already gone (Peek's NotFoundError is treated as success).
1752
+ */
1753
+ deleteEngine(engineId: string): Promise<void>;
1754
+ /**
1755
+ * Upserts pricing overrides for the engine and date range in `input`. Returns
1756
+ * the resolved contexts Peek stored. Throws on an InvalidDataError from Peek.
1757
+ */
1758
+ upsertOverrides(input: UpsertOverridesInput): Promise<UpsertOverridesResult>;
1759
+ /**
1760
+ * Clears all overrides for the given activities across a date range. This is
1761
+ * an upsert with empty overrides — never clear by omitting an activity.
1762
+ */
1763
+ clearOverrides(input: ClearOverridesInput): Promise<UpsertOverridesResult>;
1764
+ private sendUpsert;
1765
+ private validateUpsertInput;
1766
+ private validateResourceOption;
1767
+ }
1768
+
1472
1769
  /**
1473
1770
  * Platform that embedded the app for this session. Verification is
1474
1771
  * brand-agnostic — one peek-auth JWT is minted for every platform — so this
@@ -1557,6 +1854,7 @@ declare class PeekAccessService {
1557
1854
  private timeslotService?;
1558
1855
  private resellerService?;
1559
1856
  private promoCodeService?;
1857
+ private pricingService?;
1560
1858
  private dailyNoteService?;
1561
1859
  private availabilityService?;
1562
1860
  private membershipService?;
@@ -1613,6 +1911,11 @@ declare class PeekAccessService {
1613
1911
  * authenticated transport. The instance is created lazily and reused.
1614
1912
  */
1615
1913
  getPromoCodeService(): PromoCodeService;
1914
+ /**
1915
+ * Returns the {@link PricingService} for this install, bound to the shared
1916
+ * authenticated transport. The instance is created lazily and reused.
1917
+ */
1918
+ getPricingService(): PricingService;
1616
1919
  /**
1617
1920
  * Returns the {@link DailyNoteService} for this install, bound to the shared
1618
1921
  * authenticated transport. The instance is created lazily and reused.
@@ -1668,6 +1971,16 @@ declare class PeekAccessService {
1668
1971
  getAllPromoCodes(): Promise<PromoCode[]>;
1669
1972
  /** Create a promo code. Delegates to {@link PromoCodeService.create}. */
1670
1973
  createPromoCode(input: CreatePromoCodeInput): Promise<CreatedPromoCode>;
1974
+ /** Create a pricing engine. Delegates to {@link PricingService.createEngine}. */
1975
+ createPricingEngine(input: CreateEngineInput): Promise<CreatedPricingEngine>;
1976
+ /** Update a pricing engine. Delegates to {@link PricingService.updateEngine}. */
1977
+ updatePricingEngine(input: UpdateEngineInput): Promise<PricingEngine>;
1978
+ /** Delete a pricing engine (idempotent). Delegates to {@link PricingService.deleteEngine}. */
1979
+ deletePricingEngine(engineId: string): Promise<void>;
1980
+ /** Upsert pricing overrides. Delegates to {@link PricingService.upsertOverrides}. */
1981
+ upsertPricingOverrides(input: UpsertOverridesInput): Promise<UpsertOverridesResult>;
1982
+ /** Clear pricing overrides for a set of activities. Delegates to {@link PricingService.clearOverrides}. */
1983
+ clearPricingOverrides(input: ClearOverridesInput): Promise<UpsertOverridesResult>;
1671
1984
  /** Today's daily note. Delegates to {@link DailyNoteService.getToday}. */
1672
1985
  getDailyNoteToday(): Promise<DailyNote | null>;
1673
1986
  /** Update today's daily note. Delegates to {@link DailyNoteService.update}. */
@@ -2129,4 +2442,4 @@ declare class AcmeApiError extends Error {
2129
2442
  constructor(statusCode: number, body: unknown, message?: string);
2130
2443
  }
2131
2444
 
2132
- 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 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, PiiAccessDisabledError, 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 };
2445
+ 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, CngProductService, type CreateBookingGuest, type CreateBookingInput, type CreateBookingTicket, type CreateEngineInput, type CreatePromoCodeInput, type CreatedBooking, type CreatedPricingEngine, 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, PiiAccessDisabledError, type Price, type PricingActivityContext, type PricingEngine, type PricingMoney, type PricingNamedRef, type PricingOverride, type PricingOverrideFilter, PricingService, 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 ResolvedOverride, type ResolvedPricingOverride, type ResolvedResourceOption, type Resource, type ResourceOptionOverride, type ResourceOptionQuantity, type ResourcePool, type ResourcePoolAccountUser, type ResourcePoolAssignment, type ResourcePoolMode, ResourcePoolService, type Review, ReviewService, type Ticket, type Timeslot, type TimeslotFilter, TimeslotService, type UpdateEngineInput, type UpdateTimeslotResult, type UpsertOverridesInput, type UpsertOverridesResult, type Waiver, noopLogger, parseBookingWebhook, parseWaiverWebhook };