@peektravel/app-utilities 0.4.1 → 0.5.1
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/README.md +36 -2
- package/dist/index.cjs +519 -103
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +352 -3
- package/dist/index.d.ts +352 -3
- package/dist/index.js +518 -104
- package/dist/index.js.map +1 -1
- package/docs/webhooks.md +9 -1
- package/llms.txt +45 -6
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -203,6 +203,73 @@ var AvailabilityService = class {
|
|
|
203
203
|
}
|
|
204
204
|
};
|
|
205
205
|
|
|
206
|
+
// src/access-options.ts
|
|
207
|
+
function resolveAccessOptions(options) {
|
|
208
|
+
return { fullCustomerAccess: options?.fullCustomerAccess ?? false };
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// src/errors.ts
|
|
212
|
+
var AdminAccountRequiredError = class extends Error {
|
|
213
|
+
/** The HTTP status that triggered this error. */
|
|
214
|
+
statusCode = 418;
|
|
215
|
+
constructor(message = "Admin account required") {
|
|
216
|
+
super(message);
|
|
217
|
+
this.name = "AdminAccountRequiredError";
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
var RateLimitError = class extends Error {
|
|
221
|
+
/** The HTTP status that triggered this error. */
|
|
222
|
+
statusCode = 429;
|
|
223
|
+
constructor(message = "Rate limit exceeded") {
|
|
224
|
+
super(message);
|
|
225
|
+
this.name = "RateLimitError";
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
var PeekGraphQLError = class extends Error {
|
|
229
|
+
/** The raw `errors` array returned by the GraphQL endpoint. */
|
|
230
|
+
graphqlErrors;
|
|
231
|
+
constructor(graphqlErrors, message = "GraphQL request failed") {
|
|
232
|
+
super(message);
|
|
233
|
+
this.name = "PeekGraphQLError";
|
|
234
|
+
this.graphqlErrors = graphqlErrors;
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
var PiiAccessDisabledError = class extends Error {
|
|
238
|
+
/** The name of the operation that was blocked (e.g. `"makePayment"`). */
|
|
239
|
+
operation;
|
|
240
|
+
constructor(operation) {
|
|
241
|
+
super(
|
|
242
|
+
`"${operation}" is disabled because this access service was created without "fullCustomerAccess"; enable it to allow payment and booking-modification operations`
|
|
243
|
+
);
|
|
244
|
+
this.name = "PiiAccessDisabledError";
|
|
245
|
+
this.operation = operation;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
var CngApiError = class extends Error {
|
|
249
|
+
/** The HTTP status that triggered this error. */
|
|
250
|
+
statusCode;
|
|
251
|
+
/** The raw response body (parsed JSON when possible, otherwise text). */
|
|
252
|
+
body;
|
|
253
|
+
constructor(statusCode, body, message) {
|
|
254
|
+
super(message ?? `CNG request failed with HTTP ${statusCode}`);
|
|
255
|
+
this.name = "CngApiError";
|
|
256
|
+
this.statusCode = statusCode;
|
|
257
|
+
this.body = body;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
var AcmeApiError = class extends Error {
|
|
261
|
+
/** The HTTP status that triggered this error. */
|
|
262
|
+
statusCode;
|
|
263
|
+
/** The raw response body (parsed JSON when possible, otherwise text). */
|
|
264
|
+
body;
|
|
265
|
+
constructor(statusCode, body, message) {
|
|
266
|
+
super(message ?? `ACME request failed with HTTP ${statusCode}`);
|
|
267
|
+
this.name = "AcmeApiError";
|
|
268
|
+
this.statusCode = statusCode;
|
|
269
|
+
this.body = body;
|
|
270
|
+
}
|
|
271
|
+
};
|
|
272
|
+
|
|
206
273
|
// src/models/peek/product.ts
|
|
207
274
|
var ACTIVITY_PRODUCT_TYPE = "ACTIVITY";
|
|
208
275
|
var RENTAL_PRODUCT_TYPE = "RENTAL";
|
|
@@ -214,17 +281,8 @@ var SEARCH_BY_ACTIVITY_DATE = "activityDate";
|
|
|
214
281
|
function normalizeBookingId(bookingId) {
|
|
215
282
|
return bookingId.toLowerCase().replace(/-/g, "_");
|
|
216
283
|
}
|
|
217
|
-
var
|
|
218
|
-
|
|
219
|
-
name
|
|
220
|
-
country
|
|
221
|
-
dateOfBirth
|
|
222
|
-
email
|
|
223
|
-
isGdpr
|
|
224
|
-
isParticipant
|
|
225
|
-
optinSms
|
|
226
|
-
optinMarketing
|
|
227
|
-
phone
|
|
284
|
+
var GUEST_IDENTITY_PII_FIELDS = "name country dateOfBirth email isGdpr";
|
|
285
|
+
var GUEST_CONTACT_PII_FIELDS = `phone
|
|
228
286
|
postalCode
|
|
229
287
|
fieldResponses {
|
|
230
288
|
id
|
|
@@ -234,9 +292,20 @@ var guestFields = `
|
|
|
234
292
|
name
|
|
235
293
|
}
|
|
236
294
|
}
|
|
237
|
-
}
|
|
295
|
+
}`;
|
|
296
|
+
function buildGuestFields(fullCustomerAccess) {
|
|
297
|
+
return `
|
|
298
|
+
id
|
|
299
|
+
${fullCustomerAccess ? GUEST_IDENTITY_PII_FIELDS : ""}
|
|
300
|
+
isParticipant
|
|
301
|
+
optinSms
|
|
302
|
+
optinMarketing
|
|
303
|
+
${fullCustomerAccess ? GUEST_CONTACT_PII_FIELDS : ""}
|
|
238
304
|
`;
|
|
239
|
-
|
|
305
|
+
}
|
|
306
|
+
function buildBookingGuestsFields(fullCustomerAccess) {
|
|
307
|
+
const guestFields = buildGuestFields(fullCustomerAccess);
|
|
308
|
+
return `
|
|
240
309
|
bookingGuests {
|
|
241
310
|
${guestFields}
|
|
242
311
|
}
|
|
@@ -244,10 +313,9 @@ var bookingGuestsFields = `
|
|
|
244
313
|
${guestFields}
|
|
245
314
|
}
|
|
246
315
|
`;
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
primaryGuest {
|
|
316
|
+
}
|
|
317
|
+
var bookingGuestsFields = buildBookingGuestsFields(true);
|
|
318
|
+
var BOOKING_PRIMARY_GUEST_PII_FIELDS = `primaryGuest {
|
|
251
319
|
name
|
|
252
320
|
email
|
|
253
321
|
phone
|
|
@@ -255,7 +323,26 @@ var bookingQueryFields = `
|
|
|
255
323
|
optinSms
|
|
256
324
|
isGdpr
|
|
257
325
|
postalCode
|
|
326
|
+
}`;
|
|
327
|
+
var BOOKING_QUESTION_ANSWERS_PII_FIELDS = `questionAnswers {
|
|
328
|
+
answer
|
|
329
|
+
questionText
|
|
330
|
+
questionLocationSnapshot {
|
|
331
|
+
latitude
|
|
332
|
+
longitude
|
|
333
|
+
}
|
|
258
334
|
}
|
|
335
|
+
tickets {
|
|
336
|
+
questionAnswers {
|
|
337
|
+
answer
|
|
338
|
+
questionText
|
|
339
|
+
}
|
|
340
|
+
}`;
|
|
341
|
+
function buildBookingQueryFields(fullCustomerAccess) {
|
|
342
|
+
return `
|
|
343
|
+
displayId
|
|
344
|
+
id
|
|
345
|
+
${fullCustomerAccess ? BOOKING_PRIMARY_GUEST_PII_FIELDS : ""}
|
|
259
346
|
activitySnapshot {
|
|
260
347
|
type
|
|
261
348
|
name
|
|
@@ -285,7 +372,7 @@ var bookingQueryFields = `
|
|
|
285
372
|
endsAt
|
|
286
373
|
endsAtUtc
|
|
287
374
|
availabilityTimeId
|
|
288
|
-
bookingPortalUrl
|
|
375
|
+
${fullCustomerAccess ? "bookingPortalUrl" : ""}
|
|
289
376
|
operatorNotes
|
|
290
377
|
value {
|
|
291
378
|
total {
|
|
@@ -327,20 +414,7 @@ var bookingQueryFields = `
|
|
|
327
414
|
}
|
|
328
415
|
}
|
|
329
416
|
}
|
|
330
|
-
|
|
331
|
-
answer
|
|
332
|
-
questionText
|
|
333
|
-
questionLocationSnapshot {
|
|
334
|
-
latitude
|
|
335
|
-
longitude
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
tickets {
|
|
339
|
-
questionAnswers {
|
|
340
|
-
answer
|
|
341
|
-
questionText
|
|
342
|
-
}
|
|
343
|
-
}
|
|
417
|
+
${fullCustomerAccess ? BOOKING_QUESTION_ANSWERS_PII_FIELDS : ""}
|
|
344
418
|
resourcePoolAssignments {
|
|
345
419
|
quantity
|
|
346
420
|
resourcePool {
|
|
@@ -358,6 +432,8 @@ var bookingQueryFields = `
|
|
|
358
432
|
}
|
|
359
433
|
}
|
|
360
434
|
`;
|
|
435
|
+
}
|
|
436
|
+
var bookingQueryFields = buildBookingQueryFields(true);
|
|
361
437
|
var PRICE_BREAKDOWN_FIELDS = `
|
|
362
438
|
convenienceFee { amount formatted }
|
|
363
439
|
deposit { amount formatted }
|
|
@@ -376,9 +452,10 @@ var TICKET_VALUE_FIELDS = `
|
|
|
376
452
|
total { amount formatted }
|
|
377
453
|
}
|
|
378
454
|
`;
|
|
379
|
-
function buildBookingsListingQuery(includeGuests, includePriceBreakdown) {
|
|
380
|
-
const guestsSection = includeGuests ?
|
|
381
|
-
const
|
|
455
|
+
function buildBookingsListingQuery(includeGuests, includePriceBreakdown, fullCustomerAccess = true) {
|
|
456
|
+
const guestsSection = includeGuests ? buildBookingGuestsFields(fullCustomerAccess) : "";
|
|
457
|
+
const baseFields = buildBookingQueryFields(fullCustomerAccess);
|
|
458
|
+
const fields = includePriceBreakdown ? baseFields.replace("value {", `value { ${PRICE_BREAKDOWN_FIELDS}`).replace("ticketQuantities {", `ticketQuantities { ${TICKET_VALUE_FIELDS}`) : baseFields;
|
|
382
459
|
return `
|
|
383
460
|
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
384
461
|
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
@@ -395,7 +472,8 @@ function buildBookingsListingQuery(includeGuests, includePriceBreakdown) {
|
|
|
395
472
|
}
|
|
396
473
|
`;
|
|
397
474
|
}
|
|
398
|
-
|
|
475
|
+
function buildBookingGuestsQuery(fullCustomerAccess) {
|
|
476
|
+
return `
|
|
399
477
|
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
400
478
|
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
401
479
|
pageInfo { endCursor hasNextPage }
|
|
@@ -404,13 +482,14 @@ var BOOKING_GUESTS_QUERY = `
|
|
|
404
482
|
... on Booking {
|
|
405
483
|
displayId
|
|
406
484
|
id
|
|
407
|
-
${
|
|
485
|
+
${buildBookingGuestsFields(fullCustomerAccess)}
|
|
408
486
|
}
|
|
409
487
|
}
|
|
410
488
|
}
|
|
411
489
|
}
|
|
412
490
|
}
|
|
413
491
|
`;
|
|
492
|
+
}
|
|
414
493
|
var BOOKING_PAYMENTS_ON_FILE_QUERY = `
|
|
415
494
|
query Sales($after: String, $first: Int, $filter: SalesFilter!, $orderBy: SalesOrdering) {
|
|
416
495
|
sales(after: $after, first: $first, filter: $filter, orderBy: $orderBy) {
|
|
@@ -996,10 +1075,23 @@ var BookingService = class {
|
|
|
996
1075
|
this.client = client;
|
|
997
1076
|
this.deps = deps;
|
|
998
1077
|
this.pageSize = options.pageSize ?? DEFAULT_PAGE_SIZE2;
|
|
1078
|
+
this.fullCustomerAccess = resolveAccessOptions(options.accessOptions).fullCustomerAccess;
|
|
999
1079
|
}
|
|
1000
1080
|
client;
|
|
1001
1081
|
deps;
|
|
1002
1082
|
pageSize;
|
|
1083
|
+
/** Whether customer PII is requested and payment operations are allowed. */
|
|
1084
|
+
fullCustomerAccess;
|
|
1085
|
+
/**
|
|
1086
|
+
* Throws a {@link PiiAccessDisabledError} for `operation` when this service was
|
|
1087
|
+
* created without `fullCustomerAccess` — used to gate payment and booking-modification
|
|
1088
|
+
* operations that touch customer financial data.
|
|
1089
|
+
*/
|
|
1090
|
+
assertPiiEnabled(operation) {
|
|
1091
|
+
if (!this.fullCustomerAccess) {
|
|
1092
|
+
throw new PiiAccessDisabledError(operation);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1003
1095
|
/**
|
|
1004
1096
|
* Returns a single booking by id, or null when not found. The `bookingId` is
|
|
1005
1097
|
* normalized internally (lowercased, `-` → `_`), so `B-ABC123` and `b_abc123`
|
|
@@ -1021,7 +1113,7 @@ var BookingService = class {
|
|
|
1021
1113
|
const includePriceBreakdown = options.includePriceBreakdown ?? false;
|
|
1022
1114
|
const body = await this.client.request(
|
|
1023
1115
|
SALES_ENDPOINT,
|
|
1024
|
-
buildBookingsListingQuery(includeGuests, includePriceBreakdown),
|
|
1116
|
+
buildBookingsListingQuery(includeGuests, includePriceBreakdown, this.fullCustomerAccess),
|
|
1025
1117
|
buildBookingsVariables({
|
|
1026
1118
|
pageSize: this.pageSize,
|
|
1027
1119
|
after: null,
|
|
@@ -1039,7 +1131,7 @@ var BookingService = class {
|
|
|
1039
1131
|
const includeGuests = input.includeGuests ?? false;
|
|
1040
1132
|
const includePriceBreakdown = input.includePriceBreakdown ?? false;
|
|
1041
1133
|
return this.fetchPaginated(
|
|
1042
|
-
buildBookingsListingQuery(includeGuests, includePriceBreakdown),
|
|
1134
|
+
buildBookingsListingQuery(includeGuests, includePriceBreakdown, this.fullCustomerAccess),
|
|
1043
1135
|
{
|
|
1044
1136
|
startDateTime: input.start,
|
|
1045
1137
|
endDateTime: input.end,
|
|
@@ -1057,7 +1149,7 @@ var BookingService = class {
|
|
|
1057
1149
|
const includeGuests = options.includeGuests ?? false;
|
|
1058
1150
|
const includePriceBreakdown = options.includePriceBreakdown ?? false;
|
|
1059
1151
|
return this.fetchPaginated(
|
|
1060
|
-
buildBookingsListingQuery(includeGuests, includePriceBreakdown),
|
|
1152
|
+
buildBookingsListingQuery(includeGuests, includePriceBreakdown, this.fullCustomerAccess),
|
|
1061
1153
|
{ timeslotId },
|
|
1062
1154
|
includeGuests,
|
|
1063
1155
|
includePriceBreakdown
|
|
@@ -1068,7 +1160,7 @@ var BookingService = class {
|
|
|
1068
1160
|
assertBookingId(bookingId);
|
|
1069
1161
|
const body = await this.client.request(
|
|
1070
1162
|
SALES_ENDPOINT,
|
|
1071
|
-
|
|
1163
|
+
buildBookingGuestsQuery(this.fullCustomerAccess),
|
|
1072
1164
|
buildBookingsVariables({
|
|
1073
1165
|
pageSize: this.pageSize,
|
|
1074
1166
|
after: null,
|
|
@@ -1079,6 +1171,7 @@ var BookingService = class {
|
|
|
1079
1171
|
}
|
|
1080
1172
|
/** Returns the payments on file for a booking, or null when not found. */
|
|
1081
1173
|
async getPaymentsOnFile(bookingId) {
|
|
1174
|
+
this.assertPiiEnabled("getPaymentsOnFile");
|
|
1082
1175
|
assertBookingId(bookingId);
|
|
1083
1176
|
const normalized = normalizeBookingId(bookingId);
|
|
1084
1177
|
const body = await this.client.request(
|
|
@@ -1163,6 +1256,7 @@ ${note}`;
|
|
|
1163
1256
|
* charge fails.
|
|
1164
1257
|
*/
|
|
1165
1258
|
async makePayment(input) {
|
|
1259
|
+
this.assertPiiEnabled("makePayment");
|
|
1166
1260
|
this.validatePaymentInput(input);
|
|
1167
1261
|
const normalized = normalizeBookingId(input.bookingId);
|
|
1168
1262
|
const onFile = await this.getPaymentsOnFile(normalized);
|
|
@@ -1205,6 +1299,7 @@ ${note}`;
|
|
|
1205
1299
|
* payments-on-file, then applies the refund.
|
|
1206
1300
|
*/
|
|
1207
1301
|
async refund(input) {
|
|
1302
|
+
this.assertPiiEnabled("refund");
|
|
1208
1303
|
this.validateRefundInput(input);
|
|
1209
1304
|
const normalized = normalizeBookingId(input.bookingId);
|
|
1210
1305
|
const onFile = await this.getPaymentsOnFile(normalized);
|
|
@@ -1245,6 +1340,7 @@ ${note}`;
|
|
|
1245
1340
|
}
|
|
1246
1341
|
/** Creates an invoice link for a booking's order. */
|
|
1247
1342
|
async createInvoiceLink(bookingId) {
|
|
1343
|
+
this.assertPiiEnabled("createInvoiceLink");
|
|
1248
1344
|
assertBookingId(bookingId);
|
|
1249
1345
|
const normalized = normalizeBookingId(bookingId);
|
|
1250
1346
|
const booking = await this.getById(normalized);
|
|
@@ -1300,6 +1396,7 @@ ${note}`;
|
|
|
1300
1396
|
* the underlying quote/order mutations fail.
|
|
1301
1397
|
*/
|
|
1302
1398
|
async addAddon(bookingId, input) {
|
|
1399
|
+
this.assertPiiEnabled("addAddon");
|
|
1303
1400
|
assertBookingId(bookingId);
|
|
1304
1401
|
const addonOptionId = (input?.addonOptionId || input?.addonId || "").trim();
|
|
1305
1402
|
if (!addonOptionId) {
|
|
@@ -1353,6 +1450,7 @@ ${note}`;
|
|
|
1353
1450
|
* variables. Returns the booking's add-ons after the change.
|
|
1354
1451
|
*/
|
|
1355
1452
|
async removeAddon(bookingId, input) {
|
|
1453
|
+
this.assertPiiEnabled("removeAddon");
|
|
1356
1454
|
assertBookingId(bookingId);
|
|
1357
1455
|
const addonOptionId = (input?.addonOptionId || input?.addonId || "").trim();
|
|
1358
1456
|
if (!addonOptionId) {
|
|
@@ -1842,57 +1940,6 @@ function createTokenManager(config) {
|
|
|
1842
1940
|
});
|
|
1843
1941
|
}
|
|
1844
1942
|
|
|
1845
|
-
// src/errors.ts
|
|
1846
|
-
var AdminAccountRequiredError = class extends Error {
|
|
1847
|
-
/** The HTTP status that triggered this error. */
|
|
1848
|
-
statusCode = 418;
|
|
1849
|
-
constructor(message = "Admin account required") {
|
|
1850
|
-
super(message);
|
|
1851
|
-
this.name = "AdminAccountRequiredError";
|
|
1852
|
-
}
|
|
1853
|
-
};
|
|
1854
|
-
var RateLimitError = class extends Error {
|
|
1855
|
-
/** The HTTP status that triggered this error. */
|
|
1856
|
-
statusCode = 429;
|
|
1857
|
-
constructor(message = "Rate limit exceeded") {
|
|
1858
|
-
super(message);
|
|
1859
|
-
this.name = "RateLimitError";
|
|
1860
|
-
}
|
|
1861
|
-
};
|
|
1862
|
-
var PeekGraphQLError = class extends Error {
|
|
1863
|
-
/** The raw `errors` array returned by the GraphQL endpoint. */
|
|
1864
|
-
graphqlErrors;
|
|
1865
|
-
constructor(graphqlErrors, message = "GraphQL request failed") {
|
|
1866
|
-
super(message);
|
|
1867
|
-
this.name = "PeekGraphQLError";
|
|
1868
|
-
this.graphqlErrors = graphqlErrors;
|
|
1869
|
-
}
|
|
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
|
-
};
|
|
1883
|
-
var AcmeApiError = class extends Error {
|
|
1884
|
-
/** The HTTP status that triggered this error. */
|
|
1885
|
-
statusCode;
|
|
1886
|
-
/** The raw response body (parsed JSON when possible, otherwise text). */
|
|
1887
|
-
body;
|
|
1888
|
-
constructor(statusCode, body, message) {
|
|
1889
|
-
super(message ?? `ACME request failed with HTTP ${statusCode}`);
|
|
1890
|
-
this.name = "AcmeApiError";
|
|
1891
|
-
this.statusCode = statusCode;
|
|
1892
|
-
this.body = body;
|
|
1893
|
-
}
|
|
1894
|
-
};
|
|
1895
|
-
|
|
1896
1943
|
// src/internal/http-transport.ts
|
|
1897
1944
|
var RATE_LIMIT_STATUS = 429;
|
|
1898
1945
|
var ADMIN_ACCOUNT_REQUIRED_STATUS = 418;
|
|
@@ -2311,7 +2358,8 @@ function encodeCursor(offset, pageSize) {
|
|
|
2311
2358
|
}
|
|
2312
2359
|
|
|
2313
2360
|
// src/internal/peek/reviews/review-queries.ts
|
|
2314
|
-
|
|
2361
|
+
function buildReviewsQuery(fullCustomerAccess) {
|
|
2362
|
+
return `
|
|
2315
2363
|
query Reviews($first: Int, $filter: ReviewFilter, $after: String) {
|
|
2316
2364
|
reviews(first: $first, filter: $filter, after: $after) {
|
|
2317
2365
|
edges {
|
|
@@ -2325,8 +2373,7 @@ var REVIEWS_QUERY = `
|
|
|
2325
2373
|
name
|
|
2326
2374
|
}
|
|
2327
2375
|
id
|
|
2328
|
-
name
|
|
2329
|
-
email
|
|
2376
|
+
${fullCustomerAccess ? "name\n email" : ""}
|
|
2330
2377
|
rating
|
|
2331
2378
|
comment
|
|
2332
2379
|
reviewedAt
|
|
@@ -2337,6 +2384,7 @@ var REVIEWS_QUERY = `
|
|
|
2337
2384
|
}
|
|
2338
2385
|
}
|
|
2339
2386
|
`;
|
|
2387
|
+
}
|
|
2340
2388
|
function buildReviewsVariables(params) {
|
|
2341
2389
|
return {
|
|
2342
2390
|
first: params.first,
|
|
@@ -2353,10 +2401,13 @@ var ERROR_PRODUCT_ID_REQUIRED = "productId is required";
|
|
|
2353
2401
|
var ERROR_INVALID_REVIEW_COUNT = `reviewCount must be an integer between ${MIN_REVIEW_COUNT} and ${MAX_REVIEW_COUNT}`;
|
|
2354
2402
|
var ERROR_INVALID_REVIEW_OFFSET = "reviewOffset must be a non-negative integer";
|
|
2355
2403
|
var ReviewService = class {
|
|
2356
|
-
constructor(client) {
|
|
2404
|
+
constructor(client, accessOptions) {
|
|
2357
2405
|
this.client = client;
|
|
2406
|
+
this.fullCustomerAccess = resolveAccessOptions(accessOptions).fullCustomerAccess;
|
|
2358
2407
|
}
|
|
2359
2408
|
client;
|
|
2409
|
+
/** Whether reviewer PII (name/email) is requested. */
|
|
2410
|
+
fullCustomerAccess;
|
|
2360
2411
|
/**
|
|
2361
2412
|
* Returns up to `reviewCount` reviews for an activity in **descending order
|
|
2362
2413
|
* by review date (newest first)**, skipping the `reviewOffset` newest reviews
|
|
@@ -2387,7 +2438,7 @@ var ReviewService = class {
|
|
|
2387
2438
|
const after = reviewOffset > 0 ? encodeCursor(reviewOffset - 1, reviewCount) : null;
|
|
2388
2439
|
const body = await this.client.request(
|
|
2389
2440
|
SALES_ENDPOINT,
|
|
2390
|
-
|
|
2441
|
+
buildReviewsQuery(this.fullCustomerAccess),
|
|
2391
2442
|
buildReviewsVariables({ activityId: productId, first: reviewCount, after })
|
|
2392
2443
|
);
|
|
2393
2444
|
const edges = body.data?.reviews?.edges ?? [];
|
|
@@ -2749,6 +2800,7 @@ function fromActivity(activity) {
|
|
|
2749
2800
|
name: activity.name,
|
|
2750
2801
|
type: activity.type,
|
|
2751
2802
|
color: activity.colorHex || "",
|
|
2803
|
+
currency: activity.currency || "",
|
|
2752
2804
|
tickets: (activity.resourceOptions ?? []).map((option) => ({
|
|
2753
2805
|
id: option.id,
|
|
2754
2806
|
name: option.name
|
|
@@ -2767,6 +2819,7 @@ function fromItemOptionNodes(nodes) {
|
|
|
2767
2819
|
name: node.item.name,
|
|
2768
2820
|
type: ADD_ON_PRODUCT_TYPE,
|
|
2769
2821
|
color: ADD_ON_COLOR,
|
|
2822
|
+
currency: "",
|
|
2770
2823
|
tickets: []
|
|
2771
2824
|
};
|
|
2772
2825
|
grouped.set(itemId, product);
|
|
@@ -2786,6 +2839,7 @@ var PRODUCTS_QUERY = `
|
|
|
2786
2839
|
deletedAt
|
|
2787
2840
|
type
|
|
2788
2841
|
colorHex
|
|
2842
|
+
currency
|
|
2789
2843
|
resourceOptions {
|
|
2790
2844
|
id
|
|
2791
2845
|
name
|
|
@@ -3012,6 +3066,325 @@ var PromoCodeService = class {
|
|
|
3012
3066
|
}
|
|
3013
3067
|
};
|
|
3014
3068
|
|
|
3069
|
+
// src/internal/peek/pricing/pricing-queries.ts
|
|
3070
|
+
var CREATE_PRICING_ENGINE_MUTATION = `
|
|
3071
|
+
mutation CreatePricingEngine($input: CreatePricingEngineInput!) {
|
|
3072
|
+
createPricingEngine(input: $input) {
|
|
3073
|
+
__typename
|
|
3074
|
+
... on CreatePricingEngineSuccess {
|
|
3075
|
+
engine {
|
|
3076
|
+
id
|
|
3077
|
+
}
|
|
3078
|
+
}
|
|
3079
|
+
... on InvalidDataError {
|
|
3080
|
+
message
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
`;
|
|
3085
|
+
var UPDATE_PRICING_ENGINE_MUTATION = `
|
|
3086
|
+
mutation UpdatePricingEngine($input: UpdatePricingEngineInput!) {
|
|
3087
|
+
updatePricingEngine(input: $input) {
|
|
3088
|
+
__typename
|
|
3089
|
+
... on UpdatePricingEngineSuccess {
|
|
3090
|
+
engine {
|
|
3091
|
+
id
|
|
3092
|
+
name
|
|
3093
|
+
}
|
|
3094
|
+
}
|
|
3095
|
+
... on InvalidDataError {
|
|
3096
|
+
message
|
|
3097
|
+
}
|
|
3098
|
+
... on NotFoundError {
|
|
3099
|
+
id
|
|
3100
|
+
message
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
}
|
|
3104
|
+
`;
|
|
3105
|
+
var DELETE_PRICING_ENGINE_MUTATION = `
|
|
3106
|
+
mutation DeletePricingEngine($id: ID!) {
|
|
3107
|
+
deletePricingEngine(id: $id) {
|
|
3108
|
+
__typename
|
|
3109
|
+
... on DeletePricingEngineSuccess {
|
|
3110
|
+
engine {
|
|
3111
|
+
id
|
|
3112
|
+
name
|
|
3113
|
+
}
|
|
3114
|
+
}
|
|
3115
|
+
... on NotFoundError {
|
|
3116
|
+
id
|
|
3117
|
+
message
|
|
3118
|
+
}
|
|
3119
|
+
}
|
|
3120
|
+
}
|
|
3121
|
+
`;
|
|
3122
|
+
var UPSERT_PRICING_OVERRIDES_MUTATION = `
|
|
3123
|
+
mutation UpsertPricingOverridesActivityContexts($input: UpsertPricingOverridesActivityContextsInput!) {
|
|
3124
|
+
upsertPricingOverridesActivityContexts(input: $input) {
|
|
3125
|
+
__typename
|
|
3126
|
+
... on UpsertPricingOverridesActivityContextsSuccess {
|
|
3127
|
+
activityContexts {
|
|
3128
|
+
date
|
|
3129
|
+
activity {
|
|
3130
|
+
id
|
|
3131
|
+
name
|
|
3132
|
+
}
|
|
3133
|
+
engine {
|
|
3134
|
+
id
|
|
3135
|
+
name
|
|
3136
|
+
}
|
|
3137
|
+
overrides {
|
|
3138
|
+
order
|
|
3139
|
+
resourceOptions {
|
|
3140
|
+
resourceOption {
|
|
3141
|
+
id
|
|
3142
|
+
name
|
|
3143
|
+
}
|
|
3144
|
+
override {
|
|
3145
|
+
... on PricingOverridesActivityContextResourceOptionPriceOverride {
|
|
3146
|
+
price {
|
|
3147
|
+
amount
|
|
3148
|
+
currency
|
|
3149
|
+
}
|
|
3150
|
+
}
|
|
3151
|
+
... on PricingOverridesActivityContextResourceOptionPercentageAdjustmentOverride {
|
|
3152
|
+
percentageAdjustment
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
filters {
|
|
3157
|
+
__typename
|
|
3158
|
+
... on PricingOverridesActivityContextStartTimeRangeFilter {
|
|
3159
|
+
startTimeRange
|
|
3160
|
+
}
|
|
3161
|
+
... on PricingOverridesActivityContextSpotsTakenFilter {
|
|
3162
|
+
minSpots
|
|
3163
|
+
maxSpots
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3168
|
+
}
|
|
3169
|
+
... on InvalidDataError {
|
|
3170
|
+
message
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
3173
|
+
}
|
|
3174
|
+
`;
|
|
3175
|
+
var SPOTS_TAKEN_FILTER_TYPENAME = "PricingOverridesActivityContextSpotsTakenFilter";
|
|
3176
|
+
function buildCreateEngineInput(input) {
|
|
3177
|
+
const activityIds = input.activityIds ?? [];
|
|
3178
|
+
return activityIds.length > 0 ? { name: input.name, filters: [{ activityIds }] } : { name: input.name };
|
|
3179
|
+
}
|
|
3180
|
+
function buildUpdateEngineInput(input) {
|
|
3181
|
+
const activityIds = input.activityIds ?? [];
|
|
3182
|
+
return {
|
|
3183
|
+
id: input.engineId,
|
|
3184
|
+
name: input.name,
|
|
3185
|
+
filters: activityIds.length > 0 ? [{ activityIds }] : []
|
|
3186
|
+
};
|
|
3187
|
+
}
|
|
3188
|
+
function buildUpsertInput(input) {
|
|
3189
|
+
return {
|
|
3190
|
+
engineId: input.engineId,
|
|
3191
|
+
dateRange: input.dateRange,
|
|
3192
|
+
activities: input.activities.map((activity) => ({
|
|
3193
|
+
activityId: activity.activityId,
|
|
3194
|
+
overrides: activity.overrides.map((override) => ({
|
|
3195
|
+
order: override.order,
|
|
3196
|
+
resourceOptions: override.resourceOptions.map(
|
|
3197
|
+
(option) => option.mode === "fixed" ? { id: option.id, price: option.price } : { id: option.id, percentageAdjustment: option.percentageAdjustment }
|
|
3198
|
+
),
|
|
3199
|
+
filters: override.filters
|
|
3200
|
+
}))
|
|
3201
|
+
}))
|
|
3202
|
+
};
|
|
3203
|
+
}
|
|
3204
|
+
function buildClearInput(input) {
|
|
3205
|
+
return {
|
|
3206
|
+
engineId: input.engineId,
|
|
3207
|
+
dateRange: input.dateRange,
|
|
3208
|
+
activities: input.activityIds.map((activityId) => ({
|
|
3209
|
+
activityId,
|
|
3210
|
+
overrides: []
|
|
3211
|
+
}))
|
|
3212
|
+
};
|
|
3213
|
+
}
|
|
3214
|
+
|
|
3215
|
+
// src/internal/peek/pricing/pricing-converter.ts
|
|
3216
|
+
function fromActivityContexts(contexts) {
|
|
3217
|
+
return contexts.map(fromActivityContext);
|
|
3218
|
+
}
|
|
3219
|
+
function fromActivityContext(context) {
|
|
3220
|
+
return {
|
|
3221
|
+
date: context.date,
|
|
3222
|
+
activity: { id: context.activity.id, name: context.activity.name },
|
|
3223
|
+
engine: { id: context.engine.id, name: context.engine.name },
|
|
3224
|
+
overrides: context.overrides.map(fromOverride)
|
|
3225
|
+
};
|
|
3226
|
+
}
|
|
3227
|
+
function fromOverride(override) {
|
|
3228
|
+
return {
|
|
3229
|
+
order: override.order,
|
|
3230
|
+
resourceOptions: override.resourceOptions.map(fromResourceOption),
|
|
3231
|
+
filters: override.filters.map(fromFilter)
|
|
3232
|
+
};
|
|
3233
|
+
}
|
|
3234
|
+
function fromResourceOption(option) {
|
|
3235
|
+
return {
|
|
3236
|
+
resourceOption: {
|
|
3237
|
+
id: option.resourceOption.id,
|
|
3238
|
+
name: option.resourceOption.name
|
|
3239
|
+
},
|
|
3240
|
+
override: fromResolvedOverride(option.override)
|
|
3241
|
+
};
|
|
3242
|
+
}
|
|
3243
|
+
function fromResolvedOverride(override) {
|
|
3244
|
+
return "price" in override ? { mode: "fixed", price: override.price } : { mode: "percentage", percentageAdjustment: override.percentageAdjustment };
|
|
3245
|
+
}
|
|
3246
|
+
function fromFilter(filter) {
|
|
3247
|
+
if (filter.__typename === SPOTS_TAKEN_FILTER_TYPENAME) {
|
|
3248
|
+
const spotsTaken = {};
|
|
3249
|
+
if (filter.minSpots !== null) spotsTaken.minSpots = filter.minSpots;
|
|
3250
|
+
if (filter.maxSpots !== null) spotsTaken.maxSpots = filter.maxSpots;
|
|
3251
|
+
return { spotsTaken };
|
|
3252
|
+
}
|
|
3253
|
+
return { startTimeRange: filter.startTimeRange };
|
|
3254
|
+
}
|
|
3255
|
+
|
|
3256
|
+
// src/internal/peek/pricing/pricing-service.ts
|
|
3257
|
+
var CURRENCY_PATTERN2 = /^[A-Z]{3}$/;
|
|
3258
|
+
var PERCENTAGE_FLOOR = -100;
|
|
3259
|
+
var ERROR_NAME_REQUIRED = "name is required";
|
|
3260
|
+
var ERROR_ENGINE_ID_REQUIRED = "engineId is required";
|
|
3261
|
+
var ERROR_DATE_RANGE_REQUIRED = "dateRange is required";
|
|
3262
|
+
var ERROR_ACTIVITIES_REQUIRED = "activities is required";
|
|
3263
|
+
var ERROR_ACTIVITY_ID_REQUIRED = "activityId is required";
|
|
3264
|
+
var ERROR_TICKET_ID_REQUIRED = "resource-option id is required";
|
|
3265
|
+
var ERROR_CURRENCY_FORMAT = "currency must be 3 uppercase letters";
|
|
3266
|
+
var ERROR_AMOUNT_NUMBER = "price amount must be a valid number";
|
|
3267
|
+
var ERROR_PERCENTAGE_NUMBER = "percentageAdjustment must be a valid number";
|
|
3268
|
+
var ERROR_PERCENTAGE_FLOOR = "percentageAdjustment must be greater than -100";
|
|
3269
|
+
var ERROR_NO_DATA = "pricing mutation returned no data";
|
|
3270
|
+
var PricingService = class {
|
|
3271
|
+
constructor(client) {
|
|
3272
|
+
this.client = client;
|
|
3273
|
+
}
|
|
3274
|
+
client;
|
|
3275
|
+
/**
|
|
3276
|
+
* Creates a pricing engine. Store the returned id and reuse it on every
|
|
3277
|
+
* subsequent override upsert. Throws on an InvalidDataError from Peek.
|
|
3278
|
+
*/
|
|
3279
|
+
async createEngine(input) {
|
|
3280
|
+
if (!input.name) throw new Error(ERROR_NAME_REQUIRED);
|
|
3281
|
+
const body = await this.client.request(
|
|
3282
|
+
SALES_ENDPOINT,
|
|
3283
|
+
CREATE_PRICING_ENGINE_MUTATION,
|
|
3284
|
+
{ input: buildCreateEngineInput(input) }
|
|
3285
|
+
);
|
|
3286
|
+
const result = body.data?.createPricingEngine;
|
|
3287
|
+
if (!result) throw new Error(ERROR_NO_DATA);
|
|
3288
|
+
if (result.__typename !== "CreatePricingEngineSuccess") {
|
|
3289
|
+
throw new Error(result.message);
|
|
3290
|
+
}
|
|
3291
|
+
return { id: result.engine.id };
|
|
3292
|
+
}
|
|
3293
|
+
/**
|
|
3294
|
+
* Updates a pricing engine's name and/or activity scope. Throws on an
|
|
3295
|
+
* InvalidDataError or NotFoundError from Peek.
|
|
3296
|
+
*/
|
|
3297
|
+
async updateEngine(input) {
|
|
3298
|
+
if (!input.engineId) throw new Error(ERROR_ENGINE_ID_REQUIRED);
|
|
3299
|
+
if (!input.name) throw new Error(ERROR_NAME_REQUIRED);
|
|
3300
|
+
const body = await this.client.request(
|
|
3301
|
+
SALES_ENDPOINT,
|
|
3302
|
+
UPDATE_PRICING_ENGINE_MUTATION,
|
|
3303
|
+
{ input: buildUpdateEngineInput(input) }
|
|
3304
|
+
);
|
|
3305
|
+
const result = body.data?.updatePricingEngine;
|
|
3306
|
+
if (!result) throw new Error(ERROR_NO_DATA);
|
|
3307
|
+
if (result.__typename !== "UpdatePricingEngineSuccess") {
|
|
3308
|
+
throw new Error(result.message);
|
|
3309
|
+
}
|
|
3310
|
+
return { id: result.engine.id, name: result.engine.name };
|
|
3311
|
+
}
|
|
3312
|
+
/**
|
|
3313
|
+
* Deletes a pricing engine. Idempotent — resolves whether the engine existed
|
|
3314
|
+
* or was already gone (Peek's NotFoundError is treated as success).
|
|
3315
|
+
*/
|
|
3316
|
+
async deleteEngine(engineId) {
|
|
3317
|
+
if (!engineId) throw new Error(ERROR_ENGINE_ID_REQUIRED);
|
|
3318
|
+
await this.client.request(
|
|
3319
|
+
SALES_ENDPOINT,
|
|
3320
|
+
DELETE_PRICING_ENGINE_MUTATION,
|
|
3321
|
+
{ id: engineId }
|
|
3322
|
+
);
|
|
3323
|
+
}
|
|
3324
|
+
/**
|
|
3325
|
+
* Upserts pricing overrides for the engine and date range in `input`. Returns
|
|
3326
|
+
* the resolved contexts Peek stored. Throws on an InvalidDataError from Peek.
|
|
3327
|
+
*/
|
|
3328
|
+
async upsertOverrides(input) {
|
|
3329
|
+
this.validateUpsertInput(input);
|
|
3330
|
+
return this.sendUpsert(buildUpsertInput(input));
|
|
3331
|
+
}
|
|
3332
|
+
/**
|
|
3333
|
+
* Clears all overrides for the given activities across a date range. This is
|
|
3334
|
+
* an upsert with empty overrides — never clear by omitting an activity.
|
|
3335
|
+
*/
|
|
3336
|
+
async clearOverrides(input) {
|
|
3337
|
+
if (!input.engineId) throw new Error(ERROR_ENGINE_ID_REQUIRED);
|
|
3338
|
+
if (!input.dateRange) throw new Error(ERROR_DATE_RANGE_REQUIRED);
|
|
3339
|
+
if (!Array.isArray(input.activityIds)) throw new Error(ERROR_ACTIVITIES_REQUIRED);
|
|
3340
|
+
for (const activityId of input.activityIds) {
|
|
3341
|
+
if (!activityId) throw new Error(ERROR_ACTIVITY_ID_REQUIRED);
|
|
3342
|
+
}
|
|
3343
|
+
return this.sendUpsert(buildClearInput(input));
|
|
3344
|
+
}
|
|
3345
|
+
async sendUpsert(rawInput) {
|
|
3346
|
+
const body = await this.client.request(
|
|
3347
|
+
SALES_ENDPOINT,
|
|
3348
|
+
UPSERT_PRICING_OVERRIDES_MUTATION,
|
|
3349
|
+
{ input: rawInput }
|
|
3350
|
+
);
|
|
3351
|
+
const result = body.data?.upsertPricingOverridesActivityContexts;
|
|
3352
|
+
if (!result) throw new Error(ERROR_NO_DATA);
|
|
3353
|
+
if (result.__typename !== "UpsertPricingOverridesActivityContextsSuccess") {
|
|
3354
|
+
throw new Error(result.message);
|
|
3355
|
+
}
|
|
3356
|
+
return { activityContexts: fromActivityContexts(result.activityContexts) };
|
|
3357
|
+
}
|
|
3358
|
+
validateUpsertInput(input) {
|
|
3359
|
+
if (!input.engineId) throw new Error(ERROR_ENGINE_ID_REQUIRED);
|
|
3360
|
+
if (!input.dateRange) throw new Error(ERROR_DATE_RANGE_REQUIRED);
|
|
3361
|
+
if (!Array.isArray(input.activities)) throw new Error(ERROR_ACTIVITIES_REQUIRED);
|
|
3362
|
+
for (const activity of input.activities) {
|
|
3363
|
+
if (!activity.activityId) throw new Error(ERROR_ACTIVITY_ID_REQUIRED);
|
|
3364
|
+
for (const override of activity.overrides) {
|
|
3365
|
+
for (const option of override.resourceOptions) {
|
|
3366
|
+
this.validateResourceOption(option);
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
validateResourceOption(option) {
|
|
3372
|
+
if (!option.id) throw new Error(ERROR_TICKET_ID_REQUIRED);
|
|
3373
|
+
if (option.mode === "fixed") {
|
|
3374
|
+
if (!CURRENCY_PATTERN2.test(option.price.currency)) {
|
|
3375
|
+
throw new Error(ERROR_CURRENCY_FORMAT);
|
|
3376
|
+
}
|
|
3377
|
+
if (Number.isNaN(Number.parseFloat(option.price.amount))) {
|
|
3378
|
+
throw new Error(ERROR_AMOUNT_NUMBER);
|
|
3379
|
+
}
|
|
3380
|
+
return;
|
|
3381
|
+
}
|
|
3382
|
+
const percentage = Number.parseFloat(option.percentageAdjustment);
|
|
3383
|
+
if (Number.isNaN(percentage)) throw new Error(ERROR_PERCENTAGE_NUMBER);
|
|
3384
|
+
if (percentage <= PERCENTAGE_FLOOR) throw new Error(ERROR_PERCENTAGE_FLOOR);
|
|
3385
|
+
}
|
|
3386
|
+
};
|
|
3387
|
+
|
|
3015
3388
|
// src/logger.ts
|
|
3016
3389
|
var noopLogger = {
|
|
3017
3390
|
info() {
|
|
@@ -3029,6 +3402,7 @@ var PEEK_TOKEN_ISSUER = "app_registry_v2";
|
|
|
3029
3402
|
var PeekAccessService = class {
|
|
3030
3403
|
client;
|
|
3031
3404
|
productServiceOptions;
|
|
3405
|
+
accessOptions;
|
|
3032
3406
|
jwtSecret;
|
|
3033
3407
|
productService;
|
|
3034
3408
|
accountUserService;
|
|
@@ -3036,6 +3410,7 @@ var PeekAccessService = class {
|
|
|
3036
3410
|
timeslotService;
|
|
3037
3411
|
resellerService;
|
|
3038
3412
|
promoCodeService;
|
|
3413
|
+
pricingService;
|
|
3039
3414
|
dailyNoteService;
|
|
3040
3415
|
availabilityService;
|
|
3041
3416
|
membershipService;
|
|
@@ -3065,6 +3440,7 @@ var PeekAccessService = class {
|
|
|
3065
3440
|
this.productServiceOptions = {
|
|
3066
3441
|
itemOptionsPageSize: config.itemOptionsPageSize
|
|
3067
3442
|
};
|
|
3443
|
+
this.accessOptions = resolveAccessOptions(config.accessOptions);
|
|
3068
3444
|
}
|
|
3069
3445
|
/**
|
|
3070
3446
|
* Verifies a Peek auth token issued by the app registry and returns the
|
|
@@ -3169,6 +3545,16 @@ var PeekAccessService = class {
|
|
|
3169
3545
|
}
|
|
3170
3546
|
return this.promoCodeService;
|
|
3171
3547
|
}
|
|
3548
|
+
/**
|
|
3549
|
+
* Returns the {@link PricingService} for this install, bound to the shared
|
|
3550
|
+
* authenticated transport. The instance is created lazily and reused.
|
|
3551
|
+
*/
|
|
3552
|
+
getPricingService() {
|
|
3553
|
+
if (!this.pricingService) {
|
|
3554
|
+
this.pricingService = new PricingService(this.client);
|
|
3555
|
+
}
|
|
3556
|
+
return this.pricingService;
|
|
3557
|
+
}
|
|
3172
3558
|
/**
|
|
3173
3559
|
* Returns the {@link DailyNoteService} for this install, bound to the shared
|
|
3174
3560
|
* authenticated transport. The instance is created lazily and reused.
|
|
@@ -3205,9 +3591,11 @@ var PeekAccessService = class {
|
|
|
3205
3591
|
*/
|
|
3206
3592
|
getBookingService() {
|
|
3207
3593
|
if (!this.bookingService) {
|
|
3208
|
-
this.bookingService = new BookingService(
|
|
3209
|
-
|
|
3210
|
-
|
|
3594
|
+
this.bookingService = new BookingService(
|
|
3595
|
+
this.client,
|
|
3596
|
+
{ productService: this.getProductService() },
|
|
3597
|
+
{ accessOptions: this.accessOptions }
|
|
3598
|
+
);
|
|
3211
3599
|
}
|
|
3212
3600
|
return this.bookingService;
|
|
3213
3601
|
}
|
|
@@ -3217,7 +3605,7 @@ var PeekAccessService = class {
|
|
|
3217
3605
|
*/
|
|
3218
3606
|
getReviewService() {
|
|
3219
3607
|
if (!this.reviewService) {
|
|
3220
|
-
this.reviewService = new ReviewService(this.client);
|
|
3608
|
+
this.reviewService = new ReviewService(this.client, this.accessOptions);
|
|
3221
3609
|
}
|
|
3222
3610
|
return this.reviewService;
|
|
3223
3611
|
}
|
|
@@ -3287,6 +3675,27 @@ var PeekAccessService = class {
|
|
|
3287
3675
|
createPromoCode(input) {
|
|
3288
3676
|
return this.getPromoCodeService().create(input);
|
|
3289
3677
|
}
|
|
3678
|
+
// ─── Pricing short-forms ──────────────────────────────────────────────────
|
|
3679
|
+
/** Create a pricing engine. Delegates to {@link PricingService.createEngine}. */
|
|
3680
|
+
createPricingEngine(input) {
|
|
3681
|
+
return this.getPricingService().createEngine(input);
|
|
3682
|
+
}
|
|
3683
|
+
/** Update a pricing engine. Delegates to {@link PricingService.updateEngine}. */
|
|
3684
|
+
updatePricingEngine(input) {
|
|
3685
|
+
return this.getPricingService().updateEngine(input);
|
|
3686
|
+
}
|
|
3687
|
+
/** Delete a pricing engine (idempotent). Delegates to {@link PricingService.deleteEngine}. */
|
|
3688
|
+
deletePricingEngine(engineId) {
|
|
3689
|
+
return this.getPricingService().deleteEngine(engineId);
|
|
3690
|
+
}
|
|
3691
|
+
/** Upsert pricing overrides. Delegates to {@link PricingService.upsertOverrides}. */
|
|
3692
|
+
upsertPricingOverrides(input) {
|
|
3693
|
+
return this.getPricingService().upsertOverrides(input);
|
|
3694
|
+
}
|
|
3695
|
+
/** Clear pricing overrides for a set of activities. Delegates to {@link PricingService.clearOverrides}. */
|
|
3696
|
+
clearPricingOverrides(input) {
|
|
3697
|
+
return this.getPricingService().clearOverrides(input);
|
|
3698
|
+
}
|
|
3290
3699
|
// ─── Daily-note short-forms ───────────────────────────────────────────────
|
|
3291
3700
|
/** Today's daily note. Delegates to {@link DailyNoteService.getToday}. */
|
|
3292
3701
|
getDailyNoteToday() {
|
|
@@ -3710,8 +4119,13 @@ function hasPriceBreakdown(node) {
|
|
|
3710
4119
|
|
|
3711
4120
|
// src/internal/peek/waivers/waiver-webhook.ts
|
|
3712
4121
|
var PAYLOAD_WAIVER_KEY = "waiver";
|
|
3713
|
-
function parseWaiverWebhook(payload) {
|
|
3714
|
-
|
|
4122
|
+
function parseWaiverWebhook(payload, options) {
|
|
4123
|
+
const waiver = fromWaiverNode(extractWaiverNode(payload));
|
|
4124
|
+
if (!resolveAccessOptions(options).fullCustomerAccess) {
|
|
4125
|
+
waiver.guestName = null;
|
|
4126
|
+
waiver.fileUrl = "";
|
|
4127
|
+
}
|
|
4128
|
+
return waiver;
|
|
3715
4129
|
}
|
|
3716
4130
|
function fromWaiverNode(node) {
|
|
3717
4131
|
const data = node ?? {};
|
|
@@ -3759,6 +4173,8 @@ exports.DailyNoteService = DailyNoteService;
|
|
|
3759
4173
|
exports.MembershipService = MembershipService;
|
|
3760
4174
|
exports.PeekAccessService = PeekAccessService;
|
|
3761
4175
|
exports.PeekGraphQLError = PeekGraphQLError;
|
|
4176
|
+
exports.PiiAccessDisabledError = PiiAccessDisabledError;
|
|
4177
|
+
exports.PricingService = PricingService;
|
|
3762
4178
|
exports.ProductService = ProductService;
|
|
3763
4179
|
exports.PromoCodeService = PromoCodeService;
|
|
3764
4180
|
exports.RENTAL_PRODUCT_TYPE = RENTAL_PRODUCT_TYPE;
|