@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.cjs +877 -696
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +195 -26
- package/dist/index.d.ts +195 -26
- package/dist/index.js +876 -698
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3,11 +3,11 @@ import { randomUUID } from 'crypto';
|
|
|
3
3
|
|
|
4
4
|
// src/peek-access-service.ts
|
|
5
5
|
|
|
6
|
-
// src/internal/gateway-endpoints.ts
|
|
6
|
+
// src/internal/peek/gateway-endpoints.ts
|
|
7
7
|
var SALES_ENDPOINT = "sales";
|
|
8
8
|
var V2_EXTENDABLE_SLUG = "peek_backoffice_api-v1";
|
|
9
9
|
|
|
10
|
-
// src/internal/account-users/account-user-converter.ts
|
|
10
|
+
// src/internal/peek/account-users/account-user-converter.ts
|
|
11
11
|
var ACTIVE_STATUS = "ACTIVE";
|
|
12
12
|
function fromAccountUserNode(node) {
|
|
13
13
|
if (!node || node.status !== ACTIVE_STATUS) {
|
|
@@ -35,7 +35,7 @@ function fromAccountUserNodes(nodes) {
|
|
|
35
35
|
return users;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
// src/internal/account-users/account-user-queries.ts
|
|
38
|
+
// src/internal/peek/account-users/account-user-queries.ts
|
|
39
39
|
var USER_QUERY = `
|
|
40
40
|
query Sales($first: Int, $after: String) {
|
|
41
41
|
accountUsers(first: $first, after: $after) {
|
|
@@ -81,7 +81,7 @@ var USER_BY_FILTER_QUERY = `
|
|
|
81
81
|
}
|
|
82
82
|
`;
|
|
83
83
|
|
|
84
|
-
// src/internal/account-users/account-user-service.ts
|
|
84
|
+
// src/internal/peek/account-users/account-user-service.ts
|
|
85
85
|
var DEFAULT_PAGE_SIZE = 50;
|
|
86
86
|
var AccountUserService = class {
|
|
87
87
|
constructor(client, options = {}) {
|
|
@@ -135,7 +135,7 @@ var AccountUserService = class {
|
|
|
135
135
|
}
|
|
136
136
|
};
|
|
137
137
|
|
|
138
|
-
// src/internal/availability/availability-queries.ts
|
|
138
|
+
// src/internal/peek/availability/availability-queries.ts
|
|
139
139
|
var AVAILABILITY_TIMES_QUERY = `
|
|
140
140
|
query Sales($activityId: ID!, $resourceOptionQuantities: [ResourceOptionQuantityData!]!, $date: Date!) {
|
|
141
141
|
availabilityTimes(activityId: $activityId, resourceOptionQuantities: $resourceOptionQuantities, date: $date) {
|
|
@@ -160,7 +160,7 @@ var AVAILABILITY_TIMES_QUERY = `
|
|
|
160
160
|
}
|
|
161
161
|
`;
|
|
162
162
|
|
|
163
|
-
// src/internal/availability/availability-service.ts
|
|
163
|
+
// src/internal/peek/availability/availability-service.ts
|
|
164
164
|
var AvailabilityService = class {
|
|
165
165
|
constructor(client) {
|
|
166
166
|
this.client = client;
|
|
@@ -181,13 +181,375 @@ var AvailabilityService = class {
|
|
|
181
181
|
}
|
|
182
182
|
};
|
|
183
183
|
|
|
184
|
-
// src/models/product.ts
|
|
184
|
+
// src/models/peek/product.ts
|
|
185
185
|
var ACTIVITY_PRODUCT_TYPE = "ACTIVITY";
|
|
186
186
|
var RENTAL_PRODUCT_TYPE = "RENTAL";
|
|
187
187
|
var ADD_ON_PRODUCT_TYPE = "ADD-ON";
|
|
188
188
|
|
|
189
|
-
// src/internal/bookings/booking-
|
|
189
|
+
// src/internal/peek/bookings/booking-queries.ts
|
|
190
|
+
var SEARCH_BY_PURCHASE_DATE = "purchaseDate";
|
|
191
|
+
var SEARCH_BY_ACTIVITY_DATE = "activityDate";
|
|
192
|
+
function normalizeBookingId(bookingId) {
|
|
193
|
+
return bookingId.toLowerCase().replace(/-/g, "_");
|
|
194
|
+
}
|
|
195
|
+
var guestFields = `
|
|
196
|
+
id
|
|
197
|
+
name
|
|
198
|
+
country
|
|
199
|
+
dateOfBirth
|
|
200
|
+
email
|
|
201
|
+
isGdpr
|
|
202
|
+
isParticipant
|
|
203
|
+
optinSms
|
|
204
|
+
optinMarketing
|
|
205
|
+
phone
|
|
206
|
+
postalCode
|
|
207
|
+
fieldResponses {
|
|
208
|
+
id
|
|
209
|
+
text
|
|
210
|
+
fieldLocation {
|
|
211
|
+
field {
|
|
212
|
+
name
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
`;
|
|
217
|
+
var bookingGuestsFields = `
|
|
218
|
+
bookingGuests {
|
|
219
|
+
${guestFields}
|
|
220
|
+
}
|
|
221
|
+
primaryGuest {
|
|
222
|
+
${guestFields}
|
|
223
|
+
}
|
|
224
|
+
`;
|
|
225
|
+
var bookingQueryFields = `
|
|
226
|
+
displayId
|
|
227
|
+
id
|
|
228
|
+
primaryGuest {
|
|
229
|
+
name
|
|
230
|
+
email
|
|
231
|
+
phone
|
|
232
|
+
optinMarketing
|
|
233
|
+
optinSms
|
|
234
|
+
isGdpr
|
|
235
|
+
postalCode
|
|
236
|
+
}
|
|
237
|
+
activitySnapshot {
|
|
238
|
+
type
|
|
239
|
+
name
|
|
240
|
+
id
|
|
241
|
+
}
|
|
242
|
+
ticketQuantities {
|
|
243
|
+
quantity
|
|
244
|
+
resourceOptionSnapshot {
|
|
245
|
+
name
|
|
246
|
+
id
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
reservationStatus
|
|
250
|
+
checkinStatus
|
|
251
|
+
returnStatus
|
|
252
|
+
fulfillmentStatusOverride {
|
|
253
|
+
status
|
|
254
|
+
}
|
|
255
|
+
timeSnapshot {
|
|
256
|
+
id
|
|
257
|
+
legacyId
|
|
258
|
+
}
|
|
259
|
+
purchasedAt
|
|
260
|
+
purchasedAtUtc
|
|
261
|
+
startsAt
|
|
262
|
+
startsAtUtc
|
|
263
|
+
endsAt
|
|
264
|
+
endsAtUtc
|
|
265
|
+
availabilityTimeId
|
|
266
|
+
bookingPortalUrl
|
|
267
|
+
operatorNotes
|
|
268
|
+
value {
|
|
269
|
+
total {
|
|
270
|
+
formatted
|
|
271
|
+
amount
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
balance {
|
|
275
|
+
total {
|
|
276
|
+
amount
|
|
277
|
+
formatted
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
tips {
|
|
281
|
+
price {
|
|
282
|
+
amount
|
|
283
|
+
formatted
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
order {
|
|
287
|
+
displayId
|
|
288
|
+
id
|
|
289
|
+
promoCodes {
|
|
290
|
+
code
|
|
291
|
+
}
|
|
292
|
+
channelSnapshot {
|
|
293
|
+
id
|
|
294
|
+
name
|
|
295
|
+
agent {
|
|
296
|
+
name
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
initialQuote {
|
|
300
|
+
source {
|
|
301
|
+
actor {
|
|
302
|
+
app
|
|
303
|
+
name
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
questionAnswers {
|
|
309
|
+
answer
|
|
310
|
+
questionText
|
|
311
|
+
questionLocationSnapshot {
|
|
312
|
+
latitude
|
|
313
|
+
longitude
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
tickets {
|
|
317
|
+
questionAnswers {
|
|
318
|
+
answer
|
|
319
|
+
questionText
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
resourcePoolAssignments {
|
|
323
|
+
quantity
|
|
324
|
+
resourcePool {
|
|
325
|
+
name
|
|
326
|
+
shortName
|
|
327
|
+
resources {
|
|
328
|
+
name
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
resourceAssignments {
|
|
332
|
+
resource {
|
|
333
|
+
id
|
|
334
|
+
name
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
`;
|
|
339
|
+
var PRICE_BREAKDOWN_FIELDS = `
|
|
340
|
+
convenienceFee { amount formatted }
|
|
341
|
+
deposit { amount formatted }
|
|
342
|
+
discount { amount formatted }
|
|
343
|
+
discountedPrice { amount formatted }
|
|
344
|
+
fees { amount formatted }
|
|
345
|
+
flatPartnerFee { amount formatted }
|
|
346
|
+
price { amount formatted }
|
|
347
|
+
retailPrice { amount formatted }
|
|
348
|
+
taxes { amount formatted }
|
|
349
|
+
tips { amount formatted }
|
|
350
|
+
`;
|
|
351
|
+
var TICKET_VALUE_FIELDS = `
|
|
352
|
+
value {
|
|
353
|
+
price { amount formatted }
|
|
354
|
+
total { amount formatted }
|
|
355
|
+
}
|
|
356
|
+
`;
|
|
357
|
+
function buildBookingsListingQuery(includeGuests, includePriceBreakdown) {
|
|
358
|
+
const guestsSection = includeGuests ? bookingGuestsFields : "";
|
|
359
|
+
const fields = includePriceBreakdown ? bookingQueryFields.replace("value {", `value { ${PRICE_BREAKDOWN_FIELDS}`).replace("ticketQuantities {", `ticketQuantities { ${TICKET_VALUE_FIELDS}`) : bookingQueryFields;
|
|
360
|
+
return `
|
|
361
|
+
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
362
|
+
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
363
|
+
pageInfo { endCursor hasNextPage }
|
|
364
|
+
edges {
|
|
365
|
+
node {
|
|
366
|
+
... on Booking {
|
|
367
|
+
${fields}
|
|
368
|
+
${guestsSection}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
`;
|
|
375
|
+
}
|
|
376
|
+
var BOOKING_GUESTS_QUERY = `
|
|
377
|
+
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
378
|
+
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
379
|
+
pageInfo { endCursor hasNextPage }
|
|
380
|
+
edges {
|
|
381
|
+
node {
|
|
382
|
+
... on Booking {
|
|
383
|
+
displayId
|
|
384
|
+
id
|
|
385
|
+
${bookingGuestsFields}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
`;
|
|
392
|
+
var BOOKING_PAYMENTS_ON_FILE_QUERY = `
|
|
393
|
+
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
394
|
+
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
395
|
+
pageInfo { endCursor hasNextPage }
|
|
396
|
+
edges {
|
|
397
|
+
node {
|
|
398
|
+
order {
|
|
399
|
+
payments {
|
|
400
|
+
id
|
|
401
|
+
paymentSource { id }
|
|
402
|
+
appliedAt
|
|
403
|
+
currentAmount { amount currency }
|
|
404
|
+
refundableAmount { amount currency }
|
|
405
|
+
}
|
|
406
|
+
id
|
|
407
|
+
displayId
|
|
408
|
+
paymentSources { description type id }
|
|
409
|
+
}
|
|
410
|
+
... on Booking {
|
|
411
|
+
displayId
|
|
412
|
+
id
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
`;
|
|
419
|
+
var UPDATE_OPERATOR_NOTES_MUTATION = `
|
|
420
|
+
mutation Account($input: UpdateOperatorNotesForBookingInput!) {
|
|
421
|
+
updateOperatorNotesForBooking(input: $input) {
|
|
422
|
+
booking { operatorNotes }
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
`;
|
|
426
|
+
var UPDATE_BOOKING_CHECKIN_MUTATION = `
|
|
427
|
+
mutation Account($input: UpdateBookingCheckInInput!) {
|
|
428
|
+
updateBookingCheckIn(input: $input) {
|
|
429
|
+
booking { checkinStatus }
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
`;
|
|
433
|
+
var CANCEL_BOOKING_MUTATION = `
|
|
434
|
+
mutation Account($input: CancelBookingInput!) {
|
|
435
|
+
cancelBooking(input: $input) {
|
|
436
|
+
booking { id displayId reservationStatus }
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
`;
|
|
440
|
+
var APPLY_PAYMENT_TO_ORDER_MUTATION = `
|
|
441
|
+
mutation ApplyPaymentToOrder($input: ApplyPaymentToOrderInput!) {
|
|
442
|
+
applyPaymentToOrder(input: $input) {
|
|
443
|
+
transactionId
|
|
444
|
+
errors { code detail value }
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
`;
|
|
448
|
+
var APPLY_REFUND_TO_ORDER_MUTATION = `
|
|
449
|
+
mutation ApplyRefundToOrder($input: ApplyRefundToOrderInput!) {
|
|
450
|
+
applyRefundToOrder(input: $input) {
|
|
451
|
+
transactionId
|
|
452
|
+
errors { code detail value }
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
`;
|
|
456
|
+
var CREATE_INVOICE_LINK_MUTATION = `
|
|
457
|
+
mutation CreateInvoiceLink($input: CreateInvoiceLinkInput!) {
|
|
458
|
+
createInvoiceLink(input: $input) {
|
|
459
|
+
invoiceLink { status url }
|
|
460
|
+
errors { code detail value __typename }
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
`;
|
|
464
|
+
var CREATE_QUOTE_FROM_ORDER_MUTATION = `
|
|
465
|
+
mutation CreateQuoteFromOrder($input: CreateQuoteFromOrderInput!) {
|
|
466
|
+
createQuoteFromOrder(input: $input) {
|
|
467
|
+
errors { detail value code }
|
|
468
|
+
quote {
|
|
469
|
+
id
|
|
470
|
+
saleQuotes { refid reservationStatus }
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
`;
|
|
475
|
+
var UPDATE_QUOTE_V2_MUTATION = `
|
|
476
|
+
mutation UpdateQuoteV2($input: UpdateQuoteV2Input!) {
|
|
477
|
+
updateQuoteV2(input: $input) {
|
|
478
|
+
errors { detail value code }
|
|
479
|
+
quote { id }
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
`;
|
|
483
|
+
var AMEND_ORDER_MUTATION = `
|
|
484
|
+
mutation AmendOrder($input: AmendOrderInput!) {
|
|
485
|
+
amendOrder(input: $input) {
|
|
486
|
+
errors { code detail value }
|
|
487
|
+
order { id }
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
`;
|
|
491
|
+
var CREATE_QUOTE_V2_MUTATION = `
|
|
492
|
+
mutation CreateQuoteV2($input: CreateQuoteV2Input!) {
|
|
493
|
+
createQuoteV2(input: $input) {
|
|
494
|
+
errors { detail value code }
|
|
495
|
+
quote { id }
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
`;
|
|
499
|
+
var CREATE_ORDER_FROM_QUOTE_MUTATION = `
|
|
500
|
+
mutation CreateOrderFromQuote($input: CreateOrderFromQuoteInput!) {
|
|
501
|
+
createOrderFromQuote(input: $input) {
|
|
502
|
+
errors { code detail value }
|
|
503
|
+
order {
|
|
504
|
+
id
|
|
505
|
+
sales {
|
|
506
|
+
id
|
|
507
|
+
displayId
|
|
508
|
+
... on Booking {
|
|
509
|
+
balance { total { amount currency formatted } }
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
`;
|
|
516
|
+
function buildBookingsVariables(params) {
|
|
517
|
+
const filter = {};
|
|
518
|
+
const bookingFilter = {};
|
|
519
|
+
if (params.bookingId) {
|
|
520
|
+
bookingFilter.ids = [normalizeBookingId(params.bookingId)];
|
|
521
|
+
} else if (params.timeslotId) {
|
|
522
|
+
bookingFilter.timeslotRefid = params.timeslotId;
|
|
523
|
+
} else {
|
|
524
|
+
if (params.searchBy === SEARCH_BY_ACTIVITY_DATE) {
|
|
525
|
+
bookingFilter.overlapsRange = `[${params.startDateTime},${params.endDateTime}]`;
|
|
526
|
+
} else if (params.searchBy === SEARCH_BY_PURCHASE_DATE) {
|
|
527
|
+
filter.purchasedAtRangeUtc = `[${params.startDateTime},${params.endDateTime}]`;
|
|
528
|
+
}
|
|
529
|
+
if (params.productId) {
|
|
530
|
+
bookingFilter.activityIds = [params.productId];
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
if (params.email) {
|
|
534
|
+
filter.primaryGuestEmail = params.email;
|
|
535
|
+
}
|
|
536
|
+
if (params.searchString && params.searchString.length > 0) {
|
|
537
|
+
filter.searchString = params.searchString;
|
|
538
|
+
}
|
|
539
|
+
if (Object.keys(bookingFilter).length > 0) {
|
|
540
|
+
filter.bookingFilter = bookingFilter;
|
|
541
|
+
}
|
|
542
|
+
return {
|
|
543
|
+
first: params.pageSize,
|
|
544
|
+
after: params.after,
|
|
545
|
+
orderBy: { direction: "ASC", field: "STARTS_AT" },
|
|
546
|
+
filter
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
// src/internal/peek/bookings/booking-converter.ts
|
|
190
551
|
var UNKNOWN = "unknown";
|
|
552
|
+
var PEEK_PRO_DEEP_LINK_BASE = "http://pro-app.peek.com/-/order";
|
|
191
553
|
var SOURCE_SOURCE_MAP = {
|
|
192
554
|
APP_REGISTRY: "app",
|
|
193
555
|
BOOKING_IMPORTER_FUTURE: "importer",
|
|
@@ -303,6 +665,7 @@ function fromBookingNode(node, includeGuests = false, includePriceBreakdown = fa
|
|
|
303
665
|
resellerId: data.order?.channelSnapshot?.id || null,
|
|
304
666
|
resellerName: resellerNameFromChannelSnapshot(data.order?.channelSnapshot),
|
|
305
667
|
orderId: data.order?.id || "",
|
|
668
|
+
peekProBookingDeepLink: buildPeekProBookingDeepLink(data.order?.id, data.id),
|
|
306
669
|
convenienceFee: includePriceBreakdown ? mapPrice(data.value?.convenienceFee) : void 0,
|
|
307
670
|
deposit: includePriceBreakdown ? mapPrice(data.value?.deposit) : void 0,
|
|
308
671
|
discount: includePriceBreakdown ? mapPrice(data.value?.discount) : void 0,
|
|
@@ -329,619 +692,262 @@ function convertGuests(data) {
|
|
|
329
692
|
guests.push(mapGuestNode(primaryGuestNode, true));
|
|
330
693
|
}
|
|
331
694
|
return guests;
|
|
332
|
-
}
|
|
333
|
-
function mapGuestNode(guestNode, isPrimary) {
|
|
334
|
-
const fieldResponses = Array.isArray(guestNode.fieldResponses) ? guestNode.fieldResponses : [];
|
|
335
|
-
const metadata = fieldResponses.map((response) => ({
|
|
336
|
-
id: response.id,
|
|
337
|
-
name: response.fieldLocation?.field?.name ?? "",
|
|
338
|
-
value: response.text ?? ""
|
|
339
|
-
}));
|
|
340
|
-
return {
|
|
341
|
-
id: guestNode.id,
|
|
342
|
-
name: guestNode.name ?? null,
|
|
343
|
-
country: guestNode.country ?? null,
|
|
344
|
-
dateOfBirth: guestNode.dateOfBirth ? new Date(guestNode.dateOfBirth) : null,
|
|
345
|
-
phone: guestNode.phone ?? null,
|
|
346
|
-
email: guestNode.email ?? null,
|
|
347
|
-
isGdpr: Boolean(guestNode.isGdpr),
|
|
348
|
-
isParticipant: Boolean(guestNode.isParticipant),
|
|
349
|
-
isPrimary,
|
|
350
|
-
optinSms: Boolean(guestNode.optinSms),
|
|
351
|
-
optinMarketing: Boolean(guestNode.optinMarketing),
|
|
352
|
-
postalCode: guestNode.postalCode ?? null,
|
|
353
|
-
metadata
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
function sourceFromApp(app) {
|
|
357
|
-
if (!app) return UNKNOWN;
|
|
358
|
-
return SOURCE_SOURCE_MAP[app] ?? UNKNOWN;
|
|
359
|
-
}
|
|
360
|
-
function sourceDescriptionFromApp(app) {
|
|
361
|
-
if (!app) return UNKNOWN;
|
|
362
|
-
return SOURCE_DESC_MAP[app] ?? UNKNOWN;
|
|
363
|
-
}
|
|
364
|
-
function resellerNameFromChannelSnapshot(channelSnapshot) {
|
|
365
|
-
if (!channelSnapshot) return null;
|
|
366
|
-
let out = channelSnapshot.name ?? "";
|
|
367
|
-
if (channelSnapshot.agent?.name) {
|
|
368
|
-
out += " - " + channelSnapshot.agent.name;
|
|
369
|
-
}
|
|
370
|
-
return out;
|
|
371
|
-
}
|
|
372
|
-
function ticketsToTicketArray(ticketQuantities, includePriceBreakdown) {
|
|
373
|
-
if (!ticketQuantities || ticketQuantities.length === 0) return [];
|
|
374
|
-
return ticketQuantities.map((ticket) => ({
|
|
375
|
-
name: ticket.resourceOptionSnapshot?.name || "Unknown",
|
|
376
|
-
quantity: ticket.quantity || 0,
|
|
377
|
-
ticketId: ticket.resourceOptionSnapshot?.id || "unknown",
|
|
378
|
-
listPrice: includePriceBreakdown ? mapPrice(ticket.value?.price) : void 0,
|
|
379
|
-
totalValue: includePriceBreakdown ? mapPrice(ticket.value?.total) : void 0
|
|
380
|
-
}));
|
|
381
|
-
}
|
|
382
|
-
function durationInMin(startsAt, endsAt) {
|
|
383
|
-
if (!startsAt || !endsAt) return 0;
|
|
384
|
-
const duration = new Date(endsAt).getTime() - new Date(startsAt).getTime();
|
|
385
|
-
return Math.floor(duration / 1e3 / 60);
|
|
386
|
-
}
|
|
387
|
-
function ticketQuantity(ticketQuantities) {
|
|
388
|
-
if (!ticketQuantities || ticketQuantities.length === 0) return 0;
|
|
389
|
-
return ticketQuantities.reduce((acc, ticket) => acc + (ticket.quantity || 0), 0);
|
|
390
|
-
}
|
|
391
|
-
function formatTickets(ticketQuantities) {
|
|
392
|
-
if (!ticketQuantities || ticketQuantities.length === 0) return "";
|
|
393
|
-
return ticketQuantities.map((ticket) => `${ticket.quantity || 0}x ${ticket.resourceOptionSnapshot?.name || "Unknown"}`).join(", ");
|
|
394
|
-
}
|
|
395
|
-
function mapResourcePoolAssignments(poolAssignments) {
|
|
396
|
-
if (!poolAssignments || poolAssignments.length === 0) return [];
|
|
397
|
-
return poolAssignments.flatMap(
|
|
398
|
-
(pool) => (pool.resourceAssignments ?? []).map((assignment) => ({
|
|
399
|
-
id: assignment.resource?.id || "",
|
|
400
|
-
name: assignment.resource?.name || ""
|
|
401
|
-
}))
|
|
402
|
-
);
|
|
403
|
-
}
|
|
404
|
-
function mapPrice(priceData) {
|
|
405
|
-
if (!priceData || !priceData.amount && !priceData.formatted) {
|
|
406
|
-
return void 0;
|
|
407
|
-
}
|
|
408
|
-
return {
|
|
409
|
-
amount: priceData.amount || "0",
|
|
410
|
-
display: priceData.formatted || ""
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
// src/internal/bookings/booking-guest-converter.ts
|
|
415
|
-
function fromBookingGuestsResponse(response) {
|
|
416
|
-
const firstEdge = (response?.sales?.edges ?? [])[0];
|
|
417
|
-
if (!firstEdge) {
|
|
418
|
-
return [];
|
|
419
|
-
}
|
|
420
|
-
const bookingNode = firstEdge.node;
|
|
421
|
-
const primaryGuestNode = bookingNode.primaryGuest;
|
|
422
|
-
const bookingGuestsNodes = Array.isArray(bookingNode.bookingGuests) ? bookingNode.bookingGuests : [];
|
|
423
|
-
const primaryId = primaryGuestNode?.id;
|
|
424
|
-
const guests = [];
|
|
425
|
-
for (const guestNode of bookingGuestsNodes) {
|
|
426
|
-
guests.push(mapGuestNode(guestNode, primaryId ? guestNode.id === primaryId : false));
|
|
427
|
-
}
|
|
428
|
-
const hasPrimaryInGuests = primaryId ? bookingGuestsNodes.some((guest) => guest.id === primaryId) : false;
|
|
429
|
-
if (!hasPrimaryInGuests && primaryGuestNode) {
|
|
430
|
-
guests.push(mapGuestNode(primaryGuestNode, true));
|
|
431
|
-
}
|
|
432
|
-
return guests;
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
// src/internal/bookings/payments-on-file-converter.ts
|
|
436
|
-
function fromPaymentsOnFileResponse(response, bookingId) {
|
|
437
|
-
const firstEdge = (response?.sales?.edges ?? [])[0];
|
|
438
|
-
if (!firstEdge) {
|
|
439
|
-
return null;
|
|
440
|
-
}
|
|
441
|
-
const order = firstEdge.node.order;
|
|
442
|
-
const orderId = order?.id ?? "";
|
|
443
|
-
const rawPaymentSources = order?.paymentSources ?? [];
|
|
444
|
-
const rawPayments = order?.payments ?? [];
|
|
445
|
-
const paymentsBySourceId = /* @__PURE__ */ new Map();
|
|
446
|
-
for (const payment of rawPayments) {
|
|
447
|
-
const sourceId = payment.paymentSource?.id;
|
|
448
|
-
if (!sourceId) continue;
|
|
449
|
-
const mapped = {
|
|
450
|
-
id: payment.id,
|
|
451
|
-
paidAt: dateOnly(payment.appliedAt),
|
|
452
|
-
currentAmount: payment.currentAmount,
|
|
453
|
-
refundableAmount: payment.refundableAmount
|
|
454
|
-
};
|
|
455
|
-
const existing = paymentsBySourceId.get(sourceId);
|
|
456
|
-
if (existing) {
|
|
457
|
-
existing.push(mapped);
|
|
458
|
-
} else {
|
|
459
|
-
paymentsBySourceId.set(sourceId, [mapped]);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
const paymentsOnFile = rawPaymentSources.map((source) => {
|
|
463
|
-
const payments = paymentsBySourceId.get(source.id);
|
|
464
|
-
return {
|
|
465
|
-
description: source.description,
|
|
466
|
-
id: source.id,
|
|
467
|
-
type: source.type,
|
|
468
|
-
...payments ? { payments } : {}
|
|
469
|
-
};
|
|
470
|
-
});
|
|
471
|
-
return { bookingId, orderId, paymentsOnFile };
|
|
472
|
-
}
|
|
473
|
-
function dateOnly(iso) {
|
|
474
|
-
return iso.split("T")[0] ?? iso;
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
// src/internal/bookings/addon-queries.ts
|
|
478
|
-
var RESERVATION_STATUS_CONFIRMED = "CONFIRMED";
|
|
479
|
-
var ADDON_OPTION_STATUS_CANCELED = "CANCELED";
|
|
480
|
-
var SALES_ADDONS_PAGE_SIZE = 100;
|
|
481
|
-
var SALES_ADDONS_QUERY = `
|
|
482
|
-
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
483
|
-
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
484
|
-
pageInfo { endCursor hasNextPage }
|
|
485
|
-
edges {
|
|
486
|
-
node {
|
|
487
|
-
order { id displayId }
|
|
488
|
-
... on Booking {
|
|
489
|
-
displayId
|
|
490
|
-
id
|
|
491
|
-
refid
|
|
492
|
-
reservationStatus
|
|
493
|
-
items {
|
|
494
|
-
id
|
|
495
|
-
refid
|
|
496
|
-
value { total { amount currency formatted } }
|
|
497
|
-
reservationStatus
|
|
498
|
-
options {
|
|
499
|
-
refid
|
|
500
|
-
reservationStatus
|
|
501
|
-
price { amount currency formatted }
|
|
502
|
-
itemOptionSnapshot { id name }
|
|
503
|
-
itemSnapshot { id name }
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
`;
|
|
512
|
-
function buildSalesAddonsVariables(searchString) {
|
|
695
|
+
}
|
|
696
|
+
function mapGuestNode(guestNode, isPrimary) {
|
|
697
|
+
const fieldResponses = Array.isArray(guestNode.fieldResponses) ? guestNode.fieldResponses : [];
|
|
698
|
+
const metadata = fieldResponses.map((response) => ({
|
|
699
|
+
id: response.id,
|
|
700
|
+
name: response.fieldLocation?.field?.name ?? "",
|
|
701
|
+
value: response.text ?? ""
|
|
702
|
+
}));
|
|
513
703
|
return {
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
704
|
+
id: guestNode.id,
|
|
705
|
+
name: guestNode.name ?? null,
|
|
706
|
+
country: guestNode.country ?? null,
|
|
707
|
+
dateOfBirth: guestNode.dateOfBirth ? new Date(guestNode.dateOfBirth) : null,
|
|
708
|
+
phone: guestNode.phone ?? null,
|
|
709
|
+
email: guestNode.email ?? null,
|
|
710
|
+
isGdpr: Boolean(guestNode.isGdpr),
|
|
711
|
+
isParticipant: Boolean(guestNode.isParticipant),
|
|
712
|
+
isPrimary,
|
|
713
|
+
optinSms: Boolean(guestNode.optinSms),
|
|
714
|
+
optinMarketing: Boolean(guestNode.optinMarketing),
|
|
715
|
+
postalCode: guestNode.postalCode ?? null,
|
|
716
|
+
metadata
|
|
518
717
|
};
|
|
519
718
|
}
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
function parseSaleNode(node) {
|
|
524
|
-
const bookingId = node.id || "";
|
|
525
|
-
const displayId = node.displayId || "";
|
|
526
|
-
const orderId = node.order?.id || "";
|
|
527
|
-
const bookingQuoteRefid = node.refid || "";
|
|
528
|
-
const bookingQuoteReservationStatus = node.reservationStatus || "";
|
|
529
|
-
const items = Array.isArray(node.items) ? node.items : [];
|
|
530
|
-
return items.map((item) => {
|
|
531
|
-
const options = Array.isArray(item.options) ? item.options : [];
|
|
532
|
-
const addonItemOptions = options.map((opt) => ({
|
|
533
|
-
itemId: opt.itemSnapshot?.id || "",
|
|
534
|
-
optionId: opt.itemOptionSnapshot?.id || "",
|
|
535
|
-
itemName: opt.itemSnapshot?.name || "",
|
|
536
|
-
optionName: opt.itemOptionSnapshot?.name || "",
|
|
537
|
-
optionRefid: opt.refid || "",
|
|
538
|
-
optionReservationStatus: opt.reservationStatus || "",
|
|
539
|
-
itemReservationStatus: item.reservationStatus || "",
|
|
540
|
-
itemRefid: item.refid || ""
|
|
541
|
-
}));
|
|
542
|
-
return {
|
|
543
|
-
bookingId,
|
|
544
|
-
displayId,
|
|
545
|
-
orderId,
|
|
546
|
-
total: item.value?.total ?? null,
|
|
547
|
-
bookingQuoteRefid,
|
|
548
|
-
bookingQuoteReservationStatus,
|
|
549
|
-
addonItemOptions
|
|
550
|
-
};
|
|
551
|
-
});
|
|
719
|
+
function buildPeekProBookingDeepLink(orderId, bookingId) {
|
|
720
|
+
if (!orderId || !bookingId) return "";
|
|
721
|
+
return `${PEEK_PRO_DEEP_LINK_BASE}%2F${normalizeBookingId(orderId)}%3FsaleId=${normalizeBookingId(bookingId)}`;
|
|
552
722
|
}
|
|
553
|
-
function
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
return null;
|
|
557
|
-
}
|
|
558
|
-
const addonId = options[0].itemId;
|
|
559
|
-
const addonName = options[0].itemName;
|
|
560
|
-
if (options.some((opt) => opt.itemId !== addonId)) {
|
|
561
|
-
throw new Error(ERROR_INCONSISTENT_ADDON_ITEM_ID);
|
|
562
|
-
}
|
|
563
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
564
|
-
options.filter((opt) => opt.optionReservationStatus !== ADDON_OPTION_STATUS_CANCELED).forEach((opt) => {
|
|
565
|
-
const existing = grouped.get(opt.optionId);
|
|
566
|
-
if (existing) {
|
|
567
|
-
existing.quantity += 1;
|
|
568
|
-
} else {
|
|
569
|
-
grouped.set(opt.optionId, {
|
|
570
|
-
addonOptionId: opt.optionId,
|
|
571
|
-
addonOptionName: opt.optionName,
|
|
572
|
-
quantity: 1
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
});
|
|
576
|
-
const addonOptions = Array.from(grouped.values());
|
|
577
|
-
if (addonOptions.length === 0) {
|
|
578
|
-
return null;
|
|
579
|
-
}
|
|
580
|
-
return { addonId, addonName, total: item.total, addonOptions };
|
|
723
|
+
function sourceFromApp(app) {
|
|
724
|
+
if (!app) return UNKNOWN;
|
|
725
|
+
return SOURCE_SOURCE_MAP[app] ?? UNKNOWN;
|
|
581
726
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
var SEARCH_BY_ACTIVITY_DATE = "activityDate";
|
|
586
|
-
function normalizeBookingId(bookingId) {
|
|
587
|
-
return bookingId.toLowerCase().replace(/-/g, "_");
|
|
727
|
+
function sourceDescriptionFromApp(app) {
|
|
728
|
+
if (!app) return UNKNOWN;
|
|
729
|
+
return SOURCE_DESC_MAP[app] ?? UNKNOWN;
|
|
588
730
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
name
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
email
|
|
595
|
-
isGdpr
|
|
596
|
-
isParticipant
|
|
597
|
-
optinSms
|
|
598
|
-
optinMarketing
|
|
599
|
-
phone
|
|
600
|
-
postalCode
|
|
601
|
-
fieldResponses {
|
|
602
|
-
id
|
|
603
|
-
text
|
|
604
|
-
fieldLocation {
|
|
605
|
-
field {
|
|
606
|
-
name
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
`;
|
|
611
|
-
var bookingGuestsFields = `
|
|
612
|
-
bookingGuests {
|
|
613
|
-
${guestFields}
|
|
614
|
-
}
|
|
615
|
-
primaryGuest {
|
|
616
|
-
${guestFields}
|
|
617
|
-
}
|
|
618
|
-
`;
|
|
619
|
-
var bookingQueryFields = `
|
|
620
|
-
displayId
|
|
621
|
-
id
|
|
622
|
-
primaryGuest {
|
|
623
|
-
name
|
|
624
|
-
email
|
|
625
|
-
phone
|
|
626
|
-
optinMarketing
|
|
627
|
-
optinSms
|
|
628
|
-
isGdpr
|
|
629
|
-
postalCode
|
|
630
|
-
}
|
|
631
|
-
activitySnapshot {
|
|
632
|
-
type
|
|
633
|
-
name
|
|
634
|
-
id
|
|
635
|
-
}
|
|
636
|
-
ticketQuantities {
|
|
637
|
-
quantity
|
|
638
|
-
resourceOptionSnapshot {
|
|
639
|
-
name
|
|
640
|
-
id
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
reservationStatus
|
|
644
|
-
checkinStatus
|
|
645
|
-
returnStatus
|
|
646
|
-
fulfillmentStatusOverride {
|
|
647
|
-
status
|
|
648
|
-
}
|
|
649
|
-
timeSnapshot {
|
|
650
|
-
id
|
|
651
|
-
legacyId
|
|
652
|
-
}
|
|
653
|
-
purchasedAt
|
|
654
|
-
purchasedAtUtc
|
|
655
|
-
startsAt
|
|
656
|
-
startsAtUtc
|
|
657
|
-
endsAt
|
|
658
|
-
endsAtUtc
|
|
659
|
-
availabilityTimeId
|
|
660
|
-
bookingPortalUrl
|
|
661
|
-
operatorNotes
|
|
662
|
-
value {
|
|
663
|
-
total {
|
|
664
|
-
formatted
|
|
665
|
-
amount
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
balance {
|
|
669
|
-
total {
|
|
670
|
-
amount
|
|
671
|
-
formatted
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
tips {
|
|
675
|
-
price {
|
|
676
|
-
amount
|
|
677
|
-
formatted
|
|
678
|
-
}
|
|
731
|
+
function resellerNameFromChannelSnapshot(channelSnapshot) {
|
|
732
|
+
if (!channelSnapshot) return null;
|
|
733
|
+
let out = channelSnapshot.name ?? "";
|
|
734
|
+
if (channelSnapshot.agent?.name) {
|
|
735
|
+
out += " - " + channelSnapshot.agent.name;
|
|
679
736
|
}
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
737
|
+
return out;
|
|
738
|
+
}
|
|
739
|
+
function ticketsToTicketArray(ticketQuantities, includePriceBreakdown) {
|
|
740
|
+
if (!ticketQuantities || ticketQuantities.length === 0) return [];
|
|
741
|
+
return ticketQuantities.map((ticket) => ({
|
|
742
|
+
name: ticket.resourceOptionSnapshot?.name || "Unknown",
|
|
743
|
+
quantity: ticket.quantity || 0,
|
|
744
|
+
ticketId: ticket.resourceOptionSnapshot?.id || "unknown",
|
|
745
|
+
listPrice: includePriceBreakdown ? mapPrice(ticket.value?.price) : void 0,
|
|
746
|
+
totalValue: includePriceBreakdown ? mapPrice(ticket.value?.total) : void 0
|
|
747
|
+
}));
|
|
748
|
+
}
|
|
749
|
+
function durationInMin(startsAt, endsAt) {
|
|
750
|
+
if (!startsAt || !endsAt) return 0;
|
|
751
|
+
const duration = new Date(endsAt).getTime() - new Date(startsAt).getTime();
|
|
752
|
+
return Math.floor(duration / 1e3 / 60);
|
|
753
|
+
}
|
|
754
|
+
function ticketQuantity(ticketQuantities) {
|
|
755
|
+
if (!ticketQuantities || ticketQuantities.length === 0) return 0;
|
|
756
|
+
return ticketQuantities.reduce((acc, ticket) => acc + (ticket.quantity || 0), 0);
|
|
757
|
+
}
|
|
758
|
+
function formatTickets(ticketQuantities) {
|
|
759
|
+
if (!ticketQuantities || ticketQuantities.length === 0) return "";
|
|
760
|
+
return ticketQuantities.map((ticket) => `${ticket.quantity || 0}x ${ticket.resourceOptionSnapshot?.name || "Unknown"}`).join(", ");
|
|
761
|
+
}
|
|
762
|
+
function mapResourcePoolAssignments(poolAssignments) {
|
|
763
|
+
if (!poolAssignments || poolAssignments.length === 0) return [];
|
|
764
|
+
return poolAssignments.flatMap(
|
|
765
|
+
(pool) => (pool.resourceAssignments ?? []).map((assignment) => ({
|
|
766
|
+
id: assignment.resource?.id || "",
|
|
767
|
+
name: assignment.resource?.name || ""
|
|
768
|
+
}))
|
|
769
|
+
);
|
|
770
|
+
}
|
|
771
|
+
function mapPrice(priceData) {
|
|
772
|
+
if (!priceData || !priceData.amount && !priceData.formatted) {
|
|
773
|
+
return void 0;
|
|
701
774
|
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
775
|
+
return {
|
|
776
|
+
amount: priceData.amount || "0",
|
|
777
|
+
display: priceData.formatted || ""
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// src/internal/peek/bookings/booking-guest-converter.ts
|
|
782
|
+
function fromBookingGuestsResponse(response) {
|
|
783
|
+
const firstEdge = (response?.sales?.edges ?? [])[0];
|
|
784
|
+
if (!firstEdge) {
|
|
785
|
+
return [];
|
|
709
786
|
}
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
787
|
+
const bookingNode = firstEdge.node;
|
|
788
|
+
const primaryGuestNode = bookingNode.primaryGuest;
|
|
789
|
+
const bookingGuestsNodes = Array.isArray(bookingNode.bookingGuests) ? bookingNode.bookingGuests : [];
|
|
790
|
+
const primaryId = primaryGuestNode?.id;
|
|
791
|
+
const guests = [];
|
|
792
|
+
for (const guestNode of bookingGuestsNodes) {
|
|
793
|
+
guests.push(mapGuestNode(guestNode, primaryId ? guestNode.id === primaryId : false));
|
|
715
794
|
}
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
name
|
|
720
|
-
shortName
|
|
721
|
-
resources {
|
|
722
|
-
name
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
resourceAssignments {
|
|
726
|
-
resource {
|
|
727
|
-
id
|
|
728
|
-
name
|
|
729
|
-
}
|
|
730
|
-
}
|
|
795
|
+
const hasPrimaryInGuests = primaryId ? bookingGuestsNodes.some((guest) => guest.id === primaryId) : false;
|
|
796
|
+
if (!hasPrimaryInGuests && primaryGuestNode) {
|
|
797
|
+
guests.push(mapGuestNode(primaryGuestNode, true));
|
|
731
798
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
price { amount formatted }
|
|
741
|
-
retailPrice { amount formatted }
|
|
742
|
-
taxes { amount formatted }
|
|
743
|
-
tips { amount formatted }
|
|
744
|
-
`;
|
|
745
|
-
var TICKET_VALUE_FIELDS = `
|
|
746
|
-
value {
|
|
747
|
-
price { amount formatted }
|
|
748
|
-
total { amount formatted }
|
|
799
|
+
return guests;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
// src/internal/peek/bookings/payments-on-file-converter.ts
|
|
803
|
+
function fromPaymentsOnFileResponse(response, bookingId) {
|
|
804
|
+
const firstEdge = (response?.sales?.edges ?? [])[0];
|
|
805
|
+
if (!firstEdge) {
|
|
806
|
+
return null;
|
|
749
807
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
const
|
|
753
|
-
const
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
808
|
+
const order = firstEdge.node.order;
|
|
809
|
+
const orderId = order?.id ?? "";
|
|
810
|
+
const rawPaymentSources = order?.paymentSources ?? [];
|
|
811
|
+
const rawPayments = order?.payments ?? [];
|
|
812
|
+
const paymentsBySourceId = /* @__PURE__ */ new Map();
|
|
813
|
+
for (const payment of rawPayments) {
|
|
814
|
+
const sourceId = payment.paymentSource?.id;
|
|
815
|
+
if (!sourceId) continue;
|
|
816
|
+
const mapped = {
|
|
817
|
+
id: payment.id,
|
|
818
|
+
paidAt: dateOnly(payment.appliedAt),
|
|
819
|
+
currentAmount: payment.currentAmount,
|
|
820
|
+
refundableAmount: payment.refundableAmount
|
|
821
|
+
};
|
|
822
|
+
const existing = paymentsBySourceId.get(sourceId);
|
|
823
|
+
if (existing) {
|
|
824
|
+
existing.push(mapped);
|
|
825
|
+
} else {
|
|
826
|
+
paymentsBySourceId.set(sourceId, [mapped]);
|
|
767
827
|
}
|
|
768
|
-
|
|
828
|
+
}
|
|
829
|
+
const paymentsOnFile = rawPaymentSources.map((source) => {
|
|
830
|
+
const payments = paymentsBySourceId.get(source.id);
|
|
831
|
+
return {
|
|
832
|
+
description: source.description,
|
|
833
|
+
id: source.id,
|
|
834
|
+
type: source.type,
|
|
835
|
+
...payments ? { payments } : {}
|
|
836
|
+
};
|
|
837
|
+
});
|
|
838
|
+
return { bookingId, orderId, paymentsOnFile };
|
|
769
839
|
}
|
|
770
|
-
|
|
840
|
+
function dateOnly(iso) {
|
|
841
|
+
return iso.split("T")[0] ?? iso;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// src/internal/peek/bookings/addon-queries.ts
|
|
845
|
+
var RESERVATION_STATUS_CONFIRMED = "CONFIRMED";
|
|
846
|
+
var ADDON_OPTION_STATUS_CANCELED = "CANCELED";
|
|
847
|
+
var SALES_ADDONS_PAGE_SIZE = 100;
|
|
848
|
+
var SALES_ADDONS_QUERY = `
|
|
771
849
|
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
772
850
|
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
773
851
|
pageInfo { endCursor hasNextPage }
|
|
774
852
|
edges {
|
|
775
853
|
node {
|
|
854
|
+
order { id displayId }
|
|
776
855
|
... on Booking {
|
|
777
856
|
displayId
|
|
778
857
|
id
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
}
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
`;
|
|
786
|
-
var BOOKING_PAYMENTS_ON_FILE_QUERY = `
|
|
787
|
-
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
788
|
-
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
789
|
-
pageInfo { endCursor hasNextPage }
|
|
790
|
-
edges {
|
|
791
|
-
node {
|
|
792
|
-
order {
|
|
793
|
-
payments {
|
|
858
|
+
refid
|
|
859
|
+
reservationStatus
|
|
860
|
+
items {
|
|
794
861
|
id
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
id
|
|
807
|
-
}
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
`;
|
|
813
|
-
var UPDATE_OPERATOR_NOTES_MUTATION = `
|
|
814
|
-
mutation Account($input: UpdateOperatorNotesForBookingInput!) {
|
|
815
|
-
updateOperatorNotesForBooking(input: $input) {
|
|
816
|
-
booking { operatorNotes }
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
`;
|
|
820
|
-
var UPDATE_BOOKING_CHECKIN_MUTATION = `
|
|
821
|
-
mutation Account($input: UpdateBookingCheckInInput!) {
|
|
822
|
-
updateBookingCheckIn(input: $input) {
|
|
823
|
-
booking { checkinStatus }
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
`;
|
|
827
|
-
var CANCEL_BOOKING_MUTATION = `
|
|
828
|
-
mutation Account($input: CancelBookingInput!) {
|
|
829
|
-
cancelBooking(input: $input) {
|
|
830
|
-
booking { id displayId reservationStatus }
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
`;
|
|
834
|
-
var APPLY_PAYMENT_TO_ORDER_MUTATION = `
|
|
835
|
-
mutation ApplyPaymentToOrder($input: ApplyPaymentToOrderInput!) {
|
|
836
|
-
applyPaymentToOrder(input: $input) {
|
|
837
|
-
transactionId
|
|
838
|
-
errors { code detail value }
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
`;
|
|
842
|
-
var APPLY_REFUND_TO_ORDER_MUTATION = `
|
|
843
|
-
mutation ApplyRefundToOrder($input: ApplyRefundToOrderInput!) {
|
|
844
|
-
applyRefundToOrder(input: $input) {
|
|
845
|
-
transactionId
|
|
846
|
-
errors { code detail value }
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
`;
|
|
850
|
-
var CREATE_INVOICE_LINK_MUTATION = `
|
|
851
|
-
mutation CreateInvoiceLink($input: CreateInvoiceLinkInput!) {
|
|
852
|
-
createInvoiceLink(input: $input) {
|
|
853
|
-
invoiceLink { status url }
|
|
854
|
-
errors { code detail value __typename }
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
`;
|
|
858
|
-
var CREATE_QUOTE_FROM_ORDER_MUTATION = `
|
|
859
|
-
mutation CreateQuoteFromOrder($input: CreateQuoteFromOrderInput!) {
|
|
860
|
-
createQuoteFromOrder(input: $input) {
|
|
861
|
-
errors { detail value code }
|
|
862
|
-
quote {
|
|
863
|
-
id
|
|
864
|
-
saleQuotes { refid reservationStatus }
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
`;
|
|
869
|
-
var UPDATE_QUOTE_V2_MUTATION = `
|
|
870
|
-
mutation UpdateQuoteV2($input: UpdateQuoteV2Input!) {
|
|
871
|
-
updateQuoteV2(input: $input) {
|
|
872
|
-
errors { detail value code }
|
|
873
|
-
quote { id }
|
|
874
|
-
}
|
|
875
|
-
}
|
|
876
|
-
`;
|
|
877
|
-
var AMEND_ORDER_MUTATION = `
|
|
878
|
-
mutation AmendOrder($input: AmendOrderInput!) {
|
|
879
|
-
amendOrder(input: $input) {
|
|
880
|
-
errors { code detail value }
|
|
881
|
-
order { id }
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
`;
|
|
885
|
-
var CREATE_QUOTE_V2_MUTATION = `
|
|
886
|
-
mutation CreateQuoteV2($input: CreateQuoteV2Input!) {
|
|
887
|
-
createQuoteV2(input: $input) {
|
|
888
|
-
errors { detail value code }
|
|
889
|
-
quote { id }
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
`;
|
|
893
|
-
var CREATE_ORDER_FROM_QUOTE_MUTATION = `
|
|
894
|
-
mutation CreateOrderFromQuote($input: CreateOrderFromQuoteInput!) {
|
|
895
|
-
createOrderFromQuote(input: $input) {
|
|
896
|
-
errors { code detail value }
|
|
897
|
-
order {
|
|
898
|
-
id
|
|
899
|
-
sales {
|
|
900
|
-
id
|
|
901
|
-
displayId
|
|
902
|
-
... on Booking {
|
|
903
|
-
balance { total { amount currency formatted } }
|
|
862
|
+
refid
|
|
863
|
+
value { total { amount currency formatted } }
|
|
864
|
+
reservationStatus
|
|
865
|
+
options {
|
|
866
|
+
refid
|
|
867
|
+
reservationStatus
|
|
868
|
+
price { amount currency formatted }
|
|
869
|
+
itemOptionSnapshot { id name }
|
|
870
|
+
itemSnapshot { id name }
|
|
871
|
+
}
|
|
872
|
+
}
|
|
904
873
|
}
|
|
905
874
|
}
|
|
906
875
|
}
|
|
907
876
|
}
|
|
908
877
|
}
|
|
909
878
|
`;
|
|
910
|
-
function
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
879
|
+
function buildSalesAddonsVariables(searchString) {
|
|
880
|
+
return {
|
|
881
|
+
first: SALES_ADDONS_PAGE_SIZE,
|
|
882
|
+
after: null,
|
|
883
|
+
orderBy: { direction: "DESC", field: "STARTS_AT" },
|
|
884
|
+
filter: { searchString }
|
|
885
|
+
};
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// src/internal/peek/bookings/addon-converter.ts
|
|
889
|
+
var ERROR_INCONSISTENT_ADDON_ITEM_ID = "Add-on group contains options with mismatched item IDs";
|
|
890
|
+
function parseSaleNode(node) {
|
|
891
|
+
const bookingId = node.id || "";
|
|
892
|
+
const displayId = node.displayId || "";
|
|
893
|
+
const orderId = node.order?.id || "";
|
|
894
|
+
const bookingQuoteRefid = node.refid || "";
|
|
895
|
+
const bookingQuoteReservationStatus = node.reservationStatus || "";
|
|
896
|
+
const items = Array.isArray(node.items) ? node.items : [];
|
|
897
|
+
return items.map((item) => {
|
|
898
|
+
const options = Array.isArray(item.options) ? item.options : [];
|
|
899
|
+
const addonItemOptions = options.map((opt) => ({
|
|
900
|
+
itemId: opt.itemSnapshot?.id || "",
|
|
901
|
+
optionId: opt.itemOptionSnapshot?.id || "",
|
|
902
|
+
itemName: opt.itemSnapshot?.name || "",
|
|
903
|
+
optionName: opt.itemOptionSnapshot?.name || "",
|
|
904
|
+
optionRefid: opt.refid || "",
|
|
905
|
+
optionReservationStatus: opt.reservationStatus || "",
|
|
906
|
+
itemReservationStatus: item.reservationStatus || "",
|
|
907
|
+
itemRefid: item.refid || ""
|
|
908
|
+
}));
|
|
909
|
+
return {
|
|
910
|
+
bookingId,
|
|
911
|
+
displayId,
|
|
912
|
+
orderId,
|
|
913
|
+
total: item.value?.total ?? null,
|
|
914
|
+
bookingQuoteRefid,
|
|
915
|
+
bookingQuoteReservationStatus,
|
|
916
|
+
addonItemOptions
|
|
917
|
+
};
|
|
918
|
+
});
|
|
919
|
+
}
|
|
920
|
+
function toBookingAddon(item) {
|
|
921
|
+
const options = item.addonItemOptions || [];
|
|
922
|
+
if (options.length === 0) {
|
|
923
|
+
return null;
|
|
929
924
|
}
|
|
930
|
-
|
|
931
|
-
|
|
925
|
+
const addonId = options[0].itemId;
|
|
926
|
+
const addonName = options[0].itemName;
|
|
927
|
+
if (options.some((opt) => opt.itemId !== addonId)) {
|
|
928
|
+
throw new Error(ERROR_INCONSISTENT_ADDON_ITEM_ID);
|
|
932
929
|
}
|
|
933
|
-
|
|
934
|
-
|
|
930
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
931
|
+
options.filter((opt) => opt.optionReservationStatus !== ADDON_OPTION_STATUS_CANCELED).forEach((opt) => {
|
|
932
|
+
const existing = grouped.get(opt.optionId);
|
|
933
|
+
if (existing) {
|
|
934
|
+
existing.quantity += 1;
|
|
935
|
+
} else {
|
|
936
|
+
grouped.set(opt.optionId, {
|
|
937
|
+
addonOptionId: opt.optionId,
|
|
938
|
+
addonOptionName: opt.optionName,
|
|
939
|
+
quantity: 1
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
});
|
|
943
|
+
const addonOptions = Array.from(grouped.values());
|
|
944
|
+
if (addonOptions.length === 0) {
|
|
945
|
+
return null;
|
|
935
946
|
}
|
|
936
|
-
return {
|
|
937
|
-
first: params.pageSize,
|
|
938
|
-
after: params.after,
|
|
939
|
-
orderBy: { direction: "ASC", field: "STARTS_AT" },
|
|
940
|
-
filter
|
|
941
|
-
};
|
|
947
|
+
return { addonId, addonName, total: item.total, addonOptions };
|
|
942
948
|
}
|
|
943
949
|
|
|
944
|
-
// src/internal/bookings/booking-service.ts
|
|
950
|
+
// src/internal/peek/bookings/booking-service.ts
|
|
945
951
|
var DEFAULT_PAGE_SIZE2 = 50;
|
|
946
952
|
var DEFAULT_CANCEL_NOTE = "Canceled";
|
|
947
953
|
var DEFAULT_CUSTOMER_MESSAGE = "Charge initiated via API";
|
|
@@ -1691,7 +1697,7 @@ function buildCancellation(items, addonOptionId, quantity) {
|
|
|
1691
1697
|
return { bookingQuotes, canceledCount };
|
|
1692
1698
|
}
|
|
1693
1699
|
|
|
1694
|
-
// src/internal/daily-notes/daily-note-converter.ts
|
|
1700
|
+
// src/internal/peek/daily-notes/daily-note-converter.ts
|
|
1695
1701
|
function toDailyNote(response) {
|
|
1696
1702
|
const union = response?.dailyNote;
|
|
1697
1703
|
if (!union) {
|
|
@@ -1712,7 +1718,7 @@ function cleanNote(note) {
|
|
|
1712
1718
|
return { note: note.note };
|
|
1713
1719
|
}
|
|
1714
1720
|
|
|
1715
|
-
// src/internal/daily-notes/daily-note-queries.ts
|
|
1721
|
+
// src/internal/peek/daily-notes/daily-note-queries.ts
|
|
1716
1722
|
var GLOBAL_NOTE_TYPE = "DASHBOARD";
|
|
1717
1723
|
var DAILY_NOTE_TODAY_QUERY = `
|
|
1718
1724
|
query dailyNote($type: GlobalNoteType!) {
|
|
@@ -1743,7 +1749,7 @@ function buildUpsertDailyNoteVariables(note) {
|
|
|
1743
1749
|
return { input: { type: GLOBAL_NOTE_TYPE, note } };
|
|
1744
1750
|
}
|
|
1745
1751
|
|
|
1746
|
-
// src/internal/daily-notes/daily-note-service.ts
|
|
1752
|
+
// src/internal/peek/daily-notes/daily-note-service.ts
|
|
1747
1753
|
var DailyNoteService = class {
|
|
1748
1754
|
constructor(client) {
|
|
1749
1755
|
this.client = client;
|
|
@@ -1766,6 +1772,53 @@ var DailyNoteService = class {
|
|
|
1766
1772
|
return fromUpsertResponse(body.data);
|
|
1767
1773
|
}
|
|
1768
1774
|
};
|
|
1775
|
+
var TokenManager = class {
|
|
1776
|
+
constructor(options) {
|
|
1777
|
+
this.options = options;
|
|
1778
|
+
}
|
|
1779
|
+
options;
|
|
1780
|
+
cached;
|
|
1781
|
+
/**
|
|
1782
|
+
* Returns a valid bearer token, reusing the cached one until it is within
|
|
1783
|
+
* `leewaySeconds` of expiring, at which point a fresh token is minted.
|
|
1784
|
+
*/
|
|
1785
|
+
getToken() {
|
|
1786
|
+
const now = Date.now();
|
|
1787
|
+
if (this.cached && now < this.cached.expiresAtMs) {
|
|
1788
|
+
return this.cached.token;
|
|
1789
|
+
}
|
|
1790
|
+
const { secret, issuer, installId, ttlSeconds, leewaySeconds } = this.options;
|
|
1791
|
+
const token = jwt.sign({}, secret, {
|
|
1792
|
+
expiresIn: ttlSeconds,
|
|
1793
|
+
issuer,
|
|
1794
|
+
subject: installId
|
|
1795
|
+
});
|
|
1796
|
+
this.cached = {
|
|
1797
|
+
token,
|
|
1798
|
+
expiresAtMs: now + (ttlSeconds - leewaySeconds) * 1e3
|
|
1799
|
+
};
|
|
1800
|
+
return token;
|
|
1801
|
+
}
|
|
1802
|
+
};
|
|
1803
|
+
|
|
1804
|
+
// src/access-service-config.ts
|
|
1805
|
+
var DEFAULT_TOKEN_TTL_SECONDS = 3600;
|
|
1806
|
+
var DEFAULT_TOKEN_REFRESH_LEEWAY_SECONDS = 60;
|
|
1807
|
+
var DEFAULT_RETRY_DELAYS_MS = [1e3, 2e3, 4e3];
|
|
1808
|
+
function requireNonEmpty(value, name, serviceName) {
|
|
1809
|
+
if (!value) {
|
|
1810
|
+
throw new Error(`${serviceName}: "${name}" is required`);
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
function createTokenManager(config) {
|
|
1814
|
+
return new TokenManager({
|
|
1815
|
+
secret: config.jwtSecret,
|
|
1816
|
+
issuer: config.issuer,
|
|
1817
|
+
installId: config.installId,
|
|
1818
|
+
ttlSeconds: config.tokenTtlSeconds ?? DEFAULT_TOKEN_TTL_SECONDS,
|
|
1819
|
+
leewaySeconds: config.tokenRefreshLeewaySeconds ?? DEFAULT_TOKEN_REFRESH_LEEWAY_SECONDS
|
|
1820
|
+
});
|
|
1821
|
+
}
|
|
1769
1822
|
|
|
1770
1823
|
// src/errors.ts
|
|
1771
1824
|
var AdminAccountRequiredError = class extends Error {
|
|
@@ -1793,11 +1846,49 @@ var PeekGraphQLError = class extends Error {
|
|
|
1793
1846
|
this.graphqlErrors = graphqlErrors;
|
|
1794
1847
|
}
|
|
1795
1848
|
};
|
|
1849
|
+
var CngApiError = class extends Error {
|
|
1850
|
+
/** The HTTP status that triggered this error. */
|
|
1851
|
+
statusCode;
|
|
1852
|
+
/** The raw response body (parsed JSON when possible, otherwise text). */
|
|
1853
|
+
body;
|
|
1854
|
+
constructor(statusCode, body, message) {
|
|
1855
|
+
super(message ?? `CNG request failed with HTTP ${statusCode}`);
|
|
1856
|
+
this.name = "CngApiError";
|
|
1857
|
+
this.statusCode = statusCode;
|
|
1858
|
+
this.body = body;
|
|
1859
|
+
}
|
|
1860
|
+
};
|
|
1796
1861
|
|
|
1797
|
-
// src/internal/
|
|
1862
|
+
// src/internal/http-transport.ts
|
|
1798
1863
|
var RATE_LIMIT_STATUS = 429;
|
|
1799
1864
|
var ADMIN_ACCOUNT_REQUIRED_STATUS = 418;
|
|
1800
1865
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1866
|
+
async function requestWithRetry(http, url, init, label, onResponse) {
|
|
1867
|
+
const { retryDelaysMs, logger, fetchFn } = http;
|
|
1868
|
+
for (let attempt = 0; attempt <= retryDelaysMs.length; attempt++) {
|
|
1869
|
+
const response = await fetchFn(url, init);
|
|
1870
|
+
if (response.status === ADMIN_ACCOUNT_REQUIRED_STATUS) {
|
|
1871
|
+
logger.warn(`Admin account required for ${label} (HTTP 418)`, { url });
|
|
1872
|
+
throw new AdminAccountRequiredError();
|
|
1873
|
+
}
|
|
1874
|
+
if (response.status === RATE_LIMIT_STATUS) {
|
|
1875
|
+
const delay = retryDelaysMs[attempt];
|
|
1876
|
+
if (delay !== void 0) {
|
|
1877
|
+
logger.warn(
|
|
1878
|
+
`Rate limited on ${label}, retrying in ${delay}ms (attempt ${attempt + 1}/${retryDelaysMs.length})`
|
|
1879
|
+
);
|
|
1880
|
+
await sleep(delay);
|
|
1881
|
+
continue;
|
|
1882
|
+
}
|
|
1883
|
+
logger.error(`Rate limit exceeded for ${label}`, { url });
|
|
1884
|
+
throw new RateLimitError();
|
|
1885
|
+
}
|
|
1886
|
+
return onResponse(response);
|
|
1887
|
+
}
|
|
1888
|
+
throw new RateLimitError();
|
|
1889
|
+
}
|
|
1890
|
+
|
|
1891
|
+
// src/internal/peek/graphql-client.ts
|
|
1801
1892
|
var GraphQLClient = class {
|
|
1802
1893
|
constructor(options) {
|
|
1803
1894
|
this.options = options;
|
|
@@ -1805,50 +1896,39 @@ var GraphQLClient = class {
|
|
|
1805
1896
|
options;
|
|
1806
1897
|
/**
|
|
1807
1898
|
* Executes a GraphQL query against the named endpoint and returns the raw
|
|
1808
|
-
* response body. Retries on HTTP 429 per the configured backoff
|
|
1899
|
+
* response body. Retries on HTTP 429 per the configured backoff (via the
|
|
1900
|
+
* shared {@link requestWithRetry} loop).
|
|
1809
1901
|
*/
|
|
1810
1902
|
async request(endpointName, query, variables) {
|
|
1811
|
-
const {
|
|
1903
|
+
const { logger } = this.options;
|
|
1812
1904
|
const url = this.endpoint(endpointName);
|
|
1813
1905
|
const collapsedQuery = query.replace(/\s+/g, " ").trim();
|
|
1814
1906
|
logger.info("Making GraphQL request", { url, endpointName });
|
|
1815
|
-
|
|
1816
|
-
|
|
1907
|
+
return requestWithRetry(
|
|
1908
|
+
this.options,
|
|
1909
|
+
url,
|
|
1910
|
+
{
|
|
1817
1911
|
method: "POST",
|
|
1818
1912
|
headers: this.buildHeaders(),
|
|
1819
1913
|
body: JSON.stringify({ query: collapsedQuery, variables })
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
);
|
|
1831
|
-
await sleep(delay);
|
|
1832
|
-
continue;
|
|
1914
|
+
},
|
|
1915
|
+
endpointName,
|
|
1916
|
+
async (response) => {
|
|
1917
|
+
const body = await response.json();
|
|
1918
|
+
if (body.errors) {
|
|
1919
|
+
logger.error(`GraphQL errors for ${endpointName}`, {
|
|
1920
|
+
url,
|
|
1921
|
+
graphqlErrors: JSON.stringify(body.errors)
|
|
1922
|
+
});
|
|
1923
|
+
throw new PeekGraphQLError(body.errors);
|
|
1833
1924
|
}
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
logger.error(`GraphQL errors for ${endpointName}`, {
|
|
1840
|
-
url,
|
|
1841
|
-
graphqlErrors: JSON.stringify(body.errors)
|
|
1842
|
-
});
|
|
1843
|
-
throw new PeekGraphQLError(body.errors);
|
|
1844
|
-
}
|
|
1845
|
-
if (!response.ok) {
|
|
1846
|
-
logger.error(`GraphQL request failed with HTTP ${response.status}`, { url });
|
|
1847
|
-
throw new Error(`GraphQL request failed with HTTP ${response.status}`);
|
|
1925
|
+
if (!response.ok) {
|
|
1926
|
+
logger.error(`GraphQL request failed with HTTP ${response.status}`, { url });
|
|
1927
|
+
throw new Error(`GraphQL request failed with HTTP ${response.status}`);
|
|
1928
|
+
}
|
|
1929
|
+
return body;
|
|
1848
1930
|
}
|
|
1849
|
-
|
|
1850
|
-
}
|
|
1851
|
-
throw new RateLimitError();
|
|
1931
|
+
);
|
|
1852
1932
|
}
|
|
1853
1933
|
endpoint(endpointName) {
|
|
1854
1934
|
const { baseUrl, appId, endpointPathPrefix } = this.options;
|
|
@@ -1867,7 +1947,7 @@ var GraphQLClient = class {
|
|
|
1867
1947
|
}
|
|
1868
1948
|
};
|
|
1869
1949
|
|
|
1870
|
-
// src/internal/memberships/membership-converter.ts
|
|
1950
|
+
// src/internal/peek/memberships/membership-converter.ts
|
|
1871
1951
|
function fromMembershipsResponse(response) {
|
|
1872
1952
|
return (response?.memberships ?? []).flatMap(
|
|
1873
1953
|
(membership) => (membership.membershipVariants ?? []).map((variant) => ({
|
|
@@ -1882,7 +1962,7 @@ function fromMembershipsResponse(response) {
|
|
|
1882
1962
|
);
|
|
1883
1963
|
}
|
|
1884
1964
|
|
|
1885
|
-
// src/internal/memberships/membership-queries.ts
|
|
1965
|
+
// src/internal/peek/memberships/membership-queries.ts
|
|
1886
1966
|
var MEMBERSHIPS_QUERY = `
|
|
1887
1967
|
query Sales {
|
|
1888
1968
|
memberships {
|
|
@@ -1927,7 +2007,7 @@ var CREATE_MEMBERSHIP_ORDER_FROM_QUOTE_MUTATION = `
|
|
|
1927
2007
|
}
|
|
1928
2008
|
`;
|
|
1929
2009
|
|
|
1930
|
-
// src/internal/memberships/membership-service.ts
|
|
2010
|
+
// src/internal/peek/memberships/membership-service.ts
|
|
1931
2011
|
var QUOTE_STATUS_CONFIRMED = "CONFIRMED";
|
|
1932
2012
|
var DEFAULT_BALANCE_AMOUNT = "0.00";
|
|
1933
2013
|
var DEFAULT_BALANCE_CURRENCY = "USD";
|
|
@@ -2033,7 +2113,7 @@ function validatePurchaseInput(input) {
|
|
|
2033
2113
|
}
|
|
2034
2114
|
}
|
|
2035
2115
|
|
|
2036
|
-
// src/internal/resellers/channel-converter.ts
|
|
2116
|
+
// src/internal/peek/resellers/channel-converter.ts
|
|
2037
2117
|
function fromChannelsResponse(response) {
|
|
2038
2118
|
return (response?.channels ?? []).map(fromChannelNode);
|
|
2039
2119
|
}
|
|
@@ -2054,7 +2134,7 @@ function fromChannelNode(node) {
|
|
|
2054
2134
|
};
|
|
2055
2135
|
}
|
|
2056
2136
|
|
|
2057
|
-
// src/internal/resellers/channel-queries.ts
|
|
2137
|
+
// src/internal/peek/resellers/channel-queries.ts
|
|
2058
2138
|
var CHANNELS_QUERY = `
|
|
2059
2139
|
query Sales($first: Int) {
|
|
2060
2140
|
channels {
|
|
@@ -2078,7 +2158,7 @@ var CHANNELS_QUERY = `
|
|
|
2078
2158
|
}
|
|
2079
2159
|
`;
|
|
2080
2160
|
|
|
2081
|
-
// src/internal/resellers/reseller-service.ts
|
|
2161
|
+
// src/internal/peek/resellers/reseller-service.ts
|
|
2082
2162
|
var DEFAULT_AGENTS_PER_CHANNEL = 10;
|
|
2083
2163
|
var ResellerService = class {
|
|
2084
2164
|
constructor(client) {
|
|
@@ -2097,7 +2177,7 @@ var ResellerService = class {
|
|
|
2097
2177
|
}
|
|
2098
2178
|
};
|
|
2099
2179
|
|
|
2100
|
-
// src/internal/resource-pools/resource-pool-converter.ts
|
|
2180
|
+
// src/internal/peek/resource-pools/resource-pool-converter.ts
|
|
2101
2181
|
function fromResourcePoolsResponse(response) {
|
|
2102
2182
|
return (response?.resourcePools ?? []).map(fromResourcePoolNode);
|
|
2103
2183
|
}
|
|
@@ -2125,7 +2205,7 @@ function fromAccountUser(accountUser) {
|
|
|
2125
2205
|
};
|
|
2126
2206
|
}
|
|
2127
2207
|
|
|
2128
|
-
// src/internal/resource-pools/resource-pool-queries.ts
|
|
2208
|
+
// src/internal/peek/resource-pools/resource-pool-queries.ts
|
|
2129
2209
|
var RESOURCE_POOLS_QUERY = `
|
|
2130
2210
|
query Sales($filter: ResourcePoolsFilter) {
|
|
2131
2211
|
resourcePools(filter: $filter) {
|
|
@@ -2146,7 +2226,7 @@ var RESOURCE_POOLS_QUERY = `
|
|
|
2146
2226
|
}
|
|
2147
2227
|
`;
|
|
2148
2228
|
|
|
2149
|
-
// src/internal/resource-pools/resource-pool-service.ts
|
|
2229
|
+
// src/internal/peek/resource-pools/resource-pool-service.ts
|
|
2150
2230
|
var DEFAULT_MODE = "ALL";
|
|
2151
2231
|
var ResourcePoolService = class {
|
|
2152
2232
|
constructor(client) {
|
|
@@ -2166,7 +2246,7 @@ var ResourcePoolService = class {
|
|
|
2166
2246
|
}
|
|
2167
2247
|
};
|
|
2168
2248
|
|
|
2169
|
-
// src/internal/reviews/review-converter.ts
|
|
2249
|
+
// src/internal/peek/reviews/review-converter.ts
|
|
2170
2250
|
var ISO_DATE_LENGTH = 10;
|
|
2171
2251
|
function toDateOnly(isoDateTime) {
|
|
2172
2252
|
return isoDateTime.slice(0, ISO_DATE_LENGTH);
|
|
@@ -2190,13 +2270,13 @@ function fromReviewNode(node) {
|
|
|
2190
2270
|
};
|
|
2191
2271
|
}
|
|
2192
2272
|
|
|
2193
|
-
// src/internal/reviews/review-cursor.ts
|
|
2273
|
+
// src/internal/peek/reviews/review-cursor.ts
|
|
2194
2274
|
function encodeCursor(offset, pageSize) {
|
|
2195
2275
|
const start = Math.max(0, offset - pageSize + 1);
|
|
2196
2276
|
return Buffer.from(`range:${start}..${offset},${offset}`).toString("base64");
|
|
2197
2277
|
}
|
|
2198
2278
|
|
|
2199
|
-
// src/internal/reviews/review-queries.ts
|
|
2279
|
+
// src/internal/peek/reviews/review-queries.ts
|
|
2200
2280
|
var REVIEWS_QUERY = `
|
|
2201
2281
|
query Reviews($first: Int, $filter: ReviewFilter, $after: String) {
|
|
2202
2282
|
reviews(first: $first, filter: $filter, after: $after) {
|
|
@@ -2231,7 +2311,7 @@ function buildReviewsVariables(params) {
|
|
|
2231
2311
|
};
|
|
2232
2312
|
}
|
|
2233
2313
|
|
|
2234
|
-
// src/internal/reviews/review-service.ts
|
|
2314
|
+
// src/internal/peek/reviews/review-service.ts
|
|
2235
2315
|
var DEFAULT_REVIEW_COUNT = 50;
|
|
2236
2316
|
var MIN_REVIEW_COUNT = 1;
|
|
2237
2317
|
var MAX_REVIEW_COUNT = 50;
|
|
@@ -2292,7 +2372,7 @@ var ReviewService = class {
|
|
|
2292
2372
|
}
|
|
2293
2373
|
};
|
|
2294
2374
|
|
|
2295
|
-
// src/internal/timeslots/timeslot-converter.ts
|
|
2375
|
+
// src/internal/peek/timeslots/timeslot-converter.ts
|
|
2296
2376
|
function fromTimeslotNodes(nodes, productId) {
|
|
2297
2377
|
if (!Array.isArray(nodes) || nodes.length === 0) {
|
|
2298
2378
|
return [];
|
|
@@ -2350,7 +2430,7 @@ function mapAssignedResources(allocations) {
|
|
|
2350
2430
|
});
|
|
2351
2431
|
}
|
|
2352
2432
|
|
|
2353
|
-
// src/internal/timeslots/guide-matcher.ts
|
|
2433
|
+
// src/internal/peek/timeslots/guide-matcher.ts
|
|
2354
2434
|
function matchGuideToResourcePool(guideId, guideResourcePools, accountUsers) {
|
|
2355
2435
|
const directIdMatch = guideResourcePools.find((pool) => pool.id === guideId);
|
|
2356
2436
|
if (directIdMatch) {
|
|
@@ -2384,7 +2464,7 @@ function matchGuideToResourcePool(guideId, guideResourcePools, accountUsers) {
|
|
|
2384
2464
|
return null;
|
|
2385
2465
|
}
|
|
2386
2466
|
|
|
2387
|
-
// src/internal/timeslots/resource-allocation-queries.ts
|
|
2467
|
+
// src/internal/peek/timeslots/resource-allocation-queries.ts
|
|
2388
2468
|
var RESOURCE_ALLOCATION_BULK_REQUEST_MUTATION = `
|
|
2389
2469
|
mutation ResourceAllocationBulkRequest($input: ResourceAllocationBulkRequestInput!) {
|
|
2390
2470
|
resourceAllocationBulkRequest(input: $input) {
|
|
@@ -2403,7 +2483,7 @@ function buildResourceAllocationVariables(timeslotIds, resourcePoolIds, status)
|
|
|
2403
2483
|
return { input: { timeslotIds, resourcePoolIds, status } };
|
|
2404
2484
|
}
|
|
2405
2485
|
|
|
2406
|
-
// src/internal/timeslots/timeslot-queries.ts
|
|
2486
|
+
// src/internal/peek/timeslots/timeslot-queries.ts
|
|
2407
2487
|
var TIMESLOTS_QUERY = `
|
|
2408
2488
|
query Sales($params: TimeslotsFilter!) {
|
|
2409
2489
|
timeslots(filter: $params) {
|
|
@@ -2506,7 +2586,7 @@ function buildTimeslotVariables(productId, date, filter) {
|
|
|
2506
2586
|
return { params };
|
|
2507
2587
|
}
|
|
2508
2588
|
|
|
2509
|
-
// src/internal/timeslots/timeslot-service.ts
|
|
2589
|
+
// src/internal/peek/timeslots/timeslot-service.ts
|
|
2510
2590
|
var GUIDE_CATEGORY = "guide";
|
|
2511
2591
|
var ERROR_MISSING_TIMESLOTS_OR_GUIDES = "At least one timeslot and one guide are required";
|
|
2512
2592
|
var ERROR_INVALID_ACTION = "Invalid action. Must be either assign or unassign";
|
|
@@ -2623,7 +2703,7 @@ function normalizeDate(date) {
|
|
|
2623
2703
|
return date.split("T")[0] ?? date;
|
|
2624
2704
|
}
|
|
2625
2705
|
|
|
2626
|
-
// src/internal/products/product-converter.ts
|
|
2706
|
+
// src/internal/peek/products/product-converter.ts
|
|
2627
2707
|
var ADD_ON_COLOR = "#FFFFFF";
|
|
2628
2708
|
function fromActivities(activities) {
|
|
2629
2709
|
return activities.map(fromActivity);
|
|
@@ -2662,7 +2742,7 @@ function fromItemOptionNodes(nodes) {
|
|
|
2662
2742
|
return Array.from(grouped.values());
|
|
2663
2743
|
}
|
|
2664
2744
|
|
|
2665
|
-
// src/internal/products/product-queries.ts
|
|
2745
|
+
// src/internal/peek/products/product-queries.ts
|
|
2666
2746
|
var PRODUCTS_QUERY = `
|
|
2667
2747
|
query Sales {
|
|
2668
2748
|
activities {
|
|
@@ -2702,7 +2782,7 @@ var ITEM_OPTIONS_QUERY = `
|
|
|
2702
2782
|
}
|
|
2703
2783
|
`;
|
|
2704
2784
|
|
|
2705
|
-
// src/internal/products/product-service.ts
|
|
2785
|
+
// src/internal/peek/products/product-service.ts
|
|
2706
2786
|
var DEFAULT_ITEM_OPTIONS_PAGE_SIZE = 50;
|
|
2707
2787
|
var ProductService = class {
|
|
2708
2788
|
constructor(client, options = {}) {
|
|
@@ -2779,7 +2859,7 @@ var ProductService = class {
|
|
|
2779
2859
|
}
|
|
2780
2860
|
};
|
|
2781
2861
|
|
|
2782
|
-
// src/internal/promo-codes/promo-code-queries.ts
|
|
2862
|
+
// src/internal/peek/promo-codes/promo-code-queries.ts
|
|
2783
2863
|
var PROMO_CODES_QUERY = `
|
|
2784
2864
|
query Sales($first: Int, $after: String) {
|
|
2785
2865
|
promoCodes(first: $first, after: $after) {
|
|
@@ -2818,7 +2898,7 @@ var CREATE_PROMO_CODE_MUTATION = `
|
|
|
2818
2898
|
}
|
|
2819
2899
|
`;
|
|
2820
2900
|
|
|
2821
|
-
// src/internal/promo-codes/promo-code-service.ts
|
|
2901
|
+
// src/internal/peek/promo-codes/promo-code-service.ts
|
|
2822
2902
|
var DEFAULT_PAGE_SIZE3 = 50;
|
|
2823
2903
|
var DEFAULT_CURRENCY = "USD";
|
|
2824
2904
|
var CURRENCY_PATTERN = /^[A-Z]{3}$/;
|
|
@@ -2897,34 +2977,6 @@ var PromoCodeService = class {
|
|
|
2897
2977
|
return { id: result.id, name: result.name };
|
|
2898
2978
|
}
|
|
2899
2979
|
};
|
|
2900
|
-
var TokenManager = class {
|
|
2901
|
-
constructor(options) {
|
|
2902
|
-
this.options = options;
|
|
2903
|
-
}
|
|
2904
|
-
options;
|
|
2905
|
-
cached;
|
|
2906
|
-
/**
|
|
2907
|
-
* Returns a valid bearer token, reusing the cached one until it is within
|
|
2908
|
-
* `leewaySeconds` of expiring, at which point a fresh token is minted.
|
|
2909
|
-
*/
|
|
2910
|
-
getToken() {
|
|
2911
|
-
const now = Date.now();
|
|
2912
|
-
if (this.cached && now < this.cached.expiresAtMs) {
|
|
2913
|
-
return this.cached.token;
|
|
2914
|
-
}
|
|
2915
|
-
const { secret, issuer, installId, ttlSeconds, leewaySeconds } = this.options;
|
|
2916
|
-
const token = jwt.sign({}, secret, {
|
|
2917
|
-
expiresIn: ttlSeconds,
|
|
2918
|
-
issuer,
|
|
2919
|
-
subject: installId
|
|
2920
|
-
});
|
|
2921
|
-
this.cached = {
|
|
2922
|
-
token,
|
|
2923
|
-
expiresAtMs: now + (ttlSeconds - leewaySeconds) * 1e3
|
|
2924
|
-
};
|
|
2925
|
-
return token;
|
|
2926
|
-
}
|
|
2927
|
-
};
|
|
2928
2980
|
|
|
2929
2981
|
// src/logger.ts
|
|
2930
2982
|
var noopLogger = {
|
|
@@ -2939,9 +2991,6 @@ var noopLogger = {
|
|
|
2939
2991
|
// src/peek-access-service.ts
|
|
2940
2992
|
var DEFAULT_BASE_URL = "https://apps.peekapis.com/backoffice-gql";
|
|
2941
2993
|
var DEFAULT_V2_BASE_URL = "https://app-registry.peeklabs.com/installations-api";
|
|
2942
|
-
var DEFAULT_TOKEN_TTL_SECONDS = 3600;
|
|
2943
|
-
var DEFAULT_TOKEN_REFRESH_LEEWAY_SECONDS = 60;
|
|
2944
|
-
var DEFAULT_RETRY_DELAYS_MS = [1e3, 2e3, 4e3];
|
|
2945
2994
|
var PEEK_TOKEN_ISSUER = "app_registry_v2";
|
|
2946
2995
|
var PeekAccessService = class {
|
|
2947
2996
|
client;
|
|
@@ -2960,20 +3009,14 @@ var PeekAccessService = class {
|
|
|
2960
3009
|
reviewService;
|
|
2961
3010
|
constructor(config) {
|
|
2962
3011
|
const isV2 = config.mode === "v2";
|
|
2963
|
-
requireNonEmpty(config.installId, "installId");
|
|
2964
|
-
requireNonEmpty(config.jwtSecret, "jwtSecret");
|
|
2965
|
-
requireNonEmpty(config.issuer, "issuer");
|
|
2966
|
-
requireNonEmpty(config.appId, "appId");
|
|
2967
|
-
if (!isV2) requireNonEmpty(config.gatewayKey ?? "", "gatewayKey");
|
|
3012
|
+
requireNonEmpty(config.installId, "installId", "PeekAccessService");
|
|
3013
|
+
requireNonEmpty(config.jwtSecret, "jwtSecret", "PeekAccessService");
|
|
3014
|
+
requireNonEmpty(config.issuer, "issuer", "PeekAccessService");
|
|
3015
|
+
requireNonEmpty(config.appId, "appId", "PeekAccessService");
|
|
3016
|
+
if (!isV2) requireNonEmpty(config.gatewayKey ?? "", "gatewayKey", "PeekAccessService");
|
|
2968
3017
|
this.jwtSecret = config.jwtSecret;
|
|
2969
3018
|
const logger = config.logger ?? noopLogger;
|
|
2970
|
-
const tokens =
|
|
2971
|
-
secret: config.jwtSecret,
|
|
2972
|
-
issuer: config.issuer,
|
|
2973
|
-
installId: config.installId,
|
|
2974
|
-
ttlSeconds: config.tokenTtlSeconds ?? DEFAULT_TOKEN_TTL_SECONDS,
|
|
2975
|
-
leewaySeconds: config.tokenRefreshLeewaySeconds ?? DEFAULT_TOKEN_REFRESH_LEEWAY_SECONDS
|
|
2976
|
-
});
|
|
3019
|
+
const tokens = createTokenManager(config);
|
|
2977
3020
|
const defaultBaseUrl = isV2 ? DEFAULT_V2_BASE_URL : DEFAULT_BASE_URL;
|
|
2978
3021
|
this.client = new GraphQLClient({
|
|
2979
3022
|
baseUrl: config.baseUrl ?? defaultBaseUrl,
|
|
@@ -3299,13 +3342,148 @@ var PeekAccessService = class {
|
|
|
3299
3342
|
return this.getReviewService().getReviews(productId, reviewCount, reviewOffset);
|
|
3300
3343
|
}
|
|
3301
3344
|
};
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3345
|
+
|
|
3346
|
+
// src/internal/cng/endpoints.ts
|
|
3347
|
+
var CNG_EXTENDABLE_SLUG = "cng_backoffice_api-v1";
|
|
3348
|
+
var PRODUCTS_PATH = "api/v2/commerce-config/products";
|
|
3349
|
+
|
|
3350
|
+
// src/models/cng/product.ts
|
|
3351
|
+
var ACTIVITY_PRODUCT_TYPE2 = "ACTIVITY";
|
|
3352
|
+
|
|
3353
|
+
// src/internal/cng/products/product-converter.ts
|
|
3354
|
+
function fromProductNodes(nodes) {
|
|
3355
|
+
return nodes.map(fromProductNode);
|
|
3356
|
+
}
|
|
3357
|
+
function fromProductNode(node) {
|
|
3358
|
+
return {
|
|
3359
|
+
productId: node.id || "",
|
|
3360
|
+
name: node.name || "",
|
|
3361
|
+
type: node.product_type || ACTIVITY_PRODUCT_TYPE2,
|
|
3362
|
+
color: node.color_hex || "",
|
|
3363
|
+
tickets: (node.tickets ?? []).map((ticket) => ({
|
|
3364
|
+
id: ticket.id,
|
|
3365
|
+
name: ticket.name
|
|
3366
|
+
}))
|
|
3367
|
+
};
|
|
3306
3368
|
}
|
|
3307
3369
|
|
|
3308
|
-
// src/internal/
|
|
3370
|
+
// src/internal/cng/products/product-service.ts
|
|
3371
|
+
var CngProductService = class {
|
|
3372
|
+
constructor(client) {
|
|
3373
|
+
this.client = client;
|
|
3374
|
+
}
|
|
3375
|
+
client;
|
|
3376
|
+
/**
|
|
3377
|
+
* Returns every activity as a single flat list.
|
|
3378
|
+
*
|
|
3379
|
+
* @example
|
|
3380
|
+
* ```ts
|
|
3381
|
+
* const activities = await cng.getProductService().getAllActivities();
|
|
3382
|
+
* ```
|
|
3383
|
+
*/
|
|
3384
|
+
async getAllActivities() {
|
|
3385
|
+
const body = await this.client.get(
|
|
3386
|
+
PRODUCTS_PATH
|
|
3387
|
+
);
|
|
3388
|
+
const nodes = Array.isArray(body) ? body : body?.products ?? [];
|
|
3389
|
+
return fromProductNodes(nodes ?? []);
|
|
3390
|
+
}
|
|
3391
|
+
};
|
|
3392
|
+
|
|
3393
|
+
// src/internal/cng/rest-client.ts
|
|
3394
|
+
var RestClient = class {
|
|
3395
|
+
constructor(options) {
|
|
3396
|
+
this.options = options;
|
|
3397
|
+
}
|
|
3398
|
+
options;
|
|
3399
|
+
/**
|
|
3400
|
+
* Issues a GET against the named REST path and returns the parsed JSON body.
|
|
3401
|
+
* Retries on HTTP 429 per the configured backoff (via the shared
|
|
3402
|
+
* {@link requestWithRetry} loop).
|
|
3403
|
+
*
|
|
3404
|
+
* @throws {AdminAccountRequiredError} on HTTP 418
|
|
3405
|
+
* @throws {RateLimitError} on HTTP 429 after retries are exhausted
|
|
3406
|
+
* @throws {CngApiError} on any other non-2xx response
|
|
3407
|
+
*/
|
|
3408
|
+
async get(path) {
|
|
3409
|
+
const { logger } = this.options;
|
|
3410
|
+
const url = this.endpoint(path);
|
|
3411
|
+
logger.info("Making CNG request", { url, path });
|
|
3412
|
+
return requestWithRetry(
|
|
3413
|
+
this.options,
|
|
3414
|
+
url,
|
|
3415
|
+
{ method: "GET", headers: this.buildHeaders() },
|
|
3416
|
+
path,
|
|
3417
|
+
async (response) => {
|
|
3418
|
+
const body = await this.parseBody(response);
|
|
3419
|
+
if (!response.ok) {
|
|
3420
|
+
logger.error(`CNG request failed with HTTP ${response.status}`, { url });
|
|
3421
|
+
throw new CngApiError(response.status, body);
|
|
3422
|
+
}
|
|
3423
|
+
return body;
|
|
3424
|
+
}
|
|
3425
|
+
);
|
|
3426
|
+
}
|
|
3427
|
+
/** Reads the response body as JSON, falling back to raw text when unparseable. */
|
|
3428
|
+
async parseBody(response) {
|
|
3429
|
+
const text = await response.text();
|
|
3430
|
+
try {
|
|
3431
|
+
return JSON.parse(text);
|
|
3432
|
+
} catch {
|
|
3433
|
+
return text;
|
|
3434
|
+
}
|
|
3435
|
+
}
|
|
3436
|
+
endpoint(path) {
|
|
3437
|
+
const { baseUrl, appId, extendableSlug } = this.options;
|
|
3438
|
+
return `${baseUrl}/${appId}/${extendableSlug}/${path}`;
|
|
3439
|
+
}
|
|
3440
|
+
buildHeaders() {
|
|
3441
|
+
return {
|
|
3442
|
+
"X-Peek-Auth": `Bearer ${this.options.getToken()}`,
|
|
3443
|
+
"Content-Type": "application/json"
|
|
3444
|
+
};
|
|
3445
|
+
}
|
|
3446
|
+
};
|
|
3447
|
+
|
|
3448
|
+
// src/cng-access-service.ts
|
|
3449
|
+
var DEFAULT_BASE_URL2 = "https://app-registry.peeklabs.com/installations-api";
|
|
3450
|
+
var CngAccessService = class {
|
|
3451
|
+
client;
|
|
3452
|
+
productService;
|
|
3453
|
+
constructor(config) {
|
|
3454
|
+
requireNonEmpty(config.installId, "installId", "CngAccessService");
|
|
3455
|
+
requireNonEmpty(config.jwtSecret, "jwtSecret", "CngAccessService");
|
|
3456
|
+
requireNonEmpty(config.issuer, "issuer", "CngAccessService");
|
|
3457
|
+
requireNonEmpty(config.appId, "appId", "CngAccessService");
|
|
3458
|
+
const logger = config.logger ?? noopLogger;
|
|
3459
|
+
const tokens = createTokenManager(config);
|
|
3460
|
+
this.client = new RestClient({
|
|
3461
|
+
baseUrl: config.baseUrl ?? DEFAULT_BASE_URL2,
|
|
3462
|
+
appId: config.appId,
|
|
3463
|
+
extendableSlug: CNG_EXTENDABLE_SLUG,
|
|
3464
|
+
getToken: () => tokens.getToken(),
|
|
3465
|
+
retryDelaysMs: config.retryDelaysMs ?? DEFAULT_RETRY_DELAYS_MS,
|
|
3466
|
+
logger,
|
|
3467
|
+
fetchFn: config.fetch ?? globalThis.fetch
|
|
3468
|
+
});
|
|
3469
|
+
}
|
|
3470
|
+
/**
|
|
3471
|
+
* Returns the {@link CngProductService} for this install, bound to the shared
|
|
3472
|
+
* authenticated transport. The instance is created lazily and reused.
|
|
3473
|
+
*/
|
|
3474
|
+
getProductService() {
|
|
3475
|
+
if (!this.productService) {
|
|
3476
|
+
this.productService = new CngProductService(this.client);
|
|
3477
|
+
}
|
|
3478
|
+
return this.productService;
|
|
3479
|
+
}
|
|
3480
|
+
/** All activities. Delegates to {@link CngProductService.getAllActivities}. */
|
|
3481
|
+
getAllActivities() {
|
|
3482
|
+
return this.getProductService().getAllActivities();
|
|
3483
|
+
}
|
|
3484
|
+
};
|
|
3485
|
+
|
|
3486
|
+
// src/internal/peek/bookings/booking-webhook.ts
|
|
3309
3487
|
var PAYLOAD_BOOKING_KEY = "booking";
|
|
3310
3488
|
var VALUE_OPEN_TOKEN = "value {";
|
|
3311
3489
|
var PRICE_BREAKDOWN_KEYS = [
|
|
@@ -3355,7 +3533,7 @@ function hasPriceBreakdown(node) {
|
|
|
3355
3533
|
return PRICE_BREAKDOWN_KEYS.some((key) => key in value);
|
|
3356
3534
|
}
|
|
3357
3535
|
|
|
3358
|
-
// src/internal/waivers/waiver-webhook.ts
|
|
3536
|
+
// src/internal/peek/waivers/waiver-webhook.ts
|
|
3359
3537
|
var PAYLOAD_WAIVER_KEY = "waiver";
|
|
3360
3538
|
function parseWaiverWebhook(payload) {
|
|
3361
3539
|
return fromWaiverNode(extractWaiverNode(payload));
|
|
@@ -3390,6 +3568,6 @@ function extractWaiverNode(payload) {
|
|
|
3390
3568
|
return record;
|
|
3391
3569
|
}
|
|
3392
3570
|
|
|
3393
|
-
export { ACTIVITY_PRODUCT_TYPE, ADD_ON_PRODUCT_TYPE, AccountUserService, AdminAccountRequiredError, AvailabilityService, BookingService, DailyNoteService, MembershipService, PeekAccessService, PeekGraphQLError, ProductService, PromoCodeService, RENTAL_PRODUCT_TYPE, RateLimitError, ResellerService, ResourcePoolService, ReviewService, TimeslotService, noopLogger, parseBookingWebhook, parseWaiverWebhook };
|
|
3571
|
+
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 };
|
|
3394
3572
|
//# sourceMappingURL=index.js.map
|
|
3395
3573
|
//# sourceMappingURL=index.js.map
|