@aranova/tracking-react 1.11.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -820,9 +820,58 @@ function parseConversionConfig(raw) {
820
820
  };
821
821
  }
822
822
  function parseLeadForms(value) {
823
- if (!value || typeof value !== "object") return null;
824
- const version = value.registry_version;
825
- return typeof version === "number" ? { registry_version: version } : null;
823
+ if (!isRecord(value) || typeof value.registry_version !== "number") return null;
824
+ return {
825
+ registry_version: value.registry_version,
826
+ contracts: records(value.contracts).flatMap(
827
+ (c) => typeof c.form_kind === "string" && typeof c.contract_hash === "string" ? [
828
+ {
829
+ form_kind: c.form_kind,
830
+ requires: records(c.requires).flatMap(
831
+ (r) => typeof r.role === "string" ? [
832
+ {
833
+ role: r.role,
834
+ required_when: parseCondition(r.required_when),
835
+ waived: r.waived === true
836
+ }
837
+ ] : []
838
+ ),
839
+ requires_any: records(c.requires_any).map((g) => ({
840
+ roles: strings(g.roles),
841
+ waived: g.waived === true
842
+ })),
843
+ options: records(c.options).flatMap(
844
+ (o) => typeof o.role === "string" ? [{ role: o.role, options: records(o.options).flatMap(parseContractOption) }] : []
845
+ ),
846
+ contract_hash: c.contract_hash
847
+ }
848
+ ] : []
849
+ )
850
+ };
851
+ }
852
+ function parseCondition(value) {
853
+ if (!isRecord(value) || typeof value.role !== "string") return null;
854
+ return { role: value.role, any_of: strings(value.any_of) };
855
+ }
856
+ function parseContractOption(value) {
857
+ if (typeof value.key !== "string" || typeof value.label !== "string") return [];
858
+ return [
859
+ {
860
+ key: value.key,
861
+ label: value.label,
862
+ is_non_answer: value.is_non_answer === true,
863
+ deprecated: value.deprecated === true
864
+ }
865
+ ];
866
+ }
867
+ function isRecord(value) {
868
+ return !!value && typeof value === "object" && !Array.isArray(value);
869
+ }
870
+ function records(value) {
871
+ return Array.isArray(value) ? value.filter(isRecord) : [];
872
+ }
873
+ function strings(value) {
874
+ return Array.isArray(value) ? value.filter((v) => typeof v === "string") : [];
826
875
  }
827
876
  var CACHE_PREFIX = "_aranova_cfg_";
