@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.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();
@@ -456,10 +457,10 @@ function readStoredRecord() {
456
457
  return null;
457
458
  }
458
459
  }
459
- function writeRecord(record3) {
460
- memoryRecord = record3;
460
+ function writeRecord(record4) {
461
+ memoryRecord = record4;
461
462
  try {
462
- window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record3));
463
+ window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record4));
463
464
  } catch {
464
465
  }
465
466
  }
@@ -481,9 +482,9 @@ function getOrCaptureLandingParams(sessionId, url) {
481
482
  if (memoryRecord && memoryRecord.session_id === sessionId) {
482
483
  return memoryRecord.params;
483
484
  }
484
- const record3 = { session_id: sessionId, params: captureFromUrl(url) };
485
- writeRecord(record3);
486
- return record3.params;
485
+ const record4 = { session_id: sessionId, params: captureFromUrl(url) };
486
+ writeRecord(record4);
487
+ return record4.params;
487
488
  }
488
489
  function buildLandingPayloadFields(sessionId, override) {
489
490
  const params = override ?? (typeof window === "undefined" ? null : getOrCaptureLandingParams(sessionId));
@@ -1710,8 +1711,81 @@ var SDK_PACKAGE_HEADER = "X-Aranova-Sdk-Package";
1710
1711
  var SDK_SURFACE_HEADER = "X-Aranova-Sdk-Surface";
1711
1712
  var SDK_ENVIRONMENT_HEADER = "X-Aranova-Sdk-Environment";
1712
1713
 
1713
- // ../tracking-core/src/lead-forms/lead-forms.gen.ts
1714
+ // ../tracking-core/src/ingest-typed.ts
1715
+ import { parse, safeParse } from "zod/mini";
1716
+
1717
+ // ../tracking-core/src/events/form-submit.ts
1714
1718
  import * as z2 from "zod/mini";
1719
+ var jsonValueSchema = z2.lazy(
1720
+ () => z2.union([
1721
+ z2.string(),
1722
+ z2.number(),
1723
+ z2.boolean(),
1724
+ z2.null(),
1725
+ z2.array(jsonValueSchema),
1726
+ z2.record(z2.string(), jsonValueSchema)
1727
+ ])
1728
+ ).register(z2.globalRegistry, { id: "JsonSerializableValue" });
1729
+ var contractNameSchema = z2.string().check(z2.regex(/^[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?$/));
1730
+ var contractName = contractNameSchema;
1731
+ var violationRole = z2.string().check(
1732
+ z2.maxLength(200),
1733
+ z2.regex(
1734
+ /^[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?(\|[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?)*$/
1735
+ )
1736
+ );
1737
+ var MAX_CONTRACT_VIOLATIONS = 50;
1738
+ var contractViolationSchema = z2.strictObject({
1739
+ role: z2.nullable(violationRole),
1740
+ rule: z2.string().check(z2.regex(/^[a-z][a-z_]{0,47}$/))
1741
+ });
1742
+ var formSubmitMetadataSchema = z2.strictObject({
1743
+ form: z2.strictObject({
1744
+ id: z2.string(),
1745
+ action: z2.nullable(z2.string()),
1746
+ fields: z2.optional(
1747
+ z2.array(
1748
+ z2.strictObject({
1749
+ name: z2.string(),
1750
+ type: z2.string(),
1751
+ label: z2.nullable(z2.string()),
1752
+ value: jsonValueSchema,
1753
+ role: z2.optional(z2.nullable(contractName))
1754
+ })
1755
+ )
1756
+ ),
1757
+ kind: z2.optional(z2.nullable(contractName)),
1758
+ contract_version: z2.optional(z2.nullable(z2.int().check(z2.gte(1)))),
1759
+ contract_hash: z2.optional(z2.nullable(z2.string().check(z2.maxLength(64)))),
1760
+ extra: z2.optional(
1761
+ z2.nullable(
1762
+ z2.array(
1763
+ z2.strictObject({
1764
+ key: z2.string().check(z2.maxLength(64)),
1765
+ label: z2.string().check(z2.maxLength(200)),
1766
+ value: jsonValueSchema
1767
+ })
1768
+ ).check(z2.maxLength(20))
1769
+ )
1770
+ ),
1771
+ contract_violations: z2.optional(
1772
+ z2.nullable(z2.array(contractViolationSchema).check(z2.maxLength(MAX_CONTRACT_VIOLATIONS)))
1773
+ )
1774
+ }),
1775
+ page: z2.strictObject({
1776
+ path: z2.string()
1777
+ })
1778
+ });
1779
+ var formSubmitConfigSchema = z2.strictObject({});
1780
+
1781
+ // ../tracking-core/src/ingest-typed.ts
1782
+ var clientSettings = /* @__PURE__ */ new WeakMap();
1783
+ function typedClientSettings(client) {
1784
+ return clientSettings.get(client) ?? {};
1785
+ }
1786
+
1787
+ // ../tracking-core/src/lead-forms/lead-forms.gen.ts
1788
+ import * as z3 from "zod/mini";
1715
1789
  var LEAD_FORM_REGISTRY_VERSION = 2;
1716
1790
  var LEAD_FORM_KINDS = ["booking", "quote", "contact", "consult", "callback"];
1717
1791
  var LEAD_FORM_ROLES = [
@@ -1751,28 +1825,28 @@ var LEAD_FORM_PRIMITIVES = [
1751
1825
  "number"
1752
1826
  ];
1753
1827
  var leadFormPrimitiveSchemas = /* @__PURE__ */ (() => ({
1754
- string: z2.string().check(z2.maxLength(120)),
1755
- text: z2.string().check(z2.maxLength(2e3)),
1756
- enum: z2.string().check(z2.regex(/^[a-z0-9-]{1,48}$/)),
1757
- multi_enum: z2.array(z2.string().check(z2.regex(/^[a-z0-9-]{1,48}$/))).check(z2.maxLength(10)),
1758
- bool: z2.boolean(),
1759
- date: z2.string().check(z2.regex(/^\d{4}-\d{2}-\d{2}$/)),
1760
- time_window: z2.strictObject({
1761
- start: z2.string().check(z2.regex(/^([01]\d|2[0-3]):[0-5]\d$/)),
1762
- end: z2.nullable(z2.string().check(z2.regex(/^([01]\d|2[0-3]):[0-5]\d$/))),
1763
- label: z2.optional(z2.string().check(z2.maxLength(60)))
1828
+ string: z3.string().check(z3.maxLength(120)),
1829
+ text: z3.string().check(z3.maxLength(2e3)),
1830
+ enum: z3.string().check(z3.regex(/^[a-z0-9-]{1,48}$/)),
1831
+ multi_enum: z3.array(z3.string().check(z3.regex(/^[a-z0-9-]{1,48}$/))).check(z3.maxLength(10)),
1832
+ bool: z3.boolean(),
1833
+ date: z3.string().check(z3.regex(/^\d{4}-\d{2}-\d{2}$/)),
1834
+ time_window: z3.strictObject({
1835
+ start: z3.string().check(z3.regex(/^([01]\d|2[0-3]):[0-5]\d$/)),
1836
+ end: z3.nullable(z3.string().check(z3.regex(/^([01]\d|2[0-3]):[0-5]\d$/))),
1837
+ label: z3.optional(z3.string().check(z3.maxLength(60)))
1764
1838
  }),
1765
- phone: z2.string().check(z2.regex(/^\+[1-9]\d{6,14}$/)),
1766
- email: z2.string().check(z2.maxLength(320), z2.regex(/^[^\s@]+@[^\s@]+$/)),
1767
- address: z2.strictObject({
1768
- line1: z2.string().check(z2.maxLength(120)),
1769
- line2: z2.optional(z2.string().check(z2.maxLength(120))),
1770
- city: z2.optional(z2.string().check(z2.maxLength(120))),
1771
- region: z2.optional(z2.string().check(z2.maxLength(120))),
1772
- postal_code: z2.optional(z2.string().check(z2.maxLength(120))),
1773
- country: z2.optional(z2.string().check(z2.maxLength(120)))
1839
+ phone: z3.string().check(z3.regex(/^\+[1-9]\d{6,14}$/)),
1840
+ email: z3.string().check(z3.maxLength(320), z3.regex(/^[^\s@]+@[^\s@]+$/)),
1841
+ address: z3.strictObject({
1842
+ line1: z3.string().check(z3.maxLength(120)),
1843
+ line2: z3.optional(z3.string().check(z3.maxLength(120))),
1844
+ city: z3.optional(z3.string().check(z3.maxLength(120))),
1845
+ region: z3.optional(z3.string().check(z3.maxLength(120))),
1846
+ postal_code: z3.optional(z3.string().check(z3.maxLength(120))),
1847
+ country: z3.optional(z3.string().check(z3.maxLength(120)))
1774
1848
  }),
1775
- number: z2.number()
1849
+ number: z3.number()
1776
1850
  }))();
1777
1851
  var LEAD_FORM_ROLE_SPECS = {
1778
1852
  given_name: { primitive: "string", smsLabel: "", contactIdentity: true },
@@ -1822,6 +1896,101 @@ var LEAD_FORM_ROLE_SPECS = {
1822
1896
  attribution: { primitive: "enum", smsLabel: "", uninteresting: true }
1823
1897
  };
1824
1898
 
1899
+ // ../tracking-core/src/lead-forms/submit.ts
1900
+ import { safeParse as safeParse2 } from "zod/mini";
1901
+ var KNOWN_ROLES = new Set(LEAD_FORM_ROLES);
1902
+ var ROLE_ORDER = new Map(LEAD_FORM_ROLES.map((role, index) => [role, index]));
1903
+ var ADD_ON = /^add_on:[a-z0-9_-]{1,48}$/;
1904
+ var CONTRACT_NAME = /^[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?$/;
1905
+ function judgeLeadForm(kind, formId, fields, contracts, settings) {
1906
+ const generated = contracts?.contracts[kind];
1907
+ const live = liveContract(settings.trackingConfig, kind);
1908
+ const violations = check(live === void 0 ? generated : fromLive(live), fields);
1909
+ const liveHash = live === void 0 ? void 0 : live?.contract_hash ?? null;
1910
+ if (contracts && (liveHash !== void 0 && (generated?.hash ?? null) !== liveHash || contracts.registryVersion !== LEAD_FORM_REGISTRY_VERSION)) {
1911
+ violations.push({ role: null, rule: "contract_behind" });
1912
+ }
1913
+ if (violations.length > 0 && (settings.debug || settings.environment === "development")) {
1914
+ const message = `[AranovaTracking] lead form "${formId}" (${kind}) breaks its contract: ${violations.map((v) => `${v.rule}${v.role ? ` (${v.role})` : ""}`).join(", ")}`;
1915
+ console.error(message);
1916
+ if (settings.debug) throw new Error(message);
1917
+ }
1918
+ return {
1919
+ violations,
1920
+ hash: liveHash === void 0 ? generated?.hash ?? null : liveHash
1921
+ };
1922
+ }
1923
+ function liveContract(ref, kind) {
1924
+ const leadForms = ref ? getTrackingConfigRuntime(ref).leadForms() : null;
1925
+ if (!leadForms) return void 0;
1926
+ return leadForms.contracts.find((c) => c.form_kind === kind) ?? null;
1927
+ }
1928
+ function fromLive(live) {
1929
+ if (!live) return void 0;
1930
+ return {
1931
+ requires: live.requires.map((r) => ({
1932
+ role: r.role,
1933
+ requiredWhen: r.required_when ? { role: r.required_when.role, anyOf: r.required_when.any_of } : null
1934
+ })),
1935
+ requiresAny: live.requires_any.map((g) => g.roles),
1936
+ // Deprecated keys still resolve: a cached form may send them (ADR-0024 §7).
1937
+ options: Object.fromEntries(live.options.map((o) => [o.role, o.options.map((x) => x.key)]))
1938
+ };
1939
+ }
1940
+ function check(contract, fields) {
1941
+ const answered = new Map(fields);
1942
+ const violations = [];
1943
+ for (const [role, value] of fields) {
1944
+ const primitive = primitiveOf(role);
1945
+ if (!primitive) {
1946
+ violations.push({ role: CONTRACT_NAME.test(role) ? role : null, rule: "unknown_role" });
1947
+ continue;
1948
+ }
1949
+ if (!safeParse2(leadFormPrimitiveSchemas[primitive], value).success) {
1950
+ violations.push({ role, rule: "invalid_value" });
1951
+ continue;
1952
+ }
1953
+ const allowed = contract?.options[role] ?? registryOptions(role);
1954
+ if (allowed?.length && optionKeys(value).some((key) => !allowed.includes(key))) {
1955
+ violations.push({ role, rule: "unknown_option" });
1956
+ }
1957
+ }
1958
+ for (const { role, requiredWhen } of contract?.requires ?? []) {
1959
+ const owing = requiredWhen === null || optionKeys(answered.get(requiredWhen.role)).some((key) => requiredWhen.anyOf.includes(key));
1960
+ if (owing && !answered.has(role)) violations.push({ role, rule: "missing_required" });
1961
+ }
1962
+ for (const group of contract?.requiresAny ?? []) {
1963
+ if (!group.some((role) => answered.has(role))) {
1964
+ violations.push({ role: group.join("|"), rule: "missing_any_of" });
1965
+ }
1966
+ }
1967
+ return violations;
1968
+ }
1969
+ function primitiveOf(role) {
1970
+ if (ADD_ON.test(role)) return "bool";
1971
+ return KNOWN_ROLES.has(role) ? LEAD_FORM_ROLE_SPECS[role].primitive : null;
1972
+ }
1973
+ function registryOptions(role) {
1974
+ const spec = KNOWN_ROLES.has(role) ? LEAD_FORM_ROLE_SPECS[role] : void 0;
1975
+ return spec && "options" in spec ? spec.options.map((o) => o.key) : void 0;
1976
+ }
1977
+ function optionKeys(value) {
1978
+ if (typeof value === "string") return [value];
1979
+ return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
1980
+ }
1981
+ function slotFields(dateTime) {
1982
+ const written = /^(\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2})(?::\d{2}(?:\.\d+)?)?$/.exec(dateTime);
1983
+ if (!written) {
1984
+ throw new TypeError(
1985
+ `slotFields needs the slot's wall time without an offset ("2026-10-13T09:30"), got "${dateTime}"`
1986
+ );
1987
+ }
1988
+ return { preferred_date: written[1], preferred_time: { start: written[2], end: null } };
1989
+ }
1990
+ function timeWindow(start, end, label) {
1991
+ return { start, end: end ?? null, ...label ? { label } : {} };
1992
+ }
1993
+
1825
1994
  // ../tracking-core/src/resources/http/errors.ts
1826
1995
  var AranovaApiError = class extends Error {
1827
1996
  constructor(message, options) {
@@ -1861,11 +2030,11 @@ async function apiRequest(config, method, path, body, extraHeaders) {
1861
2030
  try {
1862
2031
  const parsed = await response.json();
1863
2032
  if (parsed && typeof parsed === "object") {
1864
- const record3 = parsed;
1865
- if (typeof record3.detail === "string") detail = record3.detail;
1866
- if (typeof record3.code === "string") code = record3.code;
1867
- if (record3.context && typeof record3.context === "object") {
1868
- context = record3.context;
2033
+ const record4 = parsed;
2034
+ if (typeof record4.detail === "string") detail = record4.detail;
2035
+ if (typeof record4.code === "string") code = record4.code;
2036
+ if (record4.context && typeof record4.context === "object") {
2037
+ context = record4.context;
1869
2038
  }
1870
2039
  }
1871
2040
  } catch {
@@ -1919,7 +2088,7 @@ var DROP_OFF_KEYS = {
1919
2088
  waitForIt: "wait-for-it",
1920
2089
  dropOff: "drop-off"
1921
2090
  };
1922
- function formSubmitPayload(input, formSubmit, contractHash) {
2091
+ function formSubmitPayload(input, formSubmit, runtime) {
1923
2092
  const field = (role, name, type, label, value) => ({ name, type, label, value, role });
1924
2093
  const text = (value) => value?.trim() || void 0;
1925
2094
  const { vehicle, dropOff } = input;
@@ -1929,7 +2098,7 @@ function formSubmitPayload(input, formSubmit, contractHash) {
1929
2098
  // E.164 on the wire: it keys the customer and enhanced-conversion matching.
1930
2099
  field("phone", "phone", "tel", "Phone", toE164(input.phone) ?? input.phone),
1931
2100
  field("email", "email", "email", "Email", text(input.email)),
1932
- field("service", "service", "select", "Service", input.services),
2101
+ field("service", "service", "select", "Service", [...input.services]),
1933
2102
  field(
1934
2103
  "vehicle",
1935
2104
  "vehicle",
@@ -1954,6 +2123,14 @@ function formSubmitPayload(input, formSubmit, contractHash) {
1954
2123
  const reported = new Set(entries.map((item) => item.name));
1955
2124
  const fields = entries.filter((item) => item.value !== void 0);
1956
2125
  const extra = (formSubmit.extraFields ?? []).filter((item) => !reported.has(item.name));
2126
+ const settings = typedClientSettings(formSubmit.tracking);
2127
+ const { violations, hash } = judgeLeadForm(
2128
+ "booking",
2129
+ formSubmit.formId,
2130
+ fields.map((item) => [item.role, item.value]),
2131
+ formSubmit.contracts,
2132
+ { ...settings, trackingConfig: settings.trackingConfig ?? runtime?.ref }
2133
+ );
1957
2134
  return {
1958
2135
  form: {
1959
2136
  id: formSubmit.formId,
@@ -1961,7 +2138,8 @@ function formSubmitPayload(input, formSubmit, contractHash) {
1961
2138
  fields: [...fields, ...extra],
1962
2139
  kind: "booking",
1963
2140
  contract_version: LEAD_FORM_REGISTRY_VERSION,
1964
- ...contractHash ? { contract_hash: contractHash } : {}
2141
+ ...hash ? { contract_hash: hash } : {},
2142
+ ...violations.length > 0 ? { contract_violations: violations.slice(0, MAX_CONTRACT_VIOLATIONS) } : {}
1965
2143
  },
1966
2144
  page: { path: typeof window === "undefined" ? "/" : window.location.pathname }
1967
2145
  };
@@ -2060,10 +2238,9 @@ function createSalesBookingsClient(config, firing) {
2060
2238
  }
2061
2239
  if (formSubmit && !submittedForms.has(attemptKey)) {
2062
2240
  submittedForms.add(attemptKey);
2063
- const contract = runtime?.leadForms()?.contracts.find((c) => c.form_kind === "booking");
2064
2241
  formSubmit.tracking.trackEvent(
2065
2242
  "form_submit",
2066
- formSubmitPayload(input, formSubmit, contract?.contract_hash ?? null)
2243
+ formSubmitPayload(input, formSubmit, runtime)
2067
2244
  );
2068
2245
  }
2069
2246
  const body = {
@@ -2079,7 +2256,7 @@ function createSalesBookingsClient(config, firing) {
2079
2256
  email: input.email?.trim() || null,
2080
2257
  vehicle: input.vehicle ?? null,
2081
2258
  drop_off: input.dropOff ?? null,
2082
- services: input.services,
2259
+ services: [...input.services],
2083
2260
  notes: input.notes?.trim() || null,
2084
2261
  marketing_sms_consent: input.marketingSmsConsent === true,
2085
2262
  page_path: typeof window === "undefined" ? null : window.location.pathname
@@ -2166,7 +2343,7 @@ function fireRecordedConversions(firing, input, recorded, sale, currency) {
2166
2343
  }
2167
2344
  function createSalesClient(config) {
2168
2345
  if (config.firing) registerCapability("conversion_goals_manual");
2169
- async function record3(input) {
2346
+ async function record4(input) {
2170
2347
  const currency = input.currency ?? config.defaultCurrency;
2171
2348
  if (!currency) {
2172
2349
  throw new Error(
@@ -2192,9 +2369,9 @@ function createSalesClient(config) {
2192
2369
  return sale;
2193
2370
  }
2194
2371
  return {
2195
- record: record3,
2372
+ record: record4,
2196
2373
  // recordSale is the intent-revealing alias — same behavior, clearer call site.
2197
- recordSale: record3,
2374
+ recordSale: record4,
2198
2375
  trackConversion(key, options) {
2199
2376
  if (config.firing && "fireConversion" in config.firing) {
2200
2377
  if (options?.userData && getConsentState() !== "denied") stashUserData(options.userData);
@@ -2314,17 +2491,17 @@ function createSalesClient(config) {
2314
2491
  }
2315
2492
 
2316
2493
  // ../tracking-core/src/resources/sales/schema.ts
2317
- import * as z4 from "zod/mini";
2494
+ import * as z5 from "zod/mini";
2318
2495
 
2319
2496
  // ../tracking-core/src/resources/sales/generated/zod.gen.ts
2320
- import * as z3 from "zod/mini";
2321
- var zAutoLeapSaleFacts = z3.object({
2322
- first_order: z3.boolean(),
2323
- fleet_customer: z3.boolean(),
2324
- invoice_code: z3.string(),
2325
- invoice_id: z3.string()
2497
+ import * as z4 from "zod/mini";
2498
+ var zAutoLeapSaleFacts = z4.object({
2499
+ first_order: z4.boolean(),
2500
+ fleet_customer: z4.boolean(),
2501
+ invoice_code: z4.string(),
2502
+ invoice_id: z4.string()
2326
2503
  });
2327
- var zErrorCode = z3.enum([
2504
+ var zErrorCode = z4.enum([
2328
2505
  "missing_credentials",
2329
2506
  "invalid_api_key",
2330
2507
  "not_authenticated",
@@ -2368,37 +2545,37 @@ var zErrorCode = z3.enum([
2368
2545
  "rate_limited",
2369
2546
  "internal_error"
2370
2547
  ]);
2371
- var zSaleItemEntitySchema = z3.object({
2372
- category: z3.nullable(z3.string()),
2373
- external_item_id: z3.nullable(z3.string()),
2374
- id: z3.uuid(),
2375
- name: z3.nullable(z3.string()),
2376
- quantity: z3.string().check(z3.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
2377
- unit_cost_cents: z3.nullable(z3.int()),
2378
- unit_price_cents: z3.int()
2548
+ var zSaleItemEntitySchema = z4.object({
2549
+ category: z4.nullable(z4.string()),
2550
+ external_item_id: z4.nullable(z4.string()),
2551
+ id: z4.uuid(),
2552
+ name: z4.nullable(z4.string()),
2553
+ quantity: z4.string().check(z4.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
2554
+ unit_cost_cents: z4.nullable(z4.int()),
2555
+ unit_price_cents: z4.int()
2379
2556
  });
2380
- var zSaleItemInputSchema = z3.strictObject({
2381
- category: z3.nullish(z3.string()),
2382
- external_item_id: z3.nullish(z3.string()),
2383
- name: z3.nullish(z3.string()),
2384
- quantity: z3.string().check(z3.regex(/^\d+(\.\d{1,3})?$/)),
2385
- unit_cost_cents: z3.nullish(z3.int().check(z3.gte(0))),
2386
- unit_price_cents: z3.int().check(z3.gte(0))
2557
+ var zSaleItemInputSchema = z4.strictObject({
2558
+ category: z4.nullish(z4.string()),
2559
+ external_item_id: z4.nullish(z4.string()),
2560
+ name: z4.nullish(z4.string()),
2561
+ quantity: z4.string().check(z4.regex(/^\d+(\.\d{1,3})?$/)),
2562
+ unit_cost_cents: z4.nullish(z4.int().check(z4.gte(0))),
2563
+ unit_price_cents: z4.int().check(z4.gte(0))
2387
2564
  });
2388
- var zSaleServiceEntitySchema = z3.object({
2389
- amount_cents: z3.int(),
2390
- id: z3.uuid(),
2391
- mapped: z3.nullable(z3.boolean()),
2392
- service_id: z3.uuid(),
2393
- service_key: z3.string(),
2394
- service_label: z3.string()
2565
+ var zSaleServiceEntitySchema = z4.object({
2566
+ amount_cents: z4.int(),
2567
+ id: z4.uuid(),
2568
+ mapped: z4.nullable(z4.boolean()),
2569
+ service_id: z4.uuid(),
2570
+ service_key: z4.string(),
2571
+ service_label: z4.string()
2395
2572
  });
2396
- var zSaleServiceInputSchema = z3.strictObject({
2397
- amount_cents: z3.int().check(z3.gte(0)),
2398
- service: z3.string()
2573
+ var zSaleServiceInputSchema = z4.strictObject({
2574
+ amount_cents: z4.int().check(z4.gte(0)),
2575
+ service: z4.string()
2399
2576
  });
2400
- var zSaleSource = z3.enum(["api", "admin", "autoleap"]);
2401
- var zSmsAutomationState = z3.enum([
2577
+ var zSaleSource = z4.enum(["api", "admin", "autoleap"]);
2578
+ var zSmsAutomationState = z4.enum([
2402
2579
  "needs_check",
2403
2580
  "failed",
2404
2581
  "undelivered",
@@ -2410,7 +2587,7 @@ var zSmsAutomationState = z3.enum([
2410
2587
  "eligible",
2411
2588
  "not_applicable"
2412
2589
  ]);
2413
- var zSmsWithheldReason = z3.enum([
2590
+ var zSmsWithheldReason = z4.enum([
2414
2591
  "automation_disabled",
2415
2592
  "sms_disabled",
2416
2593
  "no_phone",
@@ -2436,77 +2613,79 @@ var zSmsWithheldReason = z3.enum([
2436
2613
  "confirmed_by_integration",
2437
2614
  "test_or_bot_session",
2438
2615
  "invalid_phone",
2439
- "recently_texted"
2616
+ "recently_texted",
2617
+ "do_not_contact",
2618
+ "do_not_text_tag"
2440
2619
  ]);
2441
- var zSaleSmsStatusSchema = z3.object({
2442
- can_send_now: z3._default(z3.boolean(), false),
2443
- last_message_at: z3.nullable(z3.iso.datetime({ offset: true })),
2444
- reason_detail: z3.nullable(z3.string()),
2620
+ var zSaleSmsStatusSchema = z4.object({
2621
+ can_send_now: z4._default(z4.boolean(), false),
2622
+ last_message_at: z4.nullable(z4.iso.datetime({ offset: true })),
2623
+ reason_detail: z4.nullable(z4.string()),
2445
2624
  state: zSmsAutomationState,
2446
- suppressed_by_other_sale: z3._default(z3.boolean(), false),
2447
- withheld_reason: z3.nullable(zSmsWithheldReason)
2625
+ suppressed_by_other_sale: z4._default(z4.boolean(), false),
2626
+ withheld_reason: z4.nullable(zSmsWithheldReason)
2448
2627
  });
2449
- var zSupportedCurrency = z3.enum(["USD", "CAD"]);
2450
- var zTrackingEnvironment = z3.enum(["production", "development"]);
2451
- var zSaleCreateSchema = z3.strictObject({
2452
- amount_total_cents: z3.nullish(z3.int().check(z3.gte(0))),
2628
+ var zSupportedCurrency = z4.enum(["USD", "CAD"]);
2629
+ var zTrackingEnvironment = z4.enum(["production", "development"]);
2630
+ var zSaleCreateSchema = z4.strictObject({
2631
+ amount_total_cents: z4.nullish(z4.int().check(z4.gte(0))),
2453
2632
  currency: zSupportedCurrency,
2454
- customer_email: z3.nullish(z3.email().check(z3.maxLength(320))),
2455
- customer_name: z3.nullish(z3.string().check(z3.maxLength(200))),
2456
- customer_phone: z3.nullish(z3.string().check(z3.maxLength(64))),
2457
- description: z3.nullish(z3.string()),
2458
- environment: z3._default(z3.optional(zTrackingEnvironment), "production"),
2459
- external_id: z3.nullish(z3.string()),
2460
- items: z3.optional(z3.array(zSaleItemInputSchema)),
2461
- metadata: z3.nullish(z3.record(z3.string(), z3.unknown())),
2462
- occurred_at: z3.iso.datetime({ offset: true }),
2463
- service: z3.nullish(z3.string()),
2464
- services: z3.nullish(z3.array(zSaleServiceInputSchema)),
2465
- sms_consent: z3.nullish(z3.boolean())
2633
+ customer_email: z4.nullish(z4.email().check(z4.maxLength(320))),
2634
+ customer_name: z4.nullish(z4.string().check(z4.maxLength(200))),
2635
+ customer_phone: z4.nullish(z4.string().check(z4.maxLength(64))),
2636
+ description: z4.nullish(z4.string()),
2637
+ environment: z4._default(z4.optional(zTrackingEnvironment), "production"),
2638
+ external_id: z4.nullish(z4.string()),
2639
+ items: z4.optional(z4.array(zSaleItemInputSchema)),
2640
+ metadata: z4.nullish(z4.record(z4.string(), z4.unknown())),
2641
+ occurred_at: z4.iso.datetime({ offset: true }),
2642
+ service: z4.nullish(z4.string()),
2643
+ services: z4.nullish(z4.array(zSaleServiceInputSchema)),
2644
+ sms_consent: z4.nullish(z4.boolean())
2466
2645
  });
2467
- var zValidationError = z3.object({
2468
- ctx: z3.optional(z3.record(z3.string(), z3.unknown())),
2469
- input: z3.optional(z3.unknown()),
2470
- loc: z3.array(z3.union([z3.string(), z3.int()])),
2471
- msg: z3.string(),
2472
- type: z3.string()
2646
+ var zValidationError = z4.object({
2647
+ ctx: z4.optional(z4.record(z4.string(), z4.unknown())),
2648
+ input: z4.optional(z4.unknown()),
2649
+ loc: z4.array(z4.union([z4.string(), z4.int()])),
2650
+ msg: z4.string(),
2651
+ type: z4.string()
2473
2652
  });
2474
- var zHttpValidationError = z3.object({
2475
- detail: z3.optional(z3.array(zValidationError))
2653
+ var zHttpValidationError = z4.object({
2654
+ detail: z4.optional(z4.array(zValidationError))
2476
2655
  });
2477
- var zValidationErrorItem = z3.object({
2478
- loc: z3.array(z3.union([z3.string(), z3.int()])),
2479
- msg: z3.string(),
2480
- type: z3.string()
2656
+ var zValidationErrorItem = z4.object({
2657
+ loc: z4.array(z4.union([z4.string(), z4.int()])),
2658
+ msg: z4.string(),
2659
+ type: z4.string()
2481
2660
  });
2482
- var zApiErrorSchema = z3.object({
2661
+ var zApiErrorSchema = z4.object({
2483
2662
  code: zErrorCode,
2484
- context: z3._default(z3.nullish(z3.record(z3.string(), z3.unknown())), null),
2485
- detail: z3.string(),
2486
- errors: z3._default(z3.nullish(z3.array(zValidationErrorItem)), null),
2487
- request_id: z3._default(z3.nullish(z3.string()), null)
2663
+ context: z4._default(z4.nullish(z4.record(z4.string(), z4.unknown())), null),
2664
+ detail: z4.string(),
2665
+ errors: z4._default(z4.nullish(z4.array(zValidationErrorItem)), null),
2666
+ request_id: z4._default(z4.nullish(z4.string()), null)
2488
2667
  });
2489
- var zWritebackEmailSource = z3.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
2490
- var zWritebackEnrichmentStatus = z3.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
2491
- var zWritebackSaleUploadCounts = z3.object({
2492
- failed: z3._default(z3.int(), 0),
2493
- pending: z3._default(z3.int(), 0),
2494
- skipped: z3._default(z3.int(), 0),
2495
- submitted: z3._default(z3.int(), 0),
2496
- total: z3._default(z3.int(), 0),
2497
- uploaded: z3._default(z3.int(), 0)
2668
+ var zWritebackEmailSource = z4.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
2669
+ var zWritebackEnrichmentStatus = z4.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
2670
+ var zWritebackSaleUploadCounts = z4.object({
2671
+ failed: z4._default(z4.int(), 0),
2672
+ pending: z4._default(z4.int(), 0),
2673
+ skipped: z4._default(z4.int(), 0),
2674
+ submitted: z4._default(z4.int(), 0),
2675
+ total: z4._default(z4.int(), 0),
2676
+ uploaded: z4._default(z4.int(), 0)
2498
2677
  });
2499
- var zSaleWritebackStatusSchema = z3.object({
2500
- blocked_reason: z3.nullable(z3.string()),
2501
- can_dispatch: z3._default(z3.boolean(), false),
2502
- email_source: z3.nullable(zWritebackEmailSource),
2503
- enrichment_status: z3.nullable(zWritebackEnrichmentStatus),
2504
- gclid_attached: z3._default(z3.boolean(), false),
2505
- identifiers_sent: z3.nullable(z3.string()),
2506
- mapped_service_ids: z3.array(z3.uuid()),
2507
- matched_submit_count: z3.nullable(z3.int()),
2508
- needs_force: z3._default(z3.boolean(), false),
2509
- rollup: z3.enum([
2678
+ var zSaleWritebackStatusSchema = z4.object({
2679
+ blocked_reason: z4.nullable(z4.string()),
2680
+ can_dispatch: z4._default(z4.boolean(), false),
2681
+ email_source: z4.nullable(zWritebackEmailSource),
2682
+ enrichment_status: z4.nullable(zWritebackEnrichmentStatus),
2683
+ gclid_attached: z4._default(z4.boolean(), false),
2684
+ identifiers_sent: z4.nullable(z4.string()),
2685
+ mapped_service_ids: z4.array(z4.uuid()),
2686
+ matched_submit_count: z4.nullable(z4.int()),
2687
+ needs_force: z4._default(z4.boolean(), false),
2688
+ rollup: z4.enum([
2510
2689
  "failed",
2511
2690
  "skipped",
2512
2691
  "pending",
@@ -2516,39 +2695,39 @@ var zSaleWritebackStatusSchema = z3.object({
2516
2695
  "out_of_window",
2517
2696
  "blocked"
2518
2697
  ]),
2519
- stale: z3._default(z3.boolean(), false),
2520
- uncovered_service_ids: z3.array(z3.uuid()),
2698
+ stale: z4._default(z4.boolean(), false),
2699
+ uncovered_service_ids: z4.array(z4.uuid()),
2521
2700
  uploads: zWritebackSaleUploadCounts
2522
2701
  });
2523
- var zSaleEntitySchema = z3.object({
2524
- amount_total_cents: z3.int(),
2525
- business_id: z3.uuid(),
2526
- business_name: z3.nullable(z3.string()),
2527
- created_at: z3.iso.datetime({ offset: true }),
2528
- currency: z3.string(),
2529
- customer_email: z3.nullable(z3.string()),
2530
- customer_name: z3.nullable(z3.string()),
2531
- customer_name_placeholder_confirmed: z3._default(z3.boolean(), false),
2532
- customer_name_placeholder_confirmed_at: z3.nullable(z3.iso.datetime({ offset: true })),
2533
- customer_phone: z3.nullable(z3.string()),
2534
- description: z3.nullable(z3.string()),
2702
+ var zSaleEntitySchema = z4.object({
2703
+ amount_total_cents: z4.int(),
2704
+ business_id: z4.uuid(),
2705
+ business_name: z4.nullable(z4.string()),
2706
+ created_at: z4.iso.datetime({ offset: true }),
2707
+ currency: z4.string(),
2708
+ customer_email: z4.nullable(z4.string()),
2709
+ customer_name: z4.nullable(z4.string()),
2710
+ customer_name_placeholder_confirmed: z4._default(z4.boolean(), false),
2711
+ customer_name_placeholder_confirmed_at: z4.nullable(z4.iso.datetime({ offset: true })),
2712
+ customer_phone: z4.nullable(z4.string()),
2713
+ description: z4.nullable(z4.string()),
2535
2714
  environment: zTrackingEnvironment,
2536
- external_id: z3.nullable(z3.string()),
2537
- id: z3.uuid(),
2538
- items: z3.array(zSaleItemEntitySchema),
2539
- metadata: z3.nullable(z3.record(z3.string(), z3.unknown())),
2540
- occurred_at: z3.iso.datetime({ offset: true }),
2541
- service_id: z3.nullable(z3.uuid()),
2542
- service_key: z3.nullable(z3.string()),
2543
- service_label: z3.nullable(z3.string()),
2544
- services: z3.array(zSaleServiceEntitySchema),
2545
- sms_automation: z3.nullable(zSaleSmsStatusSchema),
2546
- sms_consent: z3._default(z3.boolean(), false),
2547
- sms_consent_granted_at: z3.nullable(z3.iso.datetime({ offset: true })),
2715
+ external_id: z4.nullable(z4.string()),
2716
+ id: z4.uuid(),
2717
+ items: z4.array(zSaleItemEntitySchema),
2718
+ metadata: z4.nullable(z4.record(z4.string(), z4.unknown())),
2719
+ occurred_at: z4.iso.datetime({ offset: true }),
2720
+ service_id: z4.nullable(z4.uuid()),
2721
+ service_key: z4.nullable(z4.string()),
2722
+ service_label: z4.nullable(z4.string()),
2723
+ services: z4.array(zSaleServiceEntitySchema),
2724
+ sms_automation: z4.nullable(zSaleSmsStatusSchema),
2725
+ sms_consent: z4._default(z4.boolean(), false),
2726
+ sms_consent_granted_at: z4.nullable(z4.iso.datetime({ offset: true })),
2548
2727
  source: zSaleSource,
2549
- source_facts: z3.nullable(zAutoLeapSaleFacts),
2550
- updated_at: z3.iso.datetime({ offset: true }),
2551
- writeback: z3.nullable(zSaleWritebackStatusSchema)
2728
+ source_facts: z4.nullable(zAutoLeapSaleFacts),
2729
+ updated_at: z4.iso.datetime({ offset: true }),
2730
+ writeback: z4.nullable(zSaleWritebackStatusSchema)
2552
2731
  });
2553
2732
 
2554
2733
  // ../tracking-core/src/resources/sales/schema.ts
@@ -2557,11 +2736,11 @@ var saleServiceSchema = zSaleServiceInputSchema;
2557
2736
  var currencySchema = zSupportedCurrency;
2558
2737
  var SUPPORTED_CURRENCIES = currencySchema.options;
2559
2738
  var SALE_SOURCES = zSaleSource.options;
2560
- var centsSchema = z4.int().check(z4.gte(0));
2561
- var metadataSchema = z4.record(z4.string(), z4.unknown());
2562
- var customerNameSchema = z4.string().check(z4.maxLength(200));
2563
- var customerPhoneSchema = z4.string().check(z4.maxLength(64));
2564
- var customerEmailSchema = z4.email().check(z4.maxLength(320));
2739
+ var centsSchema = z5.int().check(z5.gte(0));
2740
+ var metadataSchema = z5.record(z5.string(), z5.unknown());
2741
+ var customerNameSchema = z5.string().check(z5.maxLength(200));
2742
+ var customerPhoneSchema = z5.string().check(z5.maxLength(64));
2743
+ var customerEmailSchema = z5.email().check(z5.maxLength(320));
2565
2744
  function addIssue(ctx, path, message) {
2566
2745
  ctx.issues.push({ code: "custom", input: ctx.value, path, message });
2567
2746
  }
@@ -2595,24 +2774,24 @@ function refineServiceXor(val, ctx, { requireAmount }) {
2595
2774
  );
2596
2775
  }
2597
2776
  }
2598
- var saleCreateSchema = z4.extend(zSaleCreateSchema, { items: z4._default(z4.array(saleItemSchema), []) }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: true }));
2599
- var saleUpdateSchema = z4.strictObject({
2600
- description: z4.nullish(z4.string()),
2601
- service: z4.nullish(z4.string()),
2602
- services: z4.nullish(z4.array(saleServiceSchema)),
2603
- currency: z4.optional(currencySchema),
2604
- amount_total_cents: z4.optional(centsSchema),
2605
- occurred_at: z4.optional(z4.iso.datetime()),
2606
- items: z4.optional(z4.array(saleItemSchema)),
2607
- metadata: z4.nullish(metadataSchema),
2608
- customer_name: z4.nullish(customerNameSchema),
2777
+ var saleCreateSchema = z5.extend(zSaleCreateSchema, { items: z5._default(z5.array(saleItemSchema), []) }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: true }));
2778
+ var saleUpdateSchema = z5.strictObject({
2779
+ description: z5.nullish(z5.string()),
2780
+ service: z5.nullish(z5.string()),
2781
+ services: z5.nullish(z5.array(saleServiceSchema)),
2782
+ currency: z5.optional(currencySchema),
2783
+ amount_total_cents: z5.optional(centsSchema),
2784
+ occurred_at: z5.optional(z5.iso.datetime()),
2785
+ items: z5.optional(z5.array(saleItemSchema)),
2786
+ metadata: z5.nullish(metadataSchema),
2787
+ customer_name: z5.nullish(customerNameSchema),
2609
2788
  // Re-attest when changing a filler-looking name; the server clears the
2610
2789
  // prior attestation whenever `customer_name` changes.
2611
- customer_name_placeholder_confirmed: z4.optional(z4.boolean()),
2612
- customer_phone: z4.nullish(customerPhoneSchema),
2613
- customer_email: z4.nullish(customerEmailSchema),
2790
+ customer_name_placeholder_confirmed: z5.optional(z5.boolean()),
2791
+ customer_phone: z5.nullish(customerPhoneSchema),
2792
+ customer_email: z5.nullish(customerEmailSchema),
2614
2793
  // NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
2615
- sms_consent: z4.optional(z4.boolean())
2794
+ sms_consent: z5.optional(z5.boolean())
2616
2795
  }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: false }));
2617
2796
  var TRACKING_RANGES = ["24h", "7d", "30d"];
2618
2797
  var NAMED_RANGES = [
@@ -2635,8 +2814,8 @@ async function fetchServices(config) {
2635
2814
  }
2636
2815
 
2637
2816
  // ../tracking-core/src/phone-field.ts
2638
- function phoneField(name, raw, country) {
2639
- return { name, type: "phone", value: toE164(raw, country) };
2817
+ function phoneField(name, raw, country, label = null) {
2818
+ return { name, type: "phone", label, value: toE164(raw, country) };
2640
2819
  }
2641
2820
 
2642
2821
  // src/index.ts
@@ -2652,6 +2831,7 @@ import {
2652
2831
  useBookingSlots,
2653
2832
  useBookingSubmit
2654
2833
  } from "@aranova/tracking-react/client";
2834
+ import { createLeadFormSubmit } from "@aranova/tracking-react/client";
2655
2835
  export {
2656
2836
  AdPlatformTracking,
2657
2837
  AranovaApiError,
@@ -2676,6 +2856,7 @@ export {
2676
2856
  buildBookingHandoffUrl,
2677
2857
  captureTrackingParamsFromLocation,
2678
2858
  clearStashedUserData,
2859
+ createLeadFormSubmit,
2679
2860
  createSalesClient,
2680
2861
  createTracking,
2681
2862
  createTrackingClientContext,
@@ -2711,7 +2892,9 @@ export {
2711
2892
  salesRequest,
2712
2893
  setConsentState,
2713
2894
  shopToday,
2895
+ slotFields,
2714
2896
  stashUserData,
2897
+ timeWindow,
2715
2898
  toE164,
2716
2899
  toMinor,
2717
2900
  useBookingHandoffUrl,