@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.cjs
CHANGED
|
@@ -25,11 +25,11 @@ var jwt__namespace = /*#__PURE__*/_interopNamespace(jwt);
|
|
|
25
25
|
|
|
26
26
|
// src/peek-access-service.ts
|
|
27
27
|
|
|
28
|
-
// src/internal/gateway-endpoints.ts
|
|
28
|
+
// src/internal/peek/gateway-endpoints.ts
|
|
29
29
|
var SALES_ENDPOINT = "sales";
|
|
30
30
|
var V2_EXTENDABLE_SLUG = "peek_backoffice_api-v1";
|
|
31
31
|
|
|
32
|
-
// src/internal/account-users/account-user-converter.ts
|
|
32
|
+
// src/internal/peek/account-users/account-user-converter.ts
|
|
33
33
|
var ACTIVE_STATUS = "ACTIVE";
|
|
34
34
|
function fromAccountUserNode(node) {
|
|
35
35
|
if (!node || node.status !== ACTIVE_STATUS) {
|
|
@@ -57,7 +57,7 @@ function fromAccountUserNodes(nodes) {
|
|
|
57
57
|
return users;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
// src/internal/account-users/account-user-queries.ts
|
|
60
|
+
// src/internal/peek/account-users/account-user-queries.ts
|
|
61
61
|
var USER_QUERY = `
|
|
62
62
|
query Sales($first: Int, $after: String) {
|
|
63
63
|
accountUsers(first: $first, after: $after) {
|
|
@@ -103,7 +103,7 @@ var USER_BY_FILTER_QUERY = `
|
|
|
103
103
|
}
|
|
104
104
|
`;
|
|
105
105
|
|
|
106
|
-
// src/internal/account-users/account-user-service.ts
|
|
106
|
+
// src/internal/peek/account-users/account-user-service.ts
|
|
107
107
|
var DEFAULT_PAGE_SIZE = 50;
|
|
108
108
|
var AccountUserService = class {
|
|
109
109
|
constructor(client, options = {}) {
|
|
@@ -157,7 +157,7 @@ var AccountUserService = class {
|
|
|
157
157
|
}
|
|
158
158
|
};
|
|
159
159
|
|
|
160
|
-
// src/internal/availability/availability-queries.ts
|
|
160
|
+
// src/internal/peek/availability/availability-queries.ts
|
|
161
161
|
var AVAILABILITY_TIMES_QUERY = `
|
|
162
162
|
query Sales($activityId: ID!, $resourceOptionQuantities: [ResourceOptionQuantityData!]!, $date: Date!) {
|
|
163
163
|
availabilityTimes(activityId: $activityId, resourceOptionQuantities: $resourceOptionQuantities, date: $date) {
|
|
@@ -182,7 +182,7 @@ var AVAILABILITY_TIMES_QUERY = `
|
|
|
182
182
|
}
|
|
183
183
|
`;
|
|
184
184
|
|
|
185
|
-
// src/internal/availability/availability-service.ts
|
|
185
|
+
// src/internal/peek/availability/availability-service.ts
|
|
186
186
|
var AvailabilityService = class {
|
|
187
187
|
constructor(client) {
|
|
188
188
|
this.client = client;
|
|
@@ -203,13 +203,375 @@ var AvailabilityService = class {
|
|
|
203
203
|
}
|
|
204
204
|
};
|
|
205
205
|
|
|
206
|
-
// src/models/product.ts
|
|
206
|
+
// src/models/peek/product.ts
|
|
207
207
|
var ACTIVITY_PRODUCT_TYPE = "ACTIVITY";
|
|
208
208
|
var RENTAL_PRODUCT_TYPE = "RENTAL";
|
|
209
209
|
var ADD_ON_PRODUCT_TYPE = "ADD-ON";
|
|
210
210
|
|
|
211
|
-
// src/internal/bookings/booking-
|
|
211
|
+
// src/internal/peek/bookings/booking-queries.ts
|
|
212
|
+
var SEARCH_BY_PURCHASE_DATE = "purchaseDate";
|
|
213
|
+
var SEARCH_BY_ACTIVITY_DATE = "activityDate";
|
|
214
|
+
function normalizeBookingId(bookingId) {
|
|
215
|
+
return bookingId.toLowerCase().replace(/-/g, "_");
|
|
216
|
+
}
|
|
217
|
+
var guestFields = `
|
|
218
|
+
id
|
|
219
|
+
name
|
|
220
|
+
country
|
|
221
|
+
dateOfBirth
|
|
222
|
+
email
|
|
223
|
+
isGdpr
|
|
224
|
+
isParticipant
|
|
225
|
+
optinSms
|
|
226
|
+
optinMarketing
|
|
227
|
+
phone
|
|
228
|
+
postalCode
|
|
229
|
+
fieldResponses {
|
|
230
|
+
id
|
|
231
|
+
text
|
|
232
|
+
fieldLocation {
|
|
233
|
+
field {
|
|
234
|
+
name
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
`;
|
|
239
|
+
var bookingGuestsFields = `
|
|
240
|
+
bookingGuests {
|
|
241
|
+
${guestFields}
|
|
242
|
+
}
|
|
243
|
+
primaryGuest {
|
|
244
|
+
${guestFields}
|
|
245
|
+
}
|
|
246
|
+
`;
|
|
247
|
+
var bookingQueryFields = `
|
|
248
|
+
displayId
|
|
249
|
+
id
|
|
250
|
+
primaryGuest {
|
|
251
|
+
name
|
|
252
|
+
email
|
|
253
|
+
phone
|
|
254
|
+
optinMarketing
|
|
255
|
+
optinSms
|
|
256
|
+
isGdpr
|
|
257
|
+
postalCode
|
|
258
|
+
}
|
|
259
|
+
activitySnapshot {
|
|
260
|
+
type
|
|
261
|
+
name
|
|
262
|
+
id
|
|
263
|
+
}
|
|
264
|
+
ticketQuantities {
|
|
265
|
+
quantity
|
|
266
|
+
resourceOptionSnapshot {
|
|
267
|
+
name
|
|
268
|
+
id
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
reservationStatus
|
|
272
|
+
checkinStatus
|
|
273
|
+
returnStatus
|
|
274
|
+
fulfillmentStatusOverride {
|
|
275
|
+
status
|
|
276
|
+
}
|
|
277
|
+
timeSnapshot {
|
|
278
|
+
id
|
|
279
|
+
legacyId
|
|
280
|
+
}
|
|
281
|
+
purchasedAt
|
|
282
|
+
purchasedAtUtc
|
|
283
|
+
startsAt
|
|
284
|
+
startsAtUtc
|
|
285
|
+
endsAt
|
|
286
|
+
endsAtUtc
|
|
287
|
+
availabilityTimeId
|
|
288
|
+
bookingPortalUrl
|
|
289
|
+
operatorNotes
|
|
290
|
+
value {
|
|
291
|
+
total {
|
|
292
|
+
formatted
|
|
293
|
+
amount
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
balance {
|
|
297
|
+
total {
|
|
298
|
+
amount
|
|
299
|
+
formatted
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
tips {
|
|
303
|
+
price {
|
|
304
|
+
amount
|
|
305
|
+
formatted
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
order {
|
|
309
|
+
displayId
|
|
310
|
+
id
|
|
311
|
+
promoCodes {
|
|
312
|
+
code
|
|
313
|
+
}
|
|
314
|
+
channelSnapshot {
|
|
315
|
+
id
|
|
316
|
+
name
|
|
317
|
+
agent {
|
|
318
|
+
name
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
initialQuote {
|
|
322
|
+
source {
|
|
323
|
+
actor {
|
|
324
|
+
app
|
|
325
|
+
name
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
questionAnswers {
|
|
331
|
+
answer
|
|
332
|
+
questionText
|
|
333
|
+
questionLocationSnapshot {
|
|
334
|
+
latitude
|
|
335
|
+
longitude
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
tickets {
|
|
339
|
+
questionAnswers {
|
|
340
|
+
answer
|
|
341
|
+
questionText
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
resourcePoolAssignments {
|
|
345
|
+
quantity
|
|
346
|
+
resourcePool {
|
|
347
|
+
name
|
|
348
|
+
shortName
|
|
349
|
+
resources {
|
|
350
|
+
name
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
resourceAssignments {
|
|
354
|
+
resource {
|
|
355
|
+
id
|
|
356
|
+
name
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
`;
|
|
361
|
+
var PRICE_BREAKDOWN_FIELDS = `
|
|
362
|
+
convenienceFee { amount formatted }
|
|
363
|
+
deposit { amount formatted }
|
|
364
|
+
discount { amount formatted }
|
|
365
|
+
discountedPrice { amount formatted }
|
|
366
|
+
fees { amount formatted }
|
|
367
|
+
flatPartnerFee { amount formatted }
|
|
368
|
+
price { amount formatted }
|
|
369
|
+
retailPrice { amount formatted }
|
|
370
|
+
taxes { amount formatted }
|
|
371
|
+
tips { amount formatted }
|
|
372
|
+
`;
|
|
373
|
+
var TICKET_VALUE_FIELDS = `
|
|
374
|
+
value {
|
|
375
|
+
price { amount formatted }
|
|
376
|
+
total { amount formatted }
|
|
377
|
+
}
|
|
378
|
+
`;
|
|
379
|
+
function buildBookingsListingQuery(includeGuests, includePriceBreakdown) {
|
|
380
|
+
const guestsSection = includeGuests ? bookingGuestsFields : "";
|
|
381
|
+
const fields = includePriceBreakdown ? bookingQueryFields.replace("value {", `value { ${PRICE_BREAKDOWN_FIELDS}`).replace("ticketQuantities {", `ticketQuantities { ${TICKET_VALUE_FIELDS}`) : bookingQueryFields;
|
|
382
|
+
return `
|
|
383
|
+
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
384
|
+
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
385
|
+
pageInfo { endCursor hasNextPage }
|
|
386
|
+
edges {
|
|
387
|
+
node {
|
|
388
|
+
... on Booking {
|
|
389
|
+
${fields}
|
|
390
|
+
${guestsSection}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
`;
|
|
397
|
+
}
|
|
398
|
+
var BOOKING_GUESTS_QUERY = `
|
|
399
|
+
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
400
|
+
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
401
|
+
pageInfo { endCursor hasNextPage }
|
|
402
|
+
edges {
|
|
403
|
+
node {
|
|
404
|
+
... on Booking {
|
|
405
|
+
displayId
|
|
406
|
+
id
|
|
407
|
+
${bookingGuestsFields}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
`;
|
|
414
|
+
var BOOKING_PAYMENTS_ON_FILE_QUERY = `
|
|
415
|
+
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
416
|
+
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
417
|
+
pageInfo { endCursor hasNextPage }
|
|
418
|
+
edges {
|
|
419
|
+
node {
|
|
420
|
+
order {
|
|
421
|
+
payments {
|
|
422
|
+
id
|
|
423
|
+
paymentSource { id }
|
|
424
|
+
appliedAt
|
|
425
|
+
currentAmount { amount currency }
|
|
426
|
+
refundableAmount { amount currency }
|
|
427
|
+
}
|
|
428
|
+
id
|
|
429
|
+
displayId
|
|
430
|
+
paymentSources { description type id }
|
|
431
|
+
}
|
|
432
|
+
... on Booking {
|
|
433
|
+
displayId
|
|
434
|
+
id
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
`;
|
|
441
|
+
var UPDATE_OPERATOR_NOTES_MUTATION = `
|
|
442
|
+
mutation Account($input: UpdateOperatorNotesForBookingInput!) {
|
|
443
|
+
updateOperatorNotesForBooking(input: $input) {
|
|
444
|
+
booking { operatorNotes }
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
`;
|
|
448
|
+
var UPDATE_BOOKING_CHECKIN_MUTATION = `
|
|
449
|
+
mutation Account($input: UpdateBookingCheckInInput!) {
|
|
450
|
+
updateBookingCheckIn(input: $input) {
|
|
451
|
+
booking { checkinStatus }
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
`;
|
|
455
|
+
var CANCEL_BOOKING_MUTATION = `
|
|
456
|
+
mutation Account($input: CancelBookingInput!) {
|
|
457
|
+
cancelBooking(input: $input) {
|
|
458
|
+
booking { id displayId reservationStatus }
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
`;
|
|
462
|
+
var APPLY_PAYMENT_TO_ORDER_MUTATION = `
|
|
463
|
+
mutation ApplyPaymentToOrder($input: ApplyPaymentToOrderInput!) {
|
|
464
|
+
applyPaymentToOrder(input: $input) {
|
|
465
|
+
transactionId
|
|
466
|
+
errors { code detail value }
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
`;
|
|
470
|
+
var APPLY_REFUND_TO_ORDER_MUTATION = `
|
|
471
|
+
mutation ApplyRefundToOrder($input: ApplyRefundToOrderInput!) {
|
|
472
|
+
applyRefundToOrder(input: $input) {
|
|
473
|
+
transactionId
|
|
474
|
+
errors { code detail value }
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
`;
|
|
478
|
+
var CREATE_INVOICE_LINK_MUTATION = `
|
|
479
|
+
mutation CreateInvoiceLink($input: CreateInvoiceLinkInput!) {
|
|
480
|
+
createInvoiceLink(input: $input) {
|
|
481
|
+
invoiceLink { status url }
|
|
482
|
+
errors { code detail value __typename }
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
`;
|
|
486
|
+
var CREATE_QUOTE_FROM_ORDER_MUTATION = `
|
|
487
|
+
mutation CreateQuoteFromOrder($input: CreateQuoteFromOrderInput!) {
|
|
488
|
+
createQuoteFromOrder(input: $input) {
|
|
489
|
+
errors { detail value code }
|
|
490
|
+
quote {
|
|
491
|
+
id
|
|
492
|
+
saleQuotes { refid reservationStatus }
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
`;
|
|
497
|
+
var UPDATE_QUOTE_V2_MUTATION = `
|
|
498
|
+
mutation UpdateQuoteV2($input: UpdateQuoteV2Input!) {
|
|
499
|
+
updateQuoteV2(input: $input) {
|
|
500
|
+
errors { detail value code }
|
|
501
|
+
quote { id }
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
`;
|
|
505
|
+
var AMEND_ORDER_MUTATION = `
|
|
506
|
+
mutation AmendOrder($input: AmendOrderInput!) {
|
|
507
|
+
amendOrder(input: $input) {
|
|
508
|
+
errors { code detail value }
|
|
509
|
+
order { id }
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
`;
|
|
513
|
+
var CREATE_QUOTE_V2_MUTATION = `
|
|
514
|
+
mutation CreateQuoteV2($input: CreateQuoteV2Input!) {
|
|
515
|
+
createQuoteV2(input: $input) {
|
|
516
|
+
errors { detail value code }
|
|
517
|
+
quote { id }
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
`;
|
|
521
|
+
var CREATE_ORDER_FROM_QUOTE_MUTATION = `
|
|
522
|
+
mutation CreateOrderFromQuote($input: CreateOrderFromQuoteInput!) {
|
|
523
|
+
createOrderFromQuote(input: $input) {
|
|
524
|
+
errors { code detail value }
|
|
525
|
+
order {
|
|
526
|
+
id
|
|
527
|
+
sales {
|
|
528
|
+
id
|
|
529
|
+
displayId
|
|
530
|
+
... on Booking {
|
|
531
|
+
balance { total { amount currency formatted } }
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
`;
|
|
538
|
+
function buildBookingsVariables(params) {
|
|
539
|
+
const filter = {};
|
|
540
|
+
const bookingFilter = {};
|
|
541
|
+
if (params.bookingId) {
|
|
542
|
+
bookingFilter.ids = [normalizeBookingId(params.bookingId)];
|
|
543
|
+
} else if (params.timeslotId) {
|
|
544
|
+
bookingFilter.timeslotRefid = params.timeslotId;
|
|
545
|
+
} else {
|
|
546
|
+
if (params.searchBy === SEARCH_BY_ACTIVITY_DATE) {
|
|
547
|
+
bookingFilter.overlapsRange = `[${params.startDateTime},${params.endDateTime}]`;
|
|
548
|
+
} else if (params.searchBy === SEARCH_BY_PURCHASE_DATE) {
|
|
549
|
+
filter.purchasedAtRangeUtc = `[${params.startDateTime},${params.endDateTime}]`;
|
|
550
|
+
}
|
|
551
|
+
if (params.productId) {
|
|
552
|
+
bookingFilter.activityIds = [params.productId];
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
if (params.email) {
|
|
556
|
+
filter.primaryGuestEmail = params.email;
|
|
557
|
+
}
|
|
558
|
+
if (params.searchString && params.searchString.length > 0) {
|
|
559
|
+
filter.searchString = params.searchString;
|
|
560
|
+
}
|
|
561
|
+
if (Object.keys(bookingFilter).length > 0) {
|
|
562
|
+
filter.bookingFilter = bookingFilter;
|
|
563
|
+
}
|
|
564
|
+
return {
|
|
565
|
+
first: params.pageSize,
|
|
566
|
+
after: params.after,
|
|
567
|
+
orderBy: { direction: "ASC", field: "STARTS_AT" },
|
|
568
|
+
filter
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// src/internal/peek/bookings/booking-converter.ts
|
|
212
573
|
var UNKNOWN = "unknown";
|
|
574
|
+
var PEEK_PRO_DEEP_LINK_BASE = "http://pro-app.peek.com/-/order";
|
|
213
575
|
var SOURCE_SOURCE_MAP = {
|
|
214
576
|
APP_REGISTRY: "app",
|
|
215
577
|
BOOKING_IMPORTER_FUTURE: "importer",
|
|
@@ -325,6 +687,7 @@ function fromBookingNode(node, includeGuests = false, includePriceBreakdown = fa
|
|
|
325
687
|
resellerId: data.order?.channelSnapshot?.id || null,
|
|
326
688
|
resellerName: resellerNameFromChannelSnapshot(data.order?.channelSnapshot),
|
|
327
689
|
orderId: data.order?.id || "",
|
|
690
|
+
peekProBookingDeepLink: buildPeekProBookingDeepLink(data.order?.id, data.id),
|
|
328
691
|
convenienceFee: includePriceBreakdown ? mapPrice(data.value?.convenienceFee) : void 0,
|
|
329
692
|
deposit: includePriceBreakdown ? mapPrice(data.value?.deposit) : void 0,
|
|
330
693
|
discount: includePriceBreakdown ? mapPrice(data.value?.discount) : void 0,
|
|
@@ -352,618 +715,261 @@ function convertGuests(data) {
|
|
|
352
715
|
}
|
|
353
716
|
return guests;
|
|
354
717
|
}
|
|
355
|
-
function mapGuestNode(guestNode, isPrimary) {
|
|
356
|
-
const fieldResponses = Array.isArray(guestNode.fieldResponses) ? guestNode.fieldResponses : [];
|
|
357
|
-
const metadata = fieldResponses.map((response) => ({
|
|
358
|
-
id: response.id,
|
|
359
|
-
name: response.fieldLocation?.field?.name ?? "",
|
|
360
|
-
value: response.text ?? ""
|
|
361
|
-
}));
|
|
362
|
-
return {
|
|
363
|
-
id: guestNode.id,
|
|
364
|
-
name: guestNode.name ?? null,
|
|
365
|
-
country: guestNode.country ?? null,
|
|
366
|
-
dateOfBirth: guestNode.dateOfBirth ? new Date(guestNode.dateOfBirth) : null,
|
|
367
|
-
phone: guestNode.phone ?? null,
|
|
368
|
-
email: guestNode.email ?? null,
|
|
369
|
-
isGdpr: Boolean(guestNode.isGdpr),
|
|
370
|
-
isParticipant: Boolean(guestNode.isParticipant),
|
|
371
|
-
isPrimary,
|
|
372
|
-
optinSms: Boolean(guestNode.optinSms),
|
|
373
|
-
optinMarketing: Boolean(guestNode.optinMarketing),
|
|
374
|
-
postalCode: guestNode.postalCode ?? null,
|
|
375
|
-
metadata
|
|
376
|
-
};
|
|
377
|
-
}
|
|
378
|
-
function sourceFromApp(app) {
|
|
379
|
-
if (!app) return UNKNOWN;
|
|
380
|
-
return SOURCE_SOURCE_MAP[app] ?? UNKNOWN;
|
|
381
|
-
}
|
|
382
|
-
function sourceDescriptionFromApp(app) {
|
|
383
|
-
if (!app) return UNKNOWN;
|
|
384
|
-
return SOURCE_DESC_MAP[app] ?? UNKNOWN;
|
|
385
|
-
}
|
|
386
|
-
function resellerNameFromChannelSnapshot(channelSnapshot) {
|
|
387
|
-
if (!channelSnapshot) return null;
|
|
388
|
-
let out = channelSnapshot.name ?? "";
|
|
389
|
-
if (channelSnapshot.agent?.name) {
|
|
390
|
-
out += " - " + channelSnapshot.agent.name;
|
|
391
|
-
}
|
|
392
|
-
return out;
|
|
393
|
-
}
|
|
394
|
-
function ticketsToTicketArray(ticketQuantities, includePriceBreakdown) {
|
|
395
|
-
if (!ticketQuantities || ticketQuantities.length === 0) return [];
|
|
396
|
-
return ticketQuantities.map((ticket) => ({
|
|
397
|
-
name: ticket.resourceOptionSnapshot?.name || "Unknown",
|
|
398
|
-
quantity: ticket.quantity || 0,
|
|
399
|
-
ticketId: ticket.resourceOptionSnapshot?.id || "unknown",
|
|
400
|
-
listPrice: includePriceBreakdown ? mapPrice(ticket.value?.price) : void 0,
|
|
401
|
-
totalValue: includePriceBreakdown ? mapPrice(ticket.value?.total) : void 0
|
|
402
|
-
}));
|
|
403
|
-
}
|
|
404
|
-
function durationInMin(startsAt, endsAt) {
|
|
405
|
-
if (!startsAt || !endsAt) return 0;
|
|
406
|
-
const duration = new Date(endsAt).getTime() - new Date(startsAt).getTime();
|
|
407
|
-
return Math.floor(duration / 1e3 / 60);
|
|
408
|
-
}
|
|
409
|
-
function ticketQuantity(ticketQuantities) {
|
|
410
|
-
if (!ticketQuantities || ticketQuantities.length === 0) return 0;
|
|
411
|
-
return ticketQuantities.reduce((acc, ticket) => acc + (ticket.quantity || 0), 0);
|
|
412
|
-
}
|
|
413
|
-
function formatTickets(ticketQuantities) {
|
|
414
|
-
if (!ticketQuantities || ticketQuantities.length === 0) return "";
|
|
415
|
-
return ticketQuantities.map((ticket) => `${ticket.quantity || 0}x ${ticket.resourceOptionSnapshot?.name || "Unknown"}`).join(", ");
|
|
416
|
-
}
|
|
417
|
-
function mapResourcePoolAssignments(poolAssignments) {
|
|
418
|
-
if (!poolAssignments || poolAssignments.length === 0) return [];
|
|
419
|
-
return poolAssignments.flatMap(
|
|
420
|
-
(pool) => (pool.resourceAssignments ?? []).map((assignment) => ({
|
|
421
|
-
id: assignment.resource?.id || "",
|
|
422
|
-
name: assignment.resource?.name || ""
|
|
423
|
-
}))
|
|
424
|
-
);
|
|
425
|
-
}
|
|
426
|
-
function mapPrice(priceData) {
|
|
427
|
-
if (!priceData || !priceData.amount && !priceData.formatted) {
|
|
428
|
-
return void 0;
|
|
429
|
-
}
|
|
430
|
-
return {
|
|
431
|
-
amount: priceData.amount || "0",
|
|
432
|
-
display: priceData.formatted || ""
|
|
433
|
-
};
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// src/internal/bookings/booking-guest-converter.ts
|
|
437
|
-
function fromBookingGuestsResponse(response) {
|
|
438
|
-
const firstEdge = (response?.sales?.edges ?? [])[0];
|
|
439
|
-
if (!firstEdge) {
|
|
440
|
-
return [];
|
|
441
|
-
}
|
|
442
|
-
const bookingNode = firstEdge.node;
|
|
443
|
-
const primaryGuestNode = bookingNode.primaryGuest;
|
|
444
|
-
const bookingGuestsNodes = Array.isArray(bookingNode.bookingGuests) ? bookingNode.bookingGuests : [];
|
|
445
|
-
const primaryId = primaryGuestNode?.id;
|
|
446
|
-
const guests = [];
|
|
447
|
-
for (const guestNode of bookingGuestsNodes) {
|
|
448
|
-
guests.push(mapGuestNode(guestNode, primaryId ? guestNode.id === primaryId : false));
|
|
449
|
-
}
|
|
450
|
-
const hasPrimaryInGuests = primaryId ? bookingGuestsNodes.some((guest) => guest.id === primaryId) : false;
|
|
451
|
-
if (!hasPrimaryInGuests && primaryGuestNode) {
|
|
452
|
-
guests.push(mapGuestNode(primaryGuestNode, true));
|
|
453
|
-
}
|
|
454
|
-
return guests;
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
// src/internal/bookings/payments-on-file-converter.ts
|
|
458
|
-
function fromPaymentsOnFileResponse(response, bookingId) {
|
|
459
|
-
const firstEdge = (response?.sales?.edges ?? [])[0];
|
|
460
|
-
if (!firstEdge) {
|
|
461
|
-
return null;
|
|
462
|
-
}
|
|
463
|
-
const order = firstEdge.node.order;
|
|
464
|
-
const orderId = order?.id ?? "";
|
|
465
|
-
const rawPaymentSources = order?.paymentSources ?? [];
|
|
466
|
-
const rawPayments = order?.payments ?? [];
|
|
467
|
-
const paymentsBySourceId = /* @__PURE__ */ new Map();
|
|
468
|
-
for (const payment of rawPayments) {
|
|
469
|
-
const sourceId = payment.paymentSource?.id;
|
|
470
|
-
if (!sourceId) continue;
|
|
471
|
-
const mapped = {
|
|
472
|
-
id: payment.id,
|
|
473
|
-
paidAt: dateOnly(payment.appliedAt),
|
|
474
|
-
currentAmount: payment.currentAmount,
|
|
475
|
-
refundableAmount: payment.refundableAmount
|
|
476
|
-
};
|
|
477
|
-
const existing = paymentsBySourceId.get(sourceId);
|
|
478
|
-
if (existing) {
|
|
479
|
-
existing.push(mapped);
|
|
480
|
-
} else {
|
|
481
|
-
paymentsBySourceId.set(sourceId, [mapped]);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
const paymentsOnFile = rawPaymentSources.map((source) => {
|
|
485
|
-
const payments = paymentsBySourceId.get(source.id);
|
|
486
|
-
return {
|
|
487
|
-
description: source.description,
|
|
488
|
-
id: source.id,
|
|
489
|
-
type: source.type,
|
|
490
|
-
...payments ? { payments } : {}
|
|
491
|
-
};
|
|
492
|
-
});
|
|
493
|
-
return { bookingId, orderId, paymentsOnFile };
|
|
494
|
-
}
|
|
495
|
-
function dateOnly(iso) {
|
|
496
|
-
return iso.split("T")[0] ?? iso;
|
|
497
|
-
}
|
|
498
|
-
|
|
499
|
-
// src/internal/bookings/addon-queries.ts
|
|
500
|
-
var RESERVATION_STATUS_CONFIRMED = "CONFIRMED";
|
|
501
|
-
var ADDON_OPTION_STATUS_CANCELED = "CANCELED";
|
|
502
|
-
var SALES_ADDONS_PAGE_SIZE = 100;
|
|
503
|
-
var SALES_ADDONS_QUERY = `
|
|
504
|
-
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
505
|
-
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
506
|
-
pageInfo { endCursor hasNextPage }
|
|
507
|
-
edges {
|
|
508
|
-
node {
|
|
509
|
-
order { id displayId }
|
|
510
|
-
... on Booking {
|
|
511
|
-
displayId
|
|
512
|
-
id
|
|
513
|
-
refid
|
|
514
|
-
reservationStatus
|
|
515
|
-
items {
|
|
516
|
-
id
|
|
517
|
-
refid
|
|
518
|
-
value { total { amount currency formatted } }
|
|
519
|
-
reservationStatus
|
|
520
|
-
options {
|
|
521
|
-
refid
|
|
522
|
-
reservationStatus
|
|
523
|
-
price { amount currency formatted }
|
|
524
|
-
itemOptionSnapshot { id name }
|
|
525
|
-
itemSnapshot { id name }
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
`;
|
|
534
|
-
function buildSalesAddonsVariables(searchString) {
|
|
718
|
+
function mapGuestNode(guestNode, isPrimary) {
|
|
719
|
+
const fieldResponses = Array.isArray(guestNode.fieldResponses) ? guestNode.fieldResponses : [];
|
|
720
|
+
const metadata = fieldResponses.map((response) => ({
|
|
721
|
+
id: response.id,
|
|
722
|
+
name: response.fieldLocation?.field?.name ?? "",
|
|
723
|
+
value: response.text ?? ""
|
|
724
|
+
}));
|
|
535
725
|
return {
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
726
|
+
id: guestNode.id,
|
|
727
|
+
name: guestNode.name ?? null,
|
|
728
|
+
country: guestNode.country ?? null,
|
|
729
|
+
dateOfBirth: guestNode.dateOfBirth ? new Date(guestNode.dateOfBirth) : null,
|
|
730
|
+
phone: guestNode.phone ?? null,
|
|
731
|
+
email: guestNode.email ?? null,
|
|
732
|
+
isGdpr: Boolean(guestNode.isGdpr),
|
|
733
|
+
isParticipant: Boolean(guestNode.isParticipant),
|
|
734
|
+
isPrimary,
|
|
735
|
+
optinSms: Boolean(guestNode.optinSms),
|
|
736
|
+
optinMarketing: Boolean(guestNode.optinMarketing),
|
|
737
|
+
postalCode: guestNode.postalCode ?? null,
|
|
738
|
+
metadata
|
|
540
739
|
};
|
|
541
740
|
}
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
function parseSaleNode(node) {
|
|
546
|
-
const bookingId = node.id || "";
|
|
547
|
-
const displayId = node.displayId || "";
|
|
548
|
-
const orderId = node.order?.id || "";
|
|
549
|
-
const bookingQuoteRefid = node.refid || "";
|
|
550
|
-
const bookingQuoteReservationStatus = node.reservationStatus || "";
|
|
551
|
-
const items = Array.isArray(node.items) ? node.items : [];
|
|
552
|
-
return items.map((item) => {
|
|
553
|
-
const options = Array.isArray(item.options) ? item.options : [];
|
|
554
|
-
const addonItemOptions = options.map((opt) => ({
|
|
555
|
-
itemId: opt.itemSnapshot?.id || "",
|
|
556
|
-
optionId: opt.itemOptionSnapshot?.id || "",
|
|
557
|
-
itemName: opt.itemSnapshot?.name || "",
|
|
558
|
-
optionName: opt.itemOptionSnapshot?.name || "",
|
|
559
|
-
optionRefid: opt.refid || "",
|
|
560
|
-
optionReservationStatus: opt.reservationStatus || "",
|
|
561
|
-
itemReservationStatus: item.reservationStatus || "",
|
|
562
|
-
itemRefid: item.refid || ""
|
|
563
|
-
}));
|
|
564
|
-
return {
|
|
565
|
-
bookingId,
|
|
566
|
-
displayId,
|
|
567
|
-
orderId,
|
|
568
|
-
total: item.value?.total ?? null,
|
|
569
|
-
bookingQuoteRefid,
|
|
570
|
-
bookingQuoteReservationStatus,
|
|
571
|
-
addonItemOptions
|
|
572
|
-
};
|
|
573
|
-
});
|
|
741
|
+
function buildPeekProBookingDeepLink(orderId, bookingId) {
|
|
742
|
+
if (!orderId || !bookingId) return "";
|
|
743
|
+
return `${PEEK_PRO_DEEP_LINK_BASE}%2F${normalizeBookingId(orderId)}%3FsaleId=${normalizeBookingId(bookingId)}`;
|
|
574
744
|
}
|
|
575
|
-
function
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
return null;
|
|
579
|
-
}
|
|
580
|
-
const addonId = options[0].itemId;
|
|
581
|
-
const addonName = options[0].itemName;
|
|
582
|
-
if (options.some((opt) => opt.itemId !== addonId)) {
|
|
583
|
-
throw new Error(ERROR_INCONSISTENT_ADDON_ITEM_ID);
|
|
584
|
-
}
|
|
585
|
-
const grouped = /* @__PURE__ */ new Map();
|
|
586
|
-
options.filter((opt) => opt.optionReservationStatus !== ADDON_OPTION_STATUS_CANCELED).forEach((opt) => {
|
|
587
|
-
const existing = grouped.get(opt.optionId);
|
|
588
|
-
if (existing) {
|
|
589
|
-
existing.quantity += 1;
|
|
590
|
-
} else {
|
|
591
|
-
grouped.set(opt.optionId, {
|
|
592
|
-
addonOptionId: opt.optionId,
|
|
593
|
-
addonOptionName: opt.optionName,
|
|
594
|
-
quantity: 1
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
});
|
|
598
|
-
const addonOptions = Array.from(grouped.values());
|
|
599
|
-
if (addonOptions.length === 0) {
|
|
600
|
-
return null;
|
|
601
|
-
}
|
|
602
|
-
return { addonId, addonName, total: item.total, addonOptions };
|
|
745
|
+
function sourceFromApp(app) {
|
|
746
|
+
if (!app) return UNKNOWN;
|
|
747
|
+
return SOURCE_SOURCE_MAP[app] ?? UNKNOWN;
|
|
603
748
|
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
var SEARCH_BY_ACTIVITY_DATE = "activityDate";
|
|
608
|
-
function normalizeBookingId(bookingId) {
|
|
609
|
-
return bookingId.toLowerCase().replace(/-/g, "_");
|
|
749
|
+
function sourceDescriptionFromApp(app) {
|
|
750
|
+
if (!app) return UNKNOWN;
|
|
751
|
+
return SOURCE_DESC_MAP[app] ?? UNKNOWN;
|
|
610
752
|
}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
name
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
email
|
|
617
|
-
isGdpr
|
|
618
|
-
isParticipant
|
|
619
|
-
optinSms
|
|
620
|
-
optinMarketing
|
|
621
|
-
phone
|
|
622
|
-
postalCode
|
|
623
|
-
fieldResponses {
|
|
624
|
-
id
|
|
625
|
-
text
|
|
626
|
-
fieldLocation {
|
|
627
|
-
field {
|
|
628
|
-
name
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
`;
|
|
633
|
-
var bookingGuestsFields = `
|
|
634
|
-
bookingGuests {
|
|
635
|
-
${guestFields}
|
|
636
|
-
}
|
|
637
|
-
primaryGuest {
|
|
638
|
-
${guestFields}
|
|
639
|
-
}
|
|
640
|
-
`;
|
|
641
|
-
var bookingQueryFields = `
|
|
642
|
-
displayId
|
|
643
|
-
id
|
|
644
|
-
primaryGuest {
|
|
645
|
-
name
|
|
646
|
-
email
|
|
647
|
-
phone
|
|
648
|
-
optinMarketing
|
|
649
|
-
optinSms
|
|
650
|
-
isGdpr
|
|
651
|
-
postalCode
|
|
652
|
-
}
|
|
653
|
-
activitySnapshot {
|
|
654
|
-
type
|
|
655
|
-
name
|
|
656
|
-
id
|
|
657
|
-
}
|
|
658
|
-
ticketQuantities {
|
|
659
|
-
quantity
|
|
660
|
-
resourceOptionSnapshot {
|
|
661
|
-
name
|
|
662
|
-
id
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
reservationStatus
|
|
666
|
-
checkinStatus
|
|
667
|
-
returnStatus
|
|
668
|
-
fulfillmentStatusOverride {
|
|
669
|
-
status
|
|
670
|
-
}
|
|
671
|
-
timeSnapshot {
|
|
672
|
-
id
|
|
673
|
-
legacyId
|
|
674
|
-
}
|
|
675
|
-
purchasedAt
|
|
676
|
-
purchasedAtUtc
|
|
677
|
-
startsAt
|
|
678
|
-
startsAtUtc
|
|
679
|
-
endsAt
|
|
680
|
-
endsAtUtc
|
|
681
|
-
availabilityTimeId
|
|
682
|
-
bookingPortalUrl
|
|
683
|
-
operatorNotes
|
|
684
|
-
value {
|
|
685
|
-
total {
|
|
686
|
-
formatted
|
|
687
|
-
amount
|
|
688
|
-
}
|
|
689
|
-
}
|
|
690
|
-
balance {
|
|
691
|
-
total {
|
|
692
|
-
amount
|
|
693
|
-
formatted
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
tips {
|
|
697
|
-
price {
|
|
698
|
-
amount
|
|
699
|
-
formatted
|
|
700
|
-
}
|
|
753
|
+
function resellerNameFromChannelSnapshot(channelSnapshot) {
|
|
754
|
+
if (!channelSnapshot) return null;
|
|
755
|
+
let out = channelSnapshot.name ?? "";
|
|
756
|
+
if (channelSnapshot.agent?.name) {
|
|
757
|
+
out += " - " + channelSnapshot.agent.name;
|
|
701
758
|
}
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
759
|
+
return out;
|
|
760
|
+
}
|
|
761
|
+
function ticketsToTicketArray(ticketQuantities, includePriceBreakdown) {
|
|
762
|
+
if (!ticketQuantities || ticketQuantities.length === 0) return [];
|
|
763
|
+
return ticketQuantities.map((ticket) => ({
|
|
764
|
+
name: ticket.resourceOptionSnapshot?.name || "Unknown",
|
|
765
|
+
quantity: ticket.quantity || 0,
|
|
766
|
+
ticketId: ticket.resourceOptionSnapshot?.id || "unknown",
|
|
767
|
+
listPrice: includePriceBreakdown ? mapPrice(ticket.value?.price) : void 0,
|
|
768
|
+
totalValue: includePriceBreakdown ? mapPrice(ticket.value?.total) : void 0
|
|
769
|
+
}));
|
|
770
|
+
}
|
|
771
|
+
function durationInMin(startsAt, endsAt) {
|
|
772
|
+
if (!startsAt || !endsAt) return 0;
|
|
773
|
+
const duration = new Date(endsAt).getTime() - new Date(startsAt).getTime();
|
|
774
|
+
return Math.floor(duration / 1e3 / 60);
|
|
775
|
+
}
|
|
776
|
+
function ticketQuantity(ticketQuantities) {
|
|
777
|
+
if (!ticketQuantities || ticketQuantities.length === 0) return 0;
|
|
778
|
+
return ticketQuantities.reduce((acc, ticket) => acc + (ticket.quantity || 0), 0);
|
|
779
|
+
}
|
|
780
|
+
function formatTickets(ticketQuantities) {
|
|
781
|
+
if (!ticketQuantities || ticketQuantities.length === 0) return "";
|
|
782
|
+
return ticketQuantities.map((ticket) => `${ticket.quantity || 0}x ${ticket.resourceOptionSnapshot?.name || "Unknown"}`).join(", ");
|
|
783
|
+
}
|
|
784
|
+
function mapResourcePoolAssignments(poolAssignments) {
|
|
785
|
+
if (!poolAssignments || poolAssignments.length === 0) return [];
|
|
786
|
+
return poolAssignments.flatMap(
|
|
787
|
+
(pool) => (pool.resourceAssignments ?? []).map((assignment) => ({
|
|
788
|
+
id: assignment.resource?.id || "",
|
|
789
|
+
name: assignment.resource?.name || ""
|
|
790
|
+
}))
|
|
791
|
+
);
|
|
792
|
+
}
|
|
793
|
+
function mapPrice(priceData) {
|
|
794
|
+
if (!priceData || !priceData.amount && !priceData.formatted) {
|
|
795
|
+
return void 0;
|
|
723
796
|
}
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
797
|
+
return {
|
|
798
|
+
amount: priceData.amount || "0",
|
|
799
|
+
display: priceData.formatted || ""
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
// src/internal/peek/bookings/booking-guest-converter.ts
|
|
804
|
+
function fromBookingGuestsResponse(response) {
|
|
805
|
+
const firstEdge = (response?.sales?.edges ?? [])[0];
|
|
806
|
+
if (!firstEdge) {
|
|
807
|
+
return [];
|
|
731
808
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
809
|
+
const bookingNode = firstEdge.node;
|
|
810
|
+
const primaryGuestNode = bookingNode.primaryGuest;
|
|
811
|
+
const bookingGuestsNodes = Array.isArray(bookingNode.bookingGuests) ? bookingNode.bookingGuests : [];
|
|
812
|
+
const primaryId = primaryGuestNode?.id;
|
|
813
|
+
const guests = [];
|
|
814
|
+
for (const guestNode of bookingGuestsNodes) {
|
|
815
|
+
guests.push(mapGuestNode(guestNode, primaryId ? guestNode.id === primaryId : false));
|
|
737
816
|
}
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
name
|
|
742
|
-
shortName
|
|
743
|
-
resources {
|
|
744
|
-
name
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
resourceAssignments {
|
|
748
|
-
resource {
|
|
749
|
-
id
|
|
750
|
-
name
|
|
751
|
-
}
|
|
752
|
-
}
|
|
817
|
+
const hasPrimaryInGuests = primaryId ? bookingGuestsNodes.some((guest) => guest.id === primaryId) : false;
|
|
818
|
+
if (!hasPrimaryInGuests && primaryGuestNode) {
|
|
819
|
+
guests.push(mapGuestNode(primaryGuestNode, true));
|
|
753
820
|
}
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
price { amount formatted }
|
|
763
|
-
retailPrice { amount formatted }
|
|
764
|
-
taxes { amount formatted }
|
|
765
|
-
tips { amount formatted }
|
|
766
|
-
`;
|
|
767
|
-
var TICKET_VALUE_FIELDS = `
|
|
768
|
-
value {
|
|
769
|
-
price { amount formatted }
|
|
770
|
-
total { amount formatted }
|
|
821
|
+
return guests;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
// src/internal/peek/bookings/payments-on-file-converter.ts
|
|
825
|
+
function fromPaymentsOnFileResponse(response, bookingId) {
|
|
826
|
+
const firstEdge = (response?.sales?.edges ?? [])[0];
|
|
827
|
+
if (!firstEdge) {
|
|
828
|
+
return null;
|
|
771
829
|
}
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
const
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
830
|
+
const order = firstEdge.node.order;
|
|
831
|
+
const orderId = order?.id ?? "";
|
|
832
|
+
const rawPaymentSources = order?.paymentSources ?? [];
|
|
833
|
+
const rawPayments = order?.payments ?? [];
|
|
834
|
+
const paymentsBySourceId = /* @__PURE__ */ new Map();
|
|
835
|
+
for (const payment of rawPayments) {
|
|
836
|
+
const sourceId = payment.paymentSource?.id;
|
|
837
|
+
if (!sourceId) continue;
|
|
838
|
+
const mapped = {
|
|
839
|
+
id: payment.id,
|
|
840
|
+
paidAt: dateOnly(payment.appliedAt),
|
|
841
|
+
currentAmount: payment.currentAmount,
|
|
842
|
+
refundableAmount: payment.refundableAmount
|
|
843
|
+
};
|
|
844
|
+
const existing = paymentsBySourceId.get(sourceId);
|
|
845
|
+
if (existing) {
|
|
846
|
+
existing.push(mapped);
|
|
847
|
+
} else {
|
|
848
|
+
paymentsBySourceId.set(sourceId, [mapped]);
|
|
789
849
|
}
|
|
790
|
-
|
|
850
|
+
}
|
|
851
|
+
const paymentsOnFile = rawPaymentSources.map((source) => {
|
|
852
|
+
const payments = paymentsBySourceId.get(source.id);
|
|
853
|
+
return {
|
|
854
|
+
description: source.description,
|
|
855
|
+
id: source.id,
|
|
856
|
+
type: source.type,
|
|
857
|
+
...payments ? { payments } : {}
|
|
858
|
+
};
|
|
859
|
+
});
|
|
860
|
+
return { bookingId, orderId, paymentsOnFile };
|
|
791
861
|
}
|
|
792
|
-
|
|
862
|
+
function dateOnly(iso) {
|
|
863
|
+
return iso.split("T")[0] ?? iso;
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
// src/internal/peek/bookings/addon-queries.ts
|
|
867
|
+
var RESERVATION_STATUS_CONFIRMED = "CONFIRMED";
|
|
868
|
+
var ADDON_OPTION_STATUS_CANCELED = "CANCELED";
|
|
869
|
+
var SALES_ADDONS_PAGE_SIZE = 100;
|
|
870
|
+
var SALES_ADDONS_QUERY = `
|
|
793
871
|
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
794
872
|
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
795
873
|
pageInfo { endCursor hasNextPage }
|
|
796
874
|
edges {
|
|
797
875
|
node {
|
|
876
|
+
order { id displayId }
|
|
798
877
|
... on Booking {
|
|
799
878
|
displayId
|
|
800
879
|
id
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
}
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
`;
|
|
808
|
-
var BOOKING_PAYMENTS_ON_FILE_QUERY = `
|
|
809
|
-
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
810
|
-
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
811
|
-
pageInfo { endCursor hasNextPage }
|
|
812
|
-
edges {
|
|
813
|
-
node {
|
|
814
|
-
order {
|
|
815
|
-
payments {
|
|
880
|
+
refid
|
|
881
|
+
reservationStatus
|
|
882
|
+
items {
|
|
816
883
|
id
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
id
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
`;
|
|
835
|
-
var UPDATE_OPERATOR_NOTES_MUTATION = `
|
|
836
|
-
mutation Account($input: UpdateOperatorNotesForBookingInput!) {
|
|
837
|
-
updateOperatorNotesForBooking(input: $input) {
|
|
838
|
-
booking { operatorNotes }
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
`;
|
|
842
|
-
var UPDATE_BOOKING_CHECKIN_MUTATION = `
|
|
843
|
-
mutation Account($input: UpdateBookingCheckInInput!) {
|
|
844
|
-
updateBookingCheckIn(input: $input) {
|
|
845
|
-
booking { checkinStatus }
|
|
846
|
-
}
|
|
847
|
-
}
|
|
848
|
-
`;
|
|
849
|
-
var CANCEL_BOOKING_MUTATION = `
|
|
850
|
-
mutation Account($input: CancelBookingInput!) {
|
|
851
|
-
cancelBooking(input: $input) {
|
|
852
|
-
booking { id displayId reservationStatus }
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
`;
|
|
856
|
-
var APPLY_PAYMENT_TO_ORDER_MUTATION = `
|
|
857
|
-
mutation ApplyPaymentToOrder($input: ApplyPaymentToOrderInput!) {
|
|
858
|
-
applyPaymentToOrder(input: $input) {
|
|
859
|
-
transactionId
|
|
860
|
-
errors { code detail value }
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
`;
|
|
864
|
-
var APPLY_REFUND_TO_ORDER_MUTATION = `
|
|
865
|
-
mutation ApplyRefundToOrder($input: ApplyRefundToOrderInput!) {
|
|
866
|
-
applyRefundToOrder(input: $input) {
|
|
867
|
-
transactionId
|
|
868
|
-
errors { code detail value }
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
`;
|
|
872
|
-
var CREATE_INVOICE_LINK_MUTATION = `
|
|
873
|
-
mutation CreateInvoiceLink($input: CreateInvoiceLinkInput!) {
|
|
874
|
-
createInvoiceLink(input: $input) {
|
|
875
|
-
invoiceLink { status url }
|
|
876
|
-
errors { code detail value __typename }
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
`;
|
|
880
|
-
var CREATE_QUOTE_FROM_ORDER_MUTATION = `
|
|
881
|
-
mutation CreateQuoteFromOrder($input: CreateQuoteFromOrderInput!) {
|
|
882
|
-
createQuoteFromOrder(input: $input) {
|
|
883
|
-
errors { detail value code }
|
|
884
|
-
quote {
|
|
885
|
-
id
|
|
886
|
-
saleQuotes { refid reservationStatus }
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
`;
|
|
891
|
-
var UPDATE_QUOTE_V2_MUTATION = `
|
|
892
|
-
mutation UpdateQuoteV2($input: UpdateQuoteV2Input!) {
|
|
893
|
-
updateQuoteV2(input: $input) {
|
|
894
|
-
errors { detail value code }
|
|
895
|
-
quote { id }
|
|
896
|
-
}
|
|
897
|
-
}
|
|
898
|
-
`;
|
|
899
|
-
var AMEND_ORDER_MUTATION = `
|
|
900
|
-
mutation AmendOrder($input: AmendOrderInput!) {
|
|
901
|
-
amendOrder(input: $input) {
|
|
902
|
-
errors { code detail value }
|
|
903
|
-
order { id }
|
|
904
|
-
}
|
|
905
|
-
}
|
|
906
|
-
`;
|
|
907
|
-
var CREATE_QUOTE_V2_MUTATION = `
|
|
908
|
-
mutation CreateQuoteV2($input: CreateQuoteV2Input!) {
|
|
909
|
-
createQuoteV2(input: $input) {
|
|
910
|
-
errors { detail value code }
|
|
911
|
-
quote { id }
|
|
912
|
-
}
|
|
913
|
-
}
|
|
914
|
-
`;
|
|
915
|
-
var CREATE_ORDER_FROM_QUOTE_MUTATION = `
|
|
916
|
-
mutation CreateOrderFromQuote($input: CreateOrderFromQuoteInput!) {
|
|
917
|
-
createOrderFromQuote(input: $input) {
|
|
918
|
-
errors { code detail value }
|
|
919
|
-
order {
|
|
920
|
-
id
|
|
921
|
-
sales {
|
|
922
|
-
id
|
|
923
|
-
displayId
|
|
924
|
-
... on Booking {
|
|
925
|
-
balance { total { amount currency formatted } }
|
|
884
|
+
refid
|
|
885
|
+
value { total { amount currency formatted } }
|
|
886
|
+
reservationStatus
|
|
887
|
+
options {
|
|
888
|
+
refid
|
|
889
|
+
reservationStatus
|
|
890
|
+
price { amount currency formatted }
|
|
891
|
+
itemOptionSnapshot { id name }
|
|
892
|
+
itemSnapshot { id name }
|
|
893
|
+
}
|
|
894
|
+
}
|
|
926
895
|
}
|
|
927
896
|
}
|
|
928
897
|
}
|
|
929
898
|
}
|
|
930
899
|
}
|
|
931
900
|
`;
|
|
932
|
-
function
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
901
|
+
function buildSalesAddonsVariables(searchString) {
|
|
902
|
+
return {
|
|
903
|
+
first: SALES_ADDONS_PAGE_SIZE,
|
|
904
|
+
after: null,
|
|
905
|
+
orderBy: { direction: "DESC", field: "STARTS_AT" },
|
|
906
|
+
filter: { searchString }
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// src/internal/peek/bookings/addon-converter.ts
|
|
911
|
+
var ERROR_INCONSISTENT_ADDON_ITEM_ID = "Add-on group contains options with mismatched item IDs";
|
|
912
|
+
function parseSaleNode(node) {
|
|
913
|
+
const bookingId = node.id || "";
|
|
914
|
+
const displayId = node.displayId || "";
|
|
915
|
+
const orderId = node.order?.id || "";
|
|
916
|
+
const bookingQuoteRefid = node.refid || "";
|
|
917
|
+
const bookingQuoteReservationStatus = node.reservationStatus || "";
|
|
918
|
+
const items = Array.isArray(node.items) ? node.items : [];
|
|
919
|
+
return items.map((item) => {
|
|
920
|
+
const options = Array.isArray(item.options) ? item.options : [];
|
|
921
|
+
const addonItemOptions = options.map((opt) => ({
|
|
922
|
+
itemId: opt.itemSnapshot?.id || "",
|
|
923
|
+
optionId: opt.itemOptionSnapshot?.id || "",
|
|
924
|
+
itemName: opt.itemSnapshot?.name || "",
|
|
925
|
+
optionName: opt.itemOptionSnapshot?.name || "",
|
|
926
|
+
optionRefid: opt.refid || "",
|
|
927
|
+
optionReservationStatus: opt.reservationStatus || "",
|
|
928
|
+
itemReservationStatus: item.reservationStatus || "",
|
|
929
|
+
itemRefid: item.refid || ""
|
|
930
|
+
}));
|
|
931
|
+
return {
|
|
932
|
+
bookingId,
|
|
933
|
+
displayId,
|
|
934
|
+
orderId,
|
|
935
|
+
total: item.value?.total ?? null,
|
|
936
|
+
bookingQuoteRefid,
|
|
937
|
+
bookingQuoteReservationStatus,
|
|
938
|
+
addonItemOptions
|
|
939
|
+
};
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
function toBookingAddon(item) {
|
|
943
|
+
const options = item.addonItemOptions || [];
|
|
944
|
+
if (options.length === 0) {
|
|
945
|
+
return null;
|
|
951
946
|
}
|
|
952
|
-
|
|
953
|
-
|
|
947
|
+
const addonId = options[0].itemId;
|
|
948
|
+
const addonName = options[0].itemName;
|
|
949
|
+
if (options.some((opt) => opt.itemId !== addonId)) {
|
|
950
|
+
throw new Error(ERROR_INCONSISTENT_ADDON_ITEM_ID);
|
|
954
951
|
}
|
|
955
|
-
|
|
956
|
-
|
|
952
|
+
const grouped = /* @__PURE__ */ new Map();
|
|
953
|
+
options.filter((opt) => opt.optionReservationStatus !== ADDON_OPTION_STATUS_CANCELED).forEach((opt) => {
|
|
954
|
+
const existing = grouped.get(opt.optionId);
|
|
955
|
+
if (existing) {
|
|
956
|
+
existing.quantity += 1;
|
|
957
|
+
} else {
|
|
958
|
+
grouped.set(opt.optionId, {
|
|
959
|
+
addonOptionId: opt.optionId,
|
|
960
|
+
addonOptionName: opt.optionName,
|
|
961
|
+
quantity: 1
|
|
962
|
+
});
|
|
963
|
+
}
|
|
964
|
+
});
|
|
965
|
+
const addonOptions = Array.from(grouped.values());
|
|
966
|
+
if (addonOptions.length === 0) {
|
|
967
|
+
return null;
|
|
957
968
|
}
|
|
958
|
-
return {
|
|
959
|
-
first: params.pageSize,
|
|
960
|
-
after: params.after,
|
|
961
|
-
orderBy: { direction: "ASC", field: "STARTS_AT" },
|
|
962
|
-
filter
|
|
963
|
-
};
|
|
969
|
+
return { addonId, addonName, total: item.total, addonOptions };
|
|
964
970
|
}
|
|
965
971
|
|
|
966
|
-
// src/internal/bookings/booking-service.ts
|
|
972
|
+
// src/internal/peek/bookings/booking-service.ts
|
|
967
973
|
var DEFAULT_PAGE_SIZE2 = 50;
|
|
968
974
|
var DEFAULT_CANCEL_NOTE = "Canceled";
|
|
969
975
|
var DEFAULT_CUSTOMER_MESSAGE = "Charge initiated via API";
|
|
@@ -1713,7 +1719,7 @@ function buildCancellation(items, addonOptionId, quantity) {
|
|
|
1713
1719
|
return { bookingQuotes, canceledCount };
|
|
1714
1720
|
}
|
|
1715
1721
|
|
|
1716
|
-
// src/internal/daily-notes/daily-note-converter.ts
|
|
1722
|
+
// src/internal/peek/daily-notes/daily-note-converter.ts
|
|
1717
1723
|
function toDailyNote(response) {
|
|
1718
1724
|
const union = response?.dailyNote;
|
|
1719
1725
|
if (!union) {
|
|
@@ -1734,7 +1740,7 @@ function cleanNote(note) {
|
|
|
1734
1740
|
return { note: note.note };
|
|
1735
1741
|
}
|
|
1736
1742
|
|
|
1737
|
-
// src/internal/daily-notes/daily-note-queries.ts
|
|
1743
|
+
// src/internal/peek/daily-notes/daily-note-queries.ts
|
|
1738
1744
|
var GLOBAL_NOTE_TYPE = "DASHBOARD";
|
|
1739
1745
|
var DAILY_NOTE_TODAY_QUERY = `
|
|
1740
1746
|
query dailyNote($type: GlobalNoteType!) {
|
|
@@ -1765,7 +1771,7 @@ function buildUpsertDailyNoteVariables(note) {
|
|
|
1765
1771
|
return { input: { type: GLOBAL_NOTE_TYPE, note } };
|
|
1766
1772
|
}
|
|
1767
1773
|
|
|
1768
|
-
// src/internal/daily-notes/daily-note-service.ts
|
|
1774
|
+
// src/internal/peek/daily-notes/daily-note-service.ts
|
|
1769
1775
|
var DailyNoteService = class {
|
|
1770
1776
|
constructor(client) {
|
|
1771
1777
|
this.client = client;
|
|
@@ -1788,6 +1794,53 @@ var DailyNoteService = class {
|
|
|
1788
1794
|
return fromUpsertResponse(body.data);
|
|
1789
1795
|
}
|
|
1790
1796
|
};
|
|
1797
|
+
var TokenManager = class {
|
|
1798
|
+
constructor(options) {
|
|
1799
|
+
this.options = options;
|
|
1800
|
+
}
|
|
1801
|
+
options;
|
|
1802
|
+
cached;
|
|
1803
|
+
/**
|
|
1804
|
+
* Returns a valid bearer token, reusing the cached one until it is within
|
|
1805
|
+
* `leewaySeconds` of expiring, at which point a fresh token is minted.
|
|
1806
|
+
*/
|
|
1807
|
+
getToken() {
|
|
1808
|
+
const now = Date.now();
|
|
1809
|
+
if (this.cached && now < this.cached.expiresAtMs) {
|
|
1810
|
+
return this.cached.token;
|
|
1811
|
+
}
|
|
1812
|
+
const { secret, issuer, installId, ttlSeconds, leewaySeconds } = this.options;
|
|
1813
|
+
const token = jwt__namespace.sign({}, secret, {
|
|
1814
|
+
expiresIn: ttlSeconds,
|
|
1815
|
+
issuer,
|
|
1816
|
+
subject: installId
|
|
1817
|
+
});
|
|
1818
|
+
this.cached = {
|
|
1819
|
+
token,
|
|
1820
|
+
expiresAtMs: now + (ttlSeconds - leewaySeconds) * 1e3
|
|
1821
|
+
};
|
|
1822
|
+
return token;
|
|
1823
|
+
}
|
|
1824
|
+
};
|
|
1825
|
+
|
|
1826
|
+
// src/access-service-config.ts
|
|
1827
|
+
var DEFAULT_TOKEN_TTL_SECONDS = 3600;
|
|
1828
|
+
var DEFAULT_TOKEN_REFRESH_LEEWAY_SECONDS = 60;
|
|
1829
|
+
var DEFAULT_RETRY_DELAYS_MS = [1e3, 2e3, 4e3];
|
|
1830
|
+
function requireNonEmpty(value, name, serviceName) {
|
|
1831
|
+
if (!value) {
|
|
1832
|
+
throw new Error(`${serviceName}: "${name}" is required`);
|
|
1833
|
+
}
|
|
1834
|
+
}
|
|
1835
|
+
function createTokenManager(config) {
|
|
1836
|
+
return new TokenManager({
|
|
1837
|
+
secret: config.jwtSecret,
|
|
1838
|
+
issuer: config.issuer,
|
|
1839
|
+
installId: config.installId,
|
|
1840
|
+
ttlSeconds: config.tokenTtlSeconds ?? DEFAULT_TOKEN_TTL_SECONDS,
|
|
1841
|
+
leewaySeconds: config.tokenRefreshLeewaySeconds ?? DEFAULT_TOKEN_REFRESH_LEEWAY_SECONDS
|
|
1842
|
+
});
|
|
1843
|
+
}
|
|
1791
1844
|
|
|
1792
1845
|
// src/errors.ts
|
|
1793
1846
|
var AdminAccountRequiredError = class extends Error {
|
|
@@ -1815,11 +1868,49 @@ var PeekGraphQLError = class extends Error {
|
|
|
1815
1868
|
this.graphqlErrors = graphqlErrors;
|
|
1816
1869
|
}
|
|
1817
1870
|
};
|
|
1871
|
+
var CngApiError = class extends Error {
|
|
1872
|
+
/** The HTTP status that triggered this error. */
|
|
1873
|
+
statusCode;
|
|
1874
|
+
/** The raw response body (parsed JSON when possible, otherwise text). */
|
|
1875
|
+
body;
|
|
1876
|
+
constructor(statusCode, body, message) {
|
|
1877
|
+
super(message ?? `CNG request failed with HTTP ${statusCode}`);
|
|
1878
|
+
this.name = "CngApiError";
|
|
1879
|
+
this.statusCode = statusCode;
|
|
1880
|
+
this.body = body;
|
|
1881
|
+
}
|
|
1882
|
+
};
|
|
1818
1883
|
|
|
1819
|
-
// src/internal/
|
|
1884
|
+
// src/internal/http-transport.ts
|
|
1820
1885
|
var RATE_LIMIT_STATUS = 429;
|
|
1821
1886
|
var ADMIN_ACCOUNT_REQUIRED_STATUS = 418;
|
|
1822
1887
|
var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
1888
|
+
async function requestWithRetry(http, url, init, label, onResponse) {
|
|
1889
|
+
const { retryDelaysMs, logger, fetchFn } = http;
|
|
1890
|
+
for (let attempt = 0; attempt <= retryDelaysMs.length; attempt++) {
|
|
1891
|
+
const response = await fetchFn(url, init);
|
|
1892
|
+
if (response.status === ADMIN_ACCOUNT_REQUIRED_STATUS) {
|
|
1893
|
+
logger.warn(`Admin account required for ${label} (HTTP 418)`, { url });
|
|
1894
|
+
throw new AdminAccountRequiredError();
|
|
1895
|
+
}
|
|
1896
|
+
if (response.status === RATE_LIMIT_STATUS) {
|
|
1897
|
+
const delay = retryDelaysMs[attempt];
|
|
1898
|
+
if (delay !== void 0) {
|
|
1899
|
+
logger.warn(
|
|
1900
|
+
`Rate limited on ${label}, retrying in ${delay}ms (attempt ${attempt + 1}/${retryDelaysMs.length})`
|
|
1901
|
+
);
|
|
1902
|
+
await sleep(delay);
|
|
1903
|
+
continue;
|
|
1904
|
+
}
|
|
1905
|
+
logger.error(`Rate limit exceeded for ${label}`, { url });
|
|
1906
|
+
throw new RateLimitError();
|
|
1907
|
+
}
|
|
1908
|
+
return onResponse(response);
|
|
1909
|
+
}
|
|
1910
|
+
throw new RateLimitError();
|
|
1911
|
+
}
|
|
1912
|
+
|
|
1913
|
+
// src/internal/peek/graphql-client.ts
|
|
1823
1914
|
var GraphQLClient = class {
|
|
1824
1915
|
constructor(options) {
|
|
1825
1916
|
this.options = options;
|
|
@@ -1827,50 +1918,39 @@ var GraphQLClient = class {
|
|
|
1827
1918
|
options;
|
|
1828
1919
|
/**
|
|
1829
1920
|
* Executes a GraphQL query against the named endpoint and returns the raw
|
|
1830
|
-
* response body. Retries on HTTP 429 per the configured backoff
|
|
1921
|
+
* response body. Retries on HTTP 429 per the configured backoff (via the
|
|
1922
|
+
* shared {@link requestWithRetry} loop).
|
|
1831
1923
|
*/
|
|
1832
1924
|
async request(endpointName, query, variables) {
|
|
1833
|
-
const {
|
|
1925
|
+
const { logger } = this.options;
|
|
1834
1926
|
const url = this.endpoint(endpointName);
|
|
1835
1927
|
const collapsedQuery = query.replace(/\s+/g, " ").trim();
|
|
1836
1928
|
logger.info("Making GraphQL request", { url, endpointName });
|
|
1837
|
-
|
|
1838
|
-
|
|
1929
|
+
return requestWithRetry(
|
|
1930
|
+
this.options,
|
|
1931
|
+
url,
|
|
1932
|
+
{
|
|
1839
1933
|
method: "POST",
|
|
1840
1934
|
headers: this.buildHeaders(),
|
|
1841
1935
|
body: JSON.stringify({ query: collapsedQuery, variables })
|
|
1842
|
-
}
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
);
|
|
1853
|
-
await sleep(delay);
|
|
1854
|
-
continue;
|
|
1936
|
+
},
|
|
1937
|
+
endpointName,
|
|
1938
|
+
async (response) => {
|
|
1939
|
+
const body = await response.json();
|
|
1940
|
+
if (body.errors) {
|
|
1941
|
+
logger.error(`GraphQL errors for ${endpointName}`, {
|
|
1942
|
+
url,
|
|
1943
|
+
graphqlErrors: JSON.stringify(body.errors)
|
|
1944
|
+
});
|
|
1945
|
+
throw new PeekGraphQLError(body.errors);
|
|
1855
1946
|
}
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
logger.error(`GraphQL errors for ${endpointName}`, {
|
|
1862
|
-
url,
|
|
1863
|
-
graphqlErrors: JSON.stringify(body.errors)
|
|
1864
|
-
});
|
|
1865
|
-
throw new PeekGraphQLError(body.errors);
|
|
1866
|
-
}
|
|
1867
|
-
if (!response.ok) {
|
|
1868
|
-
logger.error(`GraphQL request failed with HTTP ${response.status}`, { url });
|
|
1869
|
-
throw new Error(`GraphQL request failed with HTTP ${response.status}`);
|
|
1947
|
+
if (!response.ok) {
|
|
1948
|
+
logger.error(`GraphQL request failed with HTTP ${response.status}`, { url });
|
|
1949
|
+
throw new Error(`GraphQL request failed with HTTP ${response.status}`);
|
|
1950
|
+
}
|
|
1951
|
+
return body;
|
|
1870
1952
|
}
|
|
1871
|
-
|
|
1872
|
-
}
|
|
1873
|
-
throw new RateLimitError();
|
|
1953
|
+
);
|
|
1874
1954
|
}
|
|
1875
1955
|
endpoint(endpointName) {
|
|
1876
1956
|
const { baseUrl, appId, endpointPathPrefix } = this.options;
|
|
@@ -1889,7 +1969,7 @@ var GraphQLClient = class {
|
|
|
1889
1969
|
}
|
|
1890
1970
|
};
|
|
1891
1971
|
|
|
1892
|
-
// src/internal/memberships/membership-converter.ts
|
|
1972
|
+
// src/internal/peek/memberships/membership-converter.ts
|
|
1893
1973
|
function fromMembershipsResponse(response) {
|
|
1894
1974
|
return (response?.memberships ?? []).flatMap(
|
|
1895
1975
|
(membership) => (membership.membershipVariants ?? []).map((variant) => ({
|
|
@@ -1904,7 +1984,7 @@ function fromMembershipsResponse(response) {
|
|
|
1904
1984
|
);
|
|
1905
1985
|
}
|
|
1906
1986
|
|
|
1907
|
-
// src/internal/memberships/membership-queries.ts
|
|
1987
|
+
// src/internal/peek/memberships/membership-queries.ts
|
|
1908
1988
|
var MEMBERSHIPS_QUERY = `
|
|
1909
1989
|
query Sales {
|
|
1910
1990
|
memberships {
|
|
@@ -1949,7 +2029,7 @@ var CREATE_MEMBERSHIP_ORDER_FROM_QUOTE_MUTATION = `
|
|
|
1949
2029
|
}
|
|
1950
2030
|
`;
|
|
1951
2031
|
|
|
1952
|
-
// src/internal/memberships/membership-service.ts
|
|
2032
|
+
// src/internal/peek/memberships/membership-service.ts
|
|
1953
2033
|
var QUOTE_STATUS_CONFIRMED = "CONFIRMED";
|
|
1954
2034
|
var DEFAULT_BALANCE_AMOUNT = "0.00";
|
|
1955
2035
|
var DEFAULT_BALANCE_CURRENCY = "USD";
|
|
@@ -2055,7 +2135,7 @@ function validatePurchaseInput(input) {
|
|
|
2055
2135
|
}
|
|
2056
2136
|
}
|
|
2057
2137
|
|
|
2058
|
-
// src/internal/resellers/channel-converter.ts
|
|
2138
|
+
// src/internal/peek/resellers/channel-converter.ts
|
|
2059
2139
|
function fromChannelsResponse(response) {
|
|
2060
2140
|
return (response?.channels ?? []).map(fromChannelNode);
|
|
2061
2141
|
}
|
|
@@ -2076,7 +2156,7 @@ function fromChannelNode(node) {
|
|
|
2076
2156
|
};
|
|
2077
2157
|
}
|
|
2078
2158
|
|
|
2079
|
-
// src/internal/resellers/channel-queries.ts
|
|
2159
|
+
// src/internal/peek/resellers/channel-queries.ts
|
|
2080
2160
|
var CHANNELS_QUERY = `
|
|
2081
2161
|
query Sales($first: Int) {
|
|
2082
2162
|
channels {
|
|
@@ -2100,7 +2180,7 @@ var CHANNELS_QUERY = `
|
|
|
2100
2180
|
}
|
|
2101
2181
|
`;
|
|
2102
2182
|
|
|
2103
|
-
// src/internal/resellers/reseller-service.ts
|
|
2183
|
+
// src/internal/peek/resellers/reseller-service.ts
|
|
2104
2184
|
var DEFAULT_AGENTS_PER_CHANNEL = 10;
|
|
2105
2185
|
var ResellerService = class {
|
|
2106
2186
|
constructor(client) {
|
|
@@ -2119,7 +2199,7 @@ var ResellerService = class {
|
|
|
2119
2199
|
}
|
|
2120
2200
|
};
|
|
2121
2201
|
|
|
2122
|
-
// src/internal/resource-pools/resource-pool-converter.ts
|
|
2202
|
+
// src/internal/peek/resource-pools/resource-pool-converter.ts
|
|
2123
2203
|
function fromResourcePoolsResponse(response) {
|
|
2124
2204
|
return (response?.resourcePools ?? []).map(fromResourcePoolNode);
|
|
2125
2205
|
}
|
|
@@ -2147,7 +2227,7 @@ function fromAccountUser(accountUser) {
|
|
|
2147
2227
|
};
|
|
2148
2228
|
}
|
|
2149
2229
|
|
|
2150
|
-
// src/internal/resource-pools/resource-pool-queries.ts
|
|
2230
|
+
// src/internal/peek/resource-pools/resource-pool-queries.ts
|
|
2151
2231
|
var RESOURCE_POOLS_QUERY = `
|
|
2152
2232
|
query Sales($filter: ResourcePoolsFilter) {
|
|
2153
2233
|
resourcePools(filter: $filter) {
|
|
@@ -2168,7 +2248,7 @@ var RESOURCE_POOLS_QUERY = `
|
|
|
2168
2248
|
}
|
|
2169
2249
|
`;
|
|
2170
2250
|
|
|
2171
|
-
// src/internal/resource-pools/resource-pool-service.ts
|
|
2251
|
+
// src/internal/peek/resource-pools/resource-pool-service.ts
|
|
2172
2252
|
var DEFAULT_MODE = "ALL";
|
|
2173
2253
|
var ResourcePoolService = class {
|
|
2174
2254
|
constructor(client) {
|
|
@@ -2188,7 +2268,7 @@ var ResourcePoolService = class {
|
|
|
2188
2268
|
}
|
|
2189
2269
|
};
|
|
2190
2270
|
|
|
2191
|
-
// src/internal/reviews/review-converter.ts
|
|
2271
|
+
// src/internal/peek/reviews/review-converter.ts
|
|
2192
2272
|
var ISO_DATE_LENGTH = 10;
|
|
2193
2273
|
function toDateOnly(isoDateTime) {
|
|
2194
2274
|
return isoDateTime.slice(0, ISO_DATE_LENGTH);
|
|
@@ -2212,13 +2292,13 @@ function fromReviewNode(node) {
|
|
|
2212
2292
|
};
|
|
2213
2293
|
}
|
|
2214
2294
|
|
|
2215
|
-
// src/internal/reviews/review-cursor.ts
|
|
2295
|
+
// src/internal/peek/reviews/review-cursor.ts
|
|
2216
2296
|
function encodeCursor(offset, pageSize) {
|
|
2217
2297
|
const start = Math.max(0, offset - pageSize + 1);
|
|
2218
2298
|
return Buffer.from(`range:${start}..${offset},${offset}`).toString("base64");
|
|
2219
2299
|
}
|
|
2220
2300
|
|
|
2221
|
-
// src/internal/reviews/review-queries.ts
|
|
2301
|
+
// src/internal/peek/reviews/review-queries.ts
|
|
2222
2302
|
var REVIEWS_QUERY = `
|
|
2223
2303
|
query Reviews($first: Int, $filter: ReviewFilter, $after: String) {
|
|
2224
2304
|
reviews(first: $first, filter: $filter, after: $after) {
|
|
@@ -2253,7 +2333,7 @@ function buildReviewsVariables(params) {
|
|
|
2253
2333
|
};
|
|
2254
2334
|
}
|
|
2255
2335
|
|
|
2256
|
-
// src/internal/reviews/review-service.ts
|
|
2336
|
+
// src/internal/peek/reviews/review-service.ts
|
|
2257
2337
|
var DEFAULT_REVIEW_COUNT = 50;
|
|
2258
2338
|
var MIN_REVIEW_COUNT = 1;
|
|
2259
2339
|
var MAX_REVIEW_COUNT = 50;
|
|
@@ -2314,7 +2394,7 @@ var ReviewService = class {
|
|
|
2314
2394
|
}
|
|
2315
2395
|
};
|
|
2316
2396
|
|
|
2317
|
-
// src/internal/timeslots/timeslot-converter.ts
|
|
2397
|
+
// src/internal/peek/timeslots/timeslot-converter.ts
|
|
2318
2398
|
function fromTimeslotNodes(nodes, productId) {
|
|
2319
2399
|
if (!Array.isArray(nodes) || nodes.length === 0) {
|
|
2320
2400
|
return [];
|
|
@@ -2372,7 +2452,7 @@ function mapAssignedResources(allocations) {
|
|
|
2372
2452
|
});
|
|
2373
2453
|
}
|
|
2374
2454
|
|
|
2375
|
-
// src/internal/timeslots/guide-matcher.ts
|
|
2455
|
+
// src/internal/peek/timeslots/guide-matcher.ts
|
|
2376
2456
|
function matchGuideToResourcePool(guideId, guideResourcePools, accountUsers) {
|
|
2377
2457
|
const directIdMatch = guideResourcePools.find((pool) => pool.id === guideId);
|
|
2378
2458
|
if (directIdMatch) {
|
|
@@ -2406,7 +2486,7 @@ function matchGuideToResourcePool(guideId, guideResourcePools, accountUsers) {
|
|
|
2406
2486
|
return null;
|
|
2407
2487
|
}
|
|
2408
2488
|
|
|
2409
|
-
// src/internal/timeslots/resource-allocation-queries.ts
|
|
2489
|
+
// src/internal/peek/timeslots/resource-allocation-queries.ts
|
|
2410
2490
|
var RESOURCE_ALLOCATION_BULK_REQUEST_MUTATION = `
|
|
2411
2491
|
mutation ResourceAllocationBulkRequest($input: ResourceAllocationBulkRequestInput!) {
|
|
2412
2492
|
resourceAllocationBulkRequest(input: $input) {
|
|
@@ -2425,7 +2505,7 @@ function buildResourceAllocationVariables(timeslotIds, resourcePoolIds, status)
|
|
|
2425
2505
|
return { input: { timeslotIds, resourcePoolIds, status } };
|
|
2426
2506
|
}
|
|
2427
2507
|
|
|
2428
|
-
// src/internal/timeslots/timeslot-queries.ts
|
|
2508
|
+
// src/internal/peek/timeslots/timeslot-queries.ts
|
|
2429
2509
|
var TIMESLOTS_QUERY = `
|
|
2430
2510
|
query Sales($params: TimeslotsFilter!) {
|
|
2431
2511
|
timeslots(filter: $params) {
|
|
@@ -2528,7 +2608,7 @@ function buildTimeslotVariables(productId, date, filter) {
|
|
|
2528
2608
|
return { params };
|
|
2529
2609
|
}
|
|
2530
2610
|
|
|
2531
|
-
// src/internal/timeslots/timeslot-service.ts
|
|
2611
|
+
// src/internal/peek/timeslots/timeslot-service.ts
|
|
2532
2612
|
var GUIDE_CATEGORY = "guide";
|
|
2533
2613
|
var ERROR_MISSING_TIMESLOTS_OR_GUIDES = "At least one timeslot and one guide are required";
|
|
2534
2614
|
var ERROR_INVALID_ACTION = "Invalid action. Must be either assign or unassign";
|
|
@@ -2645,7 +2725,7 @@ function normalizeDate(date) {
|
|
|
2645
2725
|
return date.split("T")[0] ?? date;
|
|
2646
2726
|
}
|
|
2647
2727
|
|
|
2648
|
-
// src/internal/products/product-converter.ts
|
|
2728
|
+
// src/internal/peek/products/product-converter.ts
|
|
2649
2729
|
var ADD_ON_COLOR = "#FFFFFF";
|
|
2650
2730
|
function fromActivities(activities) {
|
|
2651
2731
|
return activities.map(fromActivity);
|
|
@@ -2684,7 +2764,7 @@ function fromItemOptionNodes(nodes) {
|
|
|
2684
2764
|
return Array.from(grouped.values());
|
|
2685
2765
|
}
|
|
2686
2766
|
|
|
2687
|
-
// src/internal/products/product-queries.ts
|
|
2767
|
+
// src/internal/peek/products/product-queries.ts
|
|
2688
2768
|
var PRODUCTS_QUERY = `
|
|
2689
2769
|
query Sales {
|
|
2690
2770
|
activities {
|
|
@@ -2724,7 +2804,7 @@ var ITEM_OPTIONS_QUERY = `
|
|
|
2724
2804
|
}
|
|
2725
2805
|
`;
|
|
2726
2806
|
|
|
2727
|
-
// src/internal/products/product-service.ts
|
|
2807
|
+
// src/internal/peek/products/product-service.ts
|
|
2728
2808
|
var DEFAULT_ITEM_OPTIONS_PAGE_SIZE = 50;
|
|
2729
2809
|
var ProductService = class {
|
|
2730
2810
|
constructor(client, options = {}) {
|
|
@@ -2801,7 +2881,7 @@ var ProductService = class {
|
|
|
2801
2881
|
}
|
|
2802
2882
|
};
|
|
2803
2883
|
|
|
2804
|
-
// src/internal/promo-codes/promo-code-queries.ts
|
|
2884
|
+
// src/internal/peek/promo-codes/promo-code-queries.ts
|
|
2805
2885
|
var PROMO_CODES_QUERY = `
|
|
2806
2886
|
query Sales($first: Int, $after: String) {
|
|
2807
2887
|
promoCodes(first: $first, after: $after) {
|
|
@@ -2840,7 +2920,7 @@ var CREATE_PROMO_CODE_MUTATION = `
|
|
|
2840
2920
|
}
|
|
2841
2921
|
`;
|
|
2842
2922
|
|
|
2843
|
-
// src/internal/promo-codes/promo-code-service.ts
|
|
2923
|
+
// src/internal/peek/promo-codes/promo-code-service.ts
|
|
2844
2924
|
var DEFAULT_PAGE_SIZE3 = 50;
|
|
2845
2925
|
var DEFAULT_CURRENCY = "USD";
|
|
2846
2926
|
var CURRENCY_PATTERN = /^[A-Z]{3}$/;
|
|
@@ -2919,34 +2999,6 @@ var PromoCodeService = class {
|
|
|
2919
2999
|
return { id: result.id, name: result.name };
|
|
2920
3000
|
}
|
|
2921
3001
|
};
|
|
2922
|
-
var TokenManager = class {
|
|
2923
|
-
constructor(options) {
|
|
2924
|
-
this.options = options;
|
|
2925
|
-
}
|
|
2926
|
-
options;
|
|
2927
|
-
cached;
|
|
2928
|
-
/**
|
|
2929
|
-
* Returns a valid bearer token, reusing the cached one until it is within
|
|
2930
|
-
* `leewaySeconds` of expiring, at which point a fresh token is minted.
|
|
2931
|
-
*/
|
|
2932
|
-
getToken() {
|
|
2933
|
-
const now = Date.now();
|
|
2934
|
-
if (this.cached && now < this.cached.expiresAtMs) {
|
|
2935
|
-
return this.cached.token;
|
|
2936
|
-
}
|
|
2937
|
-
const { secret, issuer, installId, ttlSeconds, leewaySeconds } = this.options;
|
|
2938
|
-
const token = jwt__namespace.sign({}, secret, {
|
|
2939
|
-
expiresIn: ttlSeconds,
|
|
2940
|
-
issuer,
|
|
2941
|
-
subject: installId
|
|
2942
|
-
});
|
|
2943
|
-
this.cached = {
|
|
2944
|
-
token,
|
|
2945
|
-
expiresAtMs: now + (ttlSeconds - leewaySeconds) * 1e3
|
|
2946
|
-
};
|
|
2947
|
-
return token;
|
|
2948
|
-
}
|
|
2949
|
-
};
|
|
2950
3002
|
|
|
2951
3003
|
// src/logger.ts
|
|
2952
3004
|
var noopLogger = {
|
|
@@ -2961,9 +3013,6 @@ var noopLogger = {
|
|
|
2961
3013
|
// src/peek-access-service.ts
|
|
2962
3014
|
var DEFAULT_BASE_URL = "https://apps.peekapis.com/backoffice-gql";
|
|
2963
3015
|
var DEFAULT_V2_BASE_URL = "https://app-registry.peeklabs.com/installations-api";
|
|
2964
|
-
var DEFAULT_TOKEN_TTL_SECONDS = 3600;
|
|
2965
|
-
var DEFAULT_TOKEN_REFRESH_LEEWAY_SECONDS = 60;
|
|
2966
|
-
var DEFAULT_RETRY_DELAYS_MS = [1e3, 2e3, 4e3];
|
|
2967
3016
|
var PEEK_TOKEN_ISSUER = "app_registry_v2";
|
|
2968
3017
|
var PeekAccessService = class {
|
|
2969
3018
|
client;
|
|
@@ -2982,20 +3031,14 @@ var PeekAccessService = class {
|
|
|
2982
3031
|
reviewService;
|
|
2983
3032
|
constructor(config) {
|
|
2984
3033
|
const isV2 = config.mode === "v2";
|
|
2985
|
-
requireNonEmpty(config.installId, "installId");
|
|
2986
|
-
requireNonEmpty(config.jwtSecret, "jwtSecret");
|
|
2987
|
-
requireNonEmpty(config.issuer, "issuer");
|
|
2988
|
-
requireNonEmpty(config.appId, "appId");
|
|
2989
|
-
if (!isV2) requireNonEmpty(config.gatewayKey ?? "", "gatewayKey");
|
|
3034
|
+
requireNonEmpty(config.installId, "installId", "PeekAccessService");
|
|
3035
|
+
requireNonEmpty(config.jwtSecret, "jwtSecret", "PeekAccessService");
|
|
3036
|
+
requireNonEmpty(config.issuer, "issuer", "PeekAccessService");
|
|
3037
|
+
requireNonEmpty(config.appId, "appId", "PeekAccessService");
|
|
3038
|
+
if (!isV2) requireNonEmpty(config.gatewayKey ?? "", "gatewayKey", "PeekAccessService");
|
|
2990
3039
|
this.jwtSecret = config.jwtSecret;
|
|
2991
3040
|
const logger = config.logger ?? noopLogger;
|
|
2992
|
-
const tokens =
|
|
2993
|
-
secret: config.jwtSecret,
|
|
2994
|
-
issuer: config.issuer,
|
|
2995
|
-
installId: config.installId,
|
|
2996
|
-
ttlSeconds: config.tokenTtlSeconds ?? DEFAULT_TOKEN_TTL_SECONDS,
|
|
2997
|
-
leewaySeconds: config.tokenRefreshLeewaySeconds ?? DEFAULT_TOKEN_REFRESH_LEEWAY_SECONDS
|
|
2998
|
-
});
|
|
3041
|
+
const tokens = createTokenManager(config);
|
|
2999
3042
|
const defaultBaseUrl = isV2 ? DEFAULT_V2_BASE_URL : DEFAULT_BASE_URL;
|
|
3000
3043
|
this.client = new GraphQLClient({
|
|
3001
3044
|
baseUrl: config.baseUrl ?? defaultBaseUrl,
|
|
@@ -3321,13 +3364,148 @@ var PeekAccessService = class {
|
|
|
3321
3364
|
return this.getReviewService().getReviews(productId, reviewCount, reviewOffset);
|
|
3322
3365
|
}
|
|
3323
3366
|
};
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3367
|
+
|
|
3368
|
+
// src/internal/cng/endpoints.ts
|
|
3369
|
+
var CNG_EXTENDABLE_SLUG = "cng_backoffice_api-v1";
|
|
3370
|
+
var PRODUCTS_PATH = "api/v2/commerce-config/products";
|
|
3371
|
+
|
|
3372
|
+
// src/models/cng/product.ts
|
|
3373
|
+
var ACTIVITY_PRODUCT_TYPE2 = "ACTIVITY";
|
|
3374
|
+
|
|
3375
|
+
// src/internal/cng/products/product-converter.ts
|
|
3376
|
+
function fromProductNodes(nodes) {
|
|
3377
|
+
return nodes.map(fromProductNode);
|
|
3378
|
+
}
|
|
3379
|
+
function fromProductNode(node) {
|
|
3380
|
+
return {
|
|
3381
|
+
productId: node.id || "",
|
|
3382
|
+
name: node.name || "",
|
|
3383
|
+
type: node.product_type || ACTIVITY_PRODUCT_TYPE2,
|
|
3384
|
+
color: node.color_hex || "",
|
|
3385
|
+
tickets: (node.tickets ?? []).map((ticket) => ({
|
|
3386
|
+
id: ticket.id,
|
|
3387
|
+
name: ticket.name
|
|
3388
|
+
}))
|
|
3389
|
+
};
|
|
3328
3390
|
}
|
|
3329
3391
|
|
|
3330
|
-
// src/internal/
|
|
3392
|
+
// src/internal/cng/products/product-service.ts
|
|
3393
|
+
var CngProductService = class {
|
|
3394
|
+
constructor(client) {
|
|
3395
|
+
this.client = client;
|
|
3396
|
+
}
|
|
3397
|
+
client;
|
|
3398
|
+
/**
|
|
3399
|
+
* Returns every activity as a single flat list.
|
|
3400
|
+
*
|
|
3401
|
+
* @example
|
|
3402
|
+
* ```ts
|
|
3403
|
+
* const activities = await cng.getProductService().getAllActivities();
|
|
3404
|
+
* ```
|
|
3405
|
+
*/
|
|
3406
|
+
async getAllActivities() {
|
|
3407
|
+
const body = await this.client.get(
|
|
3408
|
+
PRODUCTS_PATH
|
|
3409
|
+
);
|
|
3410
|
+
const nodes = Array.isArray(body) ? body : body?.products ?? [];
|
|
3411
|
+
return fromProductNodes(nodes ?? []);
|
|
3412
|
+
}
|
|
3413
|
+
};
|
|
3414
|
+
|
|
3415
|
+
// src/internal/cng/rest-client.ts
|
|
3416
|
+
var RestClient = class {
|
|
3417
|
+
constructor(options) {
|
|
3418
|
+
this.options = options;
|
|
3419
|
+
}
|
|
3420
|
+
options;
|
|
3421
|
+
/**
|
|
3422
|
+
* Issues a GET against the named REST path and returns the parsed JSON body.
|
|
3423
|
+
* Retries on HTTP 429 per the configured backoff (via the shared
|
|
3424
|
+
* {@link requestWithRetry} loop).
|
|
3425
|
+
*
|
|
3426
|
+
* @throws {AdminAccountRequiredError} on HTTP 418
|
|
3427
|
+
* @throws {RateLimitError} on HTTP 429 after retries are exhausted
|
|
3428
|
+
* @throws {CngApiError} on any other non-2xx response
|
|
3429
|
+
*/
|
|
3430
|
+
async get(path) {
|
|
3431
|
+
const { logger } = this.options;
|
|
3432
|
+
const url = this.endpoint(path);
|
|
3433
|
+
logger.info("Making CNG request", { url, path });
|
|
3434
|
+
return requestWithRetry(
|
|
3435
|
+
this.options,
|
|
3436
|
+
url,
|
|
3437
|
+
{ method: "GET", headers: this.buildHeaders() },
|
|
3438
|
+
path,
|
|
3439
|
+
async (response) => {
|
|
3440
|
+
const body = await this.parseBody(response);
|
|
3441
|
+
if (!response.ok) {
|
|
3442
|
+
logger.error(`CNG request failed with HTTP ${response.status}`, { url });
|
|
3443
|
+
throw new CngApiError(response.status, body);
|
|
3444
|
+
}
|
|
3445
|
+
return body;
|
|
3446
|
+
}
|
|
3447
|
+
);
|
|
3448
|
+
}
|
|
3449
|
+
/** Reads the response body as JSON, falling back to raw text when unparseable. */
|
|
3450
|
+
async parseBody(response) {
|
|
3451
|
+
const text = await response.text();
|
|
3452
|
+
try {
|
|
3453
|
+
return JSON.parse(text);
|
|
3454
|
+
} catch {
|
|
3455
|
+
return text;
|
|
3456
|
+
}
|
|
3457
|
+
}
|
|
3458
|
+
endpoint(path) {
|
|
3459
|
+
const { baseUrl, appId, extendableSlug } = this.options;
|
|
3460
|
+
return `${baseUrl}/${appId}/${extendableSlug}/${path}`;
|
|
3461
|
+
}
|
|
3462
|
+
buildHeaders() {
|
|
3463
|
+
return {
|
|
3464
|
+
"X-Peek-Auth": `Bearer ${this.options.getToken()}`,
|
|
3465
|
+
"Content-Type": "application/json"
|
|
3466
|
+
};
|
|
3467
|
+
}
|
|
3468
|
+
};
|
|
3469
|
+
|
|
3470
|
+
// src/cng-access-service.ts
|
|
3471
|
+
var DEFAULT_BASE_URL2 = "https://app-registry.peeklabs.com/installations-api";
|
|
3472
|
+
var CngAccessService = class {
|
|
3473
|
+
client;
|
|
3474
|
+
productService;
|
|
3475
|
+
constructor(config) {
|
|
3476
|
+
requireNonEmpty(config.installId, "installId", "CngAccessService");
|
|
3477
|
+
requireNonEmpty(config.jwtSecret, "jwtSecret", "CngAccessService");
|
|
3478
|
+
requireNonEmpty(config.issuer, "issuer", "CngAccessService");
|
|
3479
|
+
requireNonEmpty(config.appId, "appId", "CngAccessService");
|
|
3480
|
+
const logger = config.logger ?? noopLogger;
|
|
3481
|
+
const tokens = createTokenManager(config);
|
|
3482
|
+
this.client = new RestClient({
|
|
3483
|
+
baseUrl: config.baseUrl ?? DEFAULT_BASE_URL2,
|
|
3484
|
+
appId: config.appId,
|
|
3485
|
+
extendableSlug: CNG_EXTENDABLE_SLUG,
|
|
3486
|
+
getToken: () => tokens.getToken(),
|
|
3487
|
+
retryDelaysMs: config.retryDelaysMs ?? DEFAULT_RETRY_DELAYS_MS,
|
|
3488
|
+
logger,
|
|
3489
|
+
fetchFn: config.fetch ?? globalThis.fetch
|
|
3490
|
+
});
|
|
3491
|
+
}
|
|
3492
|
+
/**
|
|
3493
|
+
* Returns the {@link CngProductService} for this install, bound to the shared
|
|
3494
|
+
* authenticated transport. The instance is created lazily and reused.
|
|
3495
|
+
*/
|
|
3496
|
+
getProductService() {
|
|
3497
|
+
if (!this.productService) {
|
|
3498
|
+
this.productService = new CngProductService(this.client);
|
|
3499
|
+
}
|
|
3500
|
+
return this.productService;
|
|
3501
|
+
}
|
|
3502
|
+
/** All activities. Delegates to {@link CngProductService.getAllActivities}. */
|
|
3503
|
+
getAllActivities() {
|
|
3504
|
+
return this.getProductService().getAllActivities();
|
|
3505
|
+
}
|
|
3506
|
+
};
|
|
3507
|
+
|
|
3508
|
+
// src/internal/peek/bookings/booking-webhook.ts
|
|
3331
3509
|
var PAYLOAD_BOOKING_KEY = "booking";
|
|
3332
3510
|
var VALUE_OPEN_TOKEN = "value {";
|
|
3333
3511
|
var PRICE_BREAKDOWN_KEYS = [
|
|
@@ -3377,7 +3555,7 @@ function hasPriceBreakdown(node) {
|
|
|
3377
3555
|
return PRICE_BREAKDOWN_KEYS.some((key) => key in value);
|
|
3378
3556
|
}
|
|
3379
3557
|
|
|
3380
|
-
// src/internal/waivers/waiver-webhook.ts
|
|
3558
|
+
// src/internal/peek/waivers/waiver-webhook.ts
|
|
3381
3559
|
var PAYLOAD_WAIVER_KEY = "waiver";
|
|
3382
3560
|
function parseWaiverWebhook(payload) {
|
|
3383
3561
|
return fromWaiverNode(extractWaiverNode(payload));
|
|
@@ -3418,6 +3596,9 @@ exports.AccountUserService = AccountUserService;
|
|
|
3418
3596
|
exports.AdminAccountRequiredError = AdminAccountRequiredError;
|
|
3419
3597
|
exports.AvailabilityService = AvailabilityService;
|
|
3420
3598
|
exports.BookingService = BookingService;
|
|
3599
|
+
exports.CngAccessService = CngAccessService;
|
|
3600
|
+
exports.CngApiError = CngApiError;
|
|
3601
|
+
exports.CngProductService = CngProductService;
|
|
3421
3602
|
exports.DailyNoteService = DailyNoteService;
|
|
3422
3603
|
exports.MembershipService = MembershipService;
|
|
3423
3604
|
exports.PeekAccessService = PeekAccessService;
|