828
877
  function cacheKey(url) {
@@ -1275,6 +1324,10 @@ var TrackingConfigRuntime = class {
1275
1324
  integrations() {
1276
1325
  return this.current?.integrations ?? null;
1277
1326
  }
1327
+ /** The lead-form contracts, from the cached object like `integrations()`. */
1328
+ leadForms() {
1329
+ return this.current?.lead_forms ?? null;
1330
+ }
1278
1331
  async revalidateNow() {
1279
1332
  try {
1280
1333
  const headers = {};
@@ -1657,6 +1710,118 @@ var SDK_PACKAGE_HEADER = "X-Aranova-Sdk-Package";
1657
1710
  var SDK_SURFACE_HEADER = "X-Aranova-Sdk-Surface";
1658
1711
  var SDK_ENVIRONMENT_HEADER = "X-Aranova-Sdk-Environment";
1659
1712
 
1713
+ // ../tracking-core/src/lead-forms/lead-forms.gen.ts
1714
+ import * as z2 from "zod/mini";
1715
+ var LEAD_FORM_REGISTRY_VERSION = 2;
1716
+ var LEAD_FORM_KINDS = ["booking", "quote", "contact", "consult", "callback"];
1717
+ var LEAD_FORM_ROLES = [
1718
+ "given_name",
1719
+ "family_name",
1720
+ "phone",
1721
+ "email",
1722
+ "service",
1723
+ "preferred_date",
1724
+ "preferred_time",
1725
+ "note",
1726
+ "visit",
1727
+ "intent",
1728
+ "vehicle",
1729
+ "drop_off",
1730
+ "address",
1731
+ "patient_type",
1732
+ "matter",
1733
+ "language",
1734
+ "products",
1735
+ "goal",
1736
+ "business_type",
1737
+ "lead_volume",
1738
+ "attribution"
1739
+ ];
1740
+ var LEAD_FORM_PRIMITIVES = [
1741
+ "string",
1742
+ "text",
1743
+ "enum",
1744
+ "multi_enum",
1745
+ "bool",
1746
+ "date",
1747
+ "time_window",
1748
+ "phone",
1749
+ "email",
1750
+ "address",
1751
+ "number"
1752
+ ];
1753
+ 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)))
1764
+ }),
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)))
1774
+ }),
1775
+ number: z2.number()
1776
+ }))();
1777
+ var LEAD_FORM_ROLE_SPECS = {
1778
+ given_name: { primitive: "string", smsLabel: "", contactIdentity: true },
1779
+ family_name: { primitive: "string", smsLabel: "", contactIdentity: true },
1780
+ phone: { primitive: "phone", smsLabel: "", contactIdentity: true },
1781
+ email: { primitive: "email", smsLabel: "", contactIdentity: true },
1782
+ service: { primitive: "multi_enum", smsLabel: "Service" },
1783
+ preferred_date: { primitive: "date", smsLabel: "Date" },
1784
+ preferred_time: { primitive: "time_window", smsLabel: "Time" },
1785
+ note: { primitive: "text", smsLabel: "Note" },
1786
+ visit: {
1787
+ primitive: "enum",
1788
+ smsLabel: "Visit",
1789
+ options: [
1790
+ { key: "in-shop", label: "In shop" },
1791
+ { key: "in-home", label: "In home" },
1792
+ { key: "remote", label: "Remote" },
1793
+ { key: "on-site", label: "On site" }
1794
+ ]
1795
+ },
1796
+ intent: {
1797
+ primitive: "enum",
1798
+ smsLabel: "Wants",
1799
+ options: [
1800
+ { key: "book", label: "Book" },
1801
+ { key: "quote", label: "Quote" }
1802
+ ]
1803
+ },
1804
+ vehicle: { primitive: "string", smsLabel: "Vehicle" },
1805
+ drop_off: {
1806
+ primitive: "enum",
1807
+ smsLabel: "Drop-off",
1808
+ options: [
1809
+ { key: "wait-for-it", label: "Waiting" },
1810
+ { key: "drop-off", label: "Dropping off" }
1811
+ ]
1812
+ },
1813
+ address: { primitive: "address", smsLabel: "Address" },
1814
+ patient_type: { primitive: "enum", smsLabel: "Patient" },
1815
+ matter: { primitive: "enum", smsLabel: "Matter" },
1816
+ language: { primitive: "enum", smsLabel: "Language" },
1817
+ products: { primitive: "multi_enum", smsLabel: "Products" },
1818
+ goal: { primitive: "enum", smsLabel: "Goal" },
1819
+ business_type: { primitive: "enum", smsLabel: "Business" },
1820
+ lead_volume: { primitive: "enum", smsLabel: "Lead volume" },
1821
+ add_on: { primitive: "bool", smsLabel: "" },
1822
+ attribution: { primitive: "enum", smsLabel: "", uninteresting: true }
1823
+ };
1824
+
1660
1825
  // ../tracking-core/src/resources/http/errors.ts
