@aranova/tracking-next 0.15.0 → 0.16.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.
- package/README.md +72 -0
- package/dist/index.d.mts +129 -5
- package/dist/index.d.ts +129 -5
- package/dist/index.js +266 -67
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +276 -69
- 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.js
CHANGED
|
@@ -1273,6 +1273,7 @@ function createTrackingClient(config) {
|
|
|
1273
1273
|
return {
|
|
1274
1274
|
trackEvent,
|
|
1275
1275
|
flush,
|
|
1276
|
+
flushBeacon: flushOnUnload,
|
|
1276
1277
|
getSessionId: () => sessionId,
|
|
1277
1278
|
getVisitorId: () => visitorId,
|
|
1278
1279
|
destroy: () => {
|
|
@@ -1297,9 +1298,17 @@ var ctaClickMetadataSchema = import_zod2.z.object({
|
|
|
1297
1298
|
path: import_zod2.z.string()
|
|
1298
1299
|
}).strict(),
|
|
1299
1300
|
section: import_zod2.z.string().nullable().optional(),
|
|
1300
|
-
destination_url: import_zod2.z.string().nullable().optional()
|
|
1301
|
+
destination_url: import_zod2.z.string().nullable().optional(),
|
|
1302
|
+
// Set by auto-capture (and available to manual callers): the link target
|
|
1303
|
+
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
1304
|
+
href: import_zod2.z.string().nullable().optional(),
|
|
1305
|
+
element: import_zod2.z.string().nullable().optional()
|
|
1306
|
+
}).strict();
|
|
1307
|
+
var ctaClickConfigSchema = import_zod2.z.object({
|
|
1308
|
+
autoCapture: import_zod2.z.object({
|
|
1309
|
+
selector: import_zod2.z.string().optional()
|
|
1310
|
+
}).strict().optional()
|
|
1301
1311
|
}).strict();
|
|
1302
|
-
var ctaClickConfigSchema = import_zod2.z.object({}).strict();
|
|
1303
1312
|
|
|
1304
1313
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
1305
1314
|
var import_zod3 = require("zod");
|
|
@@ -1375,31 +1384,44 @@ var multiPageSessionConfigSchema = import_zod6.z.object({
|
|
|
1375
1384
|
pageThreshold: import_zod6.z.number().int().min(2)
|
|
1376
1385
|
}).strict();
|
|
1377
1386
|
|
|
1378
|
-
// ../tracking-core/src/events/
|
|
1387
|
+
// ../tracking-core/src/events/page-exit.ts
|
|
1379
1388
|
var import_zod7 = require("zod");
|
|
1380
|
-
var
|
|
1381
|
-
|
|
1389
|
+
var pageExitMetadataSchema = import_zod7.z.object({
|
|
1390
|
+
dwell_ms: import_zod7.z.number().int().min(0),
|
|
1391
|
+
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
1392
|
+
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
1393
|
+
max_scroll_percent: import_zod7.z.number().int().min(0).max(100).nullable(),
|
|
1382
1394
|
page: import_zod7.z.object({
|
|
1383
1395
|
path: import_zod7.z.string()
|
|
1384
|
-
}).strict()
|
|
1385
|
-
section: import_zod7.z.string().nullable().optional()
|
|
1396
|
+
}).strict()
|
|
1386
1397
|
}).strict();
|
|
1387
|
-
var
|
|
1398
|
+
var pageExitConfigSchema = import_zod7.z.object({}).strict();
|
|
1388
1399
|
|
|
1389
|
-
// ../tracking-core/src/events/
|
|
1400
|
+
// ../tracking-core/src/events/phone-click.ts
|
|
1390
1401
|
var import_zod8 = require("zod");
|
|
1391
|
-
var
|
|
1392
|
-
|
|
1402
|
+
var phoneClickMetadataSchema = import_zod8.z.object({
|
|
1403
|
+
phone_number: import_zod8.z.string(),
|
|
1393
1404
|
page: import_zod8.z.object({
|
|
1394
1405
|
path: import_zod8.z.string()
|
|
1406
|
+
}).strict(),
|
|
1407
|
+
section: import_zod8.z.string().nullable().optional()
|
|
1408
|
+
}).strict();
|
|
1409
|
+
var phoneClickConfigSchema = import_zod8.z.object({}).strict();
|
|
1410
|
+
|
|
1411
|
+
// ../tracking-core/src/events/scroll-depth.ts
|
|
1412
|
+
var import_zod9 = require("zod");
|
|
1413
|
+
var scrollDepthMetadataSchema = import_zod9.z.object({
|
|
1414
|
+
depth_percent: import_zod9.z.number().int().min(1).max(100),
|
|
1415
|
+
page: import_zod9.z.object({
|
|
1416
|
+
path: import_zod9.z.string()
|
|
1395
1417
|
}).strict()
|
|
1396
1418
|
}).strict();
|
|
1397
|
-
var scrollDepthConfigSchema =
|
|
1398
|
-
thresholds:
|
|
1419
|
+
var scrollDepthConfigSchema = import_zod9.z.object({
|
|
1420
|
+
thresholds: import_zod9.z.array(import_zod9.z.number().int().min(1).max(100)).min(1)
|
|
1399
1421
|
}).strict();
|
|
1400
1422
|
|
|
1401
1423
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
1402
|
-
var
|
|
1424
|
+
var import_zod10 = require("zod");
|
|
1403
1425
|
var SPECIFIC_PAGE_NAMES = [
|
|
1404
1426
|
"contact_page",
|
|
1405
1427
|
"about_page",
|
|
@@ -1410,18 +1432,18 @@ var SPECIFIC_PAGE_NAMES = [
|
|
|
1410
1432
|
"faq_page",
|
|
1411
1433
|
"testimonials_page"
|
|
1412
1434
|
];
|
|
1413
|
-
var specificPageNameSchema =
|
|
1414
|
-
var specificPageVisitMetadataSchema =
|
|
1435
|
+
var specificPageNameSchema = import_zod10.z.enum(SPECIFIC_PAGE_NAMES);
|
|
1436
|
+
var specificPageVisitMetadataSchema = import_zod10.z.object({
|
|
1415
1437
|
page_name: specificPageNameSchema,
|
|
1416
|
-
page:
|
|
1417
|
-
path:
|
|
1438
|
+
page: import_zod10.z.object({
|
|
1439
|
+
path: import_zod10.z.string()
|
|
1418
1440
|
}).strict()
|
|
1419
1441
|
}).strict();
|
|
1420
|
-
var specificPageVisitConfigSchema =
|
|
1421
|
-
pages:
|
|
1422
|
-
|
|
1442
|
+
var specificPageVisitConfigSchema = import_zod10.z.object({
|
|
1443
|
+
pages: import_zod10.z.array(
|
|
1444
|
+
import_zod10.z.object({
|
|
1423
1445
|
name: specificPageNameSchema,
|
|
1424
|
-
pathPattern:
|
|
1446
|
+
pathPattern: import_zod10.z.custom((value) => value instanceof RegExp, {
|
|
1425
1447
|
message: "pathPattern must be a RegExp"
|
|
1426
1448
|
})
|
|
1427
1449
|
}).strict()
|
|
@@ -1429,15 +1451,15 @@ var specificPageVisitConfigSchema = import_zod9.z.object({
|
|
|
1429
1451
|
}).strict();
|
|
1430
1452
|
|
|
1431
1453
|
// ../tracking-core/src/events/time-on-site.ts
|
|
1432
|
-
var
|
|
1433
|
-
var timeOnSiteMetadataSchema =
|
|
1434
|
-
duration_ms:
|
|
1435
|
-
page:
|
|
1436
|
-
path:
|
|
1454
|
+
var import_zod11 = require("zod");
|
|
1455
|
+
var timeOnSiteMetadataSchema = import_zod11.z.object({
|
|
1456
|
+
duration_ms: import_zod11.z.number().int().nonnegative(),
|
|
1457
|
+
page: import_zod11.z.object({
|
|
1458
|
+
path: import_zod11.z.string()
|
|
1437
1459
|
}).strict()
|
|
1438
1460
|
}).strict();
|
|
1439
|
-
var timeOnSiteConfigSchema =
|
|
1440
|
-
thresholdSeconds:
|
|
1461
|
+
var timeOnSiteConfigSchema = import_zod11.z.object({
|
|
1462
|
+
thresholdSeconds: import_zod11.z.number().int().positive()
|
|
1441
1463
|
}).strict();
|
|
1442
1464
|
|
|
1443
1465
|
// ../tracking-core/src/events/registry.ts
|
|
@@ -1479,6 +1501,11 @@ var EVENT_REGISTRY = {
|
|
|
1479
1501
|
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
1480
1502
|
configSchema: sdkHeartbeatConfigSchema
|
|
1481
1503
|
},
|
|
1504
|
+
page_exit: {
|
|
1505
|
+
kind: "automatic",
|
|
1506
|
+
metadataSchema: pageExitMetadataSchema,
|
|
1507
|
+
configSchema: pageExitConfigSchema
|
|
1508
|
+
},
|
|
1482
1509
|
// --- manual triggers ---
|
|
1483
1510
|
form_submit: {
|
|
1484
1511
|
kind: "manual",
|
|
@@ -1722,6 +1749,163 @@ function attachFormStart(client, config) {
|
|
|
1722
1749
|
};
|
|
1723
1750
|
}
|
|
1724
1751
|
|
|
1752
|
+
// ../tracking-core/src/triggers/page-exit.ts
|
|
1753
|
+
function attachPageExit(client) {
|
|
1754
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
1755
|
+
return () => {
|
|
1756
|
+
};
|
|
1757
|
+
}
|
|
1758
|
+
let currentPath2 = window.location.pathname;
|
|
1759
|
+
let activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1760
|
+
let accumulatedMs = 0;
|
|
1761
|
+
let maxScrollPercent = null;
|
|
1762
|
+
let rafId = null;
|
|
1763
|
+
function getScrollPercent() {
|
|
1764
|
+
const doc = document.documentElement;
|
|
1765
|
+
const scrollTop = window.scrollY || doc.scrollTop;
|
|
1766
|
+
const scrollHeight = doc.scrollHeight;
|
|
1767
|
+
const clientHeight = doc.clientHeight;
|
|
1768
|
+
if (scrollHeight <= clientHeight) return 100;
|
|
1769
|
+
return Math.round((scrollTop + clientHeight) / scrollHeight * 100);
|
|
1770
|
+
}
|
|
1771
|
+
function onScroll() {
|
|
1772
|
+
if (rafId !== null) return;
|
|
1773
|
+
rafId = requestAnimationFrame(() => {
|
|
1774
|
+
rafId = null;
|
|
1775
|
+
const percent = getScrollPercent();
|
|
1776
|
+
if (percent >= 1 && (maxScrollPercent === null || percent > maxScrollPercent)) {
|
|
1777
|
+
maxScrollPercent = Math.min(percent, 100);
|
|
1778
|
+
}
|
|
1779
|
+
});
|
|
1780
|
+
}
|
|
1781
|
+
function settledDwellMs() {
|
|
1782
|
+
let total = accumulatedMs;
|
|
1783
|
+
if (activeSince !== null) {
|
|
1784
|
+
total += Date.now() - activeSince;
|
|
1785
|
+
}
|
|
1786
|
+
return Math.max(0, Math.round(total));
|
|
1787
|
+
}
|
|
1788
|
+
function emitSegment(path, flush) {
|
|
1789
|
+
const dwell = settledDwellMs();
|
|
1790
|
+
if (dwell === 0) return;
|
|
1791
|
+
client.trackEvent({
|
|
1792
|
+
eventType: "page_exit",
|
|
1793
|
+
metadata: {
|
|
1794
|
+
dwell_ms: dwell,
|
|
1795
|
+
max_scroll_percent: maxScrollPercent,
|
|
1796
|
+
page: { path }
|
|
1797
|
+
},
|
|
1798
|
+
pageUrl: window.location.href,
|
|
1799
|
+
occurredAt: null
|
|
1800
|
+
});
|
|
1801
|
+
if (flush) {
|
|
1802
|
+
client.flushBeacon();
|
|
1803
|
+
}
|
|
1804
|
+
accumulatedMs = 0;
|
|
1805
|
+
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1806
|
+
}
|
|
1807
|
+
function onNavigate() {
|
|
1808
|
+
const newPath = window.location.pathname;
|
|
1809
|
+
if (newPath === currentPath2) return;
|
|
1810
|
+
emitSegment(currentPath2, false);
|
|
1811
|
+
currentPath2 = newPath;
|
|
1812
|
+
maxScrollPercent = null;
|
|
1813
|
+
accumulatedMs = 0;
|
|
1814
|
+
activeSince = document.visibilityState === "visible" ? Date.now() : null;
|
|
1815
|
+
}
|
|
1816
|
+
function onVisibilityChange() {
|
|
1817
|
+
if (document.visibilityState === "hidden") {
|
|
1818
|
+
emitSegment(currentPath2, true);
|
|
1819
|
+
} else {
|
|
1820
|
+
activeSince = Date.now();
|
|
1821
|
+
}
|
|
1822
|
+
}
|
|
1823
|
+
function onPageHide() {
|
|
1824
|
+
emitSegment(currentPath2, true);
|
|
1825
|
+
}
|
|
1826
|
+
const originalPushState = history.pushState.bind(history);
|
|
1827
|
+
const originalReplaceState = history.replaceState.bind(history);
|
|
1828
|
+
function patchedPushState(...args) {
|
|
1829
|
+
originalPushState(...args);
|
|
1830
|
+
setTimeout(onNavigate, 0);
|
|
1831
|
+
}
|
|
1832
|
+
function patchedReplaceState(...args) {
|
|
1833
|
+
originalReplaceState(...args);
|
|
1834
|
+
setTimeout(onNavigate, 0);
|
|
1835
|
+
}
|
|
1836
|
+
history.pushState = patchedPushState;
|
|
1837
|
+
history.replaceState = patchedReplaceState;
|
|
1838
|
+
window.addEventListener("popstate", onNavigate);
|
|
1839
|
+
window.addEventListener("scroll", onScroll, { passive: true });
|
|
1840
|
+
document.addEventListener("visibilitychange", onVisibilityChange);
|
|
1841
|
+
window.addEventListener("pagehide", onPageHide);
|
|
1842
|
+
return () => {
|
|
1843
|
+
if (rafId !== null) cancelAnimationFrame(rafId);
|
|
1844
|
+
history.pushState = originalPushState;
|
|
1845
|
+
history.replaceState = originalReplaceState;
|
|
1846
|
+
window.removeEventListener("popstate", onNavigate);
|
|
1847
|
+
window.removeEventListener("scroll", onScroll);
|
|
1848
|
+
document.removeEventListener("visibilitychange", onVisibilityChange);
|
|
1849
|
+
window.removeEventListener("pagehide", onPageHide);
|
|
1850
|
+
};
|
|
1851
|
+
}
|
|
1852
|
+
|
|
1853
|
+
// ../tracking-core/src/triggers/cta-click-capture.ts
|
|
1854
|
+
var DEFAULT_CTA_SELECTOR = "[data-aranova-cta]";
|
|
1855
|
+
var CTA_NAME_MAX_LENGTH = 120;
|
|
1856
|
+
function describeElement(el) {
|
|
1857
|
+
const tag = el.tagName.toLowerCase();
|
|
1858
|
+
return el.id ? `${tag}#${el.id}` : tag;
|
|
1859
|
+
}
|
|
1860
|
+
function resolveCtaName(el) {
|
|
1861
|
+
const explicit = el.getAttribute("data-aranova-cta");
|
|
1862
|
+
if (explicit && explicit.trim().length > 0) return explicit.trim();
|
|
1863
|
+
const text = (el.textContent ?? "").trim().replace(/\s+/g, " ");
|
|
1864
|
+
if (text.length > 0) return text.slice(0, CTA_NAME_MAX_LENGTH);
|
|
1865
|
+
return describeElement(el);
|
|
1866
|
+
}
|
|
1867
|
+
function attachCtaClickCapture(client, config) {
|
|
1868
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
1869
|
+
return () => {
|
|
1870
|
+
};
|
|
1871
|
+
}
|
|
1872
|
+
const autoCapture = config.autoCapture;
|
|
1873
|
+
if (!autoCapture) {
|
|
1874
|
+
return () => {
|
|
1875
|
+
};
|
|
1876
|
+
}
|
|
1877
|
+
const selector = autoCapture.selector ?? DEFAULT_CTA_SELECTOR;
|
|
1878
|
+
function onClick(event) {
|
|
1879
|
+
const target = event.target;
|
|
1880
|
+
if (!(target instanceof Element)) return;
|
|
1881
|
+
let matched = null;
|
|
1882
|
+
try {
|
|
1883
|
+
matched = target.closest(selector);
|
|
1884
|
+
} catch {
|
|
1885
|
+
return;
|
|
1886
|
+
}
|
|
1887
|
+
if (matched === null) return;
|
|
1888
|
+
const href = matched instanceof HTMLAnchorElement ? matched.href || null : matched.getAttribute("href");
|
|
1889
|
+
client.trackEvent({
|
|
1890
|
+
eventType: "cta_click",
|
|
1891
|
+
metadata: {
|
|
1892
|
+
cta_name: resolveCtaName(matched),
|
|
1893
|
+
page: { path: window.location.pathname },
|
|
1894
|
+
section: matched.getAttribute("data-aranova-section"),
|
|
1895
|
+
destination_url: href,
|
|
1896
|
+
href,
|
|
1897
|
+
element: describeElement(matched)
|
|
1898
|
+
},
|
|
1899
|
+
pageUrl: window.location.href,
|
|
1900
|
+
occurredAt: null
|
|
1901
|
+
});
|
|
1902
|
+
}
|
|
1903
|
+
document.addEventListener("click", onClick, true);
|
|
1904
|
+
return () => {
|
|
1905
|
+
document.removeEventListener("click", onClick, true);
|
|
1906
|
+
};
|
|
1907
|
+
}
|
|
1908
|
+
|
|
1725
1909
|
// ../tracking-core/src/resources/sales/errors.ts
|
|
1726
1910
|
var AranovaApiError = class extends Error {
|
|
1727
1911
|
constructor(message, options) {
|
|
@@ -1928,42 +2112,42 @@ function createSalesClient(config) {
|
|
|
1928
2112
|
}
|
|
1929
2113
|
|
|
1930
2114
|
// ../tracking-core/src/resources/sales/schema.ts
|
|
1931
|
-
var
|
|
2115
|
+
var import_zod12 = require("zod");
|
|
1932
2116
|
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
1933
2117
|
var TRACKING_ENVIRONMENTS = ["production", "development"];
|
|
1934
|
-
var currencySchema =
|
|
1935
|
-
var centsSchema =
|
|
1936
|
-
var quantitySchema =
|
|
1937
|
-
var metadataSchema =
|
|
1938
|
-
var saleItemSchema =
|
|
1939
|
-
external_item_id:
|
|
1940
|
-
name:
|
|
1941
|
-
category:
|
|
2118
|
+
var currencySchema = import_zod12.z.enum(SUPPORTED_CURRENCIES);
|
|
2119
|
+
var centsSchema = import_zod12.z.number().int().nonnegative();
|
|
2120
|
+
var quantitySchema = import_zod12.z.string().regex(/^\d+(\.\d{1,3})?$/);
|
|
2121
|
+
var metadataSchema = import_zod12.z.record(import_zod12.z.unknown());
|
|
2122
|
+
var saleItemSchema = import_zod12.z.object({
|
|
2123
|
+
external_item_id: import_zod12.z.string().nullable().optional(),
|
|
2124
|
+
name: import_zod12.z.string().nullable().optional(),
|
|
2125
|
+
category: import_zod12.z.string().nullable().optional(),
|
|
1942
2126
|
quantity: quantitySchema,
|
|
1943
2127
|
unit_price_cents: centsSchema,
|
|
1944
2128
|
// Non-negativity validated on the wire — same contract as the other cents
|
|
1945
2129
|
// fields — and backstopped by the DB CHECK.
|
|
1946
2130
|
unit_cost_cents: centsSchema.nullable().optional()
|
|
1947
2131
|
}).strict();
|
|
1948
|
-
var saleServiceSchema =
|
|
1949
|
-
service:
|
|
2132
|
+
var saleServiceSchema = import_zod12.z.object({
|
|
2133
|
+
service: import_zod12.z.string(),
|
|
1950
2134
|
amount_cents: centsSchema
|
|
1951
2135
|
}).strict();
|
|
1952
|
-
var customerNameSchema =
|
|
1953
|
-
var customerPhoneSchema =
|
|
1954
|
-
var customerEmailSchema =
|
|
2136
|
+
var customerNameSchema = import_zod12.z.string().max(200);
|
|
2137
|
+
var customerPhoneSchema = import_zod12.z.string().max(64);
|
|
2138
|
+
var customerEmailSchema = import_zod12.z.string().max(320).email();
|
|
1955
2139
|
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
1956
2140
|
if (val.services != null) {
|
|
1957
2141
|
if (val.service != null) {
|
|
1958
2142
|
ctx.addIssue({
|
|
1959
|
-
code:
|
|
2143
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
1960
2144
|
message: "pass either `service` or `services`, not both",
|
|
1961
2145
|
path: ["services"]
|
|
1962
2146
|
});
|
|
1963
2147
|
}
|
|
1964
2148
|
if (val.services.length === 0) {
|
|
1965
2149
|
ctx.addIssue({
|
|
1966
|
-
code:
|
|
2150
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
1967
2151
|
message: "`services` must not be empty",
|
|
1968
2152
|
path: ["services"]
|
|
1969
2153
|
});
|
|
@@ -1971,7 +2155,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
1971
2155
|
const keys = val.services.map((s) => s.service);
|
|
1972
2156
|
if (new Set(keys).size !== keys.length) {
|
|
1973
2157
|
ctx.addIssue({
|
|
1974
|
-
code:
|
|
2158
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
1975
2159
|
message: "`services` must not list the same service more than once",
|
|
1976
2160
|
path: ["services"]
|
|
1977
2161
|
});
|
|
@@ -1980,7 +2164,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
1980
2164
|
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
1981
2165
|
if (val.amount_total_cents !== sum) {
|
|
1982
2166
|
ctx.addIssue({
|
|
1983
|
-
code:
|
|
2167
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
1984
2168
|
message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
|
|
1985
2169
|
path: ["amount_total_cents"]
|
|
1986
2170
|
});
|
|
@@ -1988,37 +2172,37 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
1988
2172
|
}
|
|
1989
2173
|
} else if (requireAmount && val.amount_total_cents == null) {
|
|
1990
2174
|
ctx.addIssue({
|
|
1991
|
-
code:
|
|
2175
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
1992
2176
|
message: "amount_total_cents is required unless `services` is provided",
|
|
1993
2177
|
path: ["amount_total_cents"]
|
|
1994
2178
|
});
|
|
1995
2179
|
}
|
|
1996
2180
|
}
|
|
1997
|
-
var saleCreateSchema =
|
|
1998
|
-
external_id:
|
|
1999
|
-
description:
|
|
2000
|
-
service:
|
|
2001
|
-
services:
|
|
2181
|
+
var saleCreateSchema = import_zod12.z.object({
|
|
2182
|
+
external_id: import_zod12.z.string().nullable().optional(),
|
|
2183
|
+
description: import_zod12.z.string().nullable().optional(),
|
|
2184
|
+
service: import_zod12.z.string().nullable().optional(),
|
|
2185
|
+
services: import_zod12.z.array(saleServiceSchema).nullable().optional(),
|
|
2002
2186
|
currency: currencySchema,
|
|
2003
2187
|
// Optional only because the plural `services` form derives it from the sum
|
|
2004
2188
|
// (see refineServiceXor); the singular/serviceless path still requires it.
|
|
2005
2189
|
amount_total_cents: centsSchema.nullable().optional(),
|
|
2006
|
-
occurred_at:
|
|
2007
|
-
environment:
|
|
2008
|
-
items:
|
|
2190
|
+
occurred_at: import_zod12.z.string().datetime(),
|
|
2191
|
+
environment: import_zod12.z.enum(TRACKING_ENVIRONMENTS).default("production"),
|
|
2192
|
+
items: import_zod12.z.array(saleItemSchema).default([]),
|
|
2009
2193
|
metadata: metadataSchema.nullable().optional(),
|
|
2010
2194
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2011
2195
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2012
2196
|
customer_email: customerEmailSchema.nullable().optional()
|
|
2013
2197
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
2014
|
-
var saleUpdateSchema =
|
|
2015
|
-
description:
|
|
2016
|
-
service:
|
|
2017
|
-
services:
|
|
2198
|
+
var saleUpdateSchema = import_zod12.z.object({
|
|
2199
|
+
description: import_zod12.z.string().nullable().optional(),
|
|
2200
|
+
service: import_zod12.z.string().nullable().optional(),
|
|
2201
|
+
services: import_zod12.z.array(saleServiceSchema).nullable().optional(),
|
|
2018
2202
|
currency: currencySchema.optional(),
|
|
2019
2203
|
amount_total_cents: centsSchema.optional(),
|
|
2020
|
-
occurred_at:
|
|
2021
|
-
items:
|
|
2204
|
+
occurred_at: import_zod12.z.string().datetime().optional(),
|
|
2205
|
+
items: import_zod12.z.array(saleItemSchema).optional(),
|
|
2022
2206
|
metadata: metadataSchema.nullable().optional(),
|
|
2023
2207
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2024
2208
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
@@ -2420,7 +2604,7 @@ function GoogleAdsTracking(props) {
|
|
|
2420
2604
|
var import_navigation = require("next/navigation");
|
|
2421
2605
|
|
|
2422
2606
|
// package.json
|
|
2423
|
-
var version = "0.
|
|
2607
|
+
var version = "0.16.1";
|
|
2424
2608
|
|
|
2425
2609
|
// src/factory.tsx
|
|
2426
2610
|
var import_react4 = require("react");
|
|
@@ -2513,6 +2697,14 @@ var PhoneField = (0, import_react3.forwardRef)(function PhoneField2({ country, v
|
|
|
2513
2697
|
|
|
2514
2698
|
// src/factory.tsx
|
|
2515
2699
|
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
2700
|
+
function PageViewTracker({ fire }) {
|
|
2701
|
+
const pathname = (0, import_navigation.usePathname)();
|
|
2702
|
+
const searchParams = (0, import_navigation.useSearchParams)();
|
|
2703
|
+
(0, import_react4.useEffect)(() => {
|
|
2704
|
+
fire();
|
|
2705
|
+
}, [pathname, searchParams, fire]);
|
|
2706
|
+
return null;
|
|
2707
|
+
}
|
|
2516
2708
|
function createTracking(options) {
|
|
2517
2709
|
const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone, conversionConfig } = options;
|
|
2518
2710
|
if (!apiKey || !endpoint) {
|
|
@@ -2539,7 +2731,6 @@ function createTracking(options) {
|
|
|
2539
2731
|
const timeOnSiteConfig = triggers.automatic.time_on_site ?? null;
|
|
2540
2732
|
function TrackingProvider({ children }) {
|
|
2541
2733
|
const pathname = (0, import_navigation.usePathname)();
|
|
2542
|
-
const searchParams = (0, import_navigation.useSearchParams)();
|
|
2543
2734
|
const client = (0, import_react4.useMemo)(
|
|
2544
2735
|
() => createTypedClient(
|
|
2545
2736
|
getOrCreateTrackingClient({
|
|
@@ -2569,7 +2760,7 @@ function createTracking(options) {
|
|
|
2569
2760
|
const autoFire = conversionStore ? createConversionAutoFire(conversionStore) : null;
|
|
2570
2761
|
return (c) => autoFire ? withConversionAutoFire(c, autoFire) : c;
|
|
2571
2762
|
}, [conversionStore]);
|
|
2572
|
-
(0, import_react4.
|
|
2763
|
+
const firePageView = (0, import_react4.useCallback)(() => {
|
|
2573
2764
|
const rawClient = getOrCreateTrackingClient({
|
|
2574
2765
|
apiKey,
|
|
2575
2766
|
endpoint,
|
|
@@ -2581,7 +2772,7 @@ function createTracking(options) {
|
|
|
2581
2772
|
debug
|
|
2582
2773
|
});
|
|
2583
2774
|
fireManualPageView(wrapClient(rawClient));
|
|
2584
|
-
}, [
|
|
2775
|
+
}, [wrapClient]);
|
|
2585
2776
|
const firedPagesRef = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
|
|
2586
2777
|
(0, import_react4.useEffect)(() => {
|
|
2587
2778
|
if (!specificPageVisitConfig || pathname === null) return;
|
|
@@ -2701,6 +2892,7 @@ function createTracking(options) {
|
|
|
2701
2892
|
debug
|
|
2702
2893
|
});
|
|
2703
2894
|
const detectorClient = wrapClient(rawClient);
|
|
2895
|
+
detachers.push(attachPageExit(detectorClient));
|
|
2704
2896
|
const scrollDepth = triggers.automatic.scroll_depth;
|
|
2705
2897
|
if (scrollDepth) {
|
|
2706
2898
|
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
@@ -2709,13 +2901,20 @@ function createTracking(options) {
|
|
|
2709
2901
|
if (formStart) {
|
|
2710
2902
|
detachers.push(attachFormStart(detectorClient, formStart));
|
|
2711
2903
|
}
|
|
2904
|
+
const ctaClick = triggers.manual?.cta_click;
|
|
2905
|
+
if (ctaClick) {
|
|
2906
|
+
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
2907
|
+
}
|
|
2712
2908
|
return () => {
|
|
2713
2909
|
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
2714
2910
|
detachers[i]();
|
|
2715
2911
|
}
|
|
2716
2912
|
};
|
|
2717
2913
|
}, []);
|
|
2718
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.
|
|
2914
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(TrackingContext.Provider, { value: client, children: [
|
|
2915
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react4.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PageViewTracker, { fire: firePageView }) }),
|
|
2916
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PhoneConfigProvider, { value: phone ?? null, children })
|
|
2917
|
+
] });
|
|
2719
2918
|
}
|
|
2720
2919
|
function useTracking() {
|
|
2721
2920
|
const client = (0, import_react4.useContext)(TrackingContext);
|