@aranova/tracking-react 1.12.0 → 1.14.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.
Files changed (36) hide show
  1. package/README.md +31 -3
  2. package/dist/{bookings-v_ucn93l.d.ts → bookings-Bw2ImtPd.d.ts} +3 -1
  3. package/dist/{bookings-Lmi0o_PA.d.mts → bookings-CDGNZUaH.d.mts} +3 -1
  4. package/dist/client.d.mts +5 -4
  5. package/dist/client.d.ts +5 -4
  6. package/dist/client.js +369 -40
  7. package/dist/client.js.map +1 -1
  8. package/dist/client.mjs +367 -39
  9. package/dist/client.mjs.map +1 -1
  10. package/dist/{form-submit-CX-CxJjQ.d.mts → form-submit-C_vJXCxh.d.mts} +11 -1
  11. package/dist/{form-submit-CX-CxJjQ.d.ts → form-submit-C_vJXCxh.d.ts} +11 -1
  12. package/dist/index.d.mts +9 -180
  13. package/dist/index.d.ts +9 -180
  14. package/dist/index.js +332 -285
  15. package/dist/index.js.map +1 -1
  16. package/dist/index.mjs +329 -285
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/{phone-utils-D12FW8tT.d.ts → phone-utils-Cfdx474X.d.mts} +178 -3
  19. package/dist/{phone-utils-BNiSqeF7.d.mts → phone-utils-D2TGPCQW.d.ts} +178 -3
  20. package/dist/phone.d.mts +2 -2
  21. package/dist/phone.d.ts +2 -2
  22. package/dist/phone.js +2 -2
  23. package/dist/phone.js.map +1 -1
  24. package/dist/phone.mjs +2 -2
  25. package/dist/phone.mjs.map +1 -1
  26. package/dist/{sales-6vMEcopj.d.mts → sales-D4aU73mR.d.mts} +1 -1
  27. package/dist/{sales-DXLGjJQ6.d.ts → sales-DkdrGIUS.d.ts} +1 -1
  28. package/dist/sales.d.mts +3 -3
  29. package/dist/sales.d.ts +3 -3
  30. package/dist/sales.js +193 -171
  31. package/dist/sales.js.map +1 -1
  32. package/dist/sales.mjs +193 -171
  33. package/dist/sales.mjs.map +1 -1
  34. package/dist/{ingest-typed-B9I1c7jr.d.ts → submit-DuvP5AGN.d.ts} +161 -4
  35. package/dist/{ingest-typed-PKFEuJ8E.d.mts → submit-rqgXl-Wg.d.mts} +161 -4
  36. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -232,7 +232,8 @@ var TRACKING_CAPABILITIES = [
232
232
  "cta_click_capture",
233
233
  "form_capture",
234
234
  "phone_click_capture",
235
- "phone_fields"
235
+ "phone_fields",
236
+ "typed_form_submit"
236
237
  ];
237
238
  var CAPABILITY_DOM_ATTRIBUTE = "data-aranova-capability";
238
239
  var registered = /* @__PURE__ */ new Set();