1661
1826
  var AranovaApiError = class extends Error {
1662
1827
  constructor(message, options) {
@@ -1750,39 +1915,54 @@ function outcomeOf(body) {
1750
1915
  if (body.status === "pending") return { status: "pending", id: body.id, mode };
1751
1916
  return { status: "failed", id: body.id, fallbackUrl: body.fallback_url, mode };
1752
1917
  }
1753
- function formSubmitPayload(input, formSubmit, labels) {
1754
- const vehicle = input.vehicle ? `${input.vehicle.year} ${input.vehicle.make} ${input.vehicle.model}` : "";
1755
- const field = (name, type, label, value) => ({
1756
- name,
1757
- type,
1758
- label,
1759
- value
1760
- });
1761
- const fields = [
1762
- field("first_name", "text", "First name", input.firstName),
1763
- field("last_name", "text", "Last name", input.lastName),
1918
+ var DROP_OFF_KEYS = {
1919
+ waitForIt: "wait-for-it",
1920
+ dropOff: "drop-off"
1921
+ };
1922
+ function formSubmitPayload(input, formSubmit, contractHash) {
1923
+ const field = (role, name, type, label, value) => ({ name, type, label, value, role });
1924
+ const text = (value) => value?.trim() || void 0;
1925
+ const { vehicle, dropOff } = input;
1926
+ const entries = [
1927
+ field("given_name", "first_name", "text", "First name", text(input.firstName)),
1928
+ field("family_name", "last_name", "text", "Last name", text(input.lastName)),
1764
1929
  // E.164 on the wire: it keys the customer and enhanced-conversion matching.
1765
- field("phone", "tel", "Phone", toE164(input.phone) ?? input.phone),
1766
- field("email", "email", "Email", input.email ?? ""),
1930
+ field("phone", "phone", "tel", "Phone", toE164(input.phone) ?? input.phone),
1931
+ field("email", "email", "email", "Email", text(input.email)),
1932
+ field("service", "service", "select", "Service", input.services),
1767
1933
  field(
1768
- "service",
1769
- "select",
1770
- "Service",
1771
- input.services.map((key) => labels.get(key) ?? key).join(", ")
1934
+ "vehicle",
1935
+ "vehicle",
1936
+ "text",
1937
+ "Vehicle",
1938
+ vehicle ? `${vehicle.year} ${vehicle.make} ${vehicle.model}` : void 0
1772
1939
  ),
1773
- field("vehicle", "text", "Vehicle", vehicle),
1774
1940
  field(
1775
- "start",
1776
- "text",
1777
- "Requested time",
1778
- `${input.startDate} ${String(input.startHour).padStart(2, "0")}:00`
1941
+ "drop_off",
1942
+ "drop_off",
1943
+ "select",
1944
+ "Drop-off",
1945
+ dropOff ? DROP_OFF_KEYS[dropOff] : void 0
1779
1946
  ),
1780
- field("note", "textarea", "Notes", input.notes ?? "")
1947
+ field("preferred_date", "preferred_date", "date", "Date", input.startDate),
1948
+ field("preferred_time", "preferred_time", "time", "Time", {
1949
+ start: `${String(input.startHour).padStart(2, "0")}:00`,
1950
+ end: null
1951
+ }),
1952
+ field("note", "note", "textarea", "Notes", text(input.notes))
1781
1953
  ];
1782
- const reported = new Set(fields.map((item) => item.name));
1954
+ const reported = new Set(entries.map((item) => item.name));
1955
+ const fields = entries.filter((item) => item.value !== void 0);
1783
1956
  const extra = (formSubmit.extraFields ?? []).filter((item) => !reported.has(item.name));
1784
1957
  return {
1785
- form: { id: formSubmit.formId, action: "/tracking/bookings", fields: [...fields, ...extra] },
1958
+ form: {
1959
+ id: formSubmit.formId,
1960
+ action: "/tracking/bookings",
1961
+ fields: [...fields, ...extra],
1962
+ kind: "booking",
1963
+ contract_version: LEAD_FORM_REGISTRY_VERSION,
1964
+ ...contractHash ? { contract_hash: contractHash } : {}
1965
+ },
1786
1966
  page: { path: typeof window === "undefined" ? "/" : window.location.pathname }
1787
1967
  };
1788
1968
  }
@@ -1880,8 +2060,11 @@ function createSalesBookingsClient(config, firing) {
1880
2060
  }
1881
2061
  if (formSubmit && !submittedForms.has(attemptKey)) {
1882
2062
  submittedForms.add(attemptKey);
1883
- const labels = new Map(booking.options.map((option) => [option.key, option.label]));
1884
- formSubmit.tracking.trackEvent("form_submit", formSubmitPayload(input, formSubmit, labels));
2063
+ const contract = runtime?.leadForms()?.contracts.find((c) => c.form_kind === "booking");
2064
+ formSubmit.tracking.trackEvent(
2065
+ "form_submit",
2066
+ formSubmitPayload(input, formSubmit, contract?.contract_hash ?? null)
2067
+ );
1885
2068
  }
1886
2069
  const body = {
1887
2070
  idempotency_key: attemptKey,
@@ -2131,17 +2314,17 @@ function createSalesClient(config) {
2131
2314
  }
2132
2315
 
2133
2316
  // ../tracking-core/src/resources/sales/schema.ts
2134
- import * as z3 from "zod/mini";
2317
+ import * as z4 from "zod/mini";
2135
2318
 
2136
2319
  // ../tracking-core/src/resources/sales/generated/zod.gen.ts
2137
- import * as z2 from "zod/mini";
2138
- var zAutoLeapSaleFacts = z2.object({
2139
- first_order: z2.boolean(),
2140
- fleet_customer: z2.boolean(),
2141
- invoice_code: z2.string(),
2142
- invoice_id: z2.string()
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()
2143
2326
  });
2144
- var zErrorCode = z2.enum([
2327
+ var zErrorCode = z3.enum([
2145
2328
  "missing_credentials",
2146
2329
  "invalid_api_key",
2147
2330
  "not_authenticated",
@@ -2185,37 +2368,37 @@ var zErrorCode = z2.enum([
2185
2368
  "rate_limited",
2186
2369
  "internal_error"
2187
2370
  ]);
2188
- var zSaleItemEntitySchema = z2.object({
2189
- category: z2.nullable(z2.string()),
2190
- external_item_id: z2.nullable(z2.string()),
2191
- id: z2.uuid(),
2192
- name: z2.nullable(z2.string()),
2193
- quantity: z2.string().check(z2.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
2194
- unit_cost_cents: z2.nullable(z2.int()),
2195
- unit_price_cents: z2.int()
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()
2196
2379
  });
2197
- var zSaleItemInputSchema = z2.strictObject({
2198
- category: z2.nullish(z2.string()),
2199
- external_item_id: z2.nullish(z2.string()),
2200
- name: z2.nullish(z2.string()),
2201
- quantity: z2.string().check(z2.regex(/^\d+(\.\d{1,3})?$/)),
2202
- unit_cost_cents: z2.nullish(z2.int().check(z2.gte(0))),
2203
- unit_price_cents: z2.int().check(z2.gte(0))
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))
2204
2387
  });
2205
- var zSaleServiceEntitySchema = z2.object({
2206
- amount_cents: z2.int(),
2207
- id: z2.uuid(),
2208
- mapped: z2.nullable(z2.boolean()),
2209
- service_id: z2.uuid(),
2210
- service_key: z2.string(),
2211
- service_label: z2.string()
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()
2212
2395
  });
2213
- var zSaleServiceInputSchema = z2.strictObject({
2214
- amount_cents: z2.int().check(z2.gte(0)),
2215
- service: z2.string()
2396
+ var zSaleServiceInputSchema = z3.strictObject({
2397
+ amount_cents: z3.int().check(z3.gte(0)),
2398
+ service: z3.string()
2216
2399
  });
2217
- var zSaleSource = z2.enum(["api", "admin", "autoleap"]);
2218
- var zSmsAutomationState = z2.enum([
2400
+ var zSaleSource = z3.enum(["api", "admin", "autoleap"]);
2401
+ var zSmsAutomationState = z3.enum([
2219
2402
  "needs_check",
2220
2403
  "failed",
2221
2404
  "undelivered",
@@ -2227,7 +2410,7 @@ var zSmsAutomationState = z2.enum([
2227
2410
  "eligible",
2228
2411
  "not_applicable"
2229
2412
  ]);
2230
- var zSmsWithheldReason = z2.enum([
2413
+ var zSmsWithheldReason = z3.enum([
2231
2414
  "automation_disabled",
2232
2415
  "sms_disabled",
2233
2416
  "no_phone",
@@ -2255,75 +2438,75 @@ var zSmsWithheldReason = z2.enum([
2255
2438
  "invalid_phone",
2256
2439
  "recently_texted"
2257
2440
  ]);
2258
- var zSaleSmsStatusSchema = z2.object({
2259
- can_send_now: z2._default(z2.boolean(), false),
2260
- last_message_at: z2.nullable(z2.iso.datetime({ offset: true })),
2261
- reason_detail: z2.nullable(z2.string()),
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()),
2262
2445
  state: zSmsAutomationState,
2263
- suppressed_by_other_sale: z2._default(z2.boolean(), false),
2264
- withheld_reason: z2.nullable(zSmsWithheldReason)
2446
+ suppressed_by_other_sale: z3._default(z3.boolean(), false),
2447
+ withheld_reason: z3.nullable(zSmsWithheldReason)
2265
2448
  });
2266
- var zSupportedCurrency = z2.enum(["USD", "CAD"]);
2267
- var zTrackingEnvironment = z2.enum(["production", "development"]);
2268
- var zSaleCreateSchema = z2.strictObject({
2269
- amount_total_cents: z2.nullish(z2.int().check(z2.gte(0))),
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))),
2270
2453
  currency: zSupportedCurrency,
2271
- customer_email: z2.nullish(z2.email().check(z2.maxLength(320))),
2272
- customer_name: z2.nullish(z2.string().check(z2.maxLength(200))),
2273
- customer_phone: z2.nullish(z2.string().check(z2.maxLength(64))),
2274
- description: z2.nullish(z2.string()),
2275
- environment: z2._default(z2.optional(zTrackingEnvironment), "production"),
2276
- external_id: z2.nullish(z2.string()),
2277
- items: z2.optional(z2.array(zSaleItemInputSchema)),
2278
- metadata: z2.nullish(z2.record(z2.string(), z2.unknown())),
2279
- occurred_at: z2.iso.datetime({ offset: true }),
2280
- service: z2.nullish(z2.string()),
2281
- services: z2.nullish(z2.array(zSaleServiceInputSchema)),
2282
- sms_consent: z2.nullish(z2.boolean())
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())
2283
2466
  });
2284
- var zValidationError = z2.object({
2285
- ctx: z2.optional(z2.record(z2.string(), z2.unknown())),
2286
- input: z2.optional(z2.unknown()),
2287
- loc: z2.array(z2.union([z2.string(), z2.int()])),
2288
- msg: z2.string(),
2289
- type: z2.string()
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()
2290
2473
  });
2291
- var zHttpValidationError = z2.object({
2292
- detail: z2.optional(z2.array(zValidationError))
2474
+ var zHttpValidationError = z3.object({
2475
+ detail: z3.optional(z3.array(zValidationError))
2293
2476
  });
2294
- var zValidationErrorItem = z2.object({
2295
- loc: z2.array(z2.union([z2.string(), z2.int()])),
2296
- msg: z2.string(),
2297
- type: z2.string()
2477
+ var zValidationErrorItem = z3.object({
2478
+ loc: z3.array(z3.union([z3.string(), z3.int()])),
2479
+ msg: z3.string(),
2480
+ type: z3.string()
2298
2481
  });
2299
- var zApiErrorSchema = z2.object({
2482
+ var zApiErrorSchema = z3.object({
2300
2483
  code: zErrorCode,
2301
- context: z2._default(z2.nullish(z2.record(z2.string(), z2.unknown())), null),
2302
- detail: z2.string(),
2303
- errors: z2._default(z2.nullish(z2.array(zValidationErrorItem)), null),
2304
- request_id: z2._default(z2.nullish(z2.string()), null)
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)
2305
2488
  });
2306
- var zWritebackEmailSource = z2.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
2307
- var zWritebackEnrichmentStatus = z2.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
2308
- var zWritebackSaleUploadCounts = z2.object({
2309
- failed: z2._default(z2.int(), 0),
2310
- pending: z2._default(z2.int(), 0),
2311
- skipped: z2._default(z2.int(), 0),
2312
- submitted: z2._default(z2.int(), 0),
2313
- total: z2._default(z2.int(), 0),
2314
- uploaded: z2._default(z2.int(), 0)
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)
2315
2498
  });
2316
- var zSaleWritebackStatusSchema = z2.object({
2317
- blocked_reason: z2.nullable(z2.string()),
2318
- can_dispatch: z2._default(z2.boolean(), false),
2319
- email_source: z2.nullable(zWritebackEmailSource),
2320
- enrichment_status: z2.nullable(zWritebackEnrichmentStatus),
2321
- gclid_attached: z2._default(z2.boolean(), false),
2322
- identifiers_sent: z2.nullable(z2.string()),
2323
- mapped_service_ids: z2.array(z2.uuid()),
2324
- matched_submit_count: z2.nullable(z2.int()),
2325
- needs_force: z2._default(z2.boolean(), false),
2326
- rollup: z2.enum([
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([
2327
2510
  "failed",
2328
2511
  "skipped",
2329
2512
  "pending",
@@ -2333,39 +2516,39 @@ var zSaleWritebackStatusSchema = z2.object({
2333
2516
  "out_of_window",
2334
2517
  "blocked"
2335
2518
  ]),
2336
- stale: z2._default(z2.boolean(), false),
2337
- uncovered_service_ids: z2.array(z2.uuid()),
2519
+ stale: z3._default(z3.boolean(), false),
2520
+ uncovered_service_ids: z3.array(z3.uuid()),
2338
2521
  uploads: zWritebackSaleUploadCounts
2339
2522
  });
2340
- var zSaleEntitySchema = z2.object({
2341
- amount_total_cents: z2.int(),
2342
- business_id: z2.uuid(),
2343
- business_name: z2.nullable(z2.string()),
2344
- created_at: z2.iso.datetime({ offset: true }),
2345
- currency: z2.string(),
2346
- customer_email: z2.nullable(z2.string()),
2347
- customer_name: z2.nullable(z2.string()),
2348
- customer_name_placeholder_confirmed: z2._default(z2.boolean(), false),
2349
- customer_name_placeholder_confirmed_at: z2.nullable(z2.iso.datetime({ offset: true })),
2350
- customer_phone: z2.nullable(z2.string()),
2351
- description: z2.nullable(z2.string()),
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()),
2352
2535
  environment: zTrackingEnvironment,
2353
- external_id: z2.nullable(z2.string()),
2354
- id: z2.uuid(),
2355
- items: z2.array(zSaleItemEntitySchema),
2356
- metadata: z2.nullable(z2.record(z2.string(), z2.unknown())),
2357
- occurred_at: z2.iso.datetime({ offset: true }),
2358
- service_id: z2.nullable(z2.uuid()),
2359
- service_key: z2.nullable(z2.string()),
2360
- service_label: z2.nullable(z2.string()),
2361
- services: z2.array(zSaleServiceEntitySchema),
2362
- sms_automation: z2.nullable(zSaleSmsStatusSchema),
2363
- sms_consent: z2._default(z2.boolean(), false),
2364
- sms_consent_granted_at: z2.nullable(z2.iso.datetime({ offset: true })),
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 })),
2365
2548
  source: zSaleSource,
2366
- source_facts: z2.nullable(zAutoLeapSaleFacts),
2367
- updated_at: z2.iso.datetime({ offset: true }),
2368
- writeback: z2.nullable(zSaleWritebackStatusSchema)
2549
+ source_facts: z3.nullable(zAutoLeapSaleFacts),
2550
+ updated_at: z3.iso.datetime({ offset: true }),
2551
+ writeback: z3.nullable(zSaleWritebackStatusSchema)
2369
2552
  });
2370
2553
 
2371
2554
  // ../tracking-core/src/resources/sales/schema.ts
@@ -2374,11 +2557,11 @@ var saleServiceSchema = zSaleServiceInputSchema;
2374
2557
  var currencySchema = zSupportedCurrency;
2375
2558
  var SUPPORTED_CURRENCIES = currencySchema.options;
2376
2559
  var SALE_SOURCES = zSaleSource.options;
2377
- var centsSchema = z3.int().check(z3.gte(0));
2378
- var metadataSchema = z3.record(z3.string(), z3.unknown());
2379
- var customerNameSchema = z3.string().check(z3.maxLength(200));
2380
- var customerPhoneSchema = z3.string().check(z3.maxLength(64));
2381
- var customerEmailSchema = z3.email().check(z3.maxLength(320));
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));
2382
2565
  function addIssue(ctx, path, message) {
2383
2566
  ctx.issues.push({ code: "custom", input: ctx.value, path, message });
2384
2567
  }
@@ -2412,24 +2595,24 @@ function refineServiceXor(val, ctx, { requireAmount }) {
2412
2595
  );
2413
2596
  }
2414
2597
  }
2415
- var saleCreateSchema = z3.extend(zSaleCreateSchema, { items: z3._default(z3.array(saleItemSchema), []) }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: true }));
2416
- var saleUpdateSchema = z3.strictObject({
2417
- description: z3.nullish(z3.string()),
2418
- service: z3.nullish(z3.string()),
2419
- services: z3.nullish(z3.array(saleServiceSchema)),
2420
- currency: z3.optional(currencySchema),
2421
- amount_total_cents: z3.optional(centsSchema),
2422
- occurred_at: z3.optional(z3.iso.datetime()),
2423
- items: z3.optional(z3.array(saleItemSchema)),
2424
- metadata: z3.nullish(metadataSchema),
2425
- customer_name: z3.nullish(customerNameSchema),
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),
2426
2609
  // Re-attest when changing a filler-looking name; the server clears the
2427
2610
  // prior attestation whenever `customer_name` changes.
2428
- customer_name_placeholder_confirmed: z3.optional(z3.boolean()),
2429
- customer_phone: z3.nullish(customerPhoneSchema),
2430
- customer_email: z3.nullish(customerEmailSchema),
2611
+ customer_name_placeholder_confirmed: z4.optional(z4.boolean()),
2612
+ customer_phone: z4.nullish(customerPhoneSchema),
2613
+ customer_email: z4.nullish(customerEmailSchema),
2431
2614
  // NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
2432
- sms_consent: z3.optional(z3.boolean())
2615
+ sms_consent: z4.optional(z4.boolean())
2433
2616
  }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: false }));
2434
2617
  var TRACKING_RANGES = ["24h", "7d", "30d"];
2435
2618
  var NAMED_RANGES = [
@@ -2456,118 +2639,6 @@ function phoneField(name, raw, country) {
2456
2639
  return { name, type: "phone", value: toE164(raw, country) };
2457
2640
  }
2458
2641
 
2459
- // ../tracking-core/src/lead-forms/lead-forms.gen.ts
2460
- import * as z4 from "zod/mini";
2461
- var LEAD_FORM_REGISTRY_VERSION = 1;
2462
- var LEAD_FORM_KINDS = ["booking", "quote", "contact", "consult", "callback"];
2463
- var LEAD_FORM_ROLES = [
2464
- "given_name",
2465
- "family_name",
2466
- "phone",
2467
- "email",
2468
- "service",
2469
- "preferred_date",
2470
- "preferred_time",
2471
- "note",
2472
- "visit",
2473
- "intent",
2474
- "vehicle",
2475
- "drop_off",
2476
- "address",
2477
- "patient_type",
2478
- "matter",
2479
- "language",
2480
- "products",
2481
- "goal",
2482
- "business_type",
2483
- "lead_volume",
2484
- "attribution"
2485
- ];
2486
- var LEAD_FORM_PRIMITIVES = [
2487
- "string",
2488
- "text",
2489
- "enum",
2490
- "multi_enum",
2491
- "bool",
2492
- "date",
2493
- "time_window",
2494
- "phone",
2495
- "email",
2496
- "address",
2497
- "number"
2498
- ];
2499
- var leadFormPrimitiveSchemas = {
2500
- string: z4.string().check(z4.maxLength(120)),
2501
- text: z4.string().check(z4.maxLength(2e3)),
2502
- enum: z4.string().check(z4.regex(/^[a-z0-9-]{1,48}$/)),
2503
- multi_enum: z4.array(z4.string().check(z4.regex(/^[a-z0-9-]{1,48}$/))).check(z4.maxLength(10)),
2504
- bool: z4.boolean(),
2505
- date: z4.string().check(z4.regex(/^\d{4}-\d{2}-\d{2}$/)),
2506
- time_window: z4.strictObject({
2507
- start: z4.string().check(z4.regex(/^([01]\d|2[0-3]):[0-5]\d$/)),
2508
- end: z4.nullable(z4.string().check(z4.regex(/^([01]\d|2[0-3]):[0-5]\d$/))),
2509
- label: z4.optional(z4.string().check(z4.maxLength(60)))
2510
- }),
2511
- phone: z4.string().check(z4.regex(/^\+[1-9]\d{6,14}$/)),
2512
- email: z4.string().check(z4.maxLength(320), z4.regex(/^[^\s@]+@[^\s@]+$/)),
2513
- address: z4.strictObject({
2514
- line1: z4.string().check(z4.maxLength(120)),
2515
- line2: z4.optional(z4.string().check(z4.maxLength(120))),
2516
- city: z4.optional(z4.string().check(z4.maxLength(120))),
2517
- region: z4.optional(z4.string().check(z4.maxLength(120))),
2518
- postal_code: z4.optional(z4.string().check(z4.maxLength(120))),
2519
- country: z4.optional(z4.string().check(z4.maxLength(120)))
2520
- }),
2521
- number: z4.number()
2522
- };
2523
- var LEAD_FORM_ROLE_SPECS = {
2524
- given_name: { primitive: "string", smsLabel: "", contactIdentity: true },
2525
- family_name: { primitive: "string", smsLabel: "", contactIdentity: true },
2526
- phone: { primitive: "phone", smsLabel: "", contactIdentity: true },
2527
- email: { primitive: "email", smsLabel: "", contactIdentity: true },
2528
- service: { primitive: "enum", smsLabel: "Service" },
2529
- preferred_date: { primitive: "date", smsLabel: "Date" },
2530
- preferred_time: { primitive: "time_window", smsLabel: "Time" },
2531
- note: { primitive: "text", smsLabel: "Note" },
2532
- visit: {
2533
- primitive: "enum",
2534
- smsLabel: "Visit",
2535
- options: [
2536
- { key: "in-shop", label: "In shop" },
2537
- { key: "in-home", label: "In home" },
2538
- { key: "remote", label: "Remote" },
2539
- { key: "on-site", label: "On site" }
2540
- ]
2541
- },
2542
- intent: {
2543
- primitive: "enum",
2544
- smsLabel: "Wants",
2545
- options: [
2546
- { key: "book", label: "Book" },
2547
- { key: "quote", label: "Quote" }
2548
- ]
2549
- },
2550
- vehicle: { primitive: "string", smsLabel: "Vehicle" },
2551
- drop_off: {
2552
- primitive: "enum",
2553
- smsLabel: "Drop-off",
2554
- options: [
2555
- { key: "wait-for-it", label: "Waiting" },
2556
- { key: "drop-off", label: "Dropping off" }
2557
- ]
2558
- },
2559
- address: { primitive: "address", smsLabel: "Address" },
2560
- patient_type: { primitive: "enum", smsLabel: "Patient" },
2561
- matter: { primitive: "enum", smsLabel: "Matter" },
2562
- language: { primitive: "enum", smsLabel: "Language" },
2563
- products: { primitive: "multi_enum", smsLabel: "Products" },
2564
- goal: { primitive: "enum", smsLabel: "Goal" },
2565
- business_type: { primitive: "enum", smsLabel: "Business" },
2566
- lead_volume: { primitive: "enum", smsLabel: "Lead volume" },
2567
- add_on: { primitive: "bool", smsLabel: "" },
2568
- attribution: { primitive: "enum", smsLabel: "", uninteresting: true }
2569
- };
2570
-
2571
2642
  // src/index.ts
2572
2643
  import {
2573
2644
  PhoneField,