@peektravel/app-utilities 0.9.3 → 0.9.5

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 CHANGED
@@ -961,6 +961,7 @@ function fromBookingMetaDataNode(node) {
961
961
  function fromFieldResponseNode(response) {
962
962
  const field = response.fieldLocation?.field;
963
963
  const prompt = response.fieldLocation?.prompt;
964
+ const { value, displayValue } = fromValueNode(response.value);
964
965
  return {
965
966
  id: field?.id || "",
966
967
  name: field?.name || "",
@@ -970,89 +971,96 @@ function fromFieldResponseNode(response) {
970
971
  promptHint: prompt?.hint ?? null,
971
972
  isRequired: Boolean(prompt?.isRequired),
972
973
  refid: response.refid || "",
973
- value: fromValueNode(response.value)
974
+ displayValue,
975
+ value
974
976
  };
975
977
  }
976
978
  function fromValueNode(value) {
977
- if (!value || !value.__typename) return null;
979
+ if (!value || !value.__typename) return { value: null, displayValue: "" };
978
980
  switch (value.__typename) {
979
981
  case "AgeFieldResponseValue": {
980
982
  const age = value.age ?? 0;
981
- return { kind: "age", age, displayValue: String(age) };
983
+ return { value: { kind: "age", age }, displayValue: String(age) };
982
984
  }
983
985
  case "AttachmentFieldResponseValue": {
984
986
  const attachmentUrl = value.attachmentUrl ?? "";
985
987
  const name = value.name ?? null;
986
988
  return {
987
- kind: "attachment",
988
- attachmentUrl,
989
- mime: value.mime ?? null,
990
- name,
991
- size: value.size ?? null,
989
+ value: {
990
+ kind: "attachment",
991
+ attachmentUrl,
992
+ mime: value.mime ?? null,
993
+ name,
994
+ size: value.size ?? null
995
+ },
992
996
  displayValue: name || attachmentUrl
993
997
  };
994
998
  }
995
999
  case "BarcodeFieldResponseValue": {
996
1000
  const barcodeValue = value.barcodeValue ?? "";
997
1001
  return {
998
- kind: "barcode",
999
- barcodeType: value.barcodeType ?? null,
1000
- barcodeValue,
1002
+ value: {
1003
+ kind: "barcode",
1004
+ barcodeType: value.barcodeType ?? null,
1005
+ barcodeValue
1006
+ },
1001
1007
  displayValue: barcodeValue
1002
1008
  };
1003
1009
  }
1004
1010
  case "BooleanFieldResponseValue": {
1005
1011
  const bool = Boolean(value.boolean);
1006
- return { kind: "boolean", boolean: bool, displayValue: yesNo(bool) };
1012
+ return { value: { kind: "boolean", boolean: bool }, displayValue: yesNo(bool) };
1007
1013
  }
1008
1014
  case "CheckboxFieldResponseValue": {
1009
1015
  const isChecked = Boolean(value.isChecked);
1010
- return { kind: "checkbox", isChecked, displayValue: yesNo(isChecked) };
1016
+ return { value: { kind: "checkbox", isChecked }, displayValue: yesNo(isChecked) };
1011
1017
  }
1012
1018
  case "CurrencyFieldResponseValue": {
1013
1019
  const currency = value.currency ?? "";
1014
- return { kind: "currency", currency, displayValue: currency };
1020
+ return { value: { kind: "currency", currency }, displayValue: currency };
1015
1021
  }
1016
1022
  case "DateFieldResponseValue": {
1017
1023
  const date = value.date ?? "";
1018
- return { kind: "date", date, displayValue: date };
1024
+ return { value: { kind: "date", date }, displayValue: date };
1019
1025
  }
1020
1026
  case "DecimalFieldResponseValue": {
1021
1027
  const decimal = value.decimal ?? null;
1022
- return { kind: "decimal", decimal, displayValue: decimal ?? "" };
1028
+ return { value: { kind: "decimal", decimal }, displayValue: decimal ?? "" };
1023
1029
  }
1024
1030
  case "DurationFieldResponseValue": {
1025
1031
  const amount = value.duration?.amount ?? 0;
1026
1032
  const unit = value.duration?.unit ?? null;
1027
- return { kind: "duration", amount, unit, displayValue: amountUnit(amount, unit) };
1033
+ return { value: { kind: "duration", amount, unit }, displayValue: amountUnit(amount, unit) };
1028
1034
  }
1029
1035
  case "EmailFieldResponseValue": {
1030
1036
  const email = value.email ?? null;
1031
- return { kind: "email", email, displayValue: email ?? "" };
1037
+ return { value: { kind: "email", email }, displayValue: email ?? "" };
1032
1038
  }
1033
1039
  case "GuestFieldResponseValue": {
1034
1040
  const name = value.name ?? null;
1035
1041
  return {
1036
- kind: "guest",
1037
- name,
1038
- email: value.email ?? null,
1039
- dateOfBirth: value.dateOfBirth ?? null,
1040
- notes: value.notes ?? null,
1041
- waiverSigned: value.waiverSigned ?? null,
1042
+ value: {
1043
+ kind: "guest",
1044
+ name,
1045
+ email: value.email ?? null,
1046
+ dateOfBirth: value.dateOfBirth ?? null,
1047
+ notes: value.notes ?? null,
1048
+ waiverSigned: value.waiverSigned ?? null
1049
+ },
1042
1050
  displayValue: name ?? ""
1043
1051
  };
1044
1052
  }
1045
1053
  case "HtmlFieldResponseValue": {
1046
1054
  const html = value.html ?? "";
1047
- return { kind: "html", html, displayValue: escapeHtml(html) };
1055
+ return { value: { kind: "html", html }, displayValue: escapeHtml(html) };
1048
1056
  }
1049
1057
  case "ImageUrlFieldResponseValue": {
1050
1058
  const imageUrl = value.imageUrl ?? "";
1051
- return { kind: "imageUrl", imageUrl, displayValue: imageUrl };
1059
+ return { value: { kind: "imageUrl", imageUrl }, displayValue: imageUrl };
1052
1060
  }
1053
1061
  case "IntegerFieldResponseValue": {
1054
1062
  const integer = value.integer ?? 0;
1055
- return { kind: "integer", integer, displayValue: String(integer) };
1063
+ return { value: { kind: "integer", integer }, displayValue: String(integer) };
1056
1064
  }
1057
1065
  case "LocationFieldResponseValue": {
1058
1066
  const streetAddress = value.streetAddress ?? null;
@@ -1061,56 +1069,58 @@ function fromValueNode(value) {
1061
1069
  const postalCode = value.postalCode ?? null;
1062
1070
  const country = value.country ?? null;
1063
1071
  return {
1064
- kind: "location",
1065
- country,
1066
- county: value.county ?? null,
1067
- locality,
1068
- postalCode,
1069
- region,
1070
- streetAddress,
1072
+ value: {
1073
+ kind: "location",
1074
+ country,
1075
+ county: value.county ?? null,
1076
+ locality,
1077
+ postalCode,
1078
+ region,
1079
+ streetAddress
1080
+ },
1071
1081
  displayValue: [streetAddress, locality, region, postalCode, country].filter((part) => part).join(", ")
1072
1082
  };
1073
1083
  }
1074
1084
  case "LongTextFieldResponseValue": {
1075
1085
  const longText = value.longText ?? "";
1076
- return { kind: "longText", longText, displayValue: longText };
1086
+ return { value: { kind: "longText", longText }, displayValue: longText };
1077
1087
  }
1078
1088
  case "MetaFieldResponseValue": {
1079
1089
  const meta = value.meta ?? null;
1080
- return { kind: "meta", meta, displayValue: meta == null ? "" : JSON.stringify(meta) };
1090
+ return { value: { kind: "meta", meta }, displayValue: meta == null ? "" : JSON.stringify(meta) };
1081
1091
  }
1082
1092
  case "PercentFieldResponseValue": {
1083
1093
  const percent = value.percent ?? null;
1084
- return { kind: "percent", percent, displayValue: percent == null ? "" : `${percent}%` };
1094
+ return { value: { kind: "percent", percent }, displayValue: percent == null ? "" : `${percent}%` };
1085
1095
  }
1086
1096
  case "PhoneFieldResponseValue": {
1087
1097
  const phone = value.phone ?? "";
1088
- return { kind: "phone", phone, displayValue: phone };
1098
+ return { value: { kind: "phone", phone }, displayValue: phone };
1089
1099
  }
1090
1100
  case "ShortTextFieldResponseValue": {
1091
1101
  const shortText = value.shortText ?? "";
1092
- return { kind: "shortText", shortText, displayValue: shortText };
1102
+ return { value: { kind: "shortText", shortText }, displayValue: shortText };
1093
1103
  }
1094
1104
  case "TimeFieldResponseValue": {
1095
1105
  const time = value.time ?? "";
1096
- return { kind: "time", time, displayValue: time };
1106
+ return { value: { kind: "time", time }, displayValue: time };
1097
1107
  }
1098
1108
  case "UrlFieldResponseValue": {
1099
1109
  const url = value.url ?? null;
1100
- return { kind: "url", url, displayValue: url ?? "" };
1110
+ return { value: { kind: "url", url }, displayValue: url ?? "" };
1101
1111
  }
1102
1112
  case "VolumeFieldResponseValue": {
1103
1113
  const amount = value.volume?.amount ?? "0";
1104
1114
  const unit = value.volume?.unit ?? null;
1105
- return { kind: "volume", amount, unit, displayValue: amountUnit(amount, unit) };
1115
+ return { value: { kind: "volume", amount, unit }, displayValue: amountUnit(amount, unit) };
1106
1116
  }
1107
1117
  case "WeightFieldResponseValue": {
1108
1118
  const amount = value.weight?.amount ?? "0";
1109
1119
  const unit = value.weight?.unit ?? null;
1110
- return { kind: "weight", amount, unit, displayValue: amountUnit(amount, unit) };
1120
+ return { value: { kind: "weight", amount, unit }, displayValue: amountUnit(amount, unit) };
1111
1121
  }
1112
1122
  default:
1113
- return null;
1123
+ return { value: null, displayValue: "" };
1114
1124
  }
1115
1125
  }
1116
1126
  function yesNo(value) {
@@ -1130,7 +1140,7 @@ function toSetMetaDataResult(node, bookingId) {
1130
1140
  };
1131
1141
  }
1132
1142
  function filterMetaDataByIntegrator(metaData, integrator) {
1133
- const prefix = `integrator:${integrator}:`;
1143
+ const prefix = `integrators:${integrator}:`;
1134
1144
  return metaData.filter((entry) => entry.slug.startsWith(prefix)).map((entry) => ({ ...entry, slug: entry.slug.slice(prefix.length) }));
1135
1145
  }
1136
1146
 
@@ -1626,7 +1636,7 @@ var BookingService = class {
1626
1636
  /**
1627
1637
  * Returns a booking's custom-field metadata (its `fieldResponses`), scoped to
1628
1638
  * this service's integrator. Only fields whose slug starts with
1629
- * `integrator:<integrator>:` are returned, and that prefix is stripped from
1639
+ * `integrators:<integrator>:` are returned, and that prefix is stripped from
1630
1640
  * each returned `slug`. Returns `[]` when the booking is not found or has no
1631
1641
  * matching fields.
1632
1642
  *
@@ -2486,6 +2496,123 @@ function buildCancellation(items, addonOptionId, quantity) {
2486
2496
  return { bookingQuotes, canceledCount };
2487
2497
  }
2488
2498
 
2499
+ // src/internal/peek/custom-questions/custom-question-converter.ts
2500
+ function fromQuestionConfigurations(configs) {
2501
+ return configs.map(
2502
+ (config) => fromQuestionNode(config.question, config.order, config.isRequired)
2503
+ );
2504
+ }
2505
+ function fromQuestionNodes(questions) {
2506
+ return questions.map((question) => fromQuestionNode(question));
2507
+ }
2508
+ function fromQuestionNode(question, order, isRequired) {
2509
+ return {
2510
+ id: question.id,
2511
+ order: order ?? 0,
2512
+ isRequired: isRequired ?? false,
2513
+ questionText: question.text,
2514
+ hintText: question.hint ?? null,
2515
+ questionType: question.questionType,
2516
+ internalLabel: question.internalLabel ?? null,
2517
+ perGuest: question.perGuest ?? false,
2518
+ defaultValue: question.answerDefaultValue ?? null,
2519
+ options: (question.options ?? []).map(fromQuestionOption)
2520
+ };
2521
+ }
2522
+ function fromQuestionOption(option) {
2523
+ return {
2524
+ id: option.id,
2525
+ order: option.order,
2526
+ value: option.text
2527
+ };
2528
+ }
2529
+
2530
+ // src/internal/peek/custom-questions/custom-question-queries.ts
2531
+ var ALL_CUSTOM_QUESTIONS_QUERY = `
2532
+ query Sales {
2533
+ questions {
2534
+ id
2535
+ questionType
2536
+ text
2537
+ answerDefaultValue
2538
+ hint
2539
+ internalLabel
2540
+ perGuest
2541
+ ... on ChoiceQuestion {
2542
+ options {
2543
+ id
2544
+ text
2545
+ order
2546
+ }
2547
+ }
2548
+ }
2549
+ }
2550
+ `;
2551
+ var CUSTOM_QUESTIONS_QUERY = `
2552
+ query Sales($id: ID!) {
2553
+ activity(id: $id) {
2554
+ id
2555
+ name
2556
+ questionActivityConfigurations {
2557
+ isRequired
2558
+ order
2559
+ question {
2560
+ id
2561
+ questionType
2562
+ text
2563
+ answerDefaultValue
2564
+ hint
2565
+ internalLabel
2566
+ perGuest
2567
+ ... on ChoiceQuestion {
2568
+ options {
2569
+ id
2570
+ text
2571
+ order
2572
+ }
2573
+ }
2574
+ }
2575
+ }
2576
+ }
2577
+ }
2578
+ `;
2579
+
2580
+ // src/internal/peek/custom-questions/custom-question-service.ts
2581
+ var CustomQuestionService = class {
2582
+ constructor(client) {
2583
+ this.client = client;
2584
+ }
2585
+ client;
2586
+ /**
2587
+ * Returns every custom question defined on the account, across all
2588
+ * activities. Choice-style questions (`SELECT_ONE`, `LOCATION`, …) carry their
2589
+ * selectable {@link CustomQuestion.options}; free-text/checkbox questions
2590
+ * return an empty option list.
2591
+ *
2592
+ * These are account-wide question **definitions**, not customer answers — no
2593
+ * PII is involved, so the result is unaffected by `fullCustomerAccess`. Unlike
2594
+ * {@link ProductService.getCustomQuestions}, the catalog carries no
2595
+ * per-activity configuration, so {@link CustomQuestion.order} is `0` and
2596
+ * {@link CustomQuestion.isRequired} is `false` on every entry.
2597
+ *
2598
+ * @returns Every custom question on the account, or an empty list when none
2599
+ * are defined.
2600
+ *
2601
+ * @example
2602
+ * ```ts
2603
+ * const questions = await peek.getCustomQuestionService().getAll();
2604
+ * ```
2605
+ */
2606
+ async getAll() {
2607
+ const body = await this.client.request(
2608
+ SALES_ENDPOINT,
2609
+ ALL_CUSTOM_QUESTIONS_QUERY,
2610
+ {}
2611
+ );
2612
+ return fromQuestionNodes(body.data?.questions ?? []);
2613
+ }
2614
+ };
2615
+
2489
2616
  // src/internal/peek/daily-notes/daily-note-converter.ts
2490
2617
  function toDailyNote(response) {
2491
2618
  const union = response?.dailyNote;
@@ -2664,7 +2791,7 @@ async function requestWithRetry(http, url, init, label, onResponse) {
2664
2791
  // src/internal/sdk-headers.ts
2665
2792
  var SDK_HEADER_NAME = "x-peek-sdk";
2666
2793
  var SDK_PLATFORM = "js";
2667
- var SDK_VERSION = "0.9.3";
2794
+ var SDK_VERSION = "0.9.5";
2668
2795
  var SDK_HEADER_VALUE = `${SDK_PLATFORM}-${SDK_VERSION}`;
2669
2796
 
2670
2797
  // src/internal/peek/graphql-client.ts
@@ -3690,33 +3817,6 @@ function fromItemOptionNodes(nodes) {
3690
3817
  return Array.from(grouped.values());
3691
3818
  }
3692
3819
 
3693
- // src/internal/peek/products/custom-question-converter.ts
3694
- function fromQuestionConfigurations(configs) {
3695
- return configs.map(fromQuestionConfiguration);
3696
- }
3697
- function fromQuestionConfiguration(config) {
3698
- const question = config.question;
3699
- return {
3700
- id: question.id,
3701
- order: config.order ?? 0,
3702
- isRequired: config.isRequired ?? false,
3703
- questionText: question.text,
3704
- hintText: question.hint ?? null,
3705
- questionType: question.questionType,
3706
- internalLabel: question.internalLabel ?? null,
3707
- perGuest: question.perGuest ?? false,
3708
- defaultValue: question.answerDefaultValue ?? null,
3709
- options: (question.options ?? []).map(fromQuestionOption)
3710
- };
3711
- }
3712
- function fromQuestionOption(option) {
3713
- return {
3714
- id: option.id,
3715
- order: option.order,
3716
- value: option.text
3717
- };
3718
- }
3719
-
3720
3820
  // src/internal/peek/products/product-queries.ts
3721
3821
  var PRODUCTS_QUERY = `
3722
3822
  query Sales {
@@ -3775,36 +3875,6 @@ var ITEM_OPTIONS_QUERY = `
3775
3875
  }
3776
3876
  `;
3777
3877
 
3778
- // src/internal/peek/products/custom-question-queries.ts
3779
- var CUSTOM_QUESTIONS_QUERY = `
3780
- query Sales($id: ID!) {
3781
- activity(id: $id) {
3782
- id
3783
- name
3784
- questionActivityConfigurations {
3785
- isRequired
3786
- order
3787
- question {
3788
- id
3789
- questionType
3790
- text
3791
- answerDefaultValue
3792
- hint
3793
- internalLabel
3794
- perGuest
3795
- ... on ChoiceQuestion {
3796
- options {
3797
- id
3798
- text
3799
- order
3800
- }
3801
- }
3802
- }
3803
- }
3804
- }
3805
- }
3806
- `;
3807
-
3808
3878
  // src/internal/peek/products/product-service.ts
3809
3879
  var ERROR_PRODUCT_ID_REQUIRED2 = "A non-empty product id is required.";
3810
3880
  var DEFAULT_ITEM_OPTIONS_PAGE_SIZE = 50;
@@ -4383,6 +4453,7 @@ var PeekAccessService = class {
4383
4453
  membershipService;
4384
4454
  bookingServices = /* @__PURE__ */ new Map();
4385
4455
  reviewService;
4456
+ customQuestionService;
4386
4457
  constructor(config) {
4387
4458
  const hasApiUrl = !!config.apiUrl;
4388
4459
  const isV2 = config.mode === "v2";
@@ -4583,6 +4654,16 @@ var PeekAccessService = class {
4583
4654
  }
4584
4655
  return this.reviewService;
4585
4656
  }
4657
+ /**
4658
+ * Returns the {@link CustomQuestionService} for this install, bound to the
4659
+ * shared authenticated transport. The instance is created lazily and reused.
4660
+ */
4661
+ getCustomQuestionService() {
4662
+ if (!this.customQuestionService) {
4663
+ this.customQuestionService = new CustomQuestionService(this.client);
4664
+ }
4665
+ return this.customQuestionService;
4666
+ }
4586
4667
  // ─── Product short-forms ─────────────────────────────────────────────────
4587
4668
  /** All products (activities + add-ons). @deprecated The access service exposes only its resource-service accessors; call the service directly instead. See {@link ProductService.getAllProducts}. */
4588
4669
  getAllProducts() {
@@ -5232,6 +5313,7 @@ exports.CngAccessService = CngAccessService;
5232
5313
  exports.CngApiError = CngApiError;
5233
5314
  exports.CngPermissionError = CngPermissionError;
5234
5315
  exports.CngProductService = CngProductService;
5316
+ exports.CustomQuestionService = CustomQuestionService;
5235
5317
  exports.DailyNoteService = DailyNoteService;
5236
5318
  exports.INSTALL_STATUSES = INSTALL_STATUSES;
5237
5319
  exports.MembershipService = MembershipService;