@aranova/tracking-react 1.11.0 → 1.13.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/sales.mjs CHANGED
@@ -241,6 +241,10 @@ function nationalDigits(phone) {
241
241
  return (parsed.isValid ? parsed.national : phone).replace(/\D/g, "");
242
242
  }
243
243
 
244
+ // ../tracking-core/src/lead-forms/lead-forms.gen.ts
245
+ import * as z from "zod/mini";
246
+ var LEAD_FORM_REGISTRY_VERSION = 2;
247
+
244
248
  // ../tracking-core/src/uuid.ts
245
249
  function uuidV4() {
246
250
  const cryptoApi = globalThis.crypto;
@@ -426,39 +430,54 @@ function outcomeOf(body) {
426
430
  if (body.status === "pending") return { status: "pending", id: body.id, mode };
427
431
  return { status: "failed", id: body.id, fallbackUrl: body.fallback_url, mode };
428
432
  }
429
- function formSubmitPayload(input, formSubmit, labels) {
430
- const vehicle = input.vehicle ? `${input.vehicle.year} ${input.vehicle.make} ${input.vehicle.model}` : "";
431
- const field = (name, type, label, value) => ({
432
- name,
433
- type,
434
- label,
435
- value
436
- });
437
- const fields = [
438
- field("first_name", "text", "First name", input.firstName),
439
- field("last_name", "text", "Last name", input.lastName),
433
+ var DROP_OFF_KEYS = {
434
+ waitForIt: "wait-for-it",
435
+ dropOff: "drop-off"
436
+ };
437
+ function formSubmitPayload(input, formSubmit, contractHash) {
438
+ const field = (role, name, type, label, value) => ({ name, type, label, value, role });
439
+ const text = (value) => value?.trim() || void 0;
440
+ const { vehicle, dropOff } = input;
441
+ const entries = [
442
+ field("given_name", "first_name", "text", "First name", text(input.firstName)),
443
+ field("family_name", "last_name", "text", "Last name", text(input.lastName)),
440
444
  // E.164 on the wire: it keys the customer and enhanced-conversion matching.
441
- field("phone", "tel", "Phone", toE164(input.phone) ?? input.phone),
442
- field("email", "email", "Email", input.email ?? ""),
445
+ field("phone", "phone", "tel", "Phone", toE164(input.phone) ?? input.phone),
446
+ field("email", "email", "email", "Email", text(input.email)),
447
+ field("service", "service", "select", "Service", input.services),
443
448
  field(
444
- "service",
445
- "select",
446
- "Service",
447
- input.services.map((key) => labels.get(key) ?? key).join(", ")
449
+ "vehicle",
450
+ "vehicle",
451
+ "text",
452
+ "Vehicle",
453
+ vehicle ? `${vehicle.year} ${vehicle.make} ${vehicle.model}` : void 0
448
454
  ),
449
- field("vehicle", "text", "Vehicle", vehicle),
450
455
  field(
451
- "start",
452
- "text",
453
- "Requested time",
454
- `${input.startDate} ${String(input.startHour).padStart(2, "0")}:00`
456
+ "drop_off",
457
+ "drop_off",
458
+ "select",
459
+ "Drop-off",
460
+ dropOff ? DROP_OFF_KEYS[dropOff] : void 0
455
461
  ),
456
- field("note", "textarea", "Notes", input.notes ?? "")
462
+ field("preferred_date", "preferred_date", "date", "Date", input.startDate),
463
+ field("preferred_time", "preferred_time", "time", "Time", {
464
+ start: `${String(input.startHour).padStart(2, "0")}:00`,
465
+ end: null
466
+ }),
467
+ field("note", "note", "textarea", "Notes", text(input.notes))
457
468
  ];
458
- const reported = new Set(fields.map((item) => item.name));
469
+ const reported = new Set(entries.map((item) => item.name));
470
+ const fields = entries.filter((item) => item.value !== void 0);
459
471
  const extra = (formSubmit.extraFields ?? []).filter((item) => !reported.has(item.name));
460
472
  return {
461
- form: { id: formSubmit.formId, action: "/tracking/bookings", fields: [...fields, ...extra] },
473
+ form: {
474
+ id: formSubmit.formId,
475
+ action: "/tracking/bookings",
476
+ fields: [...fields, ...extra],
477
+ kind: "booking",
478
+ contract_version: LEAD_FORM_REGISTRY_VERSION,
479
+ ...contractHash ? { contract_hash: contractHash } : {}
480
+ },
462
481
  page: { path: typeof window === "undefined" ? "/" : window.location.pathname }
463
482
  };
464
483
  }
@@ -556,8 +575,11 @@ function createSalesBookingsClient(config, firing) {
556
575
  }
557
576
  if (formSubmit && !submittedForms.has(attemptKey)) {
558
577
  submittedForms.add(attemptKey);
559
- const labels = new Map(booking.options.map((option) => [option.key, option.label]));
560
- formSubmit.tracking.trackEvent("form_submit", formSubmitPayload(input, formSubmit, labels));
578
+ const contract = runtime?.leadForms()?.contracts.find((c) => c.form_kind === "booking");
579
+ formSubmit.tracking.trackEvent(
580
+ "form_submit",
581
+ formSubmitPayload(input, formSubmit, contract?.contract_hash ?? null)
582
+ );
561
583
  }
562
584
  const body = {
563
585
  idempotency_key: attemptKey,
@@ -807,17 +829,17 @@ function createSalesClient(config) {
807
829
  }
808
830
 
809
831
  // ../tracking-core/src/resources/sales/schema.ts
810
- import * as z2 from "zod/mini";
832
+ import * as z3 from "zod/mini";
811
833
 
812
834
  // ../tracking-core/src/resources/sales/generated/zod.gen.ts
813
- import * as z from "zod/mini";
814
- var zAutoLeapSaleFacts = z.object({
815
- first_order: z.boolean(),
816
- fleet_customer: z.boolean(),
817
- invoice_code: z.string(),
818
- invoice_id: z.string()
835
+ import * as z2 from "zod/mini";
836
+ var zAutoLeapSaleFacts = z2.object({
837
+ first_order: z2.boolean(),
838
+ fleet_customer: z2.boolean(),
839
+ invoice_code: z2.string(),
840
+ invoice_id: z2.string()
819
841
  });
820
- var zErrorCode = z.enum([
842
+ var zErrorCode = z2.enum([
821
843
  "missing_credentials",
822
844
  "invalid_api_key",
823
845
  "not_authenticated",
@@ -861,37 +883,37 @@ var zErrorCode = z.enum([
861
883
  "rate_limited",
862
884
  "internal_error"
863
885
  ]);
864
- var zSaleItemEntitySchema = z.object({
865
- category: z.nullable(z.string()),
866
- external_item_id: z.nullable(z.string()),
867
- id: z.uuid(),
868
- name: z.nullable(z.string()),
869
- quantity: z.string().check(z.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
870
- unit_cost_cents: z.nullable(z.int()),
871
- unit_price_cents: z.int()
886
+ var zSaleItemEntitySchema = z2.object({
887
+ category: z2.nullable(z2.string()),
888
+ external_item_id: z2.nullable(z2.string()),
889
+ id: z2.uuid(),
890
+ name: z2.nullable(z2.string()),
891
+ quantity: z2.string().check(z2.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
892
+ unit_cost_cents: z2.nullable(z2.int()),
893
+ unit_price_cents: z2.int()
872
894
  });
873
- var zSaleItemInputSchema = z.strictObject({
874
- category: z.nullish(z.string()),
875
- external_item_id: z.nullish(z.string()),
876
- name: z.nullish(z.string()),
877
- quantity: z.string().check(z.regex(/^\d+(\.\d{1,3})?$/)),
878
- unit_cost_cents: z.nullish(z.int().check(z.gte(0))),
879
- unit_price_cents: z.int().check(z.gte(0))
895
+ var zSaleItemInputSchema = z2.strictObject({
896
+ category: z2.nullish(z2.string()),
897
+ external_item_id: z2.nullish(z2.string()),
898
+ name: z2.nullish(z2.string()),
899
+ quantity: z2.string().check(z2.regex(/^\d+(\.\d{1,3})?$/)),
900
+ unit_cost_cents: z2.nullish(z2.int().check(z2.gte(0))),
901
+ unit_price_cents: z2.int().check(z2.gte(0))
880
902
  });
881
- var zSaleServiceEntitySchema = z.object({
882
- amount_cents: z.int(),
883
- id: z.uuid(),
884
- mapped: z.nullable(z.boolean()),
885
- service_id: z.uuid(),
886
- service_key: z.string(),
887
- service_label: z.string()
903
+ var zSaleServiceEntitySchema = z2.object({
904
+ amount_cents: z2.int(),
905
+ id: z2.uuid(),
906
+ mapped: z2.nullable(z2.boolean()),
907
+ service_id: z2.uuid(),
908
+ service_key: z2.string(),
909
+ service_label: z2.string()
888
910
  });
889
- var zSaleServiceInputSchema = z.strictObject({
890
- amount_cents: z.int().check(z.gte(0)),
891
- service: z.string()
911
+ var zSaleServiceInputSchema = z2.strictObject({
912
+ amount_cents: z2.int().check(z2.gte(0)),
913
+ service: z2.string()
892
914
  });
893
- var zSaleSource = z.enum(["api", "admin", "autoleap"]);
894
- var zSmsAutomationState = z.enum([
915
+ var zSaleSource = z2.enum(["api", "admin", "autoleap"]);
916
+ var zSmsAutomationState = z2.enum([
895
917
  "needs_check",
896
918
  "failed",
897
919
  "undelivered",
@@ -903,7 +925,7 @@ var zSmsAutomationState = z.enum([
903
925
  "eligible",
904
926
  "not_applicable"
905
927
  ]);
906
- var zSmsWithheldReason = z.enum([
928
+ var zSmsWithheldReason = z2.enum([
907
929
  "automation_disabled",
908
930
  "sms_disabled",
909
931
  "no_phone",
@@ -931,75 +953,75 @@ var zSmsWithheldReason = z.enum([
931
953
  "invalid_phone",
932
954
  "recently_texted"
933
955
  ]);
934
- var zSaleSmsStatusSchema = z.object({
935
- can_send_now: z._default(z.boolean(), false),
936
- last_message_at: z.nullable(z.iso.datetime({ offset: true })),
937
- reason_detail: z.nullable(z.string()),
956
+ var zSaleSmsStatusSchema = z2.object({
957
+ can_send_now: z2._default(z2.boolean(), false),
958
+ last_message_at: z2.nullable(z2.iso.datetime({ offset: true })),
959
+ reason_detail: z2.nullable(z2.string()),
938
960
  state: zSmsAutomationState,
939
- suppressed_by_other_sale: z._default(z.boolean(), false),
940
- withheld_reason: z.nullable(zSmsWithheldReason)
961
+ suppressed_by_other_sale: z2._default(z2.boolean(), false),
962
+ withheld_reason: z2.nullable(zSmsWithheldReason)
941
963
  });
942
- var zSupportedCurrency = z.enum(["USD", "CAD"]);
943
- var zTrackingEnvironment = z.enum(["production", "development"]);
944
- var zSaleCreateSchema = z.strictObject({
945
- amount_total_cents: z.nullish(z.int().check(z.gte(0))),
964
+ var zSupportedCurrency = z2.enum(["USD", "CAD"]);
965
+ var zTrackingEnvironment = z2.enum(["production", "development"]);
966
+ var zSaleCreateSchema = z2.strictObject({
967
+ amount_total_cents: z2.nullish(z2.int().check(z2.gte(0))),
946
968
  currency: zSupportedCurrency,
947
- customer_email: z.nullish(z.email().check(z.maxLength(320))),
948
- customer_name: z.nullish(z.string().check(z.maxLength(200))),
949
- customer_phone: z.nullish(z.string().check(z.maxLength(64))),
950
- description: z.nullish(z.string()),
951
- environment: z._default(z.optional(zTrackingEnvironment), "production"),
952
- external_id: z.nullish(z.string()),
953
- items: z.optional(z.array(zSaleItemInputSchema)),
954
- metadata: z.nullish(z.record(z.string(), z.unknown())),
955
- occurred_at: z.iso.datetime({ offset: true }),
956
- service: z.nullish(z.string()),
957
- services: z.nullish(z.array(zSaleServiceInputSchema)),
958
- sms_consent: z.nullish(z.boolean())
969
+ customer_email: z2.nullish(z2.email().check(z2.maxLength(320))),
970
+ customer_name: z2.nullish(z2.string().check(z2.maxLength(200))),
971
+ customer_phone: z2.nullish(z2.string().check(z2.maxLength(64))),
972
+ description: z2.nullish(z2.string()),
973
+ environment: z2._default(z2.optional(zTrackingEnvironment), "production"),
974
+ external_id: z2.nullish(z2.string()),
975
+ items: z2.optional(z2.array(zSaleItemInputSchema)),
976
+ metadata: z2.nullish(z2.record(z2.string(), z2.unknown())),
977
+ occurred_at: z2.iso.datetime({ offset: true }),
978
+ service: z2.nullish(z2.string()),
979
+ services: z2.nullish(z2.array(zSaleServiceInputSchema)),
980
+ sms_consent: z2.nullish(z2.boolean())
959
981
  });
960
- var zValidationError = z.object({
961
- ctx: z.optional(z.record(z.string(), z.unknown())),
962
- input: z.optional(z.unknown()),
963
- loc: z.array(z.union([z.string(), z.int()])),
964
- msg: z.string(),
965
- type: z.string()
982
+ var zValidationError = z2.object({
983
+ ctx: z2.optional(z2.record(z2.string(), z2.unknown())),
984
+ input: z2.optional(z2.unknown()),
985
+ loc: z2.array(z2.union([z2.string(), z2.int()])),
986
+ msg: z2.string(),
987
+ type: z2.string()
966
988
  });
967
- var zHttpValidationError = z.object({
968
- detail: z.optional(z.array(zValidationError))
989
+ var zHttpValidationError = z2.object({
990
+ detail: z2.optional(z2.array(zValidationError))
969
991
  });
970
- var zValidationErrorItem = z.object({
971
- loc: z.array(z.union([z.string(), z.int()])),
972
- msg: z.string(),
973
- type: z.string()
992
+ var zValidationErrorItem = z2.object({
993
+ loc: z2.array(z2.union([z2.string(), z2.int()])),
994
+ msg: z2.string(),
995
+ type: z2.string()
974
996
  });
975
- var zApiErrorSchema = z.object({
997
+ var zApiErrorSchema = z2.object({
976
998
  code: zErrorCode,
977
- context: z._default(z.nullish(z.record(z.string(), z.unknown())), null),
978
- detail: z.string(),
979
- errors: z._default(z.nullish(z.array(zValidationErrorItem)), null),
980
- request_id: z._default(z.nullish(z.string()), null)
999
+ context: z2._default(z2.nullish(z2.record(z2.string(), z2.unknown())), null),
1000
+ detail: z2.string(),
1001
+ errors: z2._default(z2.nullish(z2.array(zValidationErrorItem)), null),
1002
+ request_id: z2._default(z2.nullish(z2.string()), null)
981
1003
  });
982
- var zWritebackEmailSource = z.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
983
- var zWritebackEnrichmentStatus = z.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
984
- var zWritebackSaleUploadCounts = z.object({
985
- failed: z._default(z.int(), 0),
986
- pending: z._default(z.int(), 0),
987
- skipped: z._default(z.int(), 0),
988
- submitted: z._default(z.int(), 0),
989
- total: z._default(z.int(), 0),
990
- uploaded: z._default(z.int(), 0)
1004
+ var zWritebackEmailSource = z2.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
1005
+ var zWritebackEnrichmentStatus = z2.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
1006
+ var zWritebackSaleUploadCounts = z2.object({
1007
+ failed: z2._default(z2.int(), 0),
1008
+ pending: z2._default(z2.int(), 0),
1009
+ skipped: z2._default(z2.int(), 0),
1010
+ submitted: z2._default(z2.int(), 0),
1011
+ total: z2._default(z2.int(), 0),
1012
+ uploaded: z2._default(z2.int(), 0)
991
1013
  });
992
- var zSaleWritebackStatusSchema = z.object({
993
- blocked_reason: z.nullable(z.string()),
994
- can_dispatch: z._default(z.boolean(), false),
995
- email_source: z.nullable(zWritebackEmailSource),
996
- enrichment_status: z.nullable(zWritebackEnrichmentStatus),
997
- gclid_attached: z._default(z.boolean(), false),
998
- identifiers_sent: z.nullable(z.string()),
999
- mapped_service_ids: z.array(z.uuid()),
1000
- matched_submit_count: z.nullable(z.int()),
1001
- needs_force: z._default(z.boolean(), false),
1002
- rollup: z.enum([
1014
+ var zSaleWritebackStatusSchema = z2.object({
1015
+ blocked_reason: z2.nullable(z2.string()),
1016
+ can_dispatch: z2._default(z2.boolean(), false),
1017
+ email_source: z2.nullable(zWritebackEmailSource),
1018
+ enrichment_status: z2.nullable(zWritebackEnrichmentStatus),
1019
+ gclid_attached: z2._default(z2.boolean(), false),
1020
+ identifiers_sent: z2.nullable(z2.string()),
1021
+ mapped_service_ids: z2.array(z2.uuid()),
1022
+ matched_submit_count: z2.nullable(z2.int()),
1023
+ needs_force: z2._default(z2.boolean(), false),
1024
+ rollup: z2.enum([
1003
1025
  "failed",
1004
1026
  "skipped",
1005
1027
  "pending",
@@ -1009,39 +1031,39 @@ var zSaleWritebackStatusSchema = z.object({
1009
1031
  "out_of_window",
1010
1032
  "blocked"
1011
1033
  ]),
1012
- stale: z._default(z.boolean(), false),
1013
- uncovered_service_ids: z.array(z.uuid()),
1034
+ stale: z2._default(z2.boolean(), false),
1035
+ uncovered_service_ids: z2.array(z2.uuid()),
1014
1036
  uploads: zWritebackSaleUploadCounts
1015
1037
  });
1016
- var zSaleEntitySchema = z.object({
1017
- amount_total_cents: z.int(),
1018
- business_id: z.uuid(),
1019
- business_name: z.nullable(z.string()),
1020
- created_at: z.iso.datetime({ offset: true }),
1021
- currency: z.string(),
1022
- customer_email: z.nullable(z.string()),
1023
- customer_name: z.nullable(z.string()),
1024
- customer_name_placeholder_confirmed: z._default(z.boolean(), false),
1025
- customer_name_placeholder_confirmed_at: z.nullable(z.iso.datetime({ offset: true })),
1026
- customer_phone: z.nullable(z.string()),
1027
- description: z.nullable(z.string()),
1038
+ var zSaleEntitySchema = z2.object({
1039
+ amount_total_cents: z2.int(),
1040
+ business_id: z2.uuid(),
1041
+ business_name: z2.nullable(z2.string()),
1042
+ created_at: z2.iso.datetime({ offset: true }),
1043
+ currency: z2.string(),
1044
+ customer_email: z2.nullable(z2.string()),
1045
+ customer_name: z2.nullable(z2.string()),
1046
+ customer_name_placeholder_confirmed: z2._default(z2.boolean(), false),
1047
+ customer_name_placeholder_confirmed_at: z2.nullable(z2.iso.datetime({ offset: true })),
1048
+ customer_phone: z2.nullable(z2.string()),
1049
+ description: z2.nullable(z2.string()),
1028
1050
  environment: zTrackingEnvironment,
1029
- external_id: z.nullable(z.string()),
1030
- id: z.uuid(),
1031
- items: z.array(zSaleItemEntitySchema),
1032
- metadata: z.nullable(z.record(z.string(), z.unknown())),
1033
- occurred_at: z.iso.datetime({ offset: true }),
1034
- service_id: z.nullable(z.uuid()),
1035
- service_key: z.nullable(z.string()),
1036
- service_label: z.nullable(z.string()),
1037
- services: z.array(zSaleServiceEntitySchema),
1038
- sms_automation: z.nullable(zSaleSmsStatusSchema),
1039
- sms_consent: z._default(z.boolean(), false),
1040
- sms_consent_granted_at: z.nullable(z.iso.datetime({ offset: true })),
1051
+ external_id: z2.nullable(z2.string()),
1052
+ id: z2.uuid(),
1053
+ items: z2.array(zSaleItemEntitySchema),
1054
+ metadata: z2.nullable(z2.record(z2.string(), z2.unknown())),
1055
+ occurred_at: z2.iso.datetime({ offset: true }),
1056
+ service_id: z2.nullable(z2.uuid()),
1057
+ service_key: z2.nullable(z2.string()),
1058
+ service_label: z2.nullable(z2.string()),
1059
+ services: z2.array(zSaleServiceEntitySchema),
1060
+ sms_automation: z2.nullable(zSaleSmsStatusSchema),
1061
+ sms_consent: z2._default(z2.boolean(), false),
1062
+ sms_consent_granted_at: z2.nullable(z2.iso.datetime({ offset: true })),
1041
1063
  source: zSaleSource,
1042
- source_facts: z.nullable(zAutoLeapSaleFacts),
1043
- updated_at: z.iso.datetime({ offset: true }),
1044
- writeback: z.nullable(zSaleWritebackStatusSchema)
1064
+ source_facts: z2.nullable(zAutoLeapSaleFacts),
1065
+ updated_at: z2.iso.datetime({ offset: true }),
1066
+ writeback: z2.nullable(zSaleWritebackStatusSchema)
1045
1067
  });
1046
1068
 
1047
1069
  // ../tracking-core/src/resources/sales/schema.ts
@@ -1050,11 +1072,11 @@ var saleServiceSchema = zSaleServiceInputSchema;
1050
1072
  var currencySchema = zSupportedCurrency;
1051
1073
  var SUPPORTED_CURRENCIES = currencySchema.options;
1052
1074
  var SALE_SOURCES = zSaleSource.options;
1053
- var centsSchema = z2.int().check(z2.gte(0));
1054
- var metadataSchema = z2.record(z2.string(), z2.unknown());
1055
- var customerNameSchema = z2.string().check(z2.maxLength(200));
1056
- var customerPhoneSchema = z2.string().check(z2.maxLength(64));
1057
- var customerEmailSchema = z2.email().check(z2.maxLength(320));
1075
+ var centsSchema = z3.int().check(z3.gte(0));
1076
+ var metadataSchema = z3.record(z3.string(), z3.unknown());
1077
+ var customerNameSchema = z3.string().check(z3.maxLength(200));
1078
+ var customerPhoneSchema = z3.string().check(z3.maxLength(64));
1079
+ var customerEmailSchema = z3.email().check(z3.maxLength(320));
1058
1080
  function addIssue(ctx, path, message) {
1059
1081
  ctx.issues.push({ code: "custom", input: ctx.value, path, message });
1060
1082
  }
@@ -1088,24 +1110,24 @@ function refineServiceXor(val, ctx, { requireAmount }) {
1088
1110
  );
1089
1111
  }
1090
1112
  }
1091
- var saleCreateSchema = z2.extend(zSaleCreateSchema, { items: z2._default(z2.array(saleItemSchema), []) }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: true }));
1092
- var saleUpdateSchema = z2.strictObject({
1093
- description: z2.nullish(z2.string()),
1094
- service: z2.nullish(z2.string()),
1095
- services: z2.nullish(z2.array(saleServiceSchema)),
1096
- currency: z2.optional(currencySchema),
1097
- amount_total_cents: z2.optional(centsSchema),
1098
- occurred_at: z2.optional(z2.iso.datetime()),
1099
- items: z2.optional(z2.array(saleItemSchema)),
1100
- metadata: z2.nullish(metadataSchema),
1101
- customer_name: z2.nullish(customerNameSchema),
1113
+ var saleCreateSchema = z3.extend(zSaleCreateSchema, { items: z3._default(z3.array(saleItemSchema), []) }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: true }));
1114
+ var saleUpdateSchema = z3.strictObject({
1115
+ description: z3.nullish(z3.string()),
1116
+ service: z3.nullish(z3.string()),
1117
+ services: z3.nullish(z3.array(saleServiceSchema)),
1118
+ currency: z3.optional(currencySchema),
1119
+ amount_total_cents: z3.optional(centsSchema),
1120
+ occurred_at: z3.optional(z3.iso.datetime()),
1121
+ items: z3.optional(z3.array(saleItemSchema)),
1122
+ metadata: z3.nullish(metadataSchema),
1123
+ customer_name: z3.nullish(customerNameSchema),
1102
1124
  // Re-attest when changing a filler-looking name; the server clears the
1103
1125
  // prior attestation whenever `customer_name` changes.
1104
- customer_name_placeholder_confirmed: z2.optional(z2.boolean()),
1105
- customer_phone: z2.nullish(customerPhoneSchema),
1106
- customer_email: z2.nullish(customerEmailSchema),
1126
+ customer_name_placeholder_confirmed: z3.optional(z3.boolean()),
1127
+ customer_phone: z3.nullish(customerPhoneSchema),
1128
+ customer_email: z3.nullish(customerEmailSchema),
1107
1129
  // NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
1108
- sms_consent: z2.optional(z2.boolean())
1130
+ sms_consent: z3.optional(z3.boolean())
1109
1131
  }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: false }));
1110
1132
  var TRACKING_RANGES = ["24h", "7d", "30d"];
1111
1133
  var NAMED_RANGES = [