@aranova/tracking-react 1.13.0 → 1.14.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.
Files changed (36) hide show
  1. package/README.md +26 -0
  2. package/dist/{bookings-C1HMPjQl.d.ts → bookings-CkfA5XOM.d.ts} +283 -8
  3. package/dist/{bookings-CHpplXU7.d.mts → bookings-DFz3BUiP.d.mts} +283 -8
  4. package/dist/client.d.mts +10 -8
  5. package/dist/client.d.ts +10 -8
  6. package/dist/client.js +382 -41
  7. package/dist/client.js.map +1 -1
  8. package/dist/client.mjs +380 -40
  9. package/dist/client.mjs.map +1 -1
  10. package/dist/index.d.mts +8 -180
  11. package/dist/index.d.ts +8 -180
  12. package/dist/index.js +375 -189
  13. package/dist/index.js.map +1 -1
  14. package/dist/index.mjs +372 -189
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/{ingest-typed-sCDoPInT.d.ts → ingest-typed-BO6Arbw-.d.mts} +6 -99
  17. package/dist/{ingest-typed-Ckt4R731.d.mts → ingest-typed-D7I4aQ7p.d.ts} +6 -99
  18. package/dist/{phone-utils-BNiSqeF7.d.mts → phone-utils-CYr6AmEP.d.mts} +231 -3
  19. package/dist/{phone-utils-D12FW8tT.d.ts → phone-utils-CYr6AmEP.d.ts} +231 -3
  20. package/dist/phone.d.mts +1 -2
  21. package/dist/phone.d.ts +1 -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-CNvzyF5T.d.ts → sales-C0FMkN4m.d.ts} +1 -1
  27. package/dist/{sales-YUH3bQl9.d.mts → sales-KbTcowYa.d.mts} +1 -1
  28. package/dist/sales.d.mts +3 -3
  29. package/dist/sales.d.ts +3 -3
  30. package/dist/sales.js +1204 -170
  31. package/dist/sales.js.map +1 -1
  32. package/dist/sales.mjs +1204 -170
  33. package/dist/sales.mjs.map +1 -1
  34. package/package.json +1 -1
  35. package/dist/form-submit-CX-CxJjQ.d.mts +0 -47
  36. package/dist/form-submit-CX-CxJjQ.d.ts +0 -47
package/dist/index.js CHANGED
@@ -53,6 +53,7 @@ __export(src_exports, {
53
53
  buildBookingHandoffUrl: () => buildBookingHandoffUrl,
54
54
  captureTrackingParamsFromLocation: () => captureTrackingParamsFromLocation,
55
55
  clearStashedUserData: () => clearStashedUserData,
56
+ createLeadFormSubmit: () => import_client4.createLeadFormSubmit,
56
57
  createSalesClient: () => createSalesClient,
57
58
  createTracking: () => import_client.createTracking,
58
59
  createTrackingClientContext: () => createTrackingClientContext,
@@ -88,7 +89,9 @@ __export(src_exports, {
88
89
  salesRequest: () => salesRequest,
89
90
  setConsentState: () => setConsentState,
90
91
  shopToday: () => shopToday,
92
+ slotFields: () => slotFields,
91
93
  stashUserData: () => stashUserData,
94
+ timeWindow: () => timeWindow,
92
95
  toE164: () => toE164,
93
96
  toMinor: () => toMinor,
94
97
  useBookingHandoffUrl: () => import_client3.useBookingHandoffUrl,
@@ -327,7 +330,8 @@ var TRACKING_CAPABILITIES = [
327
330
  "cta_click_capture",
328
331
  "form_capture",
329
332
  "phone_click_capture",
330
- "phone_fields"
333
+ "phone_fields",
334
+ "typed_form_submit"
331
335
  ];
332
336
  var CAPABILITY_DOM_ATTRIBUTE = "data-aranova-capability";
333
337
  var registered = /* @__PURE__ */ new Set();
@@ -551,10 +555,10 @@ function readStoredRecord() {
551
555
  return null;
552
556
  }
553
557
  }
554
- function writeRecord(record3) {
555
- memoryRecord = record3;
558
+ function writeRecord(record4) {
559
+ memoryRecord = record4;
556
560
  try {
557
- window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record3));
561
+ window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record4));
558
562
  } catch {
559
563
  }
560
564
  }
@@ -576,9 +580,9 @@ function getOrCaptureLandingParams(sessionId, url) {
576
580
  if (memoryRecord && memoryRecord.session_id === sessionId) {
577
581
  return memoryRecord.params;
578
582
  }
579
- const record3 = { session_id: sessionId, params: captureFromUrl(url) };
580
- writeRecord(record3);
581
- return record3.params;
583
+ const record4 = { session_id: sessionId, params: captureFromUrl(url) };
584
+ writeRecord(record4);
585
+ return record4.params;
582
586
  }
