@aranova/tracking-react 0.15.0 → 0.16.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/README.md +43 -0
- package/dist/index.d.mts +129 -5
- package/dist/index.d.ts +129 -5
- package/dist/index.js +252 -63
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +252 -63
- package/dist/index.mjs.map +1 -1
- package/dist/phone.js +88 -62
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +88 -62
- package/dist/phone.mjs.map +1 -1
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1285,6 +1285,7 @@ function createTrackingClient(config) {
|
|
|
1285
1285
|
return {
|
|
1286
1286
|
trackEvent,
|
|
1287
1287
|
flush,
|
|
1288
|
+
flushBeacon: flushOnUnload,
|
|
1288
1289
|
getSessionId: () => sessionId,
|
|
1289
1290
|
getVisitorId: () => visitorId,
|
|
1290
1291
|
destroy: () => {
|
|
@@ -1309,9 +1310,17 @@ var ctaClickMetadataSchema = z2.object({
|
|
|
1309
1310
|
path: z2.string()
|
|
1310
1311
|
}).strict(),
|
|
1311
1312
|
section: z2.string().nullable().optional(),
|
|
1312
|
-
destination_url: z2.string().nullable().optional()
|
|
1313
|
+
destination_url: z2.string().nullable().optional(),
|
|
1314
|
+
// Set by auto-capture (and available to manual callers): the link target
|
|
1315
|
+
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
1316
|
+
href: z2.string().nullable().optional(),
|
|
1317
|
+
element: z2.string().nullable().optional()
|
|
1318
|
+
}).strict();
|
|
1319
|
+
var ctaClickConfigSchema = z2.object({
|
|
1320
|
+
autoCapture: z2.object({
|
|
1321
|
+
selector: z2.string().optional()
|
|
1322
|
+
}).strict().optional()
|
|
1313
1323
|
}).strict();
|
|
1314
|
-
var ctaClickConfigSchema = z2.object({}).strict();
|
|
1315
1324
|
|
|
1316
1325
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
1317
1326
|
import { z as z3 } from "zod";
|
|
@@ -1387,31 +1396,44 @@ var multiPageSessionConfigSchema = z6.object({
|
|
|
1387
1396
|
pageThreshold: z6.number().int().min(2)
|
|
1388
1397
|
}).strict();
|
|
1389
1398
|
|
|
1390
|
-
// ../tracking-core/src/events/
|
|
1399
|
+
// ../tracking-core/src/events/page-exit.ts
|
|
1391
1400
|
import { z as z7 } from "zod";
|
|
1392
|
-
var
|
|
1393
|
-
|
|
1401
|
+
var pageExitMetadataSchema = z7.object({
|
|
1402
|
+
dwell_ms: z7.number().int().min(0),
|
|
1403
|
+
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
1404
|
+
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
1405
|
+
max_scroll_percent: z7.number().int().min(0).max(100).nullable(),
|
|
1394
1406
|
page: z7.object({
|
|
1395
1407
|
path: z7.string()
|
|
1396
|
-
}).strict()
|
|
1397
|
-
section: z7.string().nullable().optional()
|
|
1408
|
+
}).strict()
|
|
1398
1409
|
}).strict();
|
|
1399
|
-
var
|
|
1410
|
+
var pageExitConfigSchema = z7.object({}).strict();
|
|
1400
1411
|
|
|
1401
|
-
// ../tracking-core/src/events/
|
|
1412
|
+
// ../tracking-core/src/events/phone-click.ts
|
|
1402
1413
|
import { z as z8 } from "zod";
|
|
1403
|
-
var
|
|
1404
|
-
|
|
1414
|
+
var phoneClickMetadataSchema = z8.object({
|
|
1415
|
+
phone_number: z8.string(),
|
|
1405
1416
|
page: z8.object({
|
|
1406
1417
|
path: z8.string()
|
|
1418
|
+
}).strict(),
|
|
1419
|
+
section: z8.string().nullable().optional()
|
|
1420
|
+
}).strict();
|
|
1421
|
+
var phoneClickConfigSchema = z8.object({}).strict();
|
|
1422
|
+
|
|
1423
|
+
// ../tracking-core/src/events/scroll-depth.ts
|
|
1424
|
+
import { z as z9 } from "zod";
|
|
1425
|
+
var scrollDepthMetadataSchema = z9.object({
|
|
1426
|
+
depth_percent: z9.number().int().min(1).max(100),
|
|
1427
|
+
page: z9.object({
|
|
1428
|
+
path: z9.string()
|
|
1407
1429
|
}).strict()
|
|
1408
1430
|
}).strict();
|
|
1409
|
-
var scrollDepthConfigSchema =
|
|
1410
|
-
thresholds:
|
|
1431
|
+
var scrollDepthConfigSchema = z9.object({
|
|
1432
|
+
thresholds: z9.array(z9.number().int().min(1).max(100)).min(1)
|
|
1411
1433
|
}).strict();
|
|
1412
1434
|
|
|
1413
1435
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
1414
|
-
import { z as
|
|
1436
|
+
import { z as z10 } from "zod";
|
|
1415
1437
|
var SPECIFIC_PAGE_NAMES = [
|
|
1416
1438
|
"contact_page",
|
|
1417
1439
|
"about_page",
|
|
@@ -1422,18 +1444,18 @@ var SPECIFIC_PAGE_NAMES = [
|
|
|
1422
1444
|
"faq_page",
|
|
1423
1445
|
"testimonials_page"
|
|
1424
1446
|
];
|
|
1425
|
-
var specificPageNameSchema =
|
|
1426
|
-
var specificPageVisitMetadataSchema =
|
|
1447
|
+
var specificPageNameSchema = z10.enum(SPECIFIC_PAGE_NAMES);
|
|
1448
|
+
var specificPageVisitMetadataSchema = z10.object({
|
|
1427
1449
|
page_name: specificPageNameSchema,
|
|
1428
|
-
page:
|
|
1429
|
-
path:
|
|
1450
|
+
page: z10.object({
|
|
1451
|
+
path: z10.string()
|
|
1430
1452
|
}).strict()
|
|
1431
1453
|
}).strict();
|
|
1432
|
-
var specificPageVisitConfigSchema =
|
|
1433
|
-
pages:
|
|
1434
|
-
|
|
1454
|
+
var specificPageVisitConfigSchema = z10.object({
|
|
1455
|
+
pages: z10.array(
|
|
1456
|
+
z10.object({
|
|
1435
1457
|
name: specificPageNameSchema,
|
|
1436
|
-
pathPattern:
|
|
1458
|
+
pathPattern: z10.custom((value) => value instanceof RegExp, {
|
|
1437
1459
|
message: "pathPattern must be a RegExp"
|
|
1438
1460
|
})
|
|
1439
1461
|
}).strict()
|
|
@@ -1441,15 +1463,15 @@ var specificPageVisitConfigSchema = z9.object({
|
|
|
1441
1463
|
}).strict();
|
|
1442
1464
|
|
|
1443
1465
|
// ../tracking-core/src/events/time-on-site.ts
|
|
1444
|
-
import { z as
|
|
1445
|
-
var timeOnSiteMetadataSchema =
|
|
1446
|
-
duration_ms:
|
|
1447
|
-
page:
|
|
1448
|
-
path:
|
|
1466
|
+
import { z as z11 } from "zod";
|
|
1467
|
+
var timeOnSiteMetadataSchema = z11.object({
|
|
1468
|
+
duration_ms: z11.number().int().nonnegative(),
|
|
1469
|
+
page: z11.object({
|
|
1470
|
+
path: z11.string()
|
|
1449
1471
|
}).strict()
|
|
1450
1472
|
}).strict();
|
|
1451
|
-
var timeOnSiteConfigSchema =
|
|
1452
|
-
thresholdSeconds:
|
|
1473
|
+
var timeOnSiteConfigSchema = z11.object({
|
|
1474
|
+
thresholdSeconds: z11.number().int().positive()
|
|
1453
1475
|
}).strict();
|
|
1454
1476
|
|
|
1455
1477
|
// ../tracking-core/src/events/registry.ts
|
|
@@ -1491,6 +1513,11 @@ var EVENT_REGISTRY = {
|
|
|
1491
1513
|
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
1492
1514
|
configSchema: sdkHeartbeatConfigSchema
|
|
1493
1515
|
},
|
|
1516
|
+
page_exit: {
|
|
1517
|
+
kind: "automatic",
|
|
1518
|
+
metadataSchema: pageExitMetadataSchema,
|
|
1519
|
+
configSchema: pageExitConfigSchema
|
|
1520
|
+
},
|
|
1494
1521
|
// --- manual triggers ---
|
|
1495
1522
|
form_submit: {
|
|
1496
1523
|
kind: "manual",
|
|
@@ -1869,6 +1896,163 @@ function attachFormStart(client, config) {
|
|
|
1869
1896
|
};
|
|
1870
1897
|
}
|
|
1871
1898
|
|
|
1899
|
+
// ../tracking-core/src/triggers/page-exit.ts
|
|
1900
|
+
function attachPageExit(client) {
|
|
1901
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
1902
|
+
return () => {
|
|
1903
|
+
};
|
|
1904
|
+
}
|
|
1905
|
+
let currentPath2 = window.location.pathname;
|
|
1906
|
+
let activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1907
|
+
let accumulatedMs = 0;
|
|
1908
|
+
let maxScrollPercent = null;
|
|
1909
|
+
let rafId = null;
|
|
1910
|
+
function getScrollPercent() {
|
|
1911
|
+
const doc = document.documentElement;
|
|
1912
|
+
const scrollTop = window.scrollY || doc.scrollTop;
|
|
1913
|
+
const scrollHeight = doc.scrollHeight;
|
|
1914
|
+
const clientHeight = doc.clientHeight;
|
|
1915
|
+
if (scrollHeight <= clientHeight) return 100;
|
|
1916
|
+
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
1917
|
+
}
|
|
1918
|
+
function onScroll() {
|
|
1919
|
+
if (rafId !== null) return;
|
|
1920
|
+
rafId = requestAnimationFrame(() => {
|
|
1921
|
+
rafId = null;
|
|
1922
|
+
const percent = getScrollPercent();
|
|
1923
|
+
if (percent >= 1 && (maxScrollPercent === null || percent > maxScrollPercent)) {
|
|
1924
|
+
maxScrollPercent = Math.min(percent, 100);
|
|
1925
|
+
}
|
|
1926
|
+
});
|
|
1927
|
+
}
|
|
1928
|
+
function settledDwellMs() {
|
|
1929
|
+
let total = accumulatedMs;
|
|
1930
|
+
if (activeSince !== null) {
|
|
1931
|
+
total += Date.now() - activeSince;
|
|
1932
|
+
}
|
|
1933
|
+
return Math.max(0, Math.round(total));
|
|
1934
|
+
}
|
|
1935
|
+
function emitSegment(path, flush) {
|
|
1936
|
+
const dwell = settledDwellMs();
|
|
1937
|
+
if (dwell === 0) return;
|
|
1938
|
+
client.trackEvent({
|
|
1939
|
+
eventType: "page_exit",
|
|
1940
|
+
metadata: {
|
|
1941
|
+
dwell_ms: dwell,
|
|
1942
|
+
max_scroll_percent: maxScrollPercent,
|
|
1943
|
+
page: { path }
|
|
1944
|
+
},
|
|
1945
|
+
pageUrl: window.location.href,
|
|
1946
|
+
occurredAt: null
|
|
1947
|
+
});
|
|
1948
|
+
if (flush) {
|
|
1949
|
+
client.flushBeacon();
|
|
1950
|
+
}
|
|
1951
|
+
accumulatedMs = 0;
|
|
1952
|
+
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1953
|
+
}
|
|
1954
|
+
function onNavigate() {
|
|
1955
|
+
const newPath = window.location.pathname;
|
|
1956
|
+
if (newPath === currentPath2) return;
|
|
1957
|
+
emitSegment(currentPath2, false);
|
|
1958
|
+
currentPath2 = newPath;
|
|
1959
|
+
maxScrollPercent = null;
|
|
1960
|
+
accumulatedMs = 0;
|
|
1961
|
+
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1962
|
+
}
|
|
1963
|
+
function onVisibilityChange() {
|
|
1964
|
+
if (document.visibilityState === "hidden") {
|
|
1965
|
+
emitSegment(currentPath2, true);
|
|
1966
|
+
} else {
|
|
1967
|
+
activeSince = Date.now();
|
|
1968
|
+
}
|
|
1969
|
+
}
|
|
1970
|
+
function onPageHide() {
|
|
1971
|
+
emitSegment(currentPath2, true);
|
|
1972
|
+
}
|
|
1973
|
+
const originalPushState = history.pushState.bind(history);
|
|
1974
|
+
const originalReplaceState = history.replaceState.bind(history);
|
|
1975
|
+
function patchedPushState(...args) {
|
|
1976
|
+
originalPushState(...args);
|
|
1977
|
+
setTimeout(onNavigate, 0);
|
|
1978
|
+
}
|
|
1979
|
+
function patchedReplaceState(...args) {
|
|
1980
|
+
originalReplaceState(...args);
|
|
1981
|
+
setTimeout(onNavigate, 0);
|
|
1982
|
+
}
|
|
1983
|
+
history.pushState = patchedPushState;
|
|
1984
|
+
history.replaceState = patchedReplaceState;
|
|
1985
|
+
window.addEventListener("popstate", onNavigate);
|
|
1986
|
+
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1987
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
1988
|
+
window.addEventListener("pagehide", onPageHide);
|
|
1989
|
+
return () => {
|
|
1990
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
1991
|
+
history.pushState = originalPushState;
|
|
1992
|
+
history.replaceState = originalReplaceState;
|
|
1993
|
+
window.removeEventListener("popstate", onNavigate);
|
|
1994
|
+
window.removeEventListener("scroll", onScroll);
|
|
1995
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
1996
|
+
window.removeEventListener("pagehide", onPageHide);
|
|
1997
|
+
};
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
// ../tracking-core/src/triggers/cta-click-capture.ts
|
|
2001
|
+
var DEFAULT_CTA_SELECTOR = "[data-aranova-cta]";
|
|
2002
|
+
var CTA_NAME_MAX_LENGTH = 120;
|
|
2003
|
+
function describeElement(el) {
|
|
2004
|
+
const tag = el.tagName.toLowerCase();
|
|
2005
|
+
return el.id ? `${tag}#${el.id}` : tag;
|
|
2006
|
+
}
|
|
2007
|
+
function resolveCtaName(el) {
|
|
2008
|
+
const explicit = el.getAttribute("data-aranova-cta");
|
|
2009
|
+
if (explicit && explicit.trim().length > 0) return explicit.trim();
|
|
2010
|
+
const text = (el.textContent ?? "").trim().replace(/\s+/g, " ");
|
|
2011
|
+
if (text.length > 0) return text.slice(0, CTA_NAME_MAX_LENGTH);
|
|
2012
|
+
return describeElement(el);
|
|
2013
|
+
}
|
|
2014
|
+
function attachCtaClickCapture(client, config) {
|
|
2015
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
2016
|
+
return () => {
|
|
2017
|
+
};
|
|
2018
|
+
}
|
|
2019
|
+
const autoCapture = config.autoCapture;
|
|
2020
|
+
if (!autoCapture) {
|
|
2021
|
+
return () => {
|
|
2022
|
+
};
|
|
2023
|
+
}
|
|
2024
|
+
const selector = autoCapture.selector ?? DEFAULT_CTA_SELECTOR;
|
|
2025
|
+
function onClick(event) {
|
|
2026
|
+
const target = event.target;
|
|
2027
|
+
if (!(target instanceof Element)) return;
|
|
2028
|
+
let matched = null;
|
|
2029
|
+
try {
|
|
2030
|
+
matched = target.closest(selector);
|
|
2031
|
+
} catch {
|
|
2032
|
+
return;
|
|
2033
|
+
}
|
|
2034
|
+
if (matched === null) return;
|
|
2035
|
+
const href = matched instanceof HTMLAnchorElement ? matched.href || null : matched.getAttribute("href");
|
|
2036
|
+
client.trackEvent({
|
|
2037
|
+
eventType: "cta_click",
|
|
2038
|
+
metadata: {
|
|
2039
|
+
cta_name: resolveCtaName(matched),
|
|
2040
|
+
page: { path: window.location.pathname },
|
|
2041
|
+
section: matched.getAttribute("data-aranova-section"),
|
|
2042
|
+
destination_url: href,
|
|
2043
|
+
href,
|
|
2044
|
+
element: describeElement(matched)
|
|
2045
|
+
},
|
|
2046
|
+
pageUrl: window.location.href,
|
|
2047
|
+
occurredAt: null
|
|
2048
|
+
});
|
|
2049
|
+
}
|
|
2050
|
+
document.addEventListener("click", onClick, true);
|
|
2051
|
+
return () => {
|
|
2052
|
+
document.removeEventListener("click", onClick, true);
|
|
2053
|
+
};
|
|
2054
|
+
}
|
|
2055
|
+
|
|
1872
2056
|
// ../tracking-core/src/resources/sales/errors.ts
|
|
1873
2057
|
var AranovaApiError = class extends Error {
|
|
1874
2058
|
constructor(message, options) {
|
|
@@ -2075,42 +2259,42 @@ function createSalesClient(config) {
|
|
|
2075
2259
|
}
|
|
2076
2260
|
|
|
2077
2261
|
// ../tracking-core/src/resources/sales/schema.ts
|
|
2078
|
-
import { z as
|
|
2262
|
+
import { z as z12 } from "zod";
|
|
2079
2263
|
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
2080
2264
|
var TRACKING_ENVIRONMENTS = ["production", "development"];
|
|
2081
|
-
var currencySchema =
|
|
2082
|
-
var centsSchema =
|
|
2083
|
-
var quantitySchema =
|
|
2084
|
-
var metadataSchema =
|
|
2085
|
-
var saleItemSchema =
|
|
2086
|
-
external_item_id:
|
|
2087
|
-
name:
|
|
2088
|
-
category:
|
|
2265
|
+
var currencySchema = z12.enum(SUPPORTED_CURRENCIES);
|
|
2266
|
+
var centsSchema = z12.number().int().nonnegative();
|
|
2267
|
+
var quantitySchema = z12.string().regex(/^\d+(\.\d{1,3})?$/);
|
|
2268
|
+
var metadataSchema = z12.record(z12.unknown());
|
|
2269
|
+
var saleItemSchema = z12.object({
|
|
2270
|
+
external_item_id: z12.string().nullable().optional(),
|
|
2271
|
+
name: z12.string().nullable().optional(),
|
|
2272
|
+
category: z12.string().nullable().optional(),
|
|
2089
2273
|
quantity: quantitySchema,
|
|
2090
2274
|
unit_price_cents: centsSchema,
|
|
2091
2275
|
// Non-negativity validated on the wire — same contract as the other cents
|
|
2092
2276
|
// fields — and backstopped by the DB CHECK.
|
|
2093
2277
|
unit_cost_cents: centsSchema.nullable().optional()
|
|
2094
2278
|
}).strict();
|
|
2095
|
-
var saleServiceSchema =
|
|
2096
|
-
service:
|
|
2279
|
+
var saleServiceSchema = z12.object({
|
|
2280
|
+
service: z12.string(),
|
|
2097
2281
|
amount_cents: centsSchema
|
|
2098
2282
|
}).strict();
|
|
2099
|
-
var customerNameSchema =
|
|
2100
|
-
var customerPhoneSchema =
|
|
2101
|
-
var customerEmailSchema =
|
|
2283
|
+
var customerNameSchema = z12.string().max(200);
|
|
2284
|
+
var customerPhoneSchema = z12.string().max(64);
|
|
2285
|
+
var customerEmailSchema = z12.string().max(320).email();
|
|
2102
2286
|
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
2103
2287
|
if (val.services != null) {
|
|
2104
2288
|
if (val.service != null) {
|
|
2105
2289
|
ctx.addIssue({
|
|
2106
|
-
code:
|
|
2290
|
+
code: z12.ZodIssueCode.custom,
|
|
2107
2291
|
message: "pass either `service` or `services`, not both",
|
|
2108
2292
|
path: ["services"]
|
|
2109
2293
|
});
|
|
2110
2294
|
}
|
|
2111
2295
|
if (val.services.length === 0) {
|
|
2112
2296
|
ctx.addIssue({
|
|
2113
|
-
code:
|
|
2297
|
+
code: z12.ZodIssueCode.custom,
|
|
2114
2298
|
message: "`services` must not be empty",
|
|
2115
2299
|
path: ["services"]
|
|
2116
2300
|
});
|
|
@@ -2118,7 +2302,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
2118
2302
|
const keys = val.services.map((s) => s.service);
|
|
2119
2303
|
if (new Set(keys).size !== keys.length) {
|
|
2120
2304
|
ctx.addIssue({
|
|
2121
|
-
code:
|
|
2305
|
+
code: z12.ZodIssueCode.custom,
|
|
2122
2306
|
message: "`services` must not list the same service more than once",
|
|
2123
2307
|
path: ["services"]
|
|
2124
2308
|
});
|
|
@@ -2127,7 +2311,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
2127
2311
|
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
2128
2312
|
if (val.amount_total_cents !== sum) {
|
|
2129
2313
|
ctx.addIssue({
|
|
2130
|
-
code:
|
|
2314
|
+
code: z12.ZodIssueCode.custom,
|
|
2131
2315
|
message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
|
|
2132
2316
|
path: ["amount_total_cents"]
|
|
2133
2317
|
});
|
|
@@ -2135,37 +2319,37 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
2135
2319
|
}
|
|
2136
2320
|
} else if (requireAmount && val.amount_total_cents == null) {
|
|
2137
2321
|
ctx.addIssue({
|
|
2138
|
-
code:
|
|
2322
|
+
code: z12.ZodIssueCode.custom,
|
|
2139
2323
|
message: "amount_total_cents is required unless `services` is provided",
|
|
2140
2324
|
path: ["amount_total_cents"]
|
|
2141
2325
|
});
|
|
2142
2326
|
}
|
|
2143
2327
|
}
|
|
2144
|
-
var saleCreateSchema =
|
|
2145
|
-
external_id:
|
|
2146
|
-
description:
|
|
2147
|
-
service:
|
|
2148
|
-
services:
|
|
2328
|
+
var saleCreateSchema = z12.object({
|
|
2329
|
+
external_id: z12.string().nullable().optional(),
|
|
2330
|
+
description: z12.string().nullable().optional(),
|
|
2331
|
+
service: z12.string().nullable().optional(),
|
|
2332
|
+
services: z12.array(saleServiceSchema).nullable().optional(),
|
|
2149
2333
|
currency: currencySchema,
|
|
2150
2334
|
// Optional only because the plural `services` form derives it from the sum
|
|
2151
2335
|
// (see refineServiceXor); the singular/serviceless path still requires it.
|
|
2152
2336
|
amount_total_cents: centsSchema.nullable().optional(),
|
|
2153
|
-
occurred_at:
|
|
2154
|
-
environment:
|
|
2155
|
-
items:
|
|
2337
|
+
occurred_at: z12.string().datetime(),
|
|
2338
|
+
environment: z12.enum(TRACKING_ENVIRONMENTS).default("production"),
|
|
2339
|
+
items: z12.array(saleItemSchema).default([]),
|
|
2156
2340
|
metadata: metadataSchema.nullable().optional(),
|
|
2157
2341
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2158
2342
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2159
2343
|
customer_email: customerEmailSchema.nullable().optional()
|
|
2160
2344
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
2161
|
-
var saleUpdateSchema =
|
|
2162
|
-
description:
|
|
2163
|
-
service:
|
|
2164
|
-
services:
|
|
2345
|
+
var saleUpdateSchema = z12.object({
|
|
2346
|
+
description: z12.string().nullable().optional(),
|
|
2347
|
+
service: z12.string().nullable().optional(),
|
|
2348
|
+
services: z12.array(saleServiceSchema).nullable().optional(),
|
|
2165
2349
|
currency: currencySchema.optional(),
|
|
2166
2350
|
amount_total_cents: centsSchema.optional(),
|
|
2167
|
-
occurred_at:
|
|
2168
|
-
items:
|
|
2351
|
+
occurred_at: z12.string().datetime().optional(),
|
|
2352
|
+
items: z12.array(saleItemSchema).optional(),
|
|
2169
2353
|
metadata: metadataSchema.nullable().optional(),
|
|
2170
2354
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2171
2355
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
@@ -2553,7 +2737,7 @@ function GoogleAdsTracking(props) {
|
|
|
2553
2737
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo4 } from "react";
|
|
2554
2738
|
|
|
2555
2739
|
// package.json
|
|
2556
|
-
var version = "0.
|
|
2740
|
+
var version = "0.16.0";
|
|
2557
2741
|
|
|
2558
2742
|
// ../tracking-core/src/phone-react.tsx
|
|
2559
2743
|
import {
|
|
@@ -2741,6 +2925,7 @@ function createTracking(options) {
|
|
|
2741
2925
|
const detectorClient = conversionStore ? withConversionAutoFire(rawClient, createConversionAutoFire(conversionStore)) : rawClient;
|
|
2742
2926
|
detachers.push(attachAutoPageView(detectorClient));
|
|
2743
2927
|
detachers.push(attachBfcacheRestore(detectorClient));
|
|
2928
|
+
detachers.push(attachPageExit(detectorClient));
|
|
2744
2929
|
const timeOnSite = triggers.automatic.time_on_site;
|
|
2745
2930
|
if (timeOnSite) {
|
|
2746
2931
|
detachers.push(attachTimeOnSite(detectorClient, timeOnSite));
|
|
@@ -2761,6 +2946,10 @@ function createTracking(options) {
|
|
|
2761
2946
|
if (formStart) {
|
|
2762
2947
|
detachers.push(attachFormStart(detectorClient, formStart));
|
|
2763
2948
|
}
|
|
2949
|
+
const ctaClick = triggers.manual?.cta_click;
|
|
2950
|
+
if (ctaClick) {
|
|
2951
|
+
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
2952
|
+
}
|
|
2764
2953
|
return () => {
|
|
2765
2954
|
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
2766
2955
|
detachers[i]();
|