@aranova/tracking-next 0.14.2 → 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 +67 -50
- package/dist/index.d.mts +219 -99
- package/dist/index.d.ts +219 -99
- package/dist/index.js +490 -155
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +484 -155
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.js +88 -135
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +88 -135
- package/dist/middleware.mjs.map +1 -1
- package/dist/{phone-utils-CcU5mwzc.d.mts → phone-utils-DlAQK-gU.d.mts} +127 -6
- package/dist/{phone-utils-CcU5mwzc.d.ts → phone-utils-DlAQK-gU.d.ts} +127 -6
- package/dist/phone.d.mts +1 -1
- package/dist/phone.d.ts +1 -1
- package/dist/phone.js +88 -135
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +88 -135
- package/dist/phone.mjs.map +1 -1
- package/dist/sales.js +33 -29
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +33 -29
- package/dist/sales.mjs.map +1 -1
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +88 -135
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +88 -135
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -33,6 +33,7 @@ __export(src_exports, {
|
|
|
33
33
|
AdPlatformTracking: () => AdPlatformTracking,
|
|
34
34
|
AranovaApiError: () => AranovaApiError,
|
|
35
35
|
ConsentBanner: () => ConsentBanner,
|
|
36
|
+
DEFAULT_DECLINE_TTL_DAYS: () => DEFAULT_DECLINE_TTL_DAYS,
|
|
36
37
|
DEFAULT_PHONE_COUNTRY: () => DEFAULT_PHONE_COUNTRY,
|
|
37
38
|
GoogleAdsTracking: () => GoogleAdsTracking,
|
|
38
39
|
NAMED_RANGES: () => NAMED_RANGES,
|
|
@@ -52,7 +53,11 @@ __export(src_exports, {
|
|
|
52
53
|
formatPhone: () => formatPhone,
|
|
53
54
|
formatPhoneAsTyped: () => formatPhoneAsTyped,
|
|
54
55
|
fromMinor: () => fromMinor,
|
|
56
|
+
getConsentChoice: () => getConsentChoice,
|
|
55
57
|
getConsentState: () => getConsentState,
|
|
58
|
+
onConsentChange: () => onConsentChange,
|
|
59
|
+
optIn: () => optIn,
|
|
60
|
+
optOut: () => optOut,
|
|
56
61
|
parsePhone: () => parsePhone,
|
|
57
62
|
phoneField: () => phoneField,
|
|
58
63
|
resetConsent: () => resetConsent,
|
|
@@ -67,6 +72,7 @@ __export(src_exports, {
|
|
|
67
72
|
toMinor: () => toMinor,
|
|
68
73
|
useConsent: () => useConsent,
|
|
69
74
|
useConsentState: () => useConsentState,
|
|
75
|
+
useCookiePreferences: () => useCookiePreferences,
|
|
70
76
|
useGclid: () => useGclid,
|
|
71
77
|
usePhoneConfig: () => usePhoneConfig,
|
|
72
78
|
usePhoneField: () => usePhoneField,
|
|
@@ -77,13 +83,30 @@ module.exports = __toCommonJS(src_exports);
|
|
|
77
83
|
// ../tracking-core/src/consent.ts
|
|
78
84
|
var CONSENT_STATE_KEY = "consent_state";
|
|
79
85
|
var CONSENT_TIMESTAMP_KEY = "consent_timestamp";
|
|
80
|
-
var
|
|
81
|
-
|
|
82
|
-
|
|
86
|
+
var CONSENT_EXPIRES_AT_KEY = "consent_expires_at";
|
|
87
|
+
var DEFAULT_DECLINE_TTL_DAYS = 90;
|
|
88
|
+
var DAY_MS = 864e5;
|
|
89
|
+
var DEFAULT_CHOICE = {
|
|
90
|
+
state: "granted",
|
|
91
|
+
source: "default",
|
|
92
|
+
updatedAt: null,
|
|
93
|
+
expiresAt: null
|
|
94
|
+
};
|
|
95
|
+
var changeListeners = /* @__PURE__ */ new Set();
|
|
96
|
+
function onConsentChange(listener) {
|
|
97
|
+
changeListeners.add(listener);
|
|
83
98
|
return () => {
|
|
84
|
-
|
|
99
|
+
changeListeners.delete(listener);
|
|
85
100
|
};
|
|
86
101
|
}
|
|
102
|
+
function notifyConsentChanged(choice) {
|
|
103
|
+
for (const listener of changeListeners) {
|
|
104
|
+
try {
|
|
105
|
+
listener(choice);
|
|
106
|
+
} catch {
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
87
110
|
function buildConsentPayload(state) {
|
|
88
111
|
return {
|
|
89
112
|
ad_storage: state,
|
|
@@ -92,42 +115,88 @@ function buildConsentPayload(state) {
|
|
|
92
115
|
analytics_storage: state
|
|
93
116
|
};
|
|
94
117
|
}
|
|
95
|
-
function
|
|
96
|
-
if (typeof window === "undefined") return
|
|
118
|
+
function getConsentChoice() {
|
|
119
|
+
if (typeof window === "undefined") return DEFAULT_CHOICE;
|
|
97
120
|
try {
|
|
98
|
-
const
|
|
99
|
-
|
|
121
|
+
const stored = window.localStorage.getItem(CONSENT_STATE_KEY);
|
|
122
|
+
const updatedAt = window.localStorage.getItem(CONSENT_TIMESTAMP_KEY);
|
|
123
|
+
if (stored === "granted")
|
|
124
|
+
return { state: "granted", source: "explicit", updatedAt, expiresAt: null };
|
|
125
|
+
if (stored === "denied") {
|
|
126
|
+
let expiresAt = window.localStorage.getItem(CONSENT_EXPIRES_AT_KEY);
|
|
127
|
+
if (!expiresAt) {
|
|
128
|
+
expiresAt = new Date(Date.now() + DEFAULT_DECLINE_TTL_DAYS * DAY_MS).toISOString();
|
|
129
|
+
try {
|
|
130
|
+
window.localStorage.setItem(CONSENT_EXPIRES_AT_KEY, expiresAt);
|
|
131
|
+
} catch {
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (!(Date.parse(expiresAt) <= Date.now()))
|
|
135
|
+
return { state: "denied", source: "explicit", updatedAt, expiresAt };
|
|
136
|
+
}
|
|
100
137
|
} catch {
|
|
101
138
|
}
|
|
102
|
-
return
|
|
139
|
+
return DEFAULT_CHOICE;
|
|
103
140
|
}
|
|
104
|
-
function
|
|
141
|
+
function getConsentState() {
|
|
142
|
+
return getConsentChoice().state;
|
|
143
|
+
}
|
|
144
|
+
function pushConsentToPlatforms(state) {
|
|
105
145
|
if (typeof window === "undefined") return;
|
|
106
|
-
try {
|
|
107
|
-
window.localStorage.setItem(CONSENT_STATE_KEY, state);
|
|
108
|
-
window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, (/* @__PURE__ */ new Date()).toISOString());
|
|
109
|
-
} catch {
|
|
110
|
-
}
|
|
111
146
|
if (typeof window.gtag === "function")
|
|
112
147
|
window.gtag("consent", "update", buildConsentPayload(state));
|
|
113
148
|
if (typeof window.fbq === "function")
|
|
114
149
|
window.fbq("consent", state === "granted" ? "grant" : "revoke");
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
150
|
+
}
|
|
151
|
+
function setConsentState(state, options) {
|
|
152
|
+
if (typeof window === "undefined") return;
|
|
153
|
+
const requestedTtl = options?.declineTtlDays;
|
|
154
|
+
const ttlDays = typeof requestedTtl === "number" && Number.isFinite(requestedTtl) && requestedTtl > 0 ? requestedTtl : DEFAULT_DECLINE_TTL_DAYS;
|
|
155
|
+
const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
156
|
+
const expiresAt = state === "denied" ? new Date(Date.now() + ttlDays * DAY_MS).toISOString() : null;
|
|
157
|
+
try {
|
|
158
|
+
window.localStorage.setItem(CONSENT_STATE_KEY, state);
|
|
159
|
+
window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, updatedAt);
|
|
160
|
+
if (expiresAt !== null) {
|
|
161
|
+
window.localStorage.setItem(CONSENT_EXPIRES_AT_KEY, expiresAt);
|
|
162
|
+
} else {
|
|
163
|
+
window.localStorage.removeItem(CONSENT_EXPIRES_AT_KEY);
|
|
121
164
|
}
|
|
165
|
+
} catch {
|
|
122
166
|
}
|
|
167
|
+
pushConsentToPlatforms(state);
|
|
168
|
+
notifyConsentChanged({ state, source: "explicit", updatedAt, expiresAt });
|
|
169
|
+
}
|
|
170
|
+
function optIn() {
|
|
171
|
+
setConsentState("granted");
|
|
172
|
+
}
|
|
173
|
+
function optOut(options) {
|
|
174
|
+
setConsentState("denied", options);
|
|
123
175
|
}
|
|
124
176
|
function resetConsent() {
|
|
125
177
|
if (typeof window === "undefined") return;
|
|
126
178
|
try {
|
|
127
179
|
window.localStorage.removeItem(CONSENT_STATE_KEY);
|
|
128
180
|
window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
|
|
181
|
+
window.localStorage.removeItem(CONSENT_EXPIRES_AT_KEY);
|
|
129
182
|
} catch {
|
|
130
183
|
}
|
|
184
|
+
pushConsentToPlatforms("granted");
|
|
185
|
+
notifyConsentChanged(DEFAULT_CHOICE);
|
|
186
|
+
}
|
|
187
|
+
function createEffectiveConsentSnippet() {
|
|
188
|
+
return `
|
|
189
|
+
var aranovaConsent = (function () {
|
|
190
|
+
try {
|
|
191
|
+
if (window.localStorage.getItem('${CONSENT_STATE_KEY}') === 'denied') {
|
|
192
|
+
var exp = window.localStorage.getItem('${CONSENT_EXPIRES_AT_KEY}');
|
|
193
|
+
var expMs = exp ? Date.parse(exp) : NaN;
|
|
194
|
+
if (!(expMs <= Date.now())) return 'denied';
|
|
195
|
+
}
|
|
196
|
+
} catch (e) {}
|
|
197
|
+
return 'granted';
|
|
198
|
+
})();
|
|
199
|
+
`.trim();
|
|
131
200
|
}
|
|
132
201
|
|
|
133
202
|
// ../tracking-core/src/tracking.ts
|
|
@@ -242,12 +311,12 @@ function createConsentDefaultScript() {
|
|
|
242
311
|
window.dataLayer = window.dataLayer || [];
|
|
243
312
|
function gtag(){dataLayer.push(arguments);}
|
|
244
313
|
window.gtag = gtag;
|
|
314
|
+
${createEffectiveConsentSnippet()}
|
|
245
315
|
gtag('consent', 'default', {
|
|
246
|
-
ad_storage:
|
|
247
|
-
ad_user_data:
|
|
248
|
-
ad_personalization:
|
|
249
|
-
analytics_storage:
|
|
250
|
-
wait_for_update: 500,
|
|
316
|
+
ad_storage: aranovaConsent,
|
|
317
|
+
ad_user_data: aranovaConsent,
|
|
318
|
+
ad_personalization: aranovaConsent,
|
|
319
|
+
analytics_storage: aranovaConsent
|
|
251
320
|
});
|
|
252
321
|
`.trim();
|
|
253
322
|
}
|
|
@@ -261,21 +330,6 @@ gtag('js', new Date());
|
|
|
261
330
|
gtag('config', '${gtagId}');
|
|
262
331
|
`.trim();
|
|
263
332
|
}
|
|
264
|
-
function createConsentRestoreScript() {
|
|
265
|
-
return `
|
|
266
|
-
try {
|
|
267
|
-
var consentState = window.localStorage.getItem('consent_state');
|
|
268
|
-
if (window.gtag && (consentState === 'granted' || consentState === 'denied')) {
|
|
269
|
-
window.gtag('consent', 'update', {
|
|
270
|
-
ad_storage: consentState,
|
|
271
|
-
ad_user_data: consentState,
|
|
272
|
-
ad_personalization: consentState,
|
|
273
|
-
analytics_storage: consentState,
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
} catch (e) {}
|
|
277
|
-
`.trim();
|
|
278
|
-
}
|
|
279
333
|
var SEND_TO_RE = /^AW-[A-Za-z0-9]+\/[A-Za-z0-9_-]+$/;
|
|
280
334
|
function isValidSendTo(sendTo) {
|
|
281
335
|
return SEND_TO_RE.test(sendTo);
|
|
@@ -354,7 +408,8 @@ document,'script','${FB_EVENTS_SCRIPT_HOST}');`.trim();
|
|
|
354
408
|
}
|
|
355
409
|
function createMetaConsentDefaultScript() {
|
|
356
410
|
return `${fbqStubScript()}
|
|
357
|
-
|
|
411
|
+
${createEffectiveConsentSnippet()}
|
|
412
|
+
fbq('consent', aranovaConsent === 'denied' ? 'revoke' : 'grant');`;
|
|
358
413
|
}
|
|
359
414
|
function createMetaPixelInitScript(pixelId) {
|
|
360
415
|
if (!isValidMetaPixelId(pixelId)) return "";
|
|
@@ -367,14 +422,71 @@ function createMetaPixelInitScriptMulti(pixelIds) {
|
|
|
367
422
|
return `${inits.join("\n")}
|
|
368
423
|
fbq('track', 'PageView');`;
|
|
369
424
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
425
|
+
|
|
426
|
+
// ../tracking-core/src/landing.ts
|
|
427
|
+
var LANDING_STORAGE_KEY = "_aranova_track_landing";
|
|
428
|
+
var memoryRecord = null;
|
|
429
|
+
function sanitizeParams(value) {
|
|
430
|
+
if (typeof value !== "object" || value === null) return {};
|
|
431
|
+
const source = value;
|
|
432
|
+
return TRACKING_PARAM_KEYS.reduce((params, key) => {
|
|
433
|
+
const entry = source[key];
|
|
434
|
+
if (typeof entry === "string" && entry.length > 0) params[key] = entry;
|
|
435
|
+
return params;
|
|
436
|
+
}, {});
|
|
437
|
+
}
|
|
438
|
+
function readStoredRecord() {
|
|
439
|
+
try {
|
|
440
|
+
const raw = window.localStorage.getItem(LANDING_STORAGE_KEY);
|
|
441
|
+
if (!raw) return null;
|
|
442
|
+
const parsed = JSON.parse(raw);
|
|
443
|
+
if (typeof parsed.session_id !== "string" || parsed.session_id.length === 0) return null;
|
|
444
|
+
return { session_id: parsed.session_id, params: sanitizeParams(parsed.params) };
|
|
445
|
+
} catch {
|
|
446
|
+
return null;
|
|
376
447
|
}
|
|
377
|
-
}
|
|
448
|
+
}
|
|
449
|
+
function writeRecord(record) {
|
|
450
|
+
memoryRecord = record;
|
|
451
|
+
try {
|
|
452
|
+
window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record));
|
|
453
|
+
} catch {
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
function captureFromUrl(url) {
|
|
457
|
+
try {
|
|
458
|
+
const resolved = new URL(url ?? window.location.href, window.location.origin);
|
|
459
|
+
return getTrackingQueryValues(resolved.searchParams);
|
|
460
|
+
} catch {
|
|
461
|
+
return {};
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
function getOrCaptureLandingParams(sessionId, url) {
|
|
465
|
+
if (typeof window === "undefined") return {};
|
|
466
|
+
const stored = readStoredRecord();
|
|
467
|
+
if (stored && stored.session_id === sessionId) {
|
|
468
|
+
memoryRecord = stored;
|
|
469
|
+
return stored.params;
|
|
470
|
+
}
|
|
471
|
+
if (memoryRecord && memoryRecord.session_id === sessionId) {
|
|
472
|
+
return memoryRecord.params;
|
|
473
|
+
}
|
|
474
|
+
const record = { session_id: sessionId, params: captureFromUrl(url) };
|
|
475
|
+
writeRecord(record);
|
|
476
|
+
return record.params;
|
|
477
|
+
}
|
|
478
|
+
function buildLandingPayloadFields(sessionId, override) {
|
|
479
|
+
const params = override ?? (typeof window === "undefined" ? null : getOrCaptureLandingParams(sessionId));
|
|
480
|
+
if (params === null) return {};
|
|
481
|
+
return {
|
|
482
|
+
landing_gclid: params.gclid ?? null,
|
|
483
|
+
landing_fbclid: params.fbclid ?? null,
|
|
484
|
+
landing_utm_source: params.utm_source ?? null,
|
|
485
|
+
landing_utm_medium: params.utm_medium ?? null,
|
|
486
|
+
landing_utm_campaign: params.utm_campaign ?? null,
|
|
487
|
+
landing_utm_term: params.utm_term ?? null,
|
|
488
|
+
landing_utm_content: params.utm_content ?? null
|
|
489
|
+
};
|
|
378
490
|
}
|
|
379
491
|
|
|
380
492
|
// ../tracking-core/src/payloads.ts
|
|
@@ -403,6 +515,9 @@ function createTrackingSessionUpsertPayload(trackingParams, input, context) {
|
|
|
403
515
|
utm_campaign: trackingParams.utm_campaign,
|
|
404
516
|
utm_term: trackingParams.utm_term,
|
|
405
517
|
utm_content: trackingParams.utm_content,
|
|
518
|
+
// Omitted entirely when the landing isn't observable (SSR, no override) —
|
|
519
|
+
// present-as-null would wrongly tell the backend "landed with no params".
|
|
520
|
+
...buildLandingPayloadFields(input.sessionId, input.landingParams),
|
|
406
521
|
first_page: input.firstPage ?? null,
|
|
407
522
|
consent_state: input.consentState ?? null,
|
|
408
523
|
context
|
|
@@ -424,8 +539,6 @@ function createTrackingEventCreatePayload(trackingParams, input, context) {
|
|
|
424
539
|
|
|
425
540
|
// ../tracking-core/src/resources/conversion-firing.ts
|
|
426
541
|
var DEDUP_PREFIX = "_aranova_conv_";
|
|
427
|
-
var MAX_PENDING = 100;
|
|
428
|
-
var pendingQueue = [];
|
|
429
542
|
function dedupKey(input) {
|
|
430
543
|
return `${DEDUP_PREFIX}${input.transactionId ?? ""}:${input.sendTo}`;
|
|
431
544
|
}
|
|
@@ -449,23 +562,9 @@ function fireOnce(input) {
|
|
|
449
562
|
if (fireGtagConversion(input)) markFired(input);
|
|
450
563
|
}
|
|
451
564
|
function fireConversionWithConsent(input) {
|
|
452
|
-
|
|
453
|
-
if (state === "denied") return;
|
|
454
|
-
if (state === "pending") {
|
|
455
|
-
if (pendingQueue.length >= MAX_PENDING) pendingQueue.shift();
|
|
456
|
-
pendingQueue.push(input);
|
|
457
|
-
return;
|
|
458
|
-
}
|
|
565
|
+
if (getConsentState() === "denied") return;
|
|
459
566
|
fireOnce(input);
|
|
460
567
|
}
|
|
461
|
-
function flushPendingConversions() {
|
|
462
|
-
if (getConsentState() !== "granted") return;
|
|
463
|
-
while (pendingQueue.length > 0) {
|
|
464
|
-
const input = pendingQueue.shift();
|
|
465
|
-
if (input) fireOnce(input);
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
if (typeof window !== "undefined") onConsentGranted(flushPendingConversions);
|
|
469
568
|
|
|
470
569
|
// ../tracking-core/src/resources/conversion-config.ts
|
|
471
570
|
function isStringMap(value) {
|
|
@@ -973,7 +1072,13 @@ function readTrackingParams() {
|
|
|
973
1072
|
}
|
|
974
1073
|
function consentSnapshot() {
|
|
975
1074
|
try {
|
|
976
|
-
|
|
1075
|
+
const choice = getConsentChoice();
|
|
1076
|
+
return {
|
|
1077
|
+
state: choice.state,
|
|
1078
|
+
source: choice.source,
|
|
1079
|
+
updated_at: choice.updatedAt,
|
|
1080
|
+
expires_at: choice.expiresAt
|
|
1081
|
+
};
|
|
977
1082
|
} catch {
|
|
978
1083
|
return null;
|
|
979
1084
|
}
|
|
@@ -1046,6 +1151,7 @@ function createTrackingClient(config) {
|
|
|
1046
1151
|
initialParams = captureTrackingParamsFromLocation();
|
|
1047
1152
|
} catch {
|
|
1048
1153
|
}
|
|
1154
|
+
getOrCaptureLandingParams(sessionId);
|
|
1049
1155
|
try {
|
|
1050
1156
|
captureFbc();
|
|
1051
1157
|
} catch {
|
|
@@ -1095,6 +1201,11 @@ function createTrackingClient(config) {
|
|
|
1095
1201
|
utm_campaign: params.utm_campaign,
|
|
1096
1202
|
utm_term: params.utm_term,
|
|
1097
1203
|
utm_content: params.utm_content,
|
|
1204
|
+
// Landing params for the CURRENT session id — captured on the spot when
|
|
1205
|
+
// the session just rotated (the current URL is the rotated session's
|
|
1206
|
+
// landing), reused from the stored record otherwise. Keys are omitted
|
|
1207
|
+
// entirely when the landing isn't observable (SSR).
|
|
1208
|
+
...buildLandingPayloadFields(sessionId),
|
|
1098
1209
|
first_page: firstPage,
|
|
1099
1210
|
consent_state: consentSnapshot(),
|
|
1100
1211
|
context
|
|
@@ -1162,6 +1273,7 @@ function createTrackingClient(config) {
|
|
|
1162
1273
|
return {
|
|
1163
1274
|
trackEvent,
|
|
1164
1275
|
flush,
|
|
1276
|
+
flushBeacon: flushOnUnload,
|
|
1165
1277
|
getSessionId: () => sessionId,
|
|
1166
1278
|
getVisitorId: () => visitorId,
|
|
1167
1279
|
destroy: () => {
|
|
@@ -1186,9 +1298,17 @@ var ctaClickMetadataSchema = import_zod2.z.object({
|
|
|
1186
1298
|
path: import_zod2.z.string()
|
|
1187
1299
|
}).strict(),
|
|
1188
1300
|
section: import_zod2.z.string().nullable().optional(),
|
|
1189
|
-
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()
|
|
1190
1311
|
}).strict();
|
|
1191
|
-
var ctaClickConfigSchema = import_zod2.z.object({}).strict();
|
|
1192
1312
|
|
|
1193
1313
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
1194
1314
|
var import_zod3 = require("zod");
|
|
@@ -1264,31 +1384,44 @@ var multiPageSessionConfigSchema = import_zod6.z.object({
|
|
|
1264
1384
|
pageThreshold: import_zod6.z.number().int().min(2)
|
|
1265
1385
|
}).strict();
|
|
1266
1386
|
|
|
1267
|
-
// ../tracking-core/src/events/
|
|
1387
|
+
// ../tracking-core/src/events/page-exit.ts
|
|
1268
1388
|
var import_zod7 = require("zod");
|
|
1269
|
-
var
|
|
1270
|
-
|
|
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(),
|
|
1271
1394
|
page: import_zod7.z.object({
|
|
1272
1395
|
path: import_zod7.z.string()
|
|
1273
|
-
}).strict()
|
|
1274
|
-
section: import_zod7.z.string().nullable().optional()
|
|
1396
|
+
}).strict()
|
|
1275
1397
|
}).strict();
|
|
1276
|
-
var
|
|
1398
|
+
var pageExitConfigSchema = import_zod7.z.object({}).strict();
|
|
1277
1399
|
|
|
1278
|
-
// ../tracking-core/src/events/
|
|
1400
|
+
// ../tracking-core/src/events/phone-click.ts
|
|
1279
1401
|
var import_zod8 = require("zod");
|
|
1280
|
-
var
|
|
1281
|
-
|
|
1402
|
+
var phoneClickMetadataSchema = import_zod8.z.object({
|
|
1403
|
+
phone_number: import_zod8.z.string(),
|
|
1282
1404
|
page: import_zod8.z.object({
|
|
1283
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()
|
|
1284
1417
|
}).strict()
|
|
1285
1418
|
}).strict();
|
|
1286
|
-
var scrollDepthConfigSchema =
|
|
1287
|
-
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)
|
|
1288
1421
|
}).strict();
|
|
1289
1422
|
|
|
1290
1423
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
1291
|
-
var
|
|
1424
|
+
var import_zod10 = require("zod");
|
|
1292
1425
|
var SPECIFIC_PAGE_NAMES = [
|
|
1293
1426
|
"contact_page",
|
|
1294
1427
|
"about_page",
|
|
@@ -1299,18 +1432,18 @@ var SPECIFIC_PAGE_NAMES = [
|
|
|
1299
1432
|
"faq_page",
|
|
1300
1433
|
"testimonials_page"
|
|
1301
1434
|
];
|
|
1302
|
-
var specificPageNameSchema =
|
|
1303
|
-
var specificPageVisitMetadataSchema =
|
|
1435
|
+
var specificPageNameSchema = import_zod10.z.enum(SPECIFIC_PAGE_NAMES);
|
|
1436
|
+
var specificPageVisitMetadataSchema = import_zod10.z.object({
|
|
1304
1437
|
page_name: specificPageNameSchema,
|
|
1305
|
-
page:
|
|
1306
|
-
path:
|
|
1438
|
+
page: import_zod10.z.object({
|
|
1439
|
+
path: import_zod10.z.string()
|
|
1307
1440
|
}).strict()
|
|
1308
1441
|
}).strict();
|
|
1309
|
-
var specificPageVisitConfigSchema =
|
|
1310
|
-
pages:
|
|
1311
|
-
|
|
1442
|
+
var specificPageVisitConfigSchema = import_zod10.z.object({
|
|
1443
|
+
pages: import_zod10.z.array(
|
|
1444
|
+
import_zod10.z.object({
|
|
1312
1445
|
name: specificPageNameSchema,
|
|
1313
|
-
pathPattern:
|
|
1446
|
+
pathPattern: import_zod10.z.custom((value) => value instanceof RegExp, {
|
|
1314
1447
|
message: "pathPattern must be a RegExp"
|
|
1315
1448
|
})
|
|
1316
1449
|
}).strict()
|
|
@@ -1318,15 +1451,15 @@ var specificPageVisitConfigSchema = import_zod9.z.object({
|
|
|
1318
1451
|
}).strict();
|
|
1319
1452
|
|
|
1320
1453
|
// ../tracking-core/src/events/time-on-site.ts
|
|
1321
|
-
var
|
|
1322
|
-
var timeOnSiteMetadataSchema =
|
|
1323
|
-
duration_ms:
|
|
1324
|
-
page:
|
|
1325
|
-
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()
|
|
1326
1459
|
}).strict()
|
|
1327
1460
|
}).strict();
|
|
1328
|
-
var timeOnSiteConfigSchema =
|
|
1329
|
-
thresholdSeconds:
|
|
1461
|
+
var timeOnSiteConfigSchema = import_zod11.z.object({
|
|
1462
|
+
thresholdSeconds: import_zod11.z.number().int().positive()
|
|
1330
1463
|
}).strict();
|
|
1331
1464
|
|
|
1332
1465
|
// ../tracking-core/src/events/registry.ts
|
|
@@ -1368,6 +1501,11 @@ var EVENT_REGISTRY = {
|
|
|
1368
1501
|
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
1369
1502
|
configSchema: sdkHeartbeatConfigSchema
|
|
1370
1503
|
},
|
|
1504
|
+
page_exit: {
|
|
1505
|
+
kind: "automatic",
|
|
1506
|
+
metadataSchema: pageExitMetadataSchema,
|
|
1507
|
+
configSchema: pageExitConfigSchema
|
|
1508
|
+
},
|
|
1371
1509
|
// --- manual triggers ---
|
|
1372
1510
|
form_submit: {
|
|
1373
1511
|
kind: "manual",
|
|
@@ -1611,6 +1749,163 @@ function attachFormStart(client, config) {
|
|
|
1611
1749
|
};
|
|
1612
1750
|
}
|
|
1613
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
|
+
|
|
1614
1909
|
// ../tracking-core/src/resources/sales/errors.ts
|
|
1615
1910
|
var AranovaApiError = class extends Error {
|
|
1616
1911
|
constructor(message, options) {
|
|
@@ -1817,42 +2112,42 @@ function createSalesClient(config) {
|
|
|
1817
2112
|
}
|
|
1818
2113
|
|
|
1819
2114
|
// ../tracking-core/src/resources/sales/schema.ts
|
|
1820
|
-
var
|
|
2115
|
+
var import_zod12 = require("zod");
|
|
1821
2116
|
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
1822
2117
|
var TRACKING_ENVIRONMENTS = ["production", "development"];
|
|
1823
|
-
var currencySchema =
|
|
1824
|
-
var centsSchema =
|
|
1825
|
-
var quantitySchema =
|
|
1826
|
-
var metadataSchema =
|
|
1827
|
-
var saleItemSchema =
|
|
1828
|
-
external_item_id:
|
|
1829
|
-
name:
|
|
1830
|
-
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(),
|
|
1831
2126
|
quantity: quantitySchema,
|
|
1832
2127
|
unit_price_cents: centsSchema,
|
|
1833
2128
|
// Non-negativity validated on the wire — same contract as the other cents
|
|
1834
2129
|
// fields — and backstopped by the DB CHECK.
|
|
1835
2130
|
unit_cost_cents: centsSchema.nullable().optional()
|
|
1836
2131
|
}).strict();
|
|
1837
|
-
var saleServiceSchema =
|
|
1838
|
-
service:
|
|
2132
|
+
var saleServiceSchema = import_zod12.z.object({
|
|
2133
|
+
service: import_zod12.z.string(),
|
|
1839
2134
|
amount_cents: centsSchema
|
|
1840
2135
|
}).strict();
|
|
1841
|
-
var customerNameSchema =
|
|
1842
|
-
var customerPhoneSchema =
|
|
1843
|
-
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();
|
|
1844
2139
|
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
1845
2140
|
if (val.services != null) {
|
|
1846
2141
|
if (val.service != null) {
|
|
1847
2142
|
ctx.addIssue({
|
|
1848
|
-
code:
|
|
2143
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
1849
2144
|
message: "pass either `service` or `services`, not both",
|
|
1850
2145
|
path: ["services"]
|
|
1851
2146
|
});
|
|
1852
2147
|
}
|
|
1853
2148
|
if (val.services.length === 0) {
|
|
1854
2149
|
ctx.addIssue({
|
|
1855
|
-
code:
|
|
2150
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
1856
2151
|
message: "`services` must not be empty",
|
|
1857
2152
|
path: ["services"]
|
|
1858
2153
|
});
|
|
@@ -1860,7 +2155,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
1860
2155
|
const keys = val.services.map((s) => s.service);
|
|
1861
2156
|
if (new Set(keys).size !== keys.length) {
|
|
1862
2157
|
ctx.addIssue({
|
|
1863
|
-
code:
|
|
2158
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
1864
2159
|
message: "`services` must not list the same service more than once",
|
|
1865
2160
|
path: ["services"]
|
|
1866
2161
|
});
|
|
@@ -1869,7 +2164,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
1869
2164
|
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
1870
2165
|
if (val.amount_total_cents !== sum) {
|
|
1871
2166
|
ctx.addIssue({
|
|
1872
|
-
code:
|
|
2167
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
1873
2168
|
message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
|
|
1874
2169
|
path: ["amount_total_cents"]
|
|
1875
2170
|
});
|
|
@@ -1877,37 +2172,37 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
1877
2172
|
}
|
|
1878
2173
|
} else if (requireAmount && val.amount_total_cents == null) {
|
|
1879
2174
|
ctx.addIssue({
|
|
1880
|
-
code:
|
|
2175
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
1881
2176
|
message: "amount_total_cents is required unless `services` is provided",
|
|
1882
2177
|
path: ["amount_total_cents"]
|
|
1883
2178
|
});
|
|
1884
2179
|
}
|
|
1885
2180
|
}
|
|
1886
|
-
var saleCreateSchema =
|
|
1887
|
-
external_id:
|
|
1888
|
-
description:
|
|
1889
|
-
service:
|
|
1890
|
-
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(),
|
|
1891
2186
|
currency: currencySchema,
|
|
1892
2187
|
// Optional only because the plural `services` form derives it from the sum
|
|
1893
2188
|
// (see refineServiceXor); the singular/serviceless path still requires it.
|
|
1894
2189
|
amount_total_cents: centsSchema.nullable().optional(),
|
|
1895
|
-
occurred_at:
|
|
1896
|
-
environment:
|
|
1897
|
-
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([]),
|
|
1898
2193
|
metadata: metadataSchema.nullable().optional(),
|
|
1899
2194
|
customer_name: customerNameSchema.nullable().optional(),
|
|
1900
2195
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
1901
2196
|
customer_email: customerEmailSchema.nullable().optional()
|
|
1902
2197
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
1903
|
-
var saleUpdateSchema =
|
|
1904
|
-
description:
|
|
1905
|
-
service:
|
|
1906
|
-
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(),
|
|
1907
2202
|
currency: currencySchema.optional(),
|
|
1908
2203
|
amount_total_cents: centsSchema.optional(),
|
|
1909
|
-
occurred_at:
|
|
1910
|
-
items:
|
|
2204
|
+
occurred_at: import_zod12.z.string().datetime().optional(),
|
|
2205
|
+
items: import_zod12.z.array(saleItemSchema).optional(),
|
|
1911
2206
|
metadata: metadataSchema.nullable().optional(),
|
|
1912
2207
|
customer_name: customerNameSchema.nullable().optional(),
|
|
1913
2208
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
@@ -1997,36 +2292,68 @@ function useTrackingParams() {
|
|
|
1997
2292
|
}, []);
|
|
1998
2293
|
return trackingParams;
|
|
1999
2294
|
}
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2295
|
+
var DEFAULT_CHOICE2 = {
|
|
2296
|
+
state: "granted",
|
|
2297
|
+
source: "default",
|
|
2298
|
+
updatedAt: null,
|
|
2299
|
+
expiresAt: null
|
|
2300
|
+
};
|
|
2301
|
+
function useCookiePreferences(options) {
|
|
2302
|
+
const [choice, setChoice] = (0, import_react.useState)(DEFAULT_CHOICE2);
|
|
2303
|
+
const ttlDays = options?.declineTtlDays;
|
|
2005
2304
|
(0, import_react.useEffect)(() => {
|
|
2006
|
-
|
|
2305
|
+
const sync = () => setChoice(getConsentChoice());
|
|
2306
|
+
sync();
|
|
2007
2307
|
const handleStorage = (event) => {
|
|
2008
|
-
if (event.key === CONSENT_STATE_KEY
|
|
2308
|
+
if (event.key === null || event.key === CONSENT_STATE_KEY || event.key === CONSENT_EXPIRES_AT_KEY || event.key === CONSENT_TIMESTAMP_KEY)
|
|
2309
|
+
sync();
|
|
2009
2310
|
};
|
|
2010
2311
|
window.addEventListener("storage", handleStorage);
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2312
|
+
const unsubscribe = onConsentChange(sync);
|
|
2313
|
+
return () => {
|
|
2314
|
+
window.removeEventListener("storage", handleStorage);
|
|
2315
|
+
unsubscribe();
|
|
2316
|
+
};
|
|
2016
2317
|
}, []);
|
|
2017
|
-
const
|
|
2018
|
-
|
|
2019
|
-
|
|
2318
|
+
const optOutAction = (0, import_react.useCallback)(() => {
|
|
2319
|
+
optOut(ttlDays != null ? { declineTtlDays: ttlDays } : void 0);
|
|
2320
|
+
}, [ttlDays]);
|
|
2321
|
+
const optInAction = (0, import_react.useCallback)(() => {
|
|
2322
|
+
optIn();
|
|
2020
2323
|
}, []);
|
|
2021
2324
|
const reset = (0, import_react.useCallback)(() => {
|
|
2022
2325
|
resetConsent();
|
|
2023
|
-
setState("pending");
|
|
2024
2326
|
}, []);
|
|
2327
|
+
return {
|
|
2328
|
+
state: choice.state,
|
|
2329
|
+
source: choice.source,
|
|
2330
|
+
isDefault: choice.source === "default",
|
|
2331
|
+
isGranted: choice.state === "granted",
|
|
2332
|
+
isDenied: choice.state === "denied",
|
|
2333
|
+
updatedAt: choice.updatedAt,
|
|
2334
|
+
expiresAt: choice.expiresAt,
|
|
2335
|
+
optOut: optOutAction,
|
|
2336
|
+
optIn: optInAction,
|
|
2337
|
+
reset
|
|
2338
|
+
};
|
|
2339
|
+
}
|
|
2340
|
+
function useConsentState() {
|
|
2341
|
+
return useConsent().state;
|
|
2342
|
+
}
|
|
2343
|
+
function useConsent() {
|
|
2344
|
+
const {
|
|
2345
|
+
state,
|
|
2346
|
+
isGranted,
|
|
2347
|
+
isDenied,
|
|
2348
|
+
optIn: accept,
|
|
2349
|
+
optOut: decline,
|
|
2350
|
+
reset
|
|
2351
|
+
} = useCookiePreferences();
|
|
2025
2352
|
return {
|
|
2026
2353
|
state,
|
|
2027
|
-
isPending:
|
|
2028
|
-
isGranted
|
|
2029
|
-
isDenied
|
|
2354
|
+
isPending: false,
|
|
2355
|
+
isGranted,
|
|
2356
|
+
isDenied,
|
|
2030
2357
|
accept,
|
|
2031
2358
|
decline,
|
|
2032
2359
|
reset
|
|
@@ -2242,13 +2569,11 @@ function AdPlatformTracking({
|
|
|
2242
2569
|
strategy: "afterInteractive"
|
|
2243
2570
|
}
|
|
2244
2571
|
),
|
|
2245
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "gtag-init", strategy: "afterInteractive", children: gtagInitScript })
|
|
2246
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "consent-restore", strategy: "afterInteractive", children: createConsentRestoreScript() })
|
|
2572
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "gtag-init", strategy: "afterInteractive", children: gtagInitScript })
|
|
2247
2573
|
] }) : null,
|
|
2248
2574
|
metaAll.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
2249
2575
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "meta-pixel-base", strategy: "afterInteractive", children: createMetaConsentDefaultScript() }),
|
|
2250
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "meta-pixel-init", strategy: "afterInteractive", children: metaInitScript })
|
|
2251
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "meta-pixel-consent-restore", strategy: "afterInteractive", children: createMetaConsentRestoreScript() })
|
|
2576
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "meta-pixel-init", strategy: "afterInteractive", children: metaInitScript })
|
|
2252
2577
|
] }) : null
|
|
2253
2578
|
] });
|
|
2254
2579
|
}
|
|
@@ -2271,8 +2596,7 @@ function GoogleAdsTracking(props) {
|
|
|
2271
2596
|
strategy: "afterInteractive"
|
|
2272
2597
|
}
|
|
2273
2598
|
),
|
|
2274
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_script2.default, { id: "gtag-init", strategy: "afterInteractive", children: initScript })
|
|
2275
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_script2.default, { id: "consent-restore", strategy: "afterInteractive", children: createConsentRestoreScript() })
|
|
2599
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_script2.default, { id: "gtag-init", strategy: "afterInteractive", children: initScript })
|
|
2276
2600
|
] });
|
|
2277
2601
|
}
|
|
2278
2602
|
|
|
@@ -2280,7 +2604,7 @@ function GoogleAdsTracking(props) {
|
|
|
2280
2604
|
var import_navigation = require("next/navigation");
|
|
2281
2605
|
|
|
2282
2606
|
// package.json
|
|
2283
|
-
var version = "0.
|
|
2607
|
+
var version = "0.16.0";
|
|
2284
2608
|
|
|
2285
2609
|
// src/factory.tsx
|
|
2286
2610
|
var import_react4 = require("react");
|
|
@@ -2561,6 +2885,7 @@ function createTracking(options) {
|
|
|
2561
2885
|
debug
|
|
2562
2886
|
});
|
|
2563
2887
|
const detectorClient = wrapClient(rawClient);
|
|
2888
|
+
detachers.push(attachPageExit(detectorClient));
|
|
2564
2889
|
const scrollDepth = triggers.automatic.scroll_depth;
|
|
2565
2890
|
if (scrollDepth) {
|
|
2566
2891
|
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
@@ -2569,6 +2894,10 @@ function createTracking(options) {
|
|
|
2569
2894
|
if (formStart) {
|
|
2570
2895
|
detachers.push(attachFormStart(detectorClient, formStart));
|
|
2571
2896
|
}
|
|
2897
|
+
const ctaClick = triggers.manual?.cta_click;
|
|
2898
|
+
if (ctaClick) {
|
|
2899
|
+
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
2900
|
+
}
|
|
2572
2901
|
return () => {
|
|
2573
2902
|
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
2574
2903
|
detachers[i]();
|
|
@@ -2593,6 +2922,7 @@ function createTracking(options) {
|
|
|
2593
2922
|
AdPlatformTracking,
|
|
2594
2923
|
AranovaApiError,
|
|
2595
2924
|
ConsentBanner,
|
|
2925
|
+
DEFAULT_DECLINE_TTL_DAYS,
|
|
2596
2926
|
DEFAULT_PHONE_COUNTRY,
|
|
2597
2927
|
GoogleAdsTracking,
|
|
2598
2928
|
NAMED_RANGES,
|
|
@@ -2612,7 +2942,11 @@ function createTracking(options) {
|
|
|
2612
2942
|
formatPhone,
|
|
2613
2943
|
formatPhoneAsTyped,
|
|
2614
2944
|
fromMinor,
|
|
2945
|
+
getConsentChoice,
|
|
2615
2946
|
getConsentState,
|
|
2947
|
+
onConsentChange,
|
|
2948
|
+
optIn,
|
|
2949
|
+
optOut,
|
|
2616
2950
|
parsePhone,
|
|
2617
2951
|
phoneField,
|
|
2618
2952
|
resetConsent,
|
|
@@ -2627,6 +2961,7 @@ function createTracking(options) {
|
|
|
2627
2961
|
toMinor,
|
|
2628
2962
|
useConsent,
|
|
2629
2963
|
useConsentState,
|
|
2964
|
+
useCookiePreferences,
|
|
2630
2965
|
useGclid,
|
|
2631
2966
|
usePhoneConfig,
|
|
2632
2967
|
usePhoneField,
|