583
587
  function buildLandingPayloadFields(sessionId, override) {
584
588
  const params = override ?? (typeof window === "undefined" ? null : getOrCaptureLandingParams(sessionId));
@@ -1805,8 +1809,81 @@ var SDK_PACKAGE_HEADER = "X-Aranova-Sdk-Package";
1805
1809
  var SDK_SURFACE_HEADER = "X-Aranova-Sdk-Surface";
1806
1810
  var SDK_ENVIRONMENT_HEADER = "X-Aranova-Sdk-Environment";
1807
1811
 
1808
- // ../tracking-core/src/lead-forms/lead-forms.gen.ts
1812
+ // ../tracking-core/src/ingest-typed.ts
1813
+ var import_mini = require("zod/mini");
1814
+
1815
+ // ../tracking-core/src/events/form-submit.ts
1809
1816
  var z2 = __toESM(require("zod/mini"));
1817
+ var jsonValueSchema = z2.lazy(
1818
+ () => z2.union([
1819
+ z2.string(),
1820
+ z2.number(),
1821
+ z2.boolean(),
1822
+ z2.null(),
1823
+ z2.array(jsonValueSchema),
1824
+ z2.record(z2.string(), jsonValueSchema)
1825
+ ])
1826
+ ).register(z2.globalRegistry, { id: "JsonSerializableValue" });
1827
+ var contractNameSchema = z2.string().check(z2.regex(/^[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?$/));
1828
+ var contractName = contractNameSchema;
1829
+ var violationRole = z2.string().check(
1830
+ z2.maxLength(200),
1831
+ z2.regex(
1832
+ /^[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?(\|[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?)*$/
1833
+ )
1834
+ );
1835
+ var MAX_CONTRACT_VIOLATIONS = 50;
1836
+ var contractViolationSchema = z2.strictObject({
1837
+ role: z2.nullable(violationRole),
1838
+ rule: z2.string().check(z2.regex(/^[a-z][a-z_]{0,47}$/))
1839
+ });
1840
+ var formSubmitMetadataSchema = z2.strictObject({
1841
+ form: z2.strictObject({
1842
+ id: z2.string(),
1843
+ action: z2.nullable(z2.string()),
1844
+ fields: z2.optional(
1845
+ z2.array(
1846
+ z2.strictObject({
1847
+ name: z2.string(),
1848
+ type: z2.string(),
1849
+ label: z2.nullable(z2.string()),
1850
+ value: jsonValueSchema,
1851
+ role: z2.optional(z2.nullable(contractName))
1852
+ })
1853
+ )
1854
+ ),
1855
+ kind: z2.optional(z2.nullable(contractName)),
1856
+ contract_version: z2.optional(z2.nullable(z2.int().check(z2.gte(1)))),
1857
+ contract_hash: z2.optional(z2.nullable(z2.string().check(z2.maxLength(64)))),
1858
+ extra: z2.optional(
1859
+ z2.nullable(
1860
+ z2.array(
1861
+ z2.strictObject({
1862
+ key: z2.string().check(z2.maxLength(64)),
1863
+ label: z2.string().check(z2.maxLength(200)),
1864
+ value: jsonValueSchema
1865
+ })
1866
+ ).check(z2.maxLength(20))
1867
+ )
1868
+ ),
1869
+ contract_violations: z2.optional(
1870
+ z2.nullable(z2.array(contractViolationSchema).check(z2.maxLength(MAX_CONTRACT_VIOLATIONS)))
1871
+ )
1872
+ }),
1873
+ page: z2.strictObject({
1874
+ path: z2.string()
1875
+ })
1876
+ });
1877
+ var formSubmitConfigSchema = z2.strictObject({});
1878
+
1879
+ // ../tracking-core/src/ingest-typed.ts
1880
+ var clientSettings = /* @__PURE__ */ new WeakMap();
1881
+ function typedClientSettings(client) {
1882
+ return clientSettings.get(client) ?? {};
1883
+ }
1884
+
1885
+ // ../tracking-core/src/lead-forms/lead-forms.gen.ts
1886
+ var z3 = __toESM(require("zod/mini"));
1810
1887
  var LEAD_FORM_REGISTRY_VERSION = 2;
1811
1888
  var LEAD_FORM_KINDS = ["booking", "quote", "contact", "consult", "callback"];
1812
1889
  var LEAD_FORM_ROLES = [
@@ -1846,28 +1923,28 @@ var LEAD_FORM_PRIMITIVES = [
1846
1923
  "number"
1847
1924
  ];
1848
1925
  var leadFormPrimitiveSchemas = /* @__PURE__ */ (() => ({
1849
- string: z2.string().check(z2.maxLength(120)),
1850
- text: z2.string().check(z2.maxLength(2e3)),
1851
- enum: z2.string().check(z2.regex(/^[a-z0-9-]{1,48}$/)),
1852
- multi_enum: z2.array(z2.string().check(z2.regex(/^[a-z0-9-]{1,48}$/))).check(z2.maxLength(10)),
1853
- bool: z2.boolean(),
1854
- date: z2.string().check(z2.regex(/^\d{4}-\d{2}-\d{2}$/)),
1855
- time_window: z2.strictObject({
1856
- start: z2.string().check(z2.regex(/^([01]\d|2[0-3]):[0-5]\d$/)),
1857
- end: z2.nullable(z2.string().check(z2.regex(/^([01]\d|2[0-3]):[0-5]\d$/))),
1858
- label: z2.optional(z2.string().check(z2.maxLength(60)))
1926
+ string: z3.string().check(z3.maxLength(120)),
1927
+ text: z3.string().check(z3.maxLength(2e3)),
1928
+ enum: z3.string().check(z3.regex(/^[a-z0-9-]{1,48}$/)),
1929
+ multi_enum: z3.array(z3.string().check(z3.regex(/^[a-z0-9-]{1,48}$/))).check(z3.maxLength(10)),
1930
+ bool: z3.boolean(),
1931
+ date: z3.string().check(z3.regex(/^\d{4}-\d{2}-\d{2}$/)),
1932
+ time_window: z3.strictObject({
1933
+ start: z3.string().check(z3.regex(/^([01]\d|2[0-3]):[0-5]\d$/)),
1934
+ end: z3.nullable(z3.string().check(z3.regex(/^([01]\d|2[0-3]):[0-5]\d$/))),
1935
+ label: z3.optional(z3.string().check(z3.maxLength(60)))
1859
1936
  }),
1860
- phone: z2.string().check(z2.regex(/^\+[1-9]\d{6,14}$/)),
1861
- email: z2.string().check(z2.maxLength(320), z2.regex(/^[^\s@]+@[^\s@]+$/)),
1862
- address: z2.strictObject({
1863
- line1: z2.string().check(z2.maxLength(120)),
1864
- line2: z2.optional(z2.string().check(z2.maxLength(120))),
1865
- city: z2.optional(z2.string().check(z2.maxLength(120))),
1866
- region: z2.optional(z2.string().check(z2.maxLength(120))),
1867
- postal_code: z2.optional(z2.string().check(z2.maxLength(120))),
1868
- country: z2.optional(z2.string().check(z2.maxLength(120)))
1937
+ phone: z3.string().check(z3.regex(/^\+[1-9]\d{6,14}$/)),
1938
+ email: z3.string().check(z3.maxLength(320), z3.regex(/^[^\s@]+@[^\s@]+$/)),
1939
+ address: z3.strictObject({
1940
+ line1: z3.string().check(z3.maxLength(120)),
1941
+ line2: z3.optional(z3.string().check(z3.maxLength(120))),
1942
+ city: z3.optional(z3.string().check(z3.maxLength(120))),
1943
+ region: z3.optional(z3.string().check(z3.maxLength(120))),
1944
+ postal_code: z3.optional(z3.string().check(z3.maxLength(120))),
1945
+ country: z3.optional(z3.string().check(z3.maxLength(120)))
1869
1946
  }),
1870
- number: z2.number()
1947
+ number: z3.number()
1871
1948
  }))();
1872
1949
  var LEAD_FORM_ROLE_SPECS = {
1873
1950
  given_name: { primitive: "string", smsLabel: "", contactIdentity: true },
@@ -1917,6 +1994,101 @@ var LEAD_FORM_ROLE_SPECS = {
1917
1994
  attribution: { primitive: "enum", smsLabel: "", uninteresting: true }
1918
1995
  };
1919
1996
 
1997
+ // ../tracking-core/src/lead-forms/submit.ts
1998
+ var import_mini2 = require("zod/mini");
1999
+ var KNOWN_ROLES = new Set(LEAD_FORM_ROLES);
2000
+ var ROLE_ORDER = new Map(LEAD_FORM_ROLES.map((role, index) => [role, index]));
2001
+ var ADD_ON = /^add_on:[a-z0-9_-]{1,48}$/;
2002
+ var CONTRACT_NAME = /^[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?$/;
2003
+ function judgeLeadForm(kind, formId, fields, contracts, settings) {
2004
+ const generated = contracts?.contracts[kind];
2005
+ const live = liveContract(settings.trackingConfig, kind);
2006
+ const violations = check(live === void 0 ? generated : fromLive(live), fields);
2007
+ const liveHash = live === void 0 ? void 0 : live?.contract_hash ?? null;
2008
+ if (contracts && (liveHash !== void 0 && (generated?.hash ?? null) !== liveHash || contracts.registryVersion !== LEAD_FORM_REGISTRY_VERSION)) {
2009
+ violations.push({ role: null, rule: "contract_behind" });
2010
+ }
2011
+ if (violations.length > 0 && (settings.debug || settings.environment === "development")) {
2012
+ const message = `[AranovaTracking] lead form "${formId}" (${kind}) breaks its contract: ${violations.map((v) => `${v.rule}${v.role ? ` (${v.role})` : ""}`).join(", ")}`;
2013
+ console.error(message);
2014
+ if (settings.debug) throw new Error(message);
2015
+ }
2016
+ return {
2017
+ violations,
2018
+ hash: liveHash === void 0 ? generated?.hash ?? null : liveHash
2019
+ };
2020
+ }
2021
+ function liveContract(ref, kind) {
2022
+ const leadForms = ref ? getTrackingConfigRuntime(ref).leadForms() : null;
2023
+ if (!leadForms) return void 0;
2024
+ return leadForms.contracts.find((c) => c.form_kind === kind) ?? null;
2025
+ }
2026
+ function fromLive(live) {
2027
+ if (!live) return void 0;
2028
+ return {
2029
+ requires: live.requires.map((r) => ({
2030
+ role: r.role,
2031
+ requiredWhen: r.required_when ? { role: r.required_when.role, anyOf: r.required_when.any_of } : null
2032
+ })),
2033
+ requiresAny: live.requires_any.map((g) => g.roles),
2034
+ // Deprecated keys still resolve: a cached form may send them (ADR-0024 §7).
2035
+ options: Object.fromEntries(live.options.map((o) => [o.role, o.options.map((x) => x.key)]))
2036
+ };
2037
+ }
2038
+ function check(contract, fields) {
2039
+ const answered = new Map(fields);
2040
+ const violations = [];
2041
+ for (const [role, value] of fields) {
2042
+ const primitive = primitiveOf(role);
2043
+ if (!primitive) {
2044
+ violations.push({ role: CONTRACT_NAME.test(role) ? role : null, rule: "unknown_role" });
2045
+ continue;
2046
+ }
2047
+ if (!(0, import_mini2.safeParse)(leadFormPrimitiveSchemas[primitive], value).success) {
2048
+ violations.push({ role, rule: "invalid_value" });
2049
+ continue;
2050
+ }
2051
+ const allowed = contract?.options[role] ?? registryOptions(role);
2052
+ if (allowed?.length && optionKeys(value).some((key) => !allowed.includes(key))) {
2053
+ violations.push({ role, rule: "unknown_option" });
2054
+ }
2055
+ }
2056
+ for (const { role, requiredWhen } of contract?.requires ?? []) {
2057
+ const owing = requiredWhen === null || optionKeys(answered.get(requiredWhen.role)).some((key) => requiredWhen.anyOf.includes(key));
2058
+ if (owing && !answered.has(role)) violations.push({ role, rule: "missing_required" });
2059
+ }
2060
+ for (const group of contract?.requiresAny ?? []) {
2061
+ if (!group.some((role) => answered.has(role))) {
2062
+ violations.push({ role: group.join("|"), rule: "missing_any_of" });
2063
+ }
2064
+ }
2065
+ return violations;
2066
+ }
2067
+ function primitiveOf(role) {
2068
+ if (ADD_ON.test(role)) return "bool";
2069
+ return KNOWN_ROLES.has(role) ? LEAD_FORM_ROLE_SPECS[role].primitive : null;
2070
+ }
2071
+ function registryOptions(role) {
2072
+ const spec = KNOWN_ROLES.has(role) ? LEAD_FORM_ROLE_SPECS[role] : void 0;
2073
+ return spec && "options" in spec ? spec.options.map((o) => o.key) : void 0;
2074
+ }
2075
+ function optionKeys(value) {
2076
+ if (typeof value === "string") return [value];
2077
+ return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
2078
+ }
2079
+ function slotFields(dateTime) {
2080
+ const written = /^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2})(?::\d{2}(?:\.\d+)?)?$/.exec(dateTime);
2081
+ if (!written) {
2082
+ throw new TypeError(
2083
+ `slotFields needs the slot's wall time without an offset ("2026-10-13T09:30"), got "${dateTime}"`
2084
+ );
2085
+ }
2086
+ return { preferred_date: written[1], preferred_time: { start: written[2], end: null } };
2087
+ }
2088
+ function timeWindow(start, end, label) {
2089
+ return { start, end: end ?? null, ...label ? { label } : {} };
2090
+ }
2091
+
1920
2092
  // ../tracking-core/src/resources/http/errors.ts
1921
2093
  var AranovaApiError = class extends Error {
1922
2094
  constructor(message, options) {
@@ -1956,11 +2128,11 @@ async function apiRequest(config, method, path, body, extraHeaders) {
1956
2128
  try {
1957
2129
  const parsed = await response.json();
1958
2130
  if (parsed && typeof parsed === "object") {
1959
- const record3 = parsed;
1960
- if (typeof record3.detail === "string") detail = record3.detail;
1961
- if (typeof record3.code === "string") code = record3.code;
1962
- if (record3.context && typeof record3.context === "object") {
1963
- context = record3.context;
2131
+ const record4 = parsed;
2132
+ if (typeof record4.detail === "string") detail = record4.detail;
2133
+ if (typeof record4.code === "string") code = record4.code;
2134
+ if (record4.context && typeof record4.context === "object") {
2135
+ context = record4.context;
1964
2136
  }
1965
2137
  }
1966
2138
  } catch {
@@ -2014,7 +2186,7 @@ var DROP_OFF_KEYS = {
2014
2186
  waitForIt: "wait-for-it",
2015
2187
  dropOff: "drop-off"
2016
2188
  };
2017
- function formSubmitPayload(input, formSubmit, contractHash) {
2189
+ function formSubmitPayload(input, formSubmit, runtime) {
2018
2190
  const field = (role, name, type, label, value) => ({ name, type, label, value, role });
2019
2191
  const text = (value) => value?.trim() || void 0;
2020
2192
  const { vehicle, dropOff } = input;
@@ -2024,7 +2196,7 @@ function formSubmitPayload(input, formSubmit, contractHash) {
2024
2196
  // E.164 on the wire: it keys the customer and enhanced-conversion matching.
2025
2197
  field("phone", "phone", "tel", "Phone", toE164(input.phone) ?? input.phone),
2026
2198
  field("email", "email", "email", "Email", text(input.email)),
2027
- field("service", "service", "select", "Service", input.services),
2199
+ field("service", "service", "select", "Service", [...input.services]),
2028
2200
  field(
2029
2201
  "vehicle",
2030
2202
  "vehicle",
@@ -2049,6 +2221,14 @@ function formSubmitPayload(input, formSubmit, contractHash) {
2049
2221
  const reported = new Set(entries.map((item) => item.name));
2050
2222
  const fields = entries.filter((item) => item.value !== void 0);
2051
2223
  const extra = (formSubmit.extraFields ?? []).filter((item) => !reported.has(item.name));
2224
+ const settings = typedClientSettings(formSubmit.tracking);
2225
+ const { violations, hash } = judgeLeadForm(
2226
+ "booking",
2227
+ formSubmit.formId,
2228
+ fields.map((item) => [item.role, item.value]),
2229
+ formSubmit.contracts,
2230
+ { ...settings, trackingConfig: settings.trackingConfig ?? runtime?.ref }
2231
+ );
2052
2232
  return {
2053
2233
  form: {
2054
2234
  id: formSubmit.formId,
@@ -2056,7 +2236,8 @@ function formSubmitPayload(input, formSubmit, contractHash) {
2056
2236
  fields: [...fields, ...extra],
2057
2237
  kind: "booking",
2058
2238
  contract_version: LEAD_FORM_REGISTRY_VERSION,
2059
- ...contractHash ? { contract_hash: contractHash } : {}
2239
+ ...hash ? { contract_hash: hash } : {},
2240
+ ...violations.length > 0 ? { contract_violations: violations.slice(0, MAX_CONTRACT_VIOLATIONS) } : {}
2060
2241
  },
2061
2242
  page: { path: typeof window === "undefined" ? "/" : window.location.pathname }
2062
2243
  };
@@ -2155,10 +2336,9 @@ function createSalesBookingsClient(config, firing) {
2155
2336
  }
2156
2337
  if (formSubmit && !submittedForms.has(attemptKey)) {
2157
2338
  submittedForms.add(attemptKey);
2158
- const contract = runtime?.leadForms()?.contracts.find((c) => c.form_kind === "booking");
2159
2339
  formSubmit.tracking.trackEvent(
2160
2340
  "form_submit",
2161
- formSubmitPayload(input, formSubmit, contract?.contract_hash ?? null)
2341
+ formSubmitPayload(input, formSubmit, runtime)
2162
2342
  );
2163
2343
  }
2164
2344
  const body = {
@@ -2174,7 +2354,7 @@ function createSalesBookingsClient(config, firing) {
2174
2354
  email: input.email?.trim() || null,
2175
2355
  vehicle: input.vehicle ?? null,
2176
2356
  drop_off: input.dropOff ?? null,
2177
- services: input.services,
2357
+ services: [...input.services],
2178
2358
  notes: input.notes?.trim() || null,
2179
2359
  marketing_sms_consent: input.marketingSmsConsent === true,
2180
2360
  page_path: typeof window === "undefined" ? null : window.location.pathname
@@ -2261,7 +2441,7 @@ function fireRecordedConversions(firing, input, recorded, sale, currency) {
2261
2441
  }
2262
2442
  function createSalesClient(config) {
2263
2443
  if (config.firing) registerCapability("conversion_goals_manual");
2264
- async function record3(input) {
2444
+ async function record4(input) {
2265
2445
  const currency = input.currency ?? config.defaultCurrency;
2266
2446
  if (!currency) {
2267
2447
  throw new Error(
@@ -2287,9 +2467,9 @@ function createSalesClient(config) {
2287
2467
  return sale;
2288
2468
  }
2289
2469
  return {
2290
- record: record3,
2470
+ record: record4,
2291
2471
  // recordSale is the intent-revealing alias — same behavior, clearer call site.
2292
- recordSale: record3,
2472
+ recordSale: record4,
2293
2473
  trackConversion(key, options) {
2294
2474
  if (config.firing && "fireConversion" in config.firing) {
2295
2475
  if (options?.userData && getConsentState() !== "denied") stashUserData(options.userData);
@@ -2409,17 +2589,17 @@ function createSalesClient(config) {
2409
2589
  }
2410
2590
 
2411
2591
  // ../tracking-core/src/resources/sales/schema.ts
2412
- var z4 = __toESM(require("zod/mini"));
2592
+ var z5 = __toESM(require("zod/mini"));
2413
2593
 
2414
2594
  // ../tracking-core/src/resources/sales/generated/zod.gen.ts
2415
- var z3 = __toESM(require("zod/mini"));
2416
- var zAutoLeapSaleFacts = z3.object({
2417
- first_order: z3.boolean(),
2418
- fleet_customer: z3.boolean(),
2419
- invoice_code: z3.string(),
2420
- invoice_id: z3.string()
2595
+ var z4 = __toESM(require("zod/mini"));
2596
+ var zAutoLeapSaleFacts = z4.object({
2597
+ first_order: z4.boolean(),
2598
+ fleet_customer: z4.boolean(),
2599
+ invoice_code: z4.string(),
2600
+ invoice_id: z4.string()
2421
2601
  });
2422
- var zErrorCode = z3.enum([
2602
+ var zErrorCode = z4.enum([
2423
2603
  "missing_credentials",
2424
2604
  "invalid_api_key",
2425
2605
  "not_authenticated",
@@ -2463,37 +2643,37 @@ var zErrorCode = z3.enum([
2463
2643
  "rate_limited",
2464
2644
  "internal_error"
2465
2645
  ]);
2466
- var zSaleItemEntitySchema = z3.object({
2467
- category: z3.nullable(z3.string()),
2468
- external_item_id: z3.nullable(z3.string()),
2469
- id: z3.uuid(),
2470
- name: z3.nullable(z3.string()),
2471
- quantity: z3.string().check(z3.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
2472
- unit_cost_cents: z3.nullable(z3.int()),
2473
- unit_price_cents: z3.int()
2646
+ var zSaleItemEntitySchema = z4.object({
2647
+ category: z4.nullable(z4.string()),
2648
+ external_item_id: z4.nullable(z4.string()),
2649
+ id: z4.uuid(),
2650
+ name: z4.nullable(z4.string()),
2651
+ quantity: z4.string().check(z4.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
2652
+ unit_cost_cents: z4.nullable(z4.int()),
2653
+ unit_price_cents: z4.int()
2474
2654
  });
2475
- var zSaleItemInputSchema = z3.strictObject({
2476
- category: z3.nullish(z3.string()),
2477
- external_item_id: z3.nullish(z3.string()),
2478
- name: z3.nullish(z3.string()),
2479
- quantity: z3.string().check(z3.regex(/^\d+(\.\d{1,3})?$/)),
2480
- unit_cost_cents: z3.nullish(z3.int().check(z3.gte(0))),
2481
- unit_price_cents: z3.int().check(z3.gte(0))
2655
+ var zSaleItemInputSchema = z4.strictObject({
2656
+ category: z4.nullish(z4.string()),
2657
+ external_item_id: z4.nullish(z4.string()),
2658
+ name: z4.nullish(z4.string()),
2659
+ quantity: z4.string().check(z4.regex(/^\d+(\.\d{1,3})?$/)),
2660
+ unit_cost_cents: z4.nullish(z4.int().check(z4.gte(0))),
2661
+ unit_price_cents: z4.int().check(z4.gte(0))
2482
2662
  });
2483
- var zSaleServiceEntitySchema = z3.object({
2484
- amount_cents: z3.int(),
2485
- id: z3.uuid(),
2486
- mapped: z3.nullable(z3.boolean()),
2487
- service_id: z3.uuid(),
2488
- service_key: z3.string(),
2489
- service_label: z3.string()
2663
+ var zSaleServiceEntitySchema = z4.object({
2664
+ amount_cents: z4.int(),
2665
+ id: z4.uuid(),
2666
+ mapped: z4.nullable(z4.boolean()),
2667
+ service_id: z4.uuid(),
2668
+ service_key: z4.string(),
2669
+ service_label: z4.string()
2490
2670
  });
2491
- var zSaleServiceInputSchema = z3.strictObject({
2492
- amount_cents: z3.int().check(z3.gte(0)),
2493
- service: z3.string()
2671
+ var zSaleServiceInputSchema = z4.strictObject({
2672
+ amount_cents: z4.int().check(z4.gte(0)),
2673
+ service: z4.string()
2494
2674
  });
2495
- var zSaleSource = z3.enum(["api", "admin", "autoleap"]);
2496
- var zSmsAutomationState = z3.enum([
2675
+ var zSaleSource = z4.enum(["api", "admin", "autoleap"]);
2676
+ var zSmsAutomationState = z4.enum([
2497
2677
  "needs_check",
2498
2678
  "failed",
2499
2679
  "undelivered",
@@ -2505,7 +2685,7 @@ var zSmsAutomationState = z3.enum([
2505
2685
  "eligible",
2506
2686
  "not_applicable"
2507
2687
  ]);
2508
- var zSmsWithheldReason = z3.enum([
2688
+ var zSmsWithheldReason = z4.enum([
2509
2689
  "automation_disabled",
2510
2690
  "sms_disabled",
2511
2691
  "no_phone",
@@ -2531,77 +2711,79 @@ var zSmsWithheldReason = z3.enum([
2531
2711
  "confirmed_by_integration",
2532
2712
  "test_or_bot_session",
2533
2713
  "invalid_phone",
2534
- "recently_texted"
2714
+ "recently_texted",
2715
+ "do_not_contact",
2716
+ "do_not_text_tag"
2535
2717
  ]);
2536
- var zSaleSmsStatusSchema = z3.object({
2537
- can_send_now: z3._default(z3.boolean(), false),
2538
- last_message_at: z3.nullable(z3.iso.datetime({ offset: true })),
2539
- reason_detail: z3.nullable(z3.string()),
2718
+ var zSaleSmsStatusSchema = z4.object({
2719
+ can_send_now: z4._default(z4.boolean(), false),
2720
+ last_message_at: z4.nullable(z4.iso.datetime({ offset: true })),
2721
+ reason_detail: z4.nullable(z4.string()),
2540
2722
  state: zSmsAutomationState,
2541
- suppressed_by_other_sale: z3._default(z3.boolean(), false),
2542
- withheld_reason: z3.nullable(zSmsWithheldReason)
2723
+ suppressed_by_other_sale: z4._default(z4.boolean(), false),
2724
+ withheld_reason: z4.nullable(zSmsWithheldReason)
2543
2725
  });
2544
- var zSupportedCurrency = z3.enum(["USD", "CAD"]);
2545
- var zTrackingEnvironment = z3.enum(["production", "development"]);
2546
- var zSaleCreateSchema = z3.strictObject({
2547
- amount_total_cents: z3.nullish(z3.int().check(z3.gte(0))),
2726
+ var zSupportedCurrency = z4.enum(["USD", "CAD"]);
2727
+ var zTrackingEnvironment = z4.enum(["production", "development"]);
2728
+ var zSaleCreateSchema = z4.strictObject({
2729
+ amount_total_cents: z4.nullish(z4.int().check(z4.gte(0))),
2548
2730
  currency: zSupportedCurrency,
2549
- customer_email: z3.nullish(z3.email().check(z3.maxLength(320))),
2550
- customer_name: z3.nullish(z3.string().check(z3.maxLength(200))),
2551
- customer_phone: z3.nullish(z3.string().check(z3.maxLength(64))),
2552
- description: z3.nullish(z3.string()),
2553
- environment: z3._default(z3.optional(zTrackingEnvironment), "production"),
2554
- external_id: z3.nullish(z3.string()),
2555
- items: z3.optional(z3.array(zSaleItemInputSchema)),
2556
- metadata: z3.nullish(z3.record(z3.string(), z3.unknown())),
2557
- occurred_at: z3.iso.datetime({ offset: true }),
2558
- service: z3.nullish(z3.string()),
2559
- services: z3.nullish(z3.array(zSaleServiceInputSchema)),
2560
- sms_consent: z3.nullish(z3.boolean())
2731
+ customer_email: z4.nullish(z4.email().check(z4.maxLength(320))),
2732
+ customer_name: z4.nullish(z4.string().check(z4.maxLength(200))),
2733
+ customer_phone: z4.nullish(z4.string().check(z4.maxLength(64))),
2734
+ description: z4.nullish(z4.string()),
2735
+ environment: z4._default(z4.optional(zTrackingEnvironment), "production"),
2736
+ external_id: z4.nullish(z4.string()),
2737
+ items: z4.optional(z4.array(zSaleItemInputSchema)),
2738
+ metadata: z4.nullish(z4.record(z4.string(), z4.unknown())),
2739
+ occurred_at: z4.iso.datetime({ offset: true }),
2740
+ service: z4.nullish(z4.string()),
2741
+ services: z4.nullish(z4.array(zSaleServiceInputSchema)),
2742
+ sms_consent: z4.nullish(z4.boolean())
2561
2743
  });
2562
- var zValidationError = z3.object({
2563
- ctx: z3.optional(z3.record(z3.string(), z3.unknown())),
2564
- input: z3.optional(z3.unknown()),
2565
- loc: z3.array(z3.union([z3.string(), z3.int()])),
2566
- msg: z3.string(),
2567
- type: z3.string()
2744
+ var zValidationError = z4.object({
2745
+ ctx: z4.optional(z4.record(z4.string(), z4.unknown())),
2746
+ input: z4.optional(z4.unknown()),
2747
+ loc: z4.array(z4.union([z4.string(), z4.int()])),
2748
+ msg: z4.string(),
2749
+ type: z4.string()
2568
2750
  });
2569
- var zHttpValidationError = z3.object({
2570
- detail: z3.optional(z3.array(zValidationError))
2751
+ var zHttpValidationError = z4.object({
2752
+ detail: z4.optional(z4.array(zValidationError))
2571
2753
  });
2572
- var zValidationErrorItem = z3.object({
2573
- loc: z3.array(z3.union([z3.string(), z3.int()])),
2574
- msg: z3.string(),
2575
- type: z3.string()
2754
+ var zValidationErrorItem = z4.object({
2755
+ loc: z4.array(z4.union([z4.string(), z4.int()])),
2756
+ msg: z4.string(),
2757
+ type: z4.string()
2576
2758
  });
2577
- var zApiErrorSchema = z3.object({
2759
+ var zApiErrorSchema = z4.object({
2578
2760
  code: zErrorCode,
2579
- context: z3._default(z3.nullish(z3.record(z3.string(), z3.unknown())), null),
2580
- detail: z3.string(),
2581
- errors: z3._default(z3.nullish(z3.array(zValidationErrorItem)), null),
2582
- request_id: z3._default(z3.nullish(z3.string()), null)
2761
+ context: z4._default(z4.nullish(z4.record(z4.string(), z4.unknown())), null),
2762
+ detail: z4.string(),
2763
+ errors: z4._default(z4.nullish(z4.array(zValidationErrorItem)), null),
2764
+ request_id: z4._default(z4.nullish(z4.string()), null)
2583
2765
  });
2584
- var zWritebackEmailSource = z3.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
2585
- var zWritebackEnrichmentStatus = z3.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
2586
- var zWritebackSaleUploadCounts = z3.object({
2587
- failed: z3._default(z3.int(), 0),
2588
- pending: z3._default(z3.int(), 0),
2589
- skipped: z3._default(z3.int(), 0),
2590
- submitted: z3._default(z3.int(), 0),
2591
- total: z3._default(z3.int(), 0),
2592
- uploaded: z3._default(z3.int(), 0)
2766
+ var zWritebackEmailSource = z4.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
2767
+ var zWritebackEnrichmentStatus = z4.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
2768
+ var zWritebackSaleUploadCounts = z4.object({
2769
+ failed: z4._default(z4.int(), 0),
2770
+ pending: z4._default(z4.int(), 0),
2771
+ skipped: z4._default(z4.int(), 0),
2772
+ submitted: z4._default(z4.int(), 0),
2773
+ total: z4._default(z4.int(), 0),
2774
+ uploaded: z4._default(z4.int(), 0)
2593
2775
  });
2594
- var zSaleWritebackStatusSchema = z3.object({
2595
- blocked_reason: z3.nullable(z3.string()),
2596
- can_dispatch: z3._default(z3.boolean(), false),
2597
- email_source: z3.nullable(zWritebackEmailSource),
2598
- enrichment_status: z3.nullable(zWritebackEnrichmentStatus),
2599
- gclid_attached: z3._default(z3.boolean(), false),
2600
- identifiers_sent: z3.nullable(z3.string()),
2601
- mapped_service_ids: z3.array(z3.uuid()),
2602
- matched_submit_count: z3.nullable(z3.int()),
2603
- needs_force: z3._default(z3.boolean(), false),
2604
- rollup: z3.enum([
2776
+ var zSaleWritebackStatusSchema = z4.object({
2777
+ blocked_reason: z4.nullable(z4.string()),
2778
+ can_dispatch: z4._default(z4.boolean(), false),
2779
+ email_source: z4.nullable(zWritebackEmailSource),
2780
+ enrichment_status: z4.nullable(zWritebackEnrichmentStatus),
2781
+ gclid_attached: z4._default(z4.boolean(), false),
2782
+ identifiers_sent: z4.nullable(z4.string()),
2783
+ mapped_service_ids: z4.array(z4.uuid()),
2784
+ matched_submit_count: z4.nullable(z4.int()),
2785
+ needs_force: z4._default(z4.boolean(), false),
2786
+ rollup: z4.enum([
2605
2787
  "failed",
2606
2788
  "skipped",
2607
2789
  "pending",
@@ -2611,39 +2793,39 @@ var zSaleWritebackStatusSchema = z3.object({
2611
2793
  "out_of_window",
2612
2794
  "blocked"
2613
2795
  ]),
2614
- stale: z3._default(z3.boolean(), false),
2615
- uncovered_service_ids: z3.array(z3.uuid()),
2796
+ stale: z4._default(z4.boolean(), false),
2797
+ uncovered_service_ids: z4.array(z4.uuid()),
2616
2798
  uploads: zWritebackSaleUploadCounts
2617
2799
  });
2618
- var zSaleEntitySchema = z3.object({
2619
- amount_total_cents: z3.int(),
2620
- business_id: z3.uuid(),
2621
- business_name: z3.nullable(z3.string()),
2622
- created_at: z3.iso.datetime({ offset: true }),
2623
- currency: z3.string(),
2624
- customer_email: z3.nullable(z3.string()),
2625
- customer_name: z3.nullable(z3.string()),
2626
- customer_name_placeholder_confirmed: z3._default(z3.boolean(), false),
2627
- customer_name_placeholder_confirmed_at: z3.nullable(z3.iso.datetime({ offset: true })),
2628
- customer_phone: z3.nullable(z3.string()),
2629
- description: z3.nullable(z3.string()),
2800
+ var zSaleEntitySchema = z4.object({
2801
+ amount_total_cents: z4.int(),
2802
+ business_id: z4.uuid(),
2803
+ business_name: z4.nullable(z4.string()),
2804
+ created_at: z4.iso.datetime({ offset: true }),
2805
+ currency: z4.string(),
2806
+ customer_email: z4.nullable(z4.string()),
2807
+ customer_name: z4.nullable(z4.string()),
2808
+ customer_name_placeholder_confirmed: z4._default(z4.boolean(), false),
2809
+ customer_name_placeholder_confirmed_at: z4.nullable(z4.iso.datetime({ offset: true })),
2810
+ customer_phone: z4.nullable(z4.string()),
2811
+ description: z4.nullable(z4.string()),
2630
2812
  environment: zTrackingEnvironment,
2631
- external_id: z3.nullable(z3.string()),
2632
- id: z3.uuid(),
2633
- items: z3.array(zSaleItemEntitySchema),
2634
- metadata: z3.nullable(z3.record(z3.string(), z3.unknown())),
2635
- occurred_at: z3.iso.datetime({ offset: true }),
2636
- service_id: z3.nullable(z3.uuid()),
2637
- service_key: z3.nullable(z3.string()),
2638
- service_label: z3.nullable(z3.string()),
2639
- services: z3.array(zSaleServiceEntitySchema),
2640
- sms_automation: z3.nullable(zSaleSmsStatusSchema),
2641
- sms_consent: z3._default(z3.boolean(), false),
2642
- sms_consent_granted_at: z3.nullable(z3.iso.datetime({ offset: true })),
2813
+ external_id: z4.nullable(z4.string()),
2814
+ id: z4.uuid(),
2815
+ items: z4.array(zSaleItemEntitySchema),
2816
+ metadata: z4.nullable(z4.record(z4.string(), z4.unknown())),
2817
+ occurred_at: z4.iso.datetime({ offset: true }),
2818
+ service_id: z4.nullable(z4.uuid()),
2819
+ service_key: z4.nullable(z4.string()),
2820
+ service_label: z4.nullable(z4.string()),
2821
+ services: z4.array(zSaleServiceEntitySchema),
2822
+ sms_automation: z4.nullable(zSaleSmsStatusSchema),
2823
+ sms_consent: z4._default(z4.boolean(), false),
2824
+ sms_consent_granted_at: z4.nullable(z4.iso.datetime({ offset: true })),
2643
2825
  source: zSaleSource,
2644
- source_facts: z3.nullable(zAutoLeapSaleFacts),
2645
- updated_at: z3.iso.datetime({ offset: true }),
2646
- writeback: z3.nullable(zSaleWritebackStatusSchema)
2826
+ source_facts: z4.nullable(zAutoLeapSaleFacts),
2827
+ updated_at: z4.iso.datetime({ offset: true }),
2828
+ writeback: z4.nullable(zSaleWritebackStatusSchema)
2647
2829
  });
2648
2830
 
2649
2831
  // ../tracking-core/src/resources/sales/schema.ts
@@ -2652,11 +2834,11 @@ var saleServiceSchema = zSaleServiceInputSchema;
2652
2834
  var currencySchema = zSupportedCurrency;
2653
2835
  var SUPPORTED_CURRENCIES = currencySchema.options;
2654
2836
  var SALE_SOURCES = zSaleSource.options;
2655
- var centsSchema = z4.int().check(z4.gte(0));
2656
- var metadataSchema = z4.record(z4.string(), z4.unknown());
2657
- var customerNameSchema = z4.string().check(z4.maxLength(200));
2658
- var customerPhoneSchema = z4.string().check(z4.maxLength(64));
2659
- var customerEmailSchema = z4.email().check(z4.maxLength(320));
2837
+ var centsSchema = z5.int().check(z5.gte(0));
2838
+ var metadataSchema = z5.record(z5.string(), z5.unknown());
2839
+ var customerNameSchema = z5.string().check(z5.maxLength(200));
2840
+ var customerPhoneSchema = z5.string().check(z5.maxLength(64));
2841
+ var customerEmailSchema = z5.email().check(z5.maxLength(320));
2660
2842
  function addIssue(ctx, path, message) {
2661
2843
  ctx.issues.push({ code: "custom", input: ctx.value, path, message });
2662
2844
  }
@@ -2690,24 +2872,24 @@ function refineServiceXor(val, ctx, { requireAmount }) {
2690
2872
  );
2691
2873
  }
2692
2874
  }
2693
- var saleCreateSchema = z4.extend(zSaleCreateSchema, { items: z4._default(z4.array(saleItemSchema), []) }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: true }));
2694
- var saleUpdateSchema = z4.strictObject({
2695
- description: z4.nullish(z4.string()),
2696
- service: z4.nullish(z4.string()),
2697
- services: z4.nullish(z4.array(saleServiceSchema)),
2698
- currency: z4.optional(currencySchema),
2699
- amount_total_cents: z4.optional(centsSchema),
2700
- occurred_at: z4.optional(z4.iso.datetime()),
2701
- items: z4.optional(z4.array(saleItemSchema)),
2702
- metadata: z4.nullish(metadataSchema),
2703
- customer_name: z4.nullish(customerNameSchema),
2875
+ var saleCreateSchema = z5.extend(zSaleCreateSchema, { items: z5._default(z5.array(saleItemSchema), []) }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: true }));
2876
+ var saleUpdateSchema = z5.strictObject({
2877
+ description: z5.nullish(z5.string()),
2878
+ service: z5.nullish(z5.string()),
2879
+ services: z5.nullish(z5.array(saleServiceSchema)),
2880
+ currency: z5.optional(currencySchema),
2881
+ amount_total_cents: z5.optional(centsSchema),
2882
+ occurred_at: z5.optional(z5.iso.datetime()),
2883
+ items: z5.optional(z5.array(saleItemSchema)),
2884
+ metadata: z5.nullish(metadataSchema),
2885
+ customer_name: z5.nullish(customerNameSchema),
2704
2886
  // Re-attest when changing a filler-looking name; the server clears the
2705
2887
  // prior attestation whenever `customer_name` changes.
2706
- customer_name_placeholder_confirmed: z4.optional(z4.boolean()),
2707
- customer_phone: z4.nullish(customerPhoneSchema),
2708
- customer_email: z4.nullish(customerEmailSchema),
2888
+ customer_name_placeholder_confirmed: z5.optional(z5.boolean()),
2889
+ customer_phone: z5.nullish(customerPhoneSchema),
2890
+ customer_email: z5.nullish(customerEmailSchema),
2709
2891
  // NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
2710
- sms_consent: z4.optional(z4.boolean())
2892
+ sms_consent: z5.optional(z5.boolean())
2711
2893
  }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: false }));
2712
2894
  var TRACKING_RANGES = ["24h", "7d", "30d"];
2713
2895
  var NAMED_RANGES = [
@@ -2730,13 +2912,14 @@ async function fetchServices(config) {
2730
2912
  }
2731
2913
 
2732
2914
  // ../tracking-core/src/phone-field.ts
2733
- function phoneField(name, raw, country) {
2734
- return { name, type: "phone", value: toE164(raw, country) };
2915
+ function phoneField(name, raw, country, label = null) {
2916
+ return { name, type: "phone", label, value: toE164(raw, country) };
2735
2917
  }
2736
2918
 
2737
2919
  // src/index.ts
2738
2920
  var import_client2 = require("@aranova/tracking-react/client");
2739
2921
  var import_client3 = require("@aranova/tracking-react/client");
2922
+ var import_client4 = require("@aranova/tracking-react/client");
2740
2923
  // Annotate the CommonJS export names for ESM import in node:
2741
2924
  0 && (module.exports = {
2742
2925
  AdPlatformTracking,
@@ -2762,6 +2945,7 @@ var import_client3 = require("@aranova/tracking-react/client");
2762
2945
  buildBookingHandoffUrl,
2763
2946
  captureTrackingParamsFromLocation,
2764
2947
  clearStashedUserData,
2948
+ createLeadFormSubmit,
2765
2949
  createSalesClient,
2766
2950
  createTracking,
2767
2951
  createTrackingClientContext,
@@ -2797,7 +2981,9 @@ var import_client3 = require("@aranova/tracking-react/client");
2797
2981
  salesRequest,
2798
2982
  setConsentState,
2799
2983
  shopToday,
2984
+ slotFields,
2800
2985
  stashUserData,
2986
+ timeWindow,
2801
2987
  toE164,
2802
2988
  toMinor,
2803
2989
  useBookingHandoffUrl,