@@ -1324,6 +1325,10 @@ var TrackingConfigRuntime = class {
1324
1325
  integrations() {
1325
1326
  return this.current?.integrations ?? null;
1326
1327
  }
1328
+ /** The lead-form contracts, from the cached object like `integrations()`. */
1329
+ leadForms() {
1330
+ return this.current?.lead_forms ?? null;
1331
+ }
1327
1332
  async revalidateNow() {
1328
1333
  try {
1329
1334
  const headers = {};
@@ -1706,6 +1711,118 @@ var SDK_PACKAGE_HEADER = "X-Aranova-Sdk-Package";
1706
1711
  var SDK_SURFACE_HEADER = "X-Aranova-Sdk-Surface";
1707
1712
  var SDK_ENVIRONMENT_HEADER = "X-Aranova-Sdk-Environment";
1708
1713
 
1714
+ // ../tracking-core/src/lead-forms/lead-forms.gen.ts
1715
+ import * as z2 from "zod/mini";
1716
+ var LEAD_FORM_REGISTRY_VERSION = 2;
1717
+ var LEAD_FORM_KINDS = ["booking", "quote", "contact", "consult", "callback"];
1718
+ var LEAD_FORM_ROLES = [
1719
+ "given_name",
1720
+ "family_name",
1721
+ "phone",
1722
+ "email",
1723
+ "service",
1724
+ "preferred_date",
1725
+ "preferred_time",
1726
+ "note",
1727
+ "visit",
1728
+ "intent",
1729
+ "vehicle",
1730
+ "drop_off",
1731
+ "address",
1732
+ "patient_type",
1733
+ "matter",
1734
+ "language",
1735
+ "products",
1736
+ "goal",
1737
+ "business_type",
1738
+ "lead_volume",
1739
+ "attribution"
1740
+ ];
1741
+ var LEAD_FORM_PRIMITIVES = [
1742
+ "string",
1743
+ "text",
1744
+ "enum",
1745
+ "multi_enum",
1746
+ "bool",
1747
+ "date",
1748
+ "time_window",
1749
+ "phone",
1750
+ "email",
1751
+ "address",
1752
+ "number"
1753
+ ];
1754
+ var leadFormPrimitiveSchemas = /* @__PURE__ */ (() => ({
1755
+ string: z2.string().check(z2.maxLength(120)),
1756
+ text: z2.string().check(z2.maxLength(2e3)),
1757
+ enum: z2.string().check(z2.regex(/^[a-z0-9-]{1,48}$/)),
1758
+ multi_enum: z2.array(z2.string().check(z2.regex(/^[a-z0-9-]{1,48}$/))).check(z2.maxLength(10)),
1759
+ bool: z2.boolean(),
1760
+ date: z2.string().check(z2.regex(/^\d{4}-\d{2}-\d{2}$/)),
1761
+ time_window: z2.strictObject({
1762
+ start: z2.string().check(z2.regex(/^([01]\d|2[0-3]):[0-5]\d$/)),
1763
+ end: z2.nullable(z2.string().check(z2.regex(/^([01]\d|2[0-3]):[0-5]\d$/))),
1764
+ label: z2.optional(z2.string().check(z2.maxLength(60)))
1765
+ }),
1766
+ phone: z2.string().check(z2.regex(/^\+[1-9]\d{6,14}$/)),
1767
+ email: z2.string().check(z2.maxLength(320), z2.regex(/^[^\s@]+@[^\s@]+$/)),
1768
+ address: z2.strictObject({
1769
+ line1: z2.string().check(z2.maxLength(120)),
1770
+ line2: z2.optional(z2.string().check(z2.maxLength(120))),
1771
+ city: z2.optional(z2.string().check(z2.maxLength(120))),
1772
+ region: z2.optional(z2.string().check(z2.maxLength(120))),
1773
+ postal_code: z2.optional(z2.string().check(z2.maxLength(120))),
1774
+ country: z2.optional(z2.string().check(z2.maxLength(120)))
1775
+ }),
1776
+ number: z2.number()
1777
+ }))();
1778
+ var LEAD_FORM_ROLE_SPECS = {
1779
+ given_name: { primitive: "string", smsLabel: "", contactIdentity: true },
1780
+ family_name: { primitive: "string", smsLabel: "", contactIdentity: true },
1781
+ phone: { primitive: "phone", smsLabel: "", contactIdentity: true },
1782
+ email: { primitive: "email", smsLabel: "", contactIdentity: true },
1783
+ service: { primitive: "multi_enum", smsLabel: "Service" },
1784
+ preferred_date: { primitive: "date", smsLabel: "Date" },
1785
+ preferred_time: { primitive: "time_window", smsLabel: "Time" },
1786
+ note: { primitive: "text", smsLabel: "Note" },
1787
+ visit: {
1788
+ primitive: "enum",
1789
+ smsLabel: "Visit",
1790
+ options: [
1791
+ { key: "in-shop", label: "In shop" },
1792
+ { key: "in-home", label: "In home" },
1793
+ { key: "remote", label: "Remote" },
1794
+ { key: "on-site", label: "On site" }
1795
+ ]
1796
+ },
1797
+ intent: {
1798
+ primitive: "enum",
1799
+ smsLabel: "Wants",
1800
+ options: [
1801
+ { key: "book", label: "Book" },
1802
+ { key: "quote", label: "Quote" }
1803
+ ]
1804
+ },
1805
+ vehicle: { primitive: "string", smsLabel: "Vehicle" },
1806
+ drop_off: {
1807
+ primitive: "enum",
1808
+ smsLabel: "Drop-off",
1809
+ options: [
1810
+ { key: "wait-for-it", label: "Waiting" },
1811
+ { key: "drop-off", label: "Dropping off" }
1812
+ ]
1813
+ },
1814
+ address: { primitive: "address", smsLabel: "Address" },
1815
+ patient_type: { primitive: "enum", smsLabel: "Patient" },
1816
+ matter: { primitive: "enum", smsLabel: "Matter" },
1817
+ language: { primitive: "enum", smsLabel: "Language" },
1818
+ products: { primitive: "multi_enum", smsLabel: "Products" },
1819
+ goal: { primitive: "enum", smsLabel: "Goal" },
1820
+ business_type: { primitive: "enum", smsLabel: "Business" },
1821
+ lead_volume: { primitive: "enum", smsLabel: "Lead volume" },
1822
+ add_on: { primitive: "bool", smsLabel: "" },
1823
+ attribution: { primitive: "enum", smsLabel: "", uninteresting: true }
1824
+ };
1825
+
1709
1826
  // ../tracking-core/src/resources/http/errors.ts
1710
1827
  var AranovaApiError = class extends Error {
1711
1828
  constructor(message, options) {
@@ -1799,39 +1916,54 @@ function outcomeOf(body) {
1799
1916
  if (body.status === "pending") return { status: "pending", id: body.id, mode };
1800
1917
  return { status: "failed", id: body.id, fallbackUrl: body.fallback_url, mode };
1801
1918
  }
1802
- function formSubmitPayload(input, formSubmit, labels) {
1803
- const vehicle = input.vehicle ? `${input.vehicle.year} ${input.vehicle.make} ${input.vehicle.model}` : "";
1804
- const field = (name, type, label, value) => ({
1805
- name,
1806
- type,
1807
- label,
1808
- value
1809
- });
1810
- const fields = [
1811
- field("first_name", "text", "First name", input.firstName),
1812
- field("last_name", "text", "Last name", input.lastName),
1919
+ var DROP_OFF_KEYS = {
1920
+ waitForIt: "wait-for-it",
1921
+ dropOff: "drop-off"
1922
+ };
1923
+ function formSubmitPayload(input, formSubmit, contractHash) {
1924
+ const field = (role, name, type, label, value) => ({ name, type, label, value, role });
1925
+ const text = (value) => value?.trim() || void 0;
1926
+ const { vehicle, dropOff } = input;
1927
+ const entries = [
1928
+ field("given_name", "first_name", "text", "First name", text(input.firstName)),
1929
+ field("family_name", "last_name", "text", "Last name", text(input.lastName)),
1813
1930
  // E.164 on the wire: it keys the customer and enhanced-conversion matching.
1814
- field("phone", "tel", "Phone", toE164(input.phone) ?? input.phone),
1815
- field("email", "email", "Email", input.email ?? ""),
1931
+ field("phone", "phone", "tel", "Phone", toE164(input.phone) ?? input.phone),
1932
+ field("email", "email", "email", "Email", text(input.email)),
1933
+ field("service", "service", "select", "Service", input.services),
1816
1934
  field(
1817
- "service",
1818
- "select",
1819
- "Service",
1820
- input.services.map((key) => labels.get(key) ?? key).join(", ")
1935
+ "vehicle",
1936
+ "vehicle",
1937
+ "text",
1938
+ "Vehicle",
1939
+ vehicle ? `${vehicle.year} ${vehicle.make} ${vehicle.model}` : void 0
1821
1940
  ),
1822
- field("vehicle", "text", "Vehicle", vehicle),
1823
1941
  field(
1824
- "start",
1825
- "text",
1826
- "Requested time",
1827
- `${input.startDate} ${String(input.startHour).padStart(2, "0")}:00`
1942
+ "drop_off",
1943
+ "drop_off",
1944
+ "select",
1945
+ "Drop-off",
1946
+ dropOff ? DROP_OFF_KEYS[dropOff] : void 0
1828
1947
  ),
1829
- field("note", "textarea", "Notes", input.notes ?? "")
1948
+ field("preferred_date", "preferred_date", "date", "Date", input.startDate),
1949
+ field("preferred_time", "preferred_time", "time", "Time", {
1950
+ start: `${String(input.startHour).padStart(2, "0")}:00`,
1951
+ end: null
1952
+ }),
1953
+ field("note", "note", "textarea", "Notes", text(input.notes))
1830
1954
  ];
1831
- const reported = new Set(fields.map((item) => item.name));
1955
+ const reported = new Set(entries.map((item) => item.name));
1956
+ const fields = entries.filter((item) => item.value !== void 0);
1832
1957
  const extra = (formSubmit.extraFields ?? []).filter((item) => !reported.has(item.name));
1833
1958
  return {
1834
- form: { id: formSubmit.formId, action: "/tracking/bookings", fields: [...fields, ...extra] },
1959
+ form: {
1960
+ id: formSubmit.formId,
1961
+ action: "/tracking/bookings",
1962
+ fields: [...fields, ...extra],
1963
+ kind: "booking",
1964
+ contract_version: LEAD_FORM_REGISTRY_VERSION,
1965
+ ...contractHash ? { contract_hash: contractHash } : {}
1966
+ },
1835
1967
  page: { path: typeof window === "undefined" ? "/" : window.location.pathname }
1836
1968
  };
1837
1969
  }
@@ -1929,8 +2061,11 @@ function createSalesBookingsClient(config, firing) {
1929
2061
  }
1930
2062
  if (formSubmit && !submittedForms.has(attemptKey)) {
1931
2063
  submittedForms.add(attemptKey);
1932
- const labels = new Map(booking.options.map((option) => [option.key, option.label]));
1933
- formSubmit.tracking.trackEvent("form_submit", formSubmitPayload(input, formSubmit, labels));
2064
+ const contract = runtime?.leadForms()?.contracts.find((c) => c.form_kind === "booking");
2065
+ formSubmit.tracking.trackEvent(
2066
+ "form_submit",
2067
+ formSubmitPayload(input, formSubmit, contract?.contract_hash ?? null)
2068
+ );
1934
2069
  }
1935
2070
  const body = {
1936
2071
  idempotency_key: attemptKey,
@@ -2180,17 +2315,17 @@ function createSalesClient(config) {
2180
2315
  }
2181
2316
 
2182
2317
  // ../tracking-core/src/resources/sales/schema.ts
2183
- import * as z3 from "zod/mini";
2318
+ import * as z4 from "zod/mini";
2184
2319
 
2185
2320
  // ../tracking-core/src/resources/sales/generated/zod.gen.ts
2186
- import * as z2 from "zod/mini";
2187
- var zAutoLeapSaleFacts = z2.object({
2188
- first_order: z2.boolean(),
2189
- fleet_customer: z2.boolean(),
2190
- invoice_code: z2.string(),
2191
- invoice_id: z2.string()
2321
+ import * as z3 from "zod/mini";
2322
+ var zAutoLeapSaleFacts = z3.object({
2323
+ first_order: z3.boolean(),
2324
+ fleet_customer: z3.boolean(),
2325
+ invoice_code: z3.string(),
2326
+ invoice_id: z3.string()
2192
2327
  });
2193
- var zErrorCode = z2.enum([
2328
+ var zErrorCode = z3.enum([
2194
2329
  "missing_credentials",
2195
2330
  "invalid_api_key",
2196
2331
  "not_authenticated",
@@ -2234,37 +2369,37 @@ var zErrorCode = z2.enum([
2234
2369
  "rate_limited",
2235
2370
  "internal_error"
2236
2371
  ]);
2237
- var zSaleItemEntitySchema = z2.object({
2238
- category: z2.nullable(z2.string()),
2239
- external_item_id: z2.nullable(z2.string()),
2240
- id: z2.uuid(),
2241
- name: z2.nullable(z2.string()),
2242
- quantity: z2.string().check(z2.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
2243
- unit_cost_cents: z2.nullable(z2.int()),
2244
- unit_price_cents: z2.int()
2372
+ var zSaleItemEntitySchema = z3.object({
2373
+ category: z3.nullable(z3.string()),
2374
+ external_item_id: z3.nullable(z3.string()),
2375
+ id: z3.uuid(),
2376
+ name: z3.nullable(z3.string()),
2377
+ quantity: z3.string().check(z3.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
2378
+ unit_cost_cents: z3.nullable(z3.int()),
2379
+ unit_price_cents: z3.int()
2245
2380
  });
2246
- var zSaleItemInputSchema = z2.strictObject({
2247
- category: z2.nullish(z2.string()),
2248
- external_item_id: z2.nullish(z2.string()),
2249
- name: z2.nullish(z2.string()),
2250
- quantity: z2.string().check(z2.regex(/^\d+(\.\d{1,3})?$/)),
2251
- unit_cost_cents: z2.nullish(z2.int().check(z2.gte(0))),
2252
- unit_price_cents: z2.int().check(z2.gte(0))
2381
+ var zSaleItemInputSchema = z3.strictObject({
2382
+ category: z3.nullish(z3.string()),
2383
+ external_item_id: z3.nullish(z3.string()),
2384
+ name: z3.nullish(z3.string()),
2385
+ quantity: z3.string().check(z3.regex(/^\d+(\.\d{1,3})?$/)),
2386
+ unit_cost_cents: z3.nullish(z3.int().check(z3.gte(0))),
2387
+ unit_price_cents: z3.int().check(z3.gte(0))
2253
2388
  });
2254
- var zSaleServiceEntitySchema = z2.object({
2255
- amount_cents: z2.int(),
2256
- id: z2.uuid(),
2257
- mapped: z2.nullable(z2.boolean()),
2258
- service_id: z2.uuid(),
2259
- service_key: z2.string(),
2260
- service_label: z2.string()
2389
+ var zSaleServiceEntitySchema = z3.object({
2390
+ amount_cents: z3.int(),
2391
+ id: z3.uuid(),
2392
+ mapped: z3.nullable(z3.boolean()),
2393
+ service_id: z3.uuid(),
2394
+ service_key: z3.string(),
2395
+ service_label: z3.string()
2261
2396
  });
2262
- var zSaleServiceInputSchema = z2.strictObject({
2263
- amount_cents: z2.int().check(z2.gte(0)),
2264
- service: z2.string()
2397
+ var zSaleServiceInputSchema = z3.strictObject({
2398
+ amount_cents: z3.int().check(z3.gte(0)),
2399
+ service: z3.string()
2265
2400
  });
2266
- var zSaleSource = z2.enum(["api", "admin", "autoleap"]);
2267
- var zSmsAutomationState = z2.enum([
2401
+ var zSaleSource = z3.enum(["api", "admin", "autoleap"]);
2402
+ var zSmsAutomationState = z3.enum([
2268
2403
  "needs_check",
2269
2404
  "failed",
2270
2405
  "undelivered",
@@ -2276,7 +2411,7 @@ var zSmsAutomationState = z2.enum([
2276
2411
  "eligible",
2277
2412
  "not_applicable"
2278
2413
  ]);
2279
- var zSmsWithheldReason = z2.enum([
2414
+ var zSmsWithheldReason = z3.enum([
2280
2415
  "automation_disabled",
2281
2416
  "sms_disabled",
2282
2417
  "no_phone",
@@ -2304,75 +2439,75 @@ var zSmsWithheldReason = z2.enum([
2304
2439
  "invalid_phone",
2305
2440
  "recently_texted"
2306
2441
  ]);
2307
- var zSaleSmsStatusSchema = z2.object({
2308
- can_send_now: z2._default(z2.boolean(), false),
2309
- last_message_at: z2.nullable(z2.iso.datetime({ offset: true })),
2310
- reason_detail: z2.nullable(z2.string()),
2442
+ var zSaleSmsStatusSchema = z3.object({
2443
+ can_send_now: z3._default(z3.boolean(), false),
2444
+ last_message_at: z3.nullable(z3.iso.datetime({ offset: true })),
2445
+ reason_detail: z3.nullable(z3.string()),
2311
2446
  state: zSmsAutomationState,
2312
- suppressed_by_other_sale: z2._default(z2.boolean(), false),
2313
- withheld_reason: z2.nullable(zSmsWithheldReason)
2447
+ suppressed_by_other_sale: z3._default(z3.boolean(), false),
2448
+ withheld_reason: z3.nullable(zSmsWithheldReason)
2314
2449
  });
2315
- var zSupportedCurrency = z2.enum(["USD", "CAD"]);
2316
- var zTrackingEnvironment = z2.enum(["production", "development"]);
2317
- var zSaleCreateSchema = z2.strictObject({
2318
- amount_total_cents: z2.nullish(z2.int().check(z2.gte(0))),
2450
+ var zSupportedCurrency = z3.enum(["USD", "CAD"]);
2451
+ var zTrackingEnvironment = z3.enum(["production", "development"]);
2452
+ var zSaleCreateSchema = z3.strictObject({
2453
+ amount_total_cents: z3.nullish(z3.int().check(z3.gte(0))),
2319
2454
  currency: zSupportedCurrency,
2320
- customer_email: z2.nullish(z2.email().check(z2.maxLength(320))),
2321
- customer_name: z2.nullish(z2.string().check(z2.maxLength(200))),
2322
- customer_phone: z2.nullish(z2.string().check(z2.maxLength(64))),
2323
- description: z2.nullish(z2.string()),
2324
- environment: z2._default(z2.optional(zTrackingEnvironment), "production"),
2325
- external_id: z2.nullish(z2.string()),
2326
- items: z2.optional(z2.array(zSaleItemInputSchema)),
2327
- metadata: z2.nullish(z2.record(z2.string(), z2.unknown())),
2328
- occurred_at: z2.iso.datetime({ offset: true }),
2329
- service: z2.nullish(z2.string()),
2330
- services: z2.nullish(z2.array(zSaleServiceInputSchema)),
2331
- sms_consent: z2.nullish(z2.boolean())
2455
+ customer_email: z3.nullish(z3.email().check(z3.maxLength(320))),
2456
+ customer_name: z3.nullish(z3.string().check(z3.maxLength(200))),
2457
+ customer_phone: z3.nullish(z3.string().check(z3.maxLength(64))),
2458
+ description: z3.nullish(z3.string()),
2459
+ environment: z3._default(z3.optional(zTrackingEnvironment), "production"),
2460
+ external_id: z3.nullish(z3.string()),
2461
+ items: z3.optional(z3.array(zSaleItemInputSchema)),
2462
+ metadata: z3.nullish(z3.record(z3.string(), z3.unknown())),
2463
+ occurred_at: z3.iso.datetime({ offset: true }),
2464
+ service: z3.nullish(z3.string()),
2465
+ services: z3.nullish(z3.array(zSaleServiceInputSchema)),
2466
+ sms_consent: z3.nullish(z3.boolean())
2332
2467
  });
2333
- var zValidationError = z2.object({
2334
- ctx: z2.optional(z2.record(z2.string(), z2.unknown())),
2335
- input: z2.optional(z2.unknown()),
2336
- loc: z2.array(z2.union([z2.string(), z2.int()])),
2337
- msg: z2.string(),
2338
- type: z2.string()
2468
+ var zValidationError = z3.object({
2469
+ ctx: z3.optional(z3.record(z3.string(), z3.unknown())),
2470
+ input: z3.optional(z3.unknown()),
2471
+ loc: z3.array(z3.union([z3.string(), z3.int()])),
2472
+ msg: z3.string(),
2473
+ type: z3.string()
2339
2474
  });
2340
- var zHttpValidationError = z2.object({
2341
- detail: z2.optional(z2.array(zValidationError))
2475
+ var zHttpValidationError = z3.object({
2476
+ detail: z3.optional(z3.array(zValidationError))
2342
2477
  });
2343
- var zValidationErrorItem = z2.object({
2344
- loc: z2.array(z2.union([z2.string(), z2.int()])),
2345
- msg: z2.string(),
2346
- type: z2.string()
2478
+ var zValidationErrorItem = z3.object({
2479
+ loc: z3.array(z3.union([z3.string(), z3.int()])),
2480
+ msg: z3.string(),
2481
+ type: z3.string()
2347
2482
  });
2348
- var zApiErrorSchema = z2.object({
2483
+ var zApiErrorSchema = z3.object({
2349
2484
  code: zErrorCode,
2350
- context: z2._default(z2.nullish(z2.record(z2.string(), z2.unknown())), null),
2351
- detail: z2.string(),
2352
- errors: z2._default(z2.nullish(z2.array(zValidationErrorItem)), null),
2353
- request_id: z2._default(z2.nullish(z2.string()), null)
2485
+ context: z3._default(z3.nullish(z3.record(z3.string(), z3.unknown())), null),
2486
+ detail: z3.string(),
2487
+ errors: z3._default(z3.nullish(z3.array(zValidationErrorItem)), null),
2488
+ request_id: z3._default(z3.nullish(z3.string()), null)
2354
2489
  });
2355
- var zWritebackEmailSource = z2.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
2356
- var zWritebackEnrichmentStatus = z2.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
2357
- var zWritebackSaleUploadCounts = z2.object({
2358
- failed: z2._default(z2.int(), 0),
2359
- pending: z2._default(z2.int(), 0),
2360
- skipped: z2._default(z2.int(), 0),
2361
- submitted: z2._default(z2.int(), 0),
2362
- total: z2._default(z2.int(), 0),
2363
- uploaded: z2._default(z2.int(), 0)
2490
+ var zWritebackEmailSource = z3.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
2491
+ var zWritebackEnrichmentStatus = z3.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
2492
+ var zWritebackSaleUploadCounts = z3.object({
2493
+ failed: z3._default(z3.int(), 0),
2494
+ pending: z3._default(z3.int(), 0),
2495
+ skipped: z3._default(z3.int(), 0),
2496
+ submitted: z3._default(z3.int(), 0),
2497
+ total: z3._default(z3.int(), 0),
2498
+ uploaded: z3._default(z3.int(), 0)
2364
2499
  });
2365
- var zSaleWritebackStatusSchema = z2.object({
2366
- blocked_reason: z2.nullable(z2.string()),
2367
- can_dispatch: z2._default(z2.boolean(), false),
2368
- email_source: z2.nullable(zWritebackEmailSource),
2369
- enrichment_status: z2.nullable(zWritebackEnrichmentStatus),
2370
- gclid_attached: z2._default(z2.boolean(), false),
2371
- identifiers_sent: z2.nullable(z2.string()),
2372
- mapped_service_ids: z2.array(z2.uuid()),
2373
- matched_submit_count: z2.nullable(z2.int()),
2374
- needs_force: z2._default(z2.boolean(), false),
2375
- rollup: z2.enum([
2500
+ var zSaleWritebackStatusSchema = z3.object({
2501
+ blocked_reason: z3.nullable(z3.string()),
2502
+ can_dispatch: z3._default(z3.boolean(), false),
2503
+ email_source: z3.nullable(zWritebackEmailSource),
2504
+ enrichment_status: z3.nullable(zWritebackEnrichmentStatus),
2505
+ gclid_attached: z3._default(z3.boolean(), false),
2506
+ identifiers_sent: z3.nullable(z3.string()),
2507
+ mapped_service_ids: z3.array(z3.uuid()),
2508
+ matched_submit_count: z3.nullable(z3.int()),
2509
+ needs_force: z3._default(z3.boolean(), false),
2510
+ rollup: z3.enum([
2376
2511
  "failed",
2377
2512
  "skipped",
2378
2513
  "pending",
@@ -2382,39 +2517,39 @@ var zSaleWritebackStatusSchema = z2.object({
2382
2517
  "out_of_window",
2383
2518
  "blocked"
2384
2519
  ]),
2385
- stale: z2._default(z2.boolean(), false),
2386
- uncovered_service_ids: z2.array(z2.uuid()),
2520
+ stale: z3._default(z3.boolean(), false),
2521
+ uncovered_service_ids: z3.array(z3.uuid()),
2387
2522
  uploads: zWritebackSaleUploadCounts
2388
2523
  });
2389
- var zSaleEntitySchema = z2.object({
2390
- amount_total_cents: z2.int(),
2391
- business_id: z2.uuid(),
2392
- business_name: z2.nullable(z2.string()),
2393
- created_at: z2.iso.datetime({ offset: true }),
2394
- currency: z2.string(),
2395
- customer_email: z2.nullable(z2.string()),
2396
- customer_name: z2.nullable(z2.string()),
2397
- customer_name_placeholder_confirmed: z2._default(z2.boolean(), false),
2398
- customer_name_placeholder_confirmed_at: z2.nullable(z2.iso.datetime({ offset: true })),
2399
- customer_phone: z2.nullable(z2.string()),
2400
- description: z2.nullable(z2.string()),
2524
+ var zSaleEntitySchema = z3.object({
2525
+ amount_total_cents: z3.int(),
2526
+ business_id: z3.uuid(),
2527
+ business_name: z3.nullable(z3.string()),
2528
+ created_at: z3.iso.datetime({ offset: true }),
2529
+ currency: z3.string(),
2530
+ customer_email: z3.nullable(z3.string()),
2531
+ customer_name: z3.nullable(z3.string()),
2532
+ customer_name_placeholder_confirmed: z3._default(z3.boolean(), false),
2533
+ customer_name_placeholder_confirmed_at: z3.nullable(z3.iso.datetime({ offset: true })),
2534
+ customer_phone: z3.nullable(z3.string()),
2535
+ description: z3.nullable(z3.string()),
2401
2536
  environment: zTrackingEnvironment,
2402
- external_id: z2.nullable(z2.string()),
2403
- id: z2.uuid(),
2404
- items: z2.array(zSaleItemEntitySchema),
2405
- metadata: z2.nullable(z2.record(z2.string(), z2.unknown())),
2406
- occurred_at: z2.iso.datetime({ offset: true }),
2407
- service_id: z2.nullable(z2.uuid()),
2408
- service_key: z2.nullable(z2.string()),
2409
- service_label: z2.nullable(z2.string()),
2410
- services: z2.array(zSaleServiceEntitySchema),
2411
- sms_automation: z2.nullable(zSaleSmsStatusSchema),
2412
- sms_consent: z2._default(z2.boolean(), false),
2413
- sms_consent_granted_at: z2.nullable(z2.iso.datetime({ offset: true })),
2537
+ external_id: z3.nullable(z3.string()),
2538
+ id: z3.uuid(),
2539
+ items: z3.array(zSaleItemEntitySchema),
2540
+ metadata: z3.nullable(z3.record(z3.string(), z3.unknown())),
2541
+ occurred_at: z3.iso.datetime({ offset: true }),
2542
+ service_id: z3.nullable(z3.uuid()),
2543
+ service_key: z3.nullable(z3.string()),
2544
+ service_label: z3.nullable(z3.string()),
2545
+ services: z3.array(zSaleServiceEntitySchema),
2546
+ sms_automation: z3.nullable(zSaleSmsStatusSchema),
2547
+ sms_consent: z3._default(z3.boolean(), false),
2548
+ sms_consent_granted_at: z3.nullable(z3.iso.datetime({ offset: true })),
2414
2549
  source: zSaleSource,
2415
- source_facts: z2.nullable(zAutoLeapSaleFacts),
2416
- updated_at: z2.iso.datetime({ offset: true }),
2417
- writeback: z2.nullable(zSaleWritebackStatusSchema)
2550
+ source_facts: z3.nullable(zAutoLeapSaleFacts),
2551
+ updated_at: z3.iso.datetime({ offset: true }),
2552
+ writeback: z3.nullable(zSaleWritebackStatusSchema)
2418
2553
  });
2419
2554
 
2420
2555
  // ../tracking-core/src/resources/sales/schema.ts
@@ -2423,11 +2558,11 @@ var saleServiceSchema = zSaleServiceInputSchema;
2423
2558
  var currencySchema = zSupportedCurrency;
2424
2559
  var SUPPORTED_CURRENCIES = currencySchema.options;
2425
2560
  var SALE_SOURCES = zSaleSource.options;
2426
- var centsSchema = z3.int().check(z3.gte(0));
2427
- var metadataSchema = z3.record(z3.string(), z3.unknown());
2428
- var customerNameSchema = z3.string().check(z3.maxLength(200));
2429
- var customerPhoneSchema = z3.string().check(z3.maxLength(64));
2430
- var customerEmailSchema = z3.email().check(z3.maxLength(320));
2561
+ var centsSchema = z4.int().check(z4.gte(0));
2562
+ var metadataSchema = z4.record(z4.string(), z4.unknown());
2563
+ var customerNameSchema = z4.string().check(z4.maxLength(200));
2564
+ var customerPhoneSchema = z4.string().check(z4.maxLength(64));
2565
+ var customerEmailSchema = z4.email().check(z4.maxLength(320));
2431
2566
  function addIssue(ctx, path, message) {
2432
2567
  ctx.issues.push({ code: "custom", input: ctx.value, path, message });
2433
2568
  }
@@ -2461,24 +2596,24 @@ function refineServiceXor(val, ctx, { requireAmount }) {
2461
2596
  );
2462
2597
  }
2463
2598
  }
2464
- var saleCreateSchema = z3.extend(zSaleCreateSchema, { items: z3._default(z3.array(saleItemSchema), []) }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: true }));
2465
- var saleUpdateSchema = z3.strictObject({
2466
- description: z3.nullish(z3.string()),
2467
- service: z3.nullish(z3.string()),
2468
- services: z3.nullish(z3.array(saleServiceSchema)),
2469
- currency: z3.optional(currencySchema),
2470
- amount_total_cents: z3.optional(centsSchema),
2471
- occurred_at: z3.optional(z3.iso.datetime()),
2472
- items: z3.optional(z3.array(saleItemSchema)),
2473
- metadata: z3.nullish(metadataSchema),
2474
- customer_name: z3.nullish(customerNameSchema),
2599
+ var saleCreateSchema = z4.extend(zSaleCreateSchema, { items: z4._default(z4.array(saleItemSchema), []) }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: true }));
2600
+ var saleUpdateSchema = z4.strictObject({
2601
+ description: z4.nullish(z4.string()),
2602
+ service: z4.nullish(z4.string()),
2603
+ services: z4.nullish(z4.array(saleServiceSchema)),
2604
+ currency: z4.optional(currencySchema),
2605
+ amount_total_cents: z4.optional(centsSchema),
2606
+ occurred_at: z4.optional(z4.iso.datetime()),
2607
+ items: z4.optional(z4.array(saleItemSchema)),
2608
+ metadata: z4.nullish(metadataSchema),
2609
+ customer_name: z4.nullish(customerNameSchema),
2475
2610
  // Re-attest when changing a filler-looking name; the server clears the
2476
2611
  // prior attestation whenever `customer_name` changes.
2477
- customer_name_placeholder_confirmed: z3.optional(z3.boolean()),
2478
- customer_phone: z3.nullish(customerPhoneSchema),
2479
- customer_email: z3.nullish(customerEmailSchema),
2612
+ customer_name_placeholder_confirmed: z4.optional(z4.boolean()),
2613
+ customer_phone: z4.nullish(customerPhoneSchema),
2614
+ customer_email: z4.nullish(customerEmailSchema),
2480
2615
  // NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
2481
- sms_consent: z3.optional(z3.boolean())
2616
+ sms_consent: z4.optional(z4.boolean())
2482
2617
  }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: false }));
2483
2618
  var TRACKING_RANGES = ["24h", "7d", "30d"];
2484
2619
  var NAMED_RANGES = [
@@ -2501,121 +2636,26 @@ async function fetchServices(config) {
2501
2636
  }
2502
2637
 
2503
2638
  // ../tracking-core/src/phone-field.ts
2504
- function phoneField(name, raw, country) {
2505
- return { name, type: "phone", value: toE164(raw, country) };
2639
+ function phoneField(name, raw, country, label = null) {
2640
+ return { name, type: "phone", label, value: toE164(raw, country) };
2506
2641
  }
2507
2642
 
2508
- // ../tracking-core/src/lead-forms/lead-forms.gen.ts
2509
- import * as z4 from "zod/mini";
2510
- var LEAD_FORM_REGISTRY_VERSION = 1;
2511
- var LEAD_FORM_KINDS = ["booking", "quote", "contact", "consult", "callback"];
2512
- var LEAD_FORM_ROLES = [
2513
- "given_name",
2514
- "family_name",
2515
- "phone",
2516
- "email",
2517
- "service",
2518
- "preferred_date",
2519
- "preferred_time",
2520
- "note",
2521
- "visit",
2522
- "intent",
2523
- "vehicle",
2524
- "drop_off",
2525
- "address",
2526
- "patient_type",
2527
- "matter",
2528
- "language",
2529
- "products",
2530
- "goal",
2531
- "business_type",
2532
- "lead_volume",
2533
- "attribution"
2534
- ];
2535
- var LEAD_FORM_PRIMITIVES = [
2536
- "string",
2537
- "text",
2538
- "enum",
2539
- "multi_enum",
2540
- "bool",
2541
- "date",
2542
- "time_window",
2543
- "phone",
2544
- "email",
2545
- "address",
2546
- "number"
2547
- ];
2548
- var leadFormPrimitiveSchemas = {
2549
- string: z4.string().check(z4.maxLength(120)),
2550
- text: z4.string().check(z4.maxLength(2e3)),
2551
- enum: z4.string().check(z4.regex(/^[a-z0-9-]{1,48}$/)),
2552
- multi_enum: z4.array(z4.string().check(z4.regex(/^[a-z0-9-]{1,48}$/))).check(z4.maxLength(10)),
2553
- bool: z4.boolean(),
2554
- date: z4.string().check(z4.regex(/^\d{4}-\d{2}-\d{2}$/)),
2555
- time_window: z4.strictObject({
2556
- start: z4.string().check(z4.regex(/^([01]\d|2[0-3]):[0-5]\d$/)),
2557
- end: z4.nullable(z4.string().check(z4.regex(/^([01]\d|2[0-3]):[0-5]\d$/))),
2558
- label: z4.optional(z4.string().check(z4.maxLength(60)))
2559
- }),
2560
- phone: z4.string().check(z4.regex(/^\+[1-9]\d{6,14}$/)),
2561
- email: z4.string().check(z4.maxLength(320), z4.regex(/^[^\s@]+@[^\s@]+$/)),
2562
- address: z4.strictObject({
2563
- line1: z4.string().check(z4.maxLength(120)),
2564
- line2: z4.optional(z4.string().check(z4.maxLength(120))),
2565
- city: z4.optional(z4.string().check(z4.maxLength(120))),
2566
- region: z4.optional(z4.string().check(z4.maxLength(120))),
2567
- postal_code: z4.optional(z4.string().check(z4.maxLength(120))),
2568
- country: z4.optional(z4.string().check(z4.maxLength(120)))
2569
- }),
2570
- number: z4.number()
2571
- };
2572
- var LEAD_FORM_ROLE_SPECS = {
2573
- given_name: { primitive: "string", smsLabel: "", contactIdentity: true },
2574
- family_name: { primitive: "string", smsLabel: "", contactIdentity: true },
2575
- phone: { primitive: "phone", smsLabel: "", contactIdentity: true },
2576
- email: { primitive: "email", smsLabel: "", contactIdentity: true },
2577
- service: { primitive: "enum", smsLabel: "Service" },
2578
- preferred_date: { primitive: "date", smsLabel: "Date" },
2579
- preferred_time: { primitive: "time_window", smsLabel: "Time" },
2580
- note: { primitive: "text", smsLabel: "Note" },
2581
- visit: {
2582
- primitive: "enum",
2583
- smsLabel: "Visit",
2584
- options: [
2585
- { key: "in-shop", label: "In shop" },
2586
- { key: "in-home", label: "In home" },
2587
- { key: "remote", label: "Remote" },
2588
- { key: "on-site", label: "On site" }
2589
- ]
2590
- },
2591
- intent: {
2592
- primitive: "enum",
2593
- smsLabel: "Wants",
2594
- options: [
2595
- { key: "book", label: "Book" },
2596
- { key: "quote", label: "Quote" }
2597
- ]
2598
- },
2599
- vehicle: { primitive: "string", smsLabel: "Vehicle" },
2600
- drop_off: {
2601
- primitive: "enum",
2602
- smsLabel: "Drop-off",
2603
- options: [
2604
- { key: "wait-for-it", label: "Waiting" },
2605
- { key: "drop-off", label: "Dropping off" }
2606
- ]
2607
- },
2608
- address: { primitive: "address", smsLabel: "Address" },
2609
- patient_type: { primitive: "enum", smsLabel: "Patient" },
2610
- matter: { primitive: "enum", smsLabel: "Matter" },
2611
- language: { primitive: "enum", smsLabel: "Language" },
2612
- products: { primitive: "multi_enum", smsLabel: "Products" },
2613
- goal: { primitive: "enum", smsLabel: "Goal" },
2614
- business_type: { primitive: "enum", smsLabel: "Business" },
2615
- lead_volume: { primitive: "enum", smsLabel: "Lead volume" },
2616
- add_on: { primitive: "bool", smsLabel: "" },
2617
- attribution: { primitive: "enum", smsLabel: "", uninteresting: true }
2618
- };
2643
+ // ../tracking-core/src/lead-forms/submit.ts
2644
+ import { safeParse } from "zod/mini";
2645
+ var KNOWN_ROLES = new Set(LEAD_FORM_ROLES);
2646
+ var ROLE_ORDER = new Map(LEAD_FORM_ROLES.map((role, index) => [role, index]));
2647
+ function slotFields(dateTime) {
2648
+ const written = /^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2})(?::\d{2}(?:\.\d+)?)?$/.exec(dateTime);
2649
+ if (!written) {
2650
+ throw new TypeError(
2651
+ `slotFields needs the slot's wall time without an offset ("2026-10-13T09:30"), got "${dateTime}"`
2652
+ );
2653
+ }
2654
+ return { preferred_date: written[1], preferred_time: { start: written[2], end: null } };
2655
+ }
2656
+ function timeWindow(start, end, label) {
2657
+ return { start, end: end ?? null, ...label ? { label } : {} };
2658
+ }
2619
2659
 
2620
2660
  // src/index.ts
2621
2661
  import {
@@ -2630,6 +2670,7 @@ import {
2630
2670
  useBookingSlots,
2631
2671
  useBookingSubmit
2632
2672
  } from "@aranova/tracking-react/client";
2673
+ import { createLeadFormSubmit } from "@aranova/tracking-react/client";
2633
2674
  export {
2634
2675
  AdPlatformTracking,
2635
2676
  AranovaApiError,
@@ -2654,6 +2695,7 @@ export {
2654
2695
  buildBookingHandoffUrl,
2655
2696
  captureTrackingParamsFromLocation,
2656
2697
  clearStashedUserData,
2698
+ createLeadFormSubmit,
2657
2699
  createSalesClient,
2658
2700
  createTracking,
2659
2701
  createTrackingClientContext,
@@ -2689,7 +2731,9 @@ export {
2689
2731
  salesRequest,
2690
2732
  setConsentState,
2691
2733
  shopToday,
2734
+ slotFields,
2692
2735
  stashUserData,
2736
+ timeWindow,
2693
2737
  toE164,
2694
2738
  toMinor,
2695
2739
  useBookingHandoffUrl,