@aranova/tracking-next 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/middleware.js +88 -62
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +88 -62
- package/dist/middleware.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/dist/server.js +88 -62
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +88 -62
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1191,6 +1191,7 @@ function createTrackingClient(config) {
|
|
|
1191
1191
|
return {
|
|
1192
1192
|
trackEvent,
|
|
1193
1193
|
flush,
|
|
1194
|
+
flushBeacon: flushOnUnload,
|
|
1194
1195
|
getSessionId: () => sessionId,
|
|
1195
1196
|
getVisitorId: () => visitorId,
|
|
1196
1197
|
destroy: () => {
|
|
@@ -1215,9 +1216,17 @@ var ctaClickMetadataSchema = z2.object({
|
|
|
1215
1216
|
path: z2.string()
|
|
1216
1217
|
}).strict(),
|
|
1217
1218
|
section: z2.string().nullable().optional(),
|
|
1218
|
-
destination_url: z2.string().nullable().optional()
|
|
1219
|
+
destination_url: z2.string().nullable().optional(),
|
|
1220
|
+
// Set by auto-capture (and available to manual callers): the link target
|
|
1221
|
+
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
1222
|
+
href: z2.string().nullable().optional(),
|
|
1223
|
+
element: z2.string().nullable().optional()
|
|
1224
|
+
}).strict();
|
|
1225
|
+
var ctaClickConfigSchema = z2.object({
|
|
1226
|
+
autoCapture: z2.object({
|
|
1227
|
+
selector: z2.string().optional()
|
|
1228
|
+
}).strict().optional()
|
|
1219
1229
|
}).strict();
|
|
1220
|
-
var ctaClickConfigSchema = z2.object({}).strict();
|
|
1221
1230
|
|
|
1222
1231
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
1223
1232
|
import { z as z3 } from "zod";
|
|
@@ -1293,31 +1302,44 @@ var multiPageSessionConfigSchema = z6.object({
|
|
|
1293
1302
|
pageThreshold: z6.number().int().min(2)
|
|
1294
1303
|
}).strict();
|
|
1295
1304
|
|
|
1296
|
-
// ../tracking-core/src/events/
|
|
1305
|
+
// ../tracking-core/src/events/page-exit.ts
|
|
1297
1306
|
import { z as z7 } from "zod";
|
|
1298
|
-
var
|
|
1299
|
-
|
|
1307
|
+
var pageExitMetadataSchema = z7.object({
|
|
1308
|
+
dwell_ms: z7.number().int().min(0),
|
|
1309
|
+
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
1310
|
+
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
1311
|
+
max_scroll_percent: z7.number().int().min(0).max(100).nullable(),
|
|
1300
1312
|
page: z7.object({
|
|
1301
1313
|
path: z7.string()
|
|
1302
|
-
}).strict()
|
|
1303
|
-
section: z7.string().nullable().optional()
|
|
1314
|
+
}).strict()
|
|
1304
1315
|
}).strict();
|
|
1305
|
-
var
|
|
1316
|
+
var pageExitConfigSchema = z7.object({}).strict();
|
|
1306
1317
|
|
|
1307
|
-
// ../tracking-core/src/events/
|
|
1318
|
+
// ../tracking-core/src/events/phone-click.ts
|
|
1308
1319
|
import { z as z8 } from "zod";
|
|
1309
|
-
var
|
|
1310
|
-
|
|
1320
|
+
var phoneClickMetadataSchema = z8.object({
|
|
1321
|
+
phone_number: z8.string(),
|
|
1311
1322
|
page: z8.object({
|
|
1312
1323
|
path: z8.string()
|
|
1324
|
+
}).strict(),
|
|
1325
|
+
section: z8.string().nullable().optional()
|
|
1326
|
+
}).strict();
|
|
1327
|
+
var phoneClickConfigSchema = z8.object({}).strict();
|
|
1328
|
+
|
|
1329
|
+
// ../tracking-core/src/events/scroll-depth.ts
|
|
1330
|
+
import { z as z9 } from "zod";
|
|
1331
|
+
var scrollDepthMetadataSchema = z9.object({
|
|
1332
|
+
depth_percent: z9.number().int().min(1).max(100),
|
|
1333
|
+
page: z9.object({
|
|
1334
|
+
path: z9.string()
|
|
1313
1335
|
}).strict()
|
|
1314
1336
|
}).strict();
|
|
1315
|
-
var scrollDepthConfigSchema =
|
|
1316
|
-
thresholds:
|
|
1337
|
+
var scrollDepthConfigSchema = z9.object({
|
|
1338
|
+
thresholds: z9.array(z9.number().int().min(1).max(100)).min(1)
|
|
1317
1339
|
}).strict();
|
|
1318
1340
|
|
|
1319
1341
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
1320
|
-
import { z as
|
|
1342
|
+
import { z as z10 } from "zod";
|
|
1321
1343
|
var SPECIFIC_PAGE_NAMES = [
|
|
1322
1344
|
"contact_page",
|
|
1323
1345
|
"about_page",
|
|
@@ -1328,18 +1350,18 @@ var SPECIFIC_PAGE_NAMES = [
|
|
|
1328
1350
|
"faq_page",
|
|
1329
1351
|
"testimonials_page"
|
|
1330
1352
|
];
|
|
1331
|
-
var specificPageNameSchema =
|
|
1332
|
-
var specificPageVisitMetadataSchema =
|
|
1353
|
+
var specificPageNameSchema = z10.enum(SPECIFIC_PAGE_NAMES);
|
|
1354
|
+
var specificPageVisitMetadataSchema = z10.object({
|
|
1333
1355
|
page_name: specificPageNameSchema,
|
|
1334
|
-
page:
|
|
1335
|
-
path:
|
|
1356
|
+
page: z10.object({
|
|
1357
|
+
path: z10.string()
|
|
1336
1358
|
}).strict()
|
|
1337
1359
|
}).strict();
|
|
1338
|
-
var specificPageVisitConfigSchema =
|
|
1339
|
-
pages:
|
|
1340
|
-
|
|
1360
|
+
var specificPageVisitConfigSchema = z10.object({
|
|
1361
|
+
pages: z10.array(
|
|
1362
|
+
z10.object({
|
|
1341
1363
|
name: specificPageNameSchema,
|
|
1342
|
-
pathPattern:
|
|
1364
|
+
pathPattern: z10.custom((value) => value instanceof RegExp, {
|
|
1343
1365
|
message: "pathPattern must be a RegExp"
|
|
1344
1366
|
})
|
|
1345
1367
|
}).strict()
|
|
@@ -1347,15 +1369,15 @@ var specificPageVisitConfigSchema = z9.object({
|
|
|
1347
1369
|
}).strict();
|
|
1348
1370
|
|
|
1349
1371
|
// ../tracking-core/src/events/time-on-site.ts
|
|
1350
|
-
import { z as
|
|
1351
|
-
var timeOnSiteMetadataSchema =
|
|
1352
|
-
duration_ms:
|
|
1353
|
-
page:
|
|
1354
|
-
path:
|
|
1372
|
+
import { z as z11 } from "zod";
|
|
1373
|
+
var timeOnSiteMetadataSchema = z11.object({
|
|
1374
|
+
duration_ms: z11.number().int().nonnegative(),
|
|
1375
|
+
page: z11.object({
|
|
1376
|
+
path: z11.string()
|
|
1355
1377
|
}).strict()
|
|
1356
1378
|
}).strict();
|
|
1357
|
-
var timeOnSiteConfigSchema =
|
|
1358
|
-
thresholdSeconds:
|
|
1379
|
+
var timeOnSiteConfigSchema = z11.object({
|
|
1380
|
+
thresholdSeconds: z11.number().int().positive()
|
|
1359
1381
|
}).strict();
|
|
1360
1382
|
|
|
1361
1383
|
// ../tracking-core/src/events/registry.ts
|
|
@@ -1397,6 +1419,11 @@ var EVENT_REGISTRY = {
|
|
|
1397
1419
|
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
1398
1420
|
configSchema: sdkHeartbeatConfigSchema
|
|
1399
1421
|
},
|
|
1422
|
+
page_exit: {
|
|
1423
|
+
kind: "automatic",
|
|
1424
|
+
metadataSchema: pageExitMetadataSchema,
|
|
1425
|
+
configSchema: pageExitConfigSchema
|
|
1426
|
+
},
|
|
1400
1427
|
// --- manual triggers ---
|
|
1401
1428
|
form_submit: {
|
|
1402
1429
|
kind: "manual",
|
|
@@ -1640,6 +1667,163 @@ function attachFormStart(client, config) {
|
|
|
1640
1667
|
};
|
|
1641
1668
|
}
|
|
1642
1669
|
|
|
1670
|
+
// ../tracking-core/src/triggers/page-exit.ts
|
|
1671
|
+
function attachPageExit(client) {
|
|
1672
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
1673
|
+
return () => {
|
|
1674
|
+
};
|
|
1675
|
+
}
|
|
1676
|
+
let currentPath2 = window.location.pathname;
|
|
1677
|
+
let activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1678
|
+
let accumulatedMs = 0;
|
|
1679
|
+
let maxScrollPercent = null;
|
|
1680
|
+
let rafId = null;
|
|
1681
|
+
function getScrollPercent() {
|
|
1682
|
+
const doc = document.documentElement;
|
|
1683
|
+
const scrollTop = window.scrollY || doc.scrollTop;
|
|
1684
|
+
const scrollHeight = doc.scrollHeight;
|
|
1685
|
+
const clientHeight = doc.clientHeight;
|
|
1686
|
+
if (scrollHeight <= clientHeight) return 100;
|
|
1687
|
+
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
1688
|
+
}
|
|
1689
|
+
function onScroll() {
|
|
1690
|
+
if (rafId !== null) return;
|
|
1691
|
+
rafId = requestAnimationFrame(() => {
|
|
1692
|
+
rafId = null;
|
|
1693
|
+
const percent = getScrollPercent();
|
|
1694
|
+
if (percent >= 1 && (maxScrollPercent === null || percent > maxScrollPercent)) {
|
|
1695
|
+
maxScrollPercent = Math.min(percent, 100);
|
|
1696
|
+
}
|
|
1697
|
+
});
|
|
1698
|
+
}
|
|
1699
|
+
function settledDwellMs() {
|
|
1700
|
+
let total = accumulatedMs;
|
|
1701
|
+
if (activeSince !== null) {
|
|
1702
|
+
total += Date.now() - activeSince;
|
|
1703
|
+
}
|
|
1704
|
+
return Math.max(0, Math.round(total));
|
|
1705
|
+
}
|
|
1706
|
+
function emitSegment(path, flush) {
|
|
1707
|
+
const dwell = settledDwellMs();
|
|
1708
|
+
if (dwell === 0) return;
|
|
1709
|
+
client.trackEvent({
|
|
1710
|
+
eventType: "page_exit",
|
|
1711
|
+
metadata: {
|
|
1712
|
+
dwell_ms: dwell,
|
|
1713
|
+
max_scroll_percent: maxScrollPercent,
|
|
1714
|
+
page: { path }
|
|
1715
|
+
},
|
|
1716
|
+
pageUrl: window.location.href,
|
|
1717
|
+
occurredAt: null
|
|
1718
|
+
});
|
|
1719
|
+
if (flush) {
|
|
1720
|
+
client.flushBeacon();
|
|
1721
|
+
}
|
|
1722
|
+
accumulatedMs = 0;
|
|
1723
|
+
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1724
|
+
}
|
|
1725
|
+
function onNavigate() {
|
|
1726
|
+
const newPath = window.location.pathname;
|
|
1727
|
+
if (newPath === currentPath2) return;
|
|
1728
|
+
emitSegment(currentPath2, false);
|
|
1729
|
+
currentPath2 = newPath;
|
|
1730
|
+
maxScrollPercent = null;
|
|
1731
|
+
accumulatedMs = 0;
|
|
1732
|
+
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1733
|
+
}
|
|
1734
|
+
function onVisibilityChange() {
|
|
1735
|
+
if (document.visibilityState === "hidden") {
|
|
1736
|
+
emitSegment(currentPath2, true);
|
|
1737
|
+
} else {
|
|
1738
|
+
activeSince = Date.now();
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
function onPageHide() {
|
|
1742
|
+
emitSegment(currentPath2, true);
|
|
1743
|
+
}
|
|
1744
|
+
const originalPushState = history.pushState.bind(history);
|
|
1745
|
+
const originalReplaceState = history.replaceState.bind(history);
|
|
1746
|
+
function patchedPushState(...args) {
|
|
1747
|
+
originalPushState(...args);
|
|
1748
|
+
setTimeout(onNavigate, 0);
|
|
1749
|
+
}
|
|
1750
|
+
function patchedReplaceState(...args) {
|
|
1751
|
+
originalReplaceState(...args);
|
|
1752
|
+
setTimeout(onNavigate, 0);
|
|
1753
|
+
}
|
|
1754
|
+
history.pushState = patchedPushState;
|
|
1755
|
+
history.replaceState = patchedReplaceState;
|
|
1756
|
+
window.addEventListener("popstate", onNavigate);
|
|
1757
|
+
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1758
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
1759
|
+
window.addEventListener("pagehide", onPageHide);
|
|
1760
|
+
return () => {
|
|
1761
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
1762
|
+
history.pushState = originalPushState;
|
|
1763
|
+
history.replaceState = originalReplaceState;
|
|
1764
|
+
window.removeEventListener("popstate", onNavigate);
|
|
1765
|
+
window.removeEventListener("scroll", onScroll);
|
|
1766
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
1767
|
+
window.removeEventListener("pagehide", onPageHide);
|
|
1768
|
+
};
|
|
1769
|
+
}
|
|
1770
|
+
|
|
1771
|
+
// ../tracking-core/src/triggers/cta-click-capture.ts
|
|
1772
|
+
var DEFAULT_CTA_SELECTOR = "[data-aranova-cta]";
|
|
1773
|
+
var CTA_NAME_MAX_LENGTH = 120;
|
|
1774
|
+
function describeElement(el) {
|
|
1775
|
+
const tag = el.tagName.toLowerCase();
|
|
1776
|
+
return el.id ? `${tag}#${el.id}` : tag;
|
|
1777
|
+
}
|
|
1778
|
+
function resolveCtaName(el) {
|
|
1779
|
+
const explicit = el.getAttribute("data-aranova-cta");
|
|
1780
|
+
if (explicit && explicit.trim().length > 0) return explicit.trim();
|
|
1781
|
+
const text = (el.textContent ?? "").trim().replace(/\s+/g, " ");
|
|
1782
|
+
if (text.length > 0) return text.slice(0, CTA_NAME_MAX_LENGTH);
|
|
1783
|
+
return describeElement(el);
|
|
1784
|
+
}
|
|
1785
|
+
function attachCtaClickCapture(client, config) {
|
|
1786
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
1787
|
+
return () => {
|
|
1788
|
+
};
|
|
1789
|
+
}
|
|
1790
|
+
const autoCapture = config.autoCapture;
|
|
1791
|
+
if (!autoCapture) {
|
|
1792
|
+
return () => {
|
|
1793
|
+
};
|
|
1794
|
+
}
|
|
1795
|
+
const selector = autoCapture.selector ?? DEFAULT_CTA_SELECTOR;
|
|
1796
|
+
function onClick(event) {
|
|
1797
|
+
const target = event.target;
|
|
1798
|
+
if (!(target instanceof Element)) return;
|
|
1799
|
+
let matched = null;
|
|
1800
|
+
try {
|
|
1801
|
+
matched = target.closest(selector);
|
|
1802
|
+
} catch {
|
|
1803
|
+
return;
|
|
1804
|
+
}
|
|
1805
|
+
if (matched === null) return;
|
|
1806
|
+
const href = matched instanceof HTMLAnchorElement ? matched.href || null : matched.getAttribute("href");
|
|
1807
|
+
client.trackEvent({
|
|
1808
|
+
eventType: "cta_click",
|
|
1809
|
+
metadata: {
|
|
1810
|
+
cta_name: resolveCtaName(matched),
|
|
1811
|
+
page: { path: window.location.pathname },
|
|
1812
|
+
section: matched.getAttribute("data-aranova-section"),
|
|
1813
|
+
destination_url: href,
|
|
1814
|
+
href,
|
|
1815
|
+
element: describeElement(matched)
|
|
1816
|
+
},
|
|
1817
|
+
pageUrl: window.location.href,
|
|
1818
|
+
occurredAt: null
|
|
1819
|
+
});
|
|
1820
|
+
}
|
|
1821
|
+
document.addEventListener("click", onClick, true);
|
|
1822
|
+
return () => {
|
|
1823
|
+
document.removeEventListener("click", onClick, true);
|
|
1824
|
+
};
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1643
1827
|
// ../tracking-core/src/resources/sales/errors.ts
|
|
1644
1828
|
var AranovaApiError = class extends Error {
|
|
1645
1829
|
constructor(message, options) {
|
|
@@ -1846,42 +2030,42 @@ function createSalesClient(config) {
|
|
|
1846
2030
|
}
|
|
1847
2031
|
|
|
1848
2032
|
// ../tracking-core/src/resources/sales/schema.ts
|
|
1849
|
-
import { z as
|
|
2033
|
+
import { z as z12 } from "zod";
|
|
1850
2034
|
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
1851
2035
|
var TRACKING_ENVIRONMENTS = ["production", "development"];
|
|
1852
|
-
var currencySchema =
|
|
1853
|
-
var centsSchema =
|
|
1854
|
-
var quantitySchema =
|
|
1855
|
-
var metadataSchema =
|
|
1856
|
-
var saleItemSchema =
|
|
1857
|
-
external_item_id:
|
|
1858
|
-
name:
|
|
1859
|
-
category:
|
|
2036
|
+
var currencySchema = z12.enum(SUPPORTED_CURRENCIES);
|
|
2037
|
+
var centsSchema = z12.number().int().nonnegative();
|
|
2038
|
+
var quantitySchema = z12.string().regex(/^\d+(\.\d{1,3})?$/);
|
|
2039
|
+
var metadataSchema = z12.record(z12.unknown());
|
|
2040
|
+
var saleItemSchema = z12.object({
|
|
2041
|
+
external_item_id: z12.string().nullable().optional(),
|
|
2042
|
+
name: z12.string().nullable().optional(),
|
|
2043
|
+
category: z12.string().nullable().optional(),
|
|
1860
2044
|
quantity: quantitySchema,
|
|
1861
2045
|
unit_price_cents: centsSchema,
|
|
1862
2046
|
// Non-negativity validated on the wire — same contract as the other cents
|
|
1863
2047
|
// fields — and backstopped by the DB CHECK.
|
|
1864
2048
|
unit_cost_cents: centsSchema.nullable().optional()
|
|
1865
2049
|
}).strict();
|
|
1866
|
-
var saleServiceSchema =
|
|
1867
|
-
service:
|
|
2050
|
+
var saleServiceSchema = z12.object({
|
|
2051
|
+
service: z12.string(),
|
|
1868
2052
|
amount_cents: centsSchema
|
|
1869
2053
|
}).strict();
|
|
1870
|
-
var customerNameSchema =
|
|
1871
|
-
var customerPhoneSchema =
|
|
1872
|
-
var customerEmailSchema =
|
|
2054
|
+
var customerNameSchema = z12.string().max(200);
|
|
2055
|
+
var customerPhoneSchema = z12.string().max(64);
|
|
2056
|
+
var customerEmailSchema = z12.string().max(320).email();
|
|
1873
2057
|
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
1874
2058
|
if (val.services != null) {
|
|
1875
2059
|
if (val.service != null) {
|
|
1876
2060
|
ctx.addIssue({
|
|
1877
|
-
code:
|
|
2061
|
+
code: z12.ZodIssueCode.custom,
|
|
1878
2062
|
message: "pass either `service` or `services`, not both",
|
|
1879
2063
|
path: ["services"]
|
|
1880
2064
|
});
|
|
1881
2065
|
}
|
|
1882
2066
|
if (val.services.length === 0) {
|
|
1883
2067
|
ctx.addIssue({
|
|
1884
|
-
code:
|
|
2068
|
+
code: z12.ZodIssueCode.custom,
|
|
1885
2069
|
message: "`services` must not be empty",
|
|
1886
2070
|
path: ["services"]
|
|
1887
2071
|
});
|
|
@@ -1889,7 +2073,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
1889
2073
|
const keys = val.services.map((s) => s.service);
|
|
1890
2074
|
if (new Set(keys).size !== keys.length) {
|
|
1891
2075
|
ctx.addIssue({
|
|
1892
|
-
code:
|
|
2076
|
+
code: z12.ZodIssueCode.custom,
|
|
1893
2077
|
message: "`services` must not list the same service more than once",
|
|
1894
2078
|
path: ["services"]
|
|
1895
2079
|
});
|
|
@@ -1898,7 +2082,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
1898
2082
|
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
1899
2083
|
if (val.amount_total_cents !== sum) {
|
|
1900
2084
|
ctx.addIssue({
|
|
1901
|
-
code:
|
|
2085
|
+
code: z12.ZodIssueCode.custom,
|
|
1902
2086
|
message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
|
|
1903
2087
|
path: ["amount_total_cents"]
|
|
1904
2088
|
});
|
|
@@ -1906,37 +2090,37 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
1906
2090
|
}
|
|
1907
2091
|
} else if (requireAmount && val.amount_total_cents == null) {
|
|
1908
2092
|
ctx.addIssue({
|
|
1909
|
-
code:
|
|
2093
|
+
code: z12.ZodIssueCode.custom,
|
|
1910
2094
|
message: "amount_total_cents is required unless `services` is provided",
|
|
1911
2095
|
path: ["amount_total_cents"]
|
|
1912
2096
|
});
|
|
1913
2097
|
}
|
|
1914
2098
|
}
|
|
1915
|
-
var saleCreateSchema =
|
|
1916
|
-
external_id:
|
|
1917
|
-
description:
|
|
1918
|
-
service:
|
|
1919
|
-
services:
|
|
2099
|
+
var saleCreateSchema = z12.object({
|
|
2100
|
+
external_id: z12.string().nullable().optional(),
|
|
2101
|
+
description: z12.string().nullable().optional(),
|
|
2102
|
+
service: z12.string().nullable().optional(),
|
|
2103
|
+
services: z12.array(saleServiceSchema).nullable().optional(),
|
|
1920
2104
|
currency: currencySchema,
|
|
1921
2105
|
// Optional only because the plural `services` form derives it from the sum
|
|
1922
2106
|
// (see refineServiceXor); the singular/serviceless path still requires it.
|
|
1923
2107
|
amount_total_cents: centsSchema.nullable().optional(),
|
|
1924
|
-
occurred_at:
|
|
1925
|
-
environment:
|
|
1926
|
-
items:
|
|
2108
|
+
occurred_at: z12.string().datetime(),
|
|
2109
|
+
environment: z12.enum(TRACKING_ENVIRONMENTS).default("production"),
|
|
2110
|
+
items: z12.array(saleItemSchema).default([]),
|
|
1927
2111
|
metadata: metadataSchema.nullable().optional(),
|
|
1928
2112
|
customer_name: customerNameSchema.nullable().optional(),
|
|
1929
2113
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
1930
2114
|
customer_email: customerEmailSchema.nullable().optional()
|
|
1931
2115
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
1932
|
-
var saleUpdateSchema =
|
|
1933
|
-
description:
|
|
1934
|
-
service:
|
|
1935
|
-
services:
|
|
2116
|
+
var saleUpdateSchema = z12.object({
|
|
2117
|
+
description: z12.string().nullable().optional(),
|
|
2118
|
+
service: z12.string().nullable().optional(),
|
|
2119
|
+
services: z12.array(saleServiceSchema).nullable().optional(),
|
|
1936
2120
|
currency: currencySchema.optional(),
|
|
1937
2121
|
amount_total_cents: centsSchema.optional(),
|
|
1938
|
-
occurred_at:
|
|
1939
|
-
items:
|
|
2122
|
+
occurred_at: z12.string().datetime().optional(),
|
|
2123
|
+
items: z12.array(saleItemSchema).optional(),
|
|
1940
2124
|
metadata: metadataSchema.nullable().optional(),
|
|
1941
2125
|
customer_name: customerNameSchema.nullable().optional(),
|
|
1942
2126
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
@@ -2338,7 +2522,7 @@ function GoogleAdsTracking(props) {
|
|
|
2338
2522
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
2339
2523
|
|
|
2340
2524
|
// package.json
|
|
2341
|
-
var version = "0.
|
|
2525
|
+
var version = "0.16.0";
|
|
2342
2526
|
|
|
2343
2527
|
// src/factory.tsx
|
|
2344
2528
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo2, useRef } from "react";
|
|
@@ -2626,6 +2810,7 @@ function createTracking(options) {
|
|
|
2626
2810
|
debug
|
|
2627
2811
|
});
|
|
2628
2812
|
const detectorClient = wrapClient(rawClient);
|
|
2813
|
+
detachers.push(attachPageExit(detectorClient));
|
|
2629
2814
|
const scrollDepth = triggers.automatic.scroll_depth;
|
|
2630
2815
|
if (scrollDepth) {
|
|
2631
2816
|
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
@@ -2634,6 +2819,10 @@ function createTracking(options) {
|
|
|
2634
2819
|
if (formStart) {
|
|
2635
2820
|
detachers.push(attachFormStart(detectorClient, formStart));
|
|
2636
2821
|
}
|
|
2822
|
+
const ctaClick = triggers.manual?.cta_click;
|
|
2823
|
+
if (ctaClick) {
|
|
2824
|
+
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
2825
|
+
}
|
|
2637
2826
|
return () => {
|
|
2638
2827
|
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
2639
2828
|
detachers[i]();
|