@aranova/tracking-next 0.12.2 → 0.14.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 +38 -0
- package/dist/index.d.mts +52 -16
- package/dist/index.d.ts +52 -16
- package/dist/index.js +699 -181
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +697 -181
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.js +73 -0
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +73 -0
- package/dist/middleware.mjs.map +1 -1
- package/dist/{phone-utils-BVUDHwo4.d.mts → phone-utils-CcU5mwzc.d.mts} +26 -1
- package/dist/{phone-utils-BVUDHwo4.d.ts → phone-utils-CcU5mwzc.d.ts} +26 -1
- package/dist/phone.d.mts +1 -1
- package/dist/phone.d.ts +1 -1
- package/dist/phone.js +73 -0
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +73 -0
- package/dist/phone.mjs.map +1 -1
- package/dist/sales-BsJodmh0.d.mts +887 -0
- package/dist/sales-BsJodmh0.d.ts +887 -0
- package/dist/sales.d.mts +2 -784
- package/dist/sales.d.ts +2 -784
- package/dist/sales.js +172 -45
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +172 -45
- 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 +73 -0
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +73 -0
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
// ../tracking-core/src/consent.ts
|
|
2
2
|
var CONSENT_STATE_KEY = "consent_state";
|
|
3
3
|
var CONSENT_TIMESTAMP_KEY = "consent_timestamp";
|
|
4
|
+
var grantedListeners = /* @__PURE__ */ new Set();
|
|
5
|
+
function onConsentGranted(listener) {
|
|
6
|
+
grantedListeners.add(listener);
|
|
7
|
+
return () => {
|
|
8
|
+
grantedListeners.delete(listener);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
4
11
|
function buildConsentPayload(state) {
|
|
5
12
|
return {
|
|
6
13
|
ad_storage: state,
|
|
@@ -11,62 +18,142 @@ function buildConsentPayload(state) {
|
|
|
11
18
|
}
|
|
12
19
|
function getConsentState() {
|
|
13
20
|
if (typeof window === "undefined") return "pending";
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
try {
|
|
22
|
+
const storedState = window.localStorage.getItem(CONSENT_STATE_KEY);
|
|
23
|
+
if (storedState === "granted" || storedState === "denied") return storedState;
|
|
24
|
+
} catch {
|
|
25
|
+
}
|
|
16
26
|
return "pending";
|
|
17
27
|
}
|
|
18
28
|
function setConsentState(state) {
|
|
19
29
|
if (typeof window === "undefined") return;
|
|
20
|
-
|
|
21
|
-
|
|
30
|
+
try {
|
|
31
|
+
window.localStorage.setItem(CONSENT_STATE_KEY, state);
|
|
32
|
+
window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, (/* @__PURE__ */ new Date()).toISOString());
|
|
33
|
+
} catch {
|
|
34
|
+
}
|
|
22
35
|
if (typeof window.gtag === "function")
|
|
23
36
|
window.gtag("consent", "update", buildConsentPayload(state));
|
|
37
|
+
if (typeof window.fbq === "function")
|
|
38
|
+
window.fbq("consent", state === "granted" ? "grant" : "revoke");
|
|
39
|
+
if (state === "granted") {
|
|
40
|
+
for (const listener of grantedListeners) {
|
|
41
|
+
try {
|
|
42
|
+
listener();
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
24
47
|
}
|
|
25
48
|
function resetConsent() {
|
|
26
49
|
if (typeof window === "undefined") return;
|
|
27
|
-
|
|
28
|
-
|
|
50
|
+
try {
|
|
51
|
+
window.localStorage.removeItem(CONSENT_STATE_KEY);
|
|
52
|
+
window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
|
|
53
|
+
} catch {
|
|
54
|
+
}
|
|
29
55
|
}
|
|
30
56
|
|
|
31
|
-
// ../tracking-core/src/
|
|
32
|
-
|
|
57
|
+
// ../tracking-core/src/tracking.ts
|
|
58
|
+
var TRACKING_COOKIE_MAX_AGE_SECONDS = 7776e3;
|
|
59
|
+
var TRACKING_PARAM_KEYS = [
|
|
60
|
+
"gclid",
|
|
61
|
+
"fbclid",
|
|
62
|
+
"utm_source",
|
|
63
|
+
"utm_medium",
|
|
64
|
+
"utm_campaign",
|
|
65
|
+
"utm_term",
|
|
66
|
+
"utm_content"
|
|
67
|
+
];
|
|
68
|
+
function createEmptyTrackingParams() {
|
|
33
69
|
return {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
active_gtag_ids: input.activeGtagIds ?? null
|
|
70
|
+
gclid: null,
|
|
71
|
+
fbclid: null,
|
|
72
|
+
utm_source: null,
|
|
73
|
+
utm_medium: null,
|
|
74
|
+
utm_campaign: null,
|
|
75
|
+
utm_term: null,
|
|
76
|
+
utm_content: null
|
|
42
77
|
};
|
|
43
78
|
}
|
|
44
|
-
function
|
|
45
|
-
return
|
|
46
|
-
session_id: input.sessionId,
|
|
47
|
-
visitor_id: input.visitorId ?? null,
|
|
48
|
-
gclid: trackingParams.gclid,
|
|
49
|
-
fbclid: trackingParams.fbclid,
|
|
50
|
-
utm_source: trackingParams.utm_source,
|
|
51
|
-
utm_medium: trackingParams.utm_medium,
|
|
52
|
-
utm_campaign: trackingParams.utm_campaign,
|
|
53
|
-
utm_term: trackingParams.utm_term,
|
|
54
|
-
utm_content: trackingParams.utm_content,
|
|
55
|
-
first_page: input.firstPage ?? null,
|
|
56
|
-
consent_state: input.consentState ?? null,
|
|
57
|
-
context
|
|
58
|
-
};
|
|
79
|
+
function normalizeTrackingCookieValue(value) {
|
|
80
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
59
81
|
}
|
|
60
|
-
function
|
|
61
|
-
return {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
82
|
+
function getTrackingParamsFromCookieReader(readCookie) {
|
|
83
|
+
return TRACKING_PARAM_KEYS.reduce((params, key) => {
|
|
84
|
+
params[key] = normalizeTrackingCookieValue(readCookie(key));
|
|
85
|
+
return params;
|
|
86
|
+
}, createEmptyTrackingParams());
|
|
87
|
+
}
|
|
88
|
+
function getTrackingQueryValues(searchParams) {
|
|
89
|
+
return TRACKING_PARAM_KEYS.reduce((params, key) => {
|
|
90
|
+
const value = searchParams.get(key);
|
|
91
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
92
|
+
params[key] = value;
|
|
93
|
+
}
|
|
94
|
+
return params;
|
|
95
|
+
}, {});
|
|
96
|
+
}
|
|
97
|
+
var FALLBACK_STORAGE_PREFIX = "_aranova_track_";
|
|
98
|
+
function fallbackKey(name) {
|
|
99
|
+
return `${FALLBACK_STORAGE_PREFIX}${name}`;
|
|
100
|
+
}
|
|
101
|
+
function persistCookieValue(name, value, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
|
|
102
|
+
const encoded = encodeURIComponent(value);
|
|
103
|
+
if (typeof document !== "undefined") {
|
|
104
|
+
try {
|
|
105
|
+
document.cookie = `${name}=${encoded}; Max-Age=${maxAgeSeconds}; Path=/; SameSite=Lax`;
|
|
106
|
+
} catch {
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
if (typeof window !== "undefined") {
|
|
110
|
+
try {
|
|
111
|
+
window.localStorage.setItem(fallbackKey(name), encoded);
|
|
112
|
+
} catch {
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
function readCookieValue(name) {
|
|
117
|
+
if (typeof document !== "undefined") {
|
|
118
|
+
const cookies = document.cookie ? document.cookie.split("; ") : [];
|
|
119
|
+
const match = cookies.find((cookie) => cookie.startsWith(`${name}=`));
|
|
120
|
+
if (match) {
|
|
121
|
+
const [, rawValue = ""] = match.split("=");
|
|
122
|
+
return normalizeTrackingCookieValue(decodeURIComponent(rawValue));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (typeof window !== "undefined") {
|
|
126
|
+
try {
|
|
127
|
+
const stored = window.localStorage.getItem(fallbackKey(name));
|
|
128
|
+
if (stored) return normalizeTrackingCookieValue(decodeURIComponent(stored));
|
|
129
|
+
} catch {
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
function getCookieValueFromDocument(key) {
|
|
135
|
+
return readCookieValue(key);
|
|
136
|
+
}
|
|
137
|
+
function setTrackingCookie(key, value, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
|
|
138
|
+
persistCookieValue(key, value, maxAgeSeconds);
|
|
139
|
+
}
|
|
140
|
+
function mergeTrackingParams(primary, fallback) {
|
|
141
|
+
return TRACKING_PARAM_KEYS.reduce((merged, key) => {
|
|
142
|
+
merged[key] = primary[key] ?? fallback[key];
|
|
143
|
+
return merged;
|
|
144
|
+
}, createEmptyTrackingParams());
|
|
145
|
+
}
|
|
146
|
+
function persistTrackingParamsFromSearchParams(searchParams, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
|
|
147
|
+
const trackingValues = getTrackingQueryValues(searchParams);
|
|
148
|
+
Object.entries(trackingValues).forEach(([key, value]) => {
|
|
149
|
+
setTrackingCookie(key, value, maxAgeSeconds);
|
|
150
|
+
});
|
|
151
|
+
return trackingValues;
|
|
152
|
+
}
|
|
153
|
+
function captureTrackingParamsFromLocation(url = typeof window === "undefined" ? "" : window.location.href, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
|
|
154
|
+
const resolvedUrl = typeof window === "undefined" ? new URL(url || "https://example.invalid") : new URL(url, window.location.origin);
|
|
155
|
+
persistTrackingParamsFromSearchParams(resolvedUrl.searchParams, maxAgeSeconds);
|
|
156
|
+
return getTrackingParamsFromCookieReader(getCookieValueFromDocument);
|
|
70
157
|
}
|
|
71
158
|
|
|
72
159
|
// ../tracking-core/src/gtag.ts
|
|
@@ -100,17 +187,37 @@ gtag('config', '${gtagId}');
|
|
|
100
187
|
}
|
|
101
188
|
function createConsentRestoreScript() {
|
|
102
189
|
return `
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
window.gtag('
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
190
|
+
try {
|
|
191
|
+
var consentState = window.localStorage.getItem('consent_state');
|
|
192
|
+
if (window.gtag && (consentState === 'granted' || consentState === 'denied')) {
|
|
193
|
+
window.gtag('consent', 'update', {
|
|
194
|
+
ad_storage: consentState,
|
|
195
|
+
ad_user_data: consentState,
|
|
196
|
+
ad_personalization: consentState,
|
|
197
|
+
analytics_storage: consentState,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
} catch (e) {}
|
|
112
201
|
`.trim();
|
|
113
202
|
}
|
|
203
|
+
var SEND_TO_RE = /^AW-[A-Za-z0-9]+\/[A-Za-z0-9_-]+$/;
|
|
204
|
+
function isValidSendTo(sendTo) {
|
|
205
|
+
return SEND_TO_RE.test(sendTo);
|
|
206
|
+
}
|
|
207
|
+
function fireGtagConversion(input) {
|
|
208
|
+
if (typeof window === "undefined" || typeof window.gtag !== "function") return false;
|
|
209
|
+
if (!isValidSendTo(input.sendTo)) return false;
|
|
210
|
+
const params = { send_to: input.sendTo };
|
|
211
|
+
if (input.value != null) params.value = input.value;
|
|
212
|
+
if (input.currency) params.currency = input.currency;
|
|
213
|
+
if (input.transactionId) params.transaction_id = input.transactionId;
|
|
214
|
+
try {
|
|
215
|
+
window.gtag("event", "conversion", params);
|
|
216
|
+
return true;
|
|
217
|
+
} catch {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
114
221
|
function createGtagInitScriptMulti(gtagIds) {
|
|
115
222
|
const safeIds = gtagIds.filter(isValidGtagId);
|
|
116
223
|
const configs = safeIds.map((id) => `gtag('config', '${id}');`).join("\n");
|
|
@@ -123,70 +230,403 @@ ${configs}
|
|
|
123
230
|
`.trim();
|
|
124
231
|
}
|
|
125
232
|
|
|
126
|
-
// ../tracking-core/src/
|
|
127
|
-
var
|
|
128
|
-
var
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
"
|
|
136
|
-
|
|
137
|
-
|
|
233
|
+
// ../tracking-core/src/fbq.ts
|
|
234
|
+
var FB_EVENTS_SCRIPT_HOST = "https://connect.facebook.net/en_US/fbevents.js";
|
|
235
|
+
var FBC_COOKIE = "_fbc";
|
|
236
|
+
var FBP_COOKIE = "_fbp";
|
|
237
|
+
var META_PIXEL_ID_PATTERN = /^\d{15,16}$/;
|
|
238
|
+
function isValidMetaPixelId(id) {
|
|
239
|
+
return META_PIXEL_ID_PATTERN.test(id);
|
|
240
|
+
}
|
|
241
|
+
function computeFbSubdomainIndex(hostname) {
|
|
242
|
+
const labels = hostname.split(".").filter(Boolean);
|
|
243
|
+
return Math.max(0, labels.length - 1);
|
|
244
|
+
}
|
|
245
|
+
function buildFbc(fbclid, now, hostname) {
|
|
246
|
+
const host = hostname ?? (typeof window === "undefined" ? "" : window.location.hostname);
|
|
247
|
+
return `fb.${computeFbSubdomainIndex(host)}.${now}.${fbclid}`;
|
|
248
|
+
}
|
|
249
|
+
function getFbcCookie() {
|
|
250
|
+
return readCookieValue(FBC_COOKIE);
|
|
251
|
+
}
|
|
252
|
+
function getFbpCookie() {
|
|
253
|
+
return readCookieValue(FBP_COOKIE);
|
|
254
|
+
}
|
|
255
|
+
function readFbclidFromUrl() {
|
|
256
|
+
if (typeof window === "undefined") return null;
|
|
257
|
+
try {
|
|
258
|
+
const value = new URL(window.location.href).searchParams.get("fbclid");
|
|
259
|
+
return value && value.trim().length > 0 ? value : null;
|
|
260
|
+
} catch {
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
function captureFbc(now = typeof Date === "undefined" ? 0 : Date.now()) {
|
|
265
|
+
if (typeof window === "undefined") return;
|
|
266
|
+
if (getFbcCookie()) return;
|
|
267
|
+
const fbclid = readFbclidFromUrl() ?? readCookieValue("fbclid");
|
|
268
|
+
if (!fbclid) return;
|
|
269
|
+
persistCookieValue(FBC_COOKIE, buildFbc(fbclid, now), TRACKING_COOKIE_MAX_AGE_SECONDS);
|
|
270
|
+
}
|
|
271
|
+
function fbqStubScript() {
|
|
272
|
+
return `
|
|
273
|
+
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
|
|
274
|
+
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
|
|
275
|
+
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
|
|
276
|
+
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
|
|
277
|
+
document,'script','${FB_EVENTS_SCRIPT_HOST}');`.trim();
|
|
278
|
+
}
|
|
279
|
+
function createMetaConsentDefaultScript() {
|
|
280
|
+
return `${fbqStubScript()}
|
|
281
|
+
fbq('consent', 'revoke');`;
|
|
282
|
+
}
|
|
283
|
+
function createMetaPixelInitScript(pixelId) {
|
|
284
|
+
if (!isValidMetaPixelId(pixelId)) return "";
|
|
285
|
+
return `fbq('init', '${pixelId}');
|
|
286
|
+
fbq('track', 'PageView');`;
|
|
287
|
+
}
|
|
288
|
+
function createMetaPixelInitScriptMulti(pixelIds) {
|
|
289
|
+
const inits = pixelIds.filter(isValidMetaPixelId).map((id) => `fbq('init', '${id}');`);
|
|
290
|
+
if (inits.length === 0) return "";
|
|
291
|
+
return `${inits.join("\n")}
|
|
292
|
+
fbq('track', 'PageView');`;
|
|
293
|
+
}
|
|
294
|
+
function createMetaConsentRestoreScript() {
|
|
295
|
+
return `
|
|
296
|
+
try {
|
|
297
|
+
var consentState = window.localStorage.getItem('consent_state');
|
|
298
|
+
if (window.fbq && (consentState === 'granted' || consentState === 'denied')) {
|
|
299
|
+
window.fbq('consent', consentState === 'granted' ? 'grant' : 'revoke');
|
|
300
|
+
}
|
|
301
|
+
} catch (e) {}`.trim();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// ../tracking-core/src/payloads.ts
|
|
305
|
+
function createTrackingClientContext(surface, input = {}) {
|
|
138
306
|
return {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
307
|
+
surface,
|
|
308
|
+
sdk_version: input.sdkVersion ?? null,
|
|
309
|
+
package_name: input.packageName ?? null,
|
|
310
|
+
site_origin: input.siteOrigin ?? (typeof window === "undefined" ? null : window.location.origin),
|
|
311
|
+
page_title: input.pageTitle ?? (typeof document === "undefined" ? null : document.title || null),
|
|
312
|
+
referrer: input.referrer ?? (typeof document === "undefined" ? null : document.referrer || null),
|
|
313
|
+
environment: input.environment ?? "production",
|
|
314
|
+
active_gtag_ids: input.activeGtagIds ?? null
|
|
146
315
|
};
|
|
147
316
|
}
|
|
148
|
-
function
|
|
149
|
-
return
|
|
317
|
+
function createTrackingSessionUpsertPayload(trackingParams, input, context) {
|
|
318
|
+
return {
|
|
319
|
+
session_id: input.sessionId,
|
|
320
|
+
visitor_id: input.visitorId ?? null,
|
|
321
|
+
gclid: trackingParams.gclid,
|
|
322
|
+
fbclid: trackingParams.fbclid,
|
|
323
|
+
fbc: getFbcCookie(),
|
|
324
|
+
fbp: getFbpCookie(),
|
|
325
|
+
utm_source: trackingParams.utm_source,
|
|
326
|
+
utm_medium: trackingParams.utm_medium,
|
|
327
|
+
utm_campaign: trackingParams.utm_campaign,
|
|
328
|
+
utm_term: trackingParams.utm_term,
|
|
329
|
+
utm_content: trackingParams.utm_content,
|
|
330
|
+
first_page: input.firstPage ?? null,
|
|
331
|
+
consent_state: input.consentState ?? null,
|
|
332
|
+
context
|
|
333
|
+
};
|
|
150
334
|
}
|
|
151
|
-
function
|
|
152
|
-
return
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
335
|
+
function createTrackingEventCreatePayload(trackingParams, input, context) {
|
|
336
|
+
return {
|
|
337
|
+
session_id: input.sessionId,
|
|
338
|
+
event_type: input.eventType,
|
|
339
|
+
gclid: trackingParams.gclid,
|
|
340
|
+
fbclid: trackingParams.fbclid,
|
|
341
|
+
fbc: getFbcCookie(),
|
|
342
|
+
fbp: getFbpCookie(),
|
|
343
|
+
page_url: input.pageUrl ?? (typeof window === "undefined" ? null : window.location.href),
|
|
344
|
+
metadata: input.metadata ?? null,
|
|
345
|
+
context
|
|
346
|
+
};
|
|
156
347
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
348
|
+
|
|
349
|
+
// ../tracking-core/src/resources/conversion-firing.ts
|
|
350
|
+
var DEDUP_PREFIX = "_aranova_conv_";
|
|
351
|
+
var MAX_PENDING = 100;
|
|
352
|
+
var pendingQueue = [];
|
|
353
|
+
function dedupKey(input) {
|
|
354
|
+
return `${DEDUP_PREFIX}${input.transactionId ?? ""}:${input.sendTo}`;
|
|
355
|
+
}
|
|
356
|
+
function alreadyFired(input) {
|
|
357
|
+
if (!input.transactionId || typeof window === "undefined") return false;
|
|
358
|
+
try {
|
|
359
|
+
return window.sessionStorage.getItem(dedupKey(input)) !== null;
|
|
360
|
+
} catch {
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
165
363
|
}
|
|
166
|
-
function
|
|
167
|
-
if (typeof
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
return normalizeTrackingCookieValue(decodeURIComponent(rawValue));
|
|
364
|
+
function markFired(input) {
|
|
365
|
+
if (!input.transactionId || typeof window === "undefined") return;
|
|
366
|
+
try {
|
|
367
|
+
window.sessionStorage.setItem(dedupKey(input), "1");
|
|
368
|
+
} catch {
|
|
369
|
+
}
|
|
173
370
|
}
|
|
174
|
-
function
|
|
175
|
-
if (
|
|
176
|
-
|
|
177
|
-
|
|
371
|
+
function fireOnce(input) {
|
|
372
|
+
if (alreadyFired(input)) return;
|
|
373
|
+
if (fireGtagConversion(input)) markFired(input);
|
|
374
|
+
}
|
|
375
|
+
function fireConversionWithConsent(input) {
|
|
376
|
+
const state = getConsentState();
|
|
377
|
+
if (state === "denied") return;
|
|
378
|
+
if (state === "pending") {
|
|
379
|
+
if (pendingQueue.length >= MAX_PENDING) pendingQueue.shift();
|
|
380
|
+
pendingQueue.push(input);
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
fireOnce(input);
|
|
178
384
|
}
|
|
179
|
-
function
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
385
|
+
function flushPendingConversions() {
|
|
386
|
+
if (getConsentState() !== "granted") return;
|
|
387
|
+
while (pendingQueue.length > 0) {
|
|
388
|
+
const input = pendingQueue.shift();
|
|
389
|
+
if (input) fireOnce(input);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
if (typeof window !== "undefined") onConsentGranted(flushPendingConversions);
|
|
393
|
+
|
|
394
|
+
// ../tracking-core/src/resources/conversion-config.ts
|
|
395
|
+
function isStringMap(value) {
|
|
396
|
+
return typeof value === "object" && value !== null && Object.values(value).every((v) => typeof v === "string");
|
|
397
|
+
}
|
|
398
|
+
function parseFiring(value) {
|
|
399
|
+
if (!value || typeof value !== "object") return null;
|
|
400
|
+
const f = value;
|
|
401
|
+
if (typeof f.send_to !== "string") return null;
|
|
402
|
+
return {
|
|
403
|
+
send_to: f.send_to,
|
|
404
|
+
value_cents: typeof f.value_cents === "number" ? f.value_cents : null,
|
|
405
|
+
currency: typeof f.currency === "string" ? f.currency : null
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
function parseTrigger(value) {
|
|
409
|
+
if (!value || typeof value !== "object") return null;
|
|
410
|
+
const t = value;
|
|
411
|
+
if (typeof t.event_type !== "string") return null;
|
|
412
|
+
const spec = { event_type: t.event_type };
|
|
413
|
+
if (typeof t.threshold_percent === "number") spec.threshold_percent = t.threshold_percent;
|
|
414
|
+
if (typeof t.threshold_seconds === "number") spec.threshold_seconds = t.threshold_seconds;
|
|
415
|
+
if (typeof t.page_threshold === "number") spec.page_threshold = t.page_threshold;
|
|
416
|
+
if (typeof t.page_name === "string") spec.page_name = t.page_name;
|
|
417
|
+
return spec;
|
|
418
|
+
}
|
|
419
|
+
function parseConversionConfig(raw) {
|
|
420
|
+
if (!raw || typeof raw !== "object") return null;
|
|
421
|
+
const obj = raw;
|
|
422
|
+
const servicesRaw = Array.isArray(obj.services) ? obj.services : [];
|
|
423
|
+
const services = servicesRaw.flatMap((entry) => {
|
|
424
|
+
if (!entry || typeof entry !== "object") return [];
|
|
425
|
+
const s = entry;
|
|
426
|
+
if (typeof s.key !== "string") return [];
|
|
427
|
+
return [
|
|
428
|
+
{
|
|
429
|
+
key: s.key,
|
|
430
|
+
label: typeof s.label === "string" ? s.label : void 0,
|
|
431
|
+
firing: parseFiring(s.firing)
|
|
432
|
+
}
|
|
433
|
+
];
|
|
183
434
|
});
|
|
184
|
-
|
|
435
|
+
const goalsRaw = Array.isArray(obj.goals) ? obj.goals : null;
|
|
436
|
+
const goals = goalsRaw ? goalsRaw.flatMap((entry) => {
|
|
437
|
+
if (!entry || typeof entry !== "object") return [];
|
|
438
|
+
const g = entry;
|
|
439
|
+
if (typeof g.key !== "string") return [];
|
|
440
|
+
return [
|
|
441
|
+
{
|
|
442
|
+
key: g.key,
|
|
443
|
+
label: typeof g.label === "string" ? g.label : void 0,
|
|
444
|
+
kind: g.kind === "event" ? "event" : "sale",
|
|
445
|
+
trigger: parseTrigger(g.trigger),
|
|
446
|
+
firing: parseFiring(g.firing)
|
|
447
|
+
}
|
|
448
|
+
];
|
|
449
|
+
}) : services.map((s) => ({
|
|
450
|
+
key: s.key,
|
|
451
|
+
label: s.label,
|
|
452
|
+
kind: "sale",
|
|
453
|
+
trigger: null,
|
|
454
|
+
firing: s.firing
|
|
455
|
+
}));
|
|
456
|
+
return {
|
|
457
|
+
schema_version: typeof obj.schema_version === "number" ? obj.schema_version : 1,
|
|
458
|
+
config_version: typeof obj.config_version === "number" ? obj.config_version : 0,
|
|
459
|
+
business_id: typeof obj.business_id === "string" ? obj.business_id : void 0,
|
|
460
|
+
customer_id: typeof obj.customer_id === "string" ? obj.customer_id : null,
|
|
461
|
+
environment: typeof obj.environment === "string" ? obj.environment : void 0,
|
|
462
|
+
gtag_ids: isStringMap(obj.gtag_ids) ? obj.gtag_ids : {},
|
|
463
|
+
meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
|
|
464
|
+
services,
|
|
465
|
+
goals
|
|
466
|
+
};
|
|
185
467
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
468
|
+
var CACHE_PREFIX = "_aranova_cfg_";
|
|
469
|
+
function cacheKey(url) {
|
|
470
|
+
return `${CACHE_PREFIX}${url}`;
|
|
471
|
+
}
|
|
472
|
+
function readCache(url) {
|
|
473
|
+
if (typeof window === "undefined") return null;
|
|
474
|
+
try {
|
|
475
|
+
const raw = window.sessionStorage.getItem(cacheKey(url));
|
|
476
|
+
if (!raw) return null;
|
|
477
|
+
const parsed = JSON.parse(raw);
|
|
478
|
+
const config = parseConversionConfig(parsed.config);
|
|
479
|
+
if (!config) return null;
|
|
480
|
+
return {
|
|
481
|
+
etag: typeof parsed.etag === "string" ? parsed.etag : null,
|
|
482
|
+
config
|
|
483
|
+
};
|
|
484
|
+
} catch {
|
|
485
|
+
return null;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
function writeCache(url, entry) {
|
|
489
|
+
if (typeof window === "undefined") return;
|
|
490
|
+
try {
|
|
491
|
+
window.sessionStorage.setItem(cacheKey(url), JSON.stringify(entry));
|
|
492
|
+
} catch {
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
function resolveConversionConfig(options) {
|
|
496
|
+
const cached = readCache(options.cdnUrl);
|
|
497
|
+
let current = cached?.config ?? options.baked ?? null;
|
|
498
|
+
let etag = cached?.etag ?? null;
|
|
499
|
+
const goalsByKey = /* @__PURE__ */ new Map();
|
|
500
|
+
function rebuildIndex() {
|
|
501
|
+
goalsByKey.clear();
|
|
502
|
+
for (const goal of current?.goals ?? []) {
|
|
503
|
+
goalsByKey.set(goal.key, goal);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
function adopt(next, nextEtag) {
|
|
507
|
+
if (!next) return;
|
|
508
|
+
if (current && next.config_version <= current.config_version) return;
|
|
509
|
+
current = next;
|
|
510
|
+
etag = nextEtag;
|
|
511
|
+
rebuildIndex();
|
|
512
|
+
writeCache(options.cdnUrl, { etag, config: next });
|
|
513
|
+
}
|
|
514
|
+
async function revalidate() {
|
|
515
|
+
if (typeof window === "undefined") return;
|
|
516
|
+
try {
|
|
517
|
+
const doFetch = options.fetchImpl ?? globalThis.fetch;
|
|
518
|
+
if (!doFetch) return;
|
|
519
|
+
const headers = {};
|
|
520
|
+
if (etag) headers["If-None-Match"] = etag;
|
|
521
|
+
const response = await doFetch(options.cdnUrl, {
|
|
522
|
+
method: "GET",
|
|
523
|
+
headers
|
|
524
|
+
});
|
|
525
|
+
if (response.status === 304 || !response.ok) return;
|
|
526
|
+
adopt(parseConversionConfig(await response.json()), response.headers.get("ETag"));
|
|
527
|
+
} catch {
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
rebuildIndex();
|
|
531
|
+
void revalidate();
|
|
532
|
+
return {
|
|
533
|
+
getFiring: (key) => goalsByKey.get(key)?.firing ?? null,
|
|
534
|
+
getGoal: (key) => goalsByKey.get(key) ?? null,
|
|
535
|
+
listGoals: () => [...goalsByKey.values()],
|
|
536
|
+
current: () => current,
|
|
537
|
+
revalidate
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// ../tracking-core/src/resources/sales/money.ts
|
|
542
|
+
var MINOR_UNIT_EXPONENT = {
|
|
543
|
+
USD: 2,
|
|
544
|
+
CAD: 2
|
|
545
|
+
};
|
|
546
|
+
function exponentFor(currency) {
|
|
547
|
+
return MINOR_UNIT_EXPONENT[currency] ?? 2;
|
|
548
|
+
}
|
|
549
|
+
function toMinor(amount, currency) {
|
|
550
|
+
return Math.round(amount * 10 ** exponentFor(currency));
|
|
551
|
+
}
|
|
552
|
+
function fromMinor(cents, currency) {
|
|
553
|
+
return cents / 10 ** exponentFor(currency);
|
|
554
|
+
}
|
|
555
|
+
function formatMoney(cents, currency, locale) {
|
|
556
|
+
return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
|
|
557
|
+
fromMinor(cents, currency)
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
function formatDateInTz(iso, timeZone, opts, locale) {
|
|
561
|
+
const date = new Date(iso);
|
|
562
|
+
if (Number.isNaN(date.getTime())) return iso;
|
|
563
|
+
return new Intl.DateTimeFormat(locale, {
|
|
564
|
+
year: "numeric",
|
|
565
|
+
month: "short",
|
|
566
|
+
day: "2-digit",
|
|
567
|
+
hour: "2-digit",
|
|
568
|
+
minute: "2-digit",
|
|
569
|
+
...opts,
|
|
570
|
+
timeZone
|
|
571
|
+
}).format(date);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
// ../tracking-core/src/resources/conversion-autofire.ts
|
|
575
|
+
function thresholdMet(goal, eventType, metadata) {
|
|
576
|
+
const t = goal.trigger;
|
|
577
|
+
if (!t || t.event_type !== eventType) return false;
|
|
578
|
+
switch (eventType) {
|
|
579
|
+
case "scroll_depth":
|
|
580
|
+
return typeof metadata.depth_percent === "number" && t.threshold_percent != null && metadata.depth_percent >= t.threshold_percent;
|
|
581
|
+
case "time_on_site":
|
|
582
|
+
return typeof metadata.duration_ms === "number" && t.threshold_seconds != null && metadata.duration_ms >= t.threshold_seconds * 1e3;
|
|
583
|
+
case "multi_page_session":
|
|
584
|
+
return typeof metadata.page_count === "number" && t.page_threshold != null && metadata.page_count >= t.page_threshold;
|
|
585
|
+
case "specific_page_visit":
|
|
586
|
+
return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
|
|
587
|
+
case "page_view":
|
|
588
|
+
case "form_start":
|
|
589
|
+
return true;
|
|
590
|
+
// no threshold — fire whenever the detector emits
|
|
591
|
+
default:
|
|
592
|
+
return false;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
function currentPath() {
|
|
596
|
+
return typeof window === "undefined" ? "" : window.location.pathname;
|
|
597
|
+
}
|
|
598
|
+
function createConversionAutoFire(store) {
|
|
599
|
+
return {
|
|
600
|
+
onAutomaticEvent(eventType, metadata) {
|
|
601
|
+
for (const goal of store.listGoals()) {
|
|
602
|
+
if (goal.kind !== "event" || !goal.firing) continue;
|
|
603
|
+
if (!thresholdMet(goal, eventType, metadata)) continue;
|
|
604
|
+
const firing = goal.firing;
|
|
605
|
+
const cents = firing.value_cents ?? null;
|
|
606
|
+
const currency = firing.currency ?? null;
|
|
607
|
+
fireConversionWithConsent({
|
|
608
|
+
sendTo: firing.send_to,
|
|
609
|
+
value: cents != null && currency ? fromMinor(cents, currency) : null,
|
|
610
|
+
currency,
|
|
611
|
+
// Page-scoped txn id → fire once per (goal, path) per session; engagement conversions
|
|
612
|
+
// shouldn't re-fire as the visitor scrolls back and forth or re-enters a page.
|
|
613
|
+
transactionId: `auto:${goal.key}:${currentPath()}`
|
|
614
|
+
});
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
function withConversionAutoFire(client, autoFire) {
|
|
620
|
+
return {
|
|
621
|
+
...client,
|
|
622
|
+
trackEvent: (input) => {
|
|
623
|
+
client.trackEvent(input);
|
|
624
|
+
try {
|
|
625
|
+
autoFire.onAutomaticEvent(input.eventType, input.metadata ?? {});
|
|
626
|
+
} catch {
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
};
|
|
190
630
|
}
|
|
191
631
|
|
|
192
632
|
// ../tracking-core/src/session.ts
|
|
@@ -479,11 +919,22 @@ function createTrackingClient(config) {
|
|
|
479
919
|
let queue = [];
|
|
480
920
|
let flushTimer = null;
|
|
481
921
|
let firstPage = null;
|
|
922
|
+
let initialParams = createEmptyTrackingParams();
|
|
482
923
|
let destroyed = false;
|
|
483
924
|
const visitorId = getVisitorId();
|
|
484
925
|
const initialSession = getOrRotateSessionId();
|
|
485
926
|
let sessionId = initialSession.id;
|
|
486
|
-
if (typeof window !== "undefined")
|
|
927
|
+
if (typeof window !== "undefined") {
|
|
928
|
+
firstPage = window.location.href;
|
|
929
|
+
try {
|
|
930
|
+
initialParams = captureTrackingParamsFromLocation();
|
|
931
|
+
} catch {
|
|
932
|
+
}
|
|
933
|
+
try {
|
|
934
|
+
captureFbc();
|
|
935
|
+
} catch {
|
|
936
|
+
}
|
|
937
|
+
}
|
|
487
938
|
function enqueueHeartbeat() {
|
|
488
939
|
const metadata = buildHeartbeatMetadata(
|
|
489
940
|
config.surface,
|
|
@@ -508,7 +959,7 @@ function createTrackingClient(config) {
|
|
|
508
959
|
enqueueHeartbeat();
|
|
509
960
|
}
|
|
510
961
|
sessionId = rotated.id;
|
|
511
|
-
const params = readTrackingParams();
|
|
962
|
+
const params = mergeTrackingParams(readTrackingParams(), initialParams);
|
|
512
963
|
const context = buildContext(
|
|
513
964
|
config.surface,
|
|
514
965
|
sdkVersion,
|
|
@@ -521,6 +972,8 @@ function createTrackingClient(config) {
|
|
|
521
972
|
visitor_id: visitorId,
|
|
522
973
|
gclid: params.gclid,
|
|
523
974
|
fbclid: params.fbclid,
|
|
975
|
+
fbc: getFbcCookie(),
|
|
976
|
+
fbp: getFbpCookie(),
|
|
524
977
|
utm_source: params.utm_source,
|
|
525
978
|
utm_medium: params.utm_medium,
|
|
526
979
|
utm_campaign: params.utm_campaign,
|
|
@@ -912,7 +1365,7 @@ function attachScrollDepth(client, config) {
|
|
|
912
1365
|
}
|
|
913
1366
|
const thresholds = new Set(config.thresholds);
|
|
914
1367
|
let firedForPath = /* @__PURE__ */ new Set();
|
|
915
|
-
let
|
|
1368
|
+
let currentPath2 = window.location.pathname;
|
|
916
1369
|
let rafId = null;
|
|
917
1370
|
function getScrollPercent() {
|
|
918
1371
|
const doc = document.documentElement;
|
|
@@ -931,7 +1384,7 @@ function attachScrollDepth(client, config) {
|
|
|
931
1384
|
eventType: "scroll_depth",
|
|
932
1385
|
metadata: {
|
|
933
1386
|
depth_percent: threshold,
|
|
934
|
-
page: { path:
|
|
1387
|
+
page: { path: currentPath2 }
|
|
935
1388
|
},
|
|
936
1389
|
pageUrl: window.location.href,
|
|
937
1390
|
occurredAt: null
|
|
@@ -948,8 +1401,8 @@ function attachScrollDepth(client, config) {
|
|
|
948
1401
|
}
|
|
949
1402
|
function resetIfPathChanged() {
|
|
950
1403
|
const newPath = window.location.pathname;
|
|
951
|
-
if (newPath ===
|
|
952
|
-
|
|
1404
|
+
if (newPath === currentPath2) return;
|
|
1405
|
+
currentPath2 = newPath;
|
|
953
1406
|
firedForPath = /* @__PURE__ */ new Set();
|
|
954
1407
|
setTimeout(checkThresholds, 0);
|
|
955
1408
|
}
|
|
@@ -985,7 +1438,7 @@ function attachFormStart(client, config) {
|
|
|
985
1438
|
}
|
|
986
1439
|
const selector = config.selector ?? "form";
|
|
987
1440
|
let firedForms = /* @__PURE__ */ new Set();
|
|
988
|
-
let
|
|
1441
|
+
let currentPath2 = window.location.pathname;
|
|
989
1442
|
function getFormKey(form) {
|
|
990
1443
|
if (form.id) return `id:${form.id}`;
|
|
991
1444
|
const explicitAction = form.getAttribute("action");
|
|
@@ -1016,8 +1469,8 @@ function attachFormStart(client, config) {
|
|
|
1016
1469
|
}
|
|
1017
1470
|
function resetIfPathChanged() {
|
|
1018
1471
|
const newPath = window.location.pathname;
|
|
1019
|
-
if (newPath ===
|
|
1020
|
-
|
|
1472
|
+
if (newPath === currentPath2) return;
|
|
1473
|
+
currentPath2 = newPath;
|
|
1021
1474
|
firedForms = /* @__PURE__ */ new Set();
|
|
1022
1475
|
}
|
|
1023
1476
|
const originalPushState = history.pushState.bind(history);
|
|
@@ -1096,21 +1549,64 @@ async function salesRequest(config, method, path, body) {
|
|
|
1096
1549
|
}
|
|
1097
1550
|
|
|
1098
1551
|
// ../tracking-core/src/resources/sales/client.ts
|
|
1552
|
+
function fireRecordedConversions(firing, input, recorded, sale, currency) {
|
|
1553
|
+
if (!firing) return;
|
|
1554
|
+
const txnBase = input.external_id ?? sale.id;
|
|
1555
|
+
for (const item of recorded) {
|
|
1556
|
+
if (!item.service) continue;
|
|
1557
|
+
const config = firing.getFiring(item.service);
|
|
1558
|
+
if (!config) continue;
|
|
1559
|
+
const cents = item.amount_cents ?? config.value_cents ?? null;
|
|
1560
|
+
fireConversionWithConsent({
|
|
1561
|
+
sendTo: config.send_to,
|
|
1562
|
+
value: cents != null ? fromMinor(cents, currency) : null,
|
|
1563
|
+
currency: config.currency ?? currency,
|
|
1564
|
+
transactionId: `${txnBase}:${item.service}`
|
|
1565
|
+
});
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1099
1568
|
function createSalesClient(config) {
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1569
|
+
async function record(input) {
|
|
1570
|
+
const currency = input.currency ?? config.defaultCurrency;
|
|
1571
|
+
if (!currency) {
|
|
1572
|
+
throw new Error(
|
|
1573
|
+
"record: `currency` is required (pass it on the sale or set config.defaultCurrency)"
|
|
1574
|
+
);
|
|
1575
|
+
}
|
|
1576
|
+
const body = {
|
|
1577
|
+
...input,
|
|
1578
|
+
currency,
|
|
1579
|
+
occurred_at: input.occurred_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
1580
|
+
};
|
|
1581
|
+
const sale = await salesRequest(config, "POST", "/sales", body);
|
|
1582
|
+
const recorded = input.services?.length ? input.services.map((s) => ({
|
|
1583
|
+
service: s.service,
|
|
1584
|
+
amount_cents: s.amount_cents
|
|
1585
|
+
})) : [
|
|
1586
|
+
{
|
|
1587
|
+
service: input.service,
|
|
1588
|
+
amount_cents: input.amount_total_cents ?? null
|
|
1107
1589
|
}
|
|
1108
|
-
|
|
1109
|
-
|
|
1590
|
+
];
|
|
1591
|
+
fireRecordedConversions(config.firing, input, recorded, sale, currency);
|
|
1592
|
+
return sale;
|
|
1593
|
+
}
|
|
1594
|
+
return {
|
|
1595
|
+
record,
|
|
1596
|
+
// recordSale is the intent-revealing alias — same behavior, clearer call site.
|
|
1597
|
+
recordSale: record,
|
|
1598
|
+
trackConversion(key, options) {
|
|
1599
|
+
const firing = config.firing?.getFiring(key);
|
|
1600
|
+
if (!firing) return;
|
|
1601
|
+
const currency = firing.currency ?? options?.currency ?? config.defaultCurrency ?? null;
|
|
1602
|
+
const cents = firing.value_cents ?? null;
|
|
1603
|
+
const value = options?.value ?? (cents != null && currency ? fromMinor(cents, currency) : null);
|
|
1604
|
+
fireConversionWithConsent({
|
|
1605
|
+
sendTo: firing.send_to,
|
|
1606
|
+
value,
|
|
1110
1607
|
currency,
|
|
1111
|
-
|
|
1112
|
-
};
|
|
1113
|
-
return salesRequest(config, "POST", "/sales", body);
|
|
1608
|
+
transactionId: options?.transactionId ?? null
|
|
1609
|
+
});
|
|
1114
1610
|
},
|
|
1115
1611
|
async list(query) {
|
|
1116
1612
|
const { cursor, limit, sort, order, want_total, ...filters } = query ?? {};
|
|
@@ -1204,39 +1700,6 @@ function createSalesClient(config) {
|
|
|
1204
1700
|
};
|
|
1205
1701
|
}
|
|
1206
1702
|
|
|
1207
|
-
// ../tracking-core/src/resources/sales/money.ts
|
|
1208
|
-
var MINOR_UNIT_EXPONENT = {
|
|
1209
|
-
USD: 2,
|
|
1210
|
-
CAD: 2
|
|
1211
|
-
};
|
|
1212
|
-
function exponentFor(currency) {
|
|
1213
|
-
return MINOR_UNIT_EXPONENT[currency] ?? 2;
|
|
1214
|
-
}
|
|
1215
|
-
function toMinor(amount, currency) {
|
|
1216
|
-
return Math.round(amount * 10 ** exponentFor(currency));
|
|
1217
|
-
}
|
|
1218
|
-
function fromMinor(cents, currency) {
|
|
1219
|
-
return cents / 10 ** exponentFor(currency);
|
|
1220
|
-
}
|
|
1221
|
-
function formatMoney(cents, currency, locale) {
|
|
1222
|
-
return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
|
|
1223
|
-
fromMinor(cents, currency)
|
|
1224
|
-
);
|
|
1225
|
-
}
|
|
1226
|
-
function formatDateInTz(iso, timeZone, opts, locale) {
|
|
1227
|
-
const date = new Date(iso);
|
|
1228
|
-
if (Number.isNaN(date.getTime())) return iso;
|
|
1229
|
-
return new Intl.DateTimeFormat(locale, {
|
|
1230
|
-
year: "numeric",
|
|
1231
|
-
month: "short",
|
|
1232
|
-
day: "2-digit",
|
|
1233
|
-
hour: "2-digit",
|
|
1234
|
-
minute: "2-digit",
|
|
1235
|
-
...opts,
|
|
1236
|
-
timeZone
|
|
1237
|
-
}).format(date);
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
1703
|
// ../tracking-core/src/resources/sales/schema.ts
|
|
1241
1704
|
import { z as z11 } from "zod";
|
|
1242
1705
|
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
@@ -1639,26 +2102,61 @@ var ANIMATION_KEYFRAMES = `
|
|
|
1639
2102
|
}
|
|
1640
2103
|
`;
|
|
1641
2104
|
|
|
1642
|
-
// src/
|
|
2105
|
+
// src/AdPlatformTracking.tsx
|
|
1643
2106
|
import Script from "next/script";
|
|
1644
2107
|
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2108
|
+
function AdPlatformTracking({
|
|
2109
|
+
gtagId,
|
|
2110
|
+
gtagIds,
|
|
2111
|
+
metaPixelId,
|
|
2112
|
+
metaPixelIds
|
|
2113
|
+
}) {
|
|
2114
|
+
const gtagAll = gtagIds ? Object.values(gtagIds).filter((id) => id != null) : gtagId ? [gtagId] : [];
|
|
2115
|
+
const metaAll = metaPixelIds ? Object.values(metaPixelIds).filter((id) => id != null) : metaPixelId ? [metaPixelId] : [];
|
|
2116
|
+
const gtagLoaderId = gtagAll[0];
|
|
2117
|
+
const gtagInitScript = gtagAll.length === 1 ? createGtagInitScript(gtagAll[0]) : createGtagInitScriptMulti(gtagAll);
|
|
2118
|
+
const metaInitScript = metaAll.length === 1 ? createMetaPixelInitScript(metaAll[0]) : createMetaPixelInitScriptMulti(metaAll);
|
|
2119
|
+
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
2120
|
+
gtagLoaderId ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
2121
|
+
/* @__PURE__ */ jsx2(Script, { id: "consent-default", strategy: "beforeInteractive", children: createConsentDefaultScript() }),
|
|
2122
|
+
/* @__PURE__ */ jsx2(
|
|
2123
|
+
Script,
|
|
2124
|
+
{
|
|
2125
|
+
src: `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(gtagLoaderId)}`,
|
|
2126
|
+
strategy: "afterInteractive"
|
|
2127
|
+
}
|
|
2128
|
+
),
|
|
2129
|
+
/* @__PURE__ */ jsx2(Script, { id: "gtag-init", strategy: "afterInteractive", children: gtagInitScript }),
|
|
2130
|
+
/* @__PURE__ */ jsx2(Script, { id: "consent-restore", strategy: "afterInteractive", children: createConsentRestoreScript() })
|
|
2131
|
+
] }) : null,
|
|
2132
|
+
metaAll.length > 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
2133
|
+
/* @__PURE__ */ jsx2(Script, { id: "meta-pixel-base", strategy: "afterInteractive", children: createMetaConsentDefaultScript() }),
|
|
2134
|
+
/* @__PURE__ */ jsx2(Script, { id: "meta-pixel-init", strategy: "afterInteractive", children: metaInitScript }),
|
|
2135
|
+
/* @__PURE__ */ jsx2(Script, { id: "meta-pixel-consent-restore", strategy: "afterInteractive", children: createMetaConsentRestoreScript() })
|
|
2136
|
+
] }) : null
|
|
2137
|
+
] });
|
|
2138
|
+
}
|
|
2139
|
+
|
|
2140
|
+
// src/GoogleAdsTracking.tsx
|
|
2141
|
+
import Script2 from "next/script";
|
|
2142
|
+
import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1645
2143
|
function GoogleAdsTracking(props) {
|
|
1646
2144
|
const { gtagId, gtagIds } = props;
|
|
1647
2145
|
const allIds = gtagIds ? Object.values(gtagIds).filter((id) => id != null) : gtagId ? [gtagId] : [];
|
|
1648
2146
|
if (allIds.length === 0) return null;
|
|
1649
2147
|
const loaderId = allIds[0];
|
|
1650
2148
|
const initScript = allIds.length === 1 ? createGtagInitScript(loaderId) : createGtagInitScriptMulti(allIds);
|
|
1651
|
-
return /* @__PURE__ */
|
|
1652
|
-
/* @__PURE__ */
|
|
1653
|
-
/* @__PURE__ */
|
|
1654
|
-
|
|
2149
|
+
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
2150
|
+
/* @__PURE__ */ jsx3(Script2, { id: "consent-default", strategy: "beforeInteractive", children: createConsentDefaultScript() }),
|
|
2151
|
+
/* @__PURE__ */ jsx3(
|
|
2152
|
+
Script2,
|
|
1655
2153
|
{
|
|
1656
2154
|
src: `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(loaderId)}`,
|
|
1657
2155
|
strategy: "afterInteractive"
|
|
1658
2156
|
}
|
|
1659
2157
|
),
|
|
1660
|
-
/* @__PURE__ */
|
|
1661
|
-
/* @__PURE__ */
|
|
2158
|
+
/* @__PURE__ */ jsx3(Script2, { id: "gtag-init", strategy: "afterInteractive", children: initScript }),
|
|
2159
|
+
/* @__PURE__ */ jsx3(Script2, { id: "consent-restore", strategy: "afterInteractive", children: createConsentRestoreScript() })
|
|
1662
2160
|
] });
|
|
1663
2161
|
}
|
|
1664
2162
|
|
|
@@ -1666,7 +2164,7 @@ function GoogleAdsTracking(props) {
|
|
|
1666
2164
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
1667
2165
|
|
|
1668
2166
|
// package.json
|
|
1669
|
-
var version = "0.
|
|
2167
|
+
var version = "0.14.0";
|
|
1670
2168
|
|
|
1671
2169
|
// src/factory.tsx
|
|
1672
2170
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo2, useRef } from "react";
|
|
@@ -1680,7 +2178,7 @@ import {
|
|
|
1680
2178
|
useMemo,
|
|
1681
2179
|
useState as useState3
|
|
1682
2180
|
} from "react";
|
|
1683
|
-
import { jsx as
|
|
2181
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1684
2182
|
var _phoneConfigContext;
|
|
1685
2183
|
function phoneConfigContext() {
|
|
1686
2184
|
return _phoneConfigContext ?? (_phoneConfigContext = createContext(null));
|
|
@@ -1690,7 +2188,7 @@ function PhoneConfigProvider({
|
|
|
1690
2188
|
children
|
|
1691
2189
|
}) {
|
|
1692
2190
|
const Ctx = phoneConfigContext();
|
|
1693
|
-
return /* @__PURE__ */
|
|
2191
|
+
return /* @__PURE__ */ jsx4(Ctx.Provider, { value, children });
|
|
1694
2192
|
}
|
|
1695
2193
|
function usePhoneConfig() {
|
|
1696
2194
|
const ctx = useContext(phoneConfigContext());
|
|
@@ -1750,7 +2248,7 @@ var PhoneField = forwardRef(function PhoneField2({ country, value, defaultValue,
|
|
|
1750
2248
|
onChange?.(event);
|
|
1751
2249
|
};
|
|
1752
2250
|
const shown = isControlled ? formatPhoneAsTyped(value, resolvedCountry) : internal;
|
|
1753
|
-
return /* @__PURE__ */
|
|
2251
|
+
return /* @__PURE__ */ jsx4(
|
|
1754
2252
|
"input",
|
|
1755
2253
|
{
|
|
1756
2254
|
...rest,
|
|
@@ -1765,9 +2263,9 @@ var PhoneField = forwardRef(function PhoneField2({ country, value, defaultValue,
|
|
|
1765
2263
|
});
|
|
1766
2264
|
|
|
1767
2265
|
// src/factory.tsx
|
|
1768
|
-
import { jsx as
|
|
2266
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
1769
2267
|
function createTracking(options) {
|
|
1770
|
-
const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone } = options;
|
|
2268
|
+
const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone, conversionConfig } = options;
|
|
1771
2269
|
if (!apiKey || !endpoint) {
|
|
1772
2270
|
if (apiKey || endpoint) {
|
|
1773
2271
|
console.warn(
|
|
@@ -1783,7 +2281,7 @@ function createTracking(options) {
|
|
|
1783
2281
|
getVisitorId: () => ""
|
|
1784
2282
|
};
|
|
1785
2283
|
return {
|
|
1786
|
-
TrackingProvider: ({ children }) => /* @__PURE__ */
|
|
2284
|
+
TrackingProvider: ({ children }) => /* @__PURE__ */ jsx5(PhoneConfigProvider, { value: phone ?? null, children }),
|
|
1787
2285
|
useTracking: () => noopClient
|
|
1788
2286
|
};
|
|
1789
2287
|
}
|
|
@@ -1811,6 +2309,17 @@ function createTracking(options) {
|
|
|
1811
2309
|
),
|
|
1812
2310
|
[]
|
|
1813
2311
|
);
|
|
2312
|
+
const conversionStore = useMemo2(
|
|
2313
|
+
() => conversionConfig ? resolveConversionConfig({
|
|
2314
|
+
cdnUrl: conversionConfig.cdnUrl,
|
|
2315
|
+
baked: conversionConfig.baked
|
|
2316
|
+
}) : null,
|
|
2317
|
+
[]
|
|
2318
|
+
);
|
|
2319
|
+
const wrapClient = useMemo2(() => {
|
|
2320
|
+
const autoFire = conversionStore ? createConversionAutoFire(conversionStore) : null;
|
|
2321
|
+
return (c) => autoFire ? withConversionAutoFire(c, autoFire) : c;
|
|
2322
|
+
}, [conversionStore]);
|
|
1814
2323
|
useEffect3(() => {
|
|
1815
2324
|
const rawClient = getOrCreateTrackingClient({
|
|
1816
2325
|
apiKey,
|
|
@@ -1822,7 +2331,7 @@ function createTracking(options) {
|
|
|
1822
2331
|
activeGtagIds: gtagIds,
|
|
1823
2332
|
debug
|
|
1824
2333
|
});
|
|
1825
|
-
fireManualPageView(rawClient);
|
|
2334
|
+
fireManualPageView(wrapClient(rawClient));
|
|
1826
2335
|
}, [pathname, searchParams]);
|
|
1827
2336
|
const firedPagesRef = useRef(/* @__PURE__ */ new Set());
|
|
1828
2337
|
useEffect3(() => {
|
|
@@ -1837,14 +2346,18 @@ function createTracking(options) {
|
|
|
1837
2346
|
activeGtagIds: gtagIds,
|
|
1838
2347
|
debug
|
|
1839
2348
|
});
|
|
2349
|
+
const detectorClient = wrapClient(rawClient);
|
|
1840
2350
|
for (const { name, pathPattern } of specificPageVisitConfig.pages) {
|
|
1841
2351
|
if (!pathPattern.test(pathname)) continue;
|
|
1842
2352
|
const key = `${name}:${pathname}`;
|
|
1843
2353
|
if (firedPagesRef.current.has(key)) continue;
|
|
1844
2354
|
firedPagesRef.current.add(key);
|
|
1845
|
-
|
|
2355
|
+
detectorClient.trackEvent({
|
|
1846
2356
|
eventType: "specific_page_visit",
|
|
1847
|
-
metadata: {
|
|
2357
|
+
metadata: {
|
|
2358
|
+
page_name: name,
|
|
2359
|
+
page: { path: pathname }
|
|
2360
|
+
},
|
|
1848
2361
|
pageUrl: null,
|
|
1849
2362
|
occurredAt: null
|
|
1850
2363
|
});
|
|
@@ -1861,7 +2374,7 @@ function createTracking(options) {
|
|
|
1861
2374
|
activeGtagIds: gtagIds,
|
|
1862
2375
|
debug
|
|
1863
2376
|
});
|
|
1864
|
-
return attachBfcacheRestore(rawClient);
|
|
2377
|
+
return attachBfcacheRestore(wrapClient(rawClient));
|
|
1865
2378
|
}, []);
|
|
1866
2379
|
useEffect3(() => {
|
|
1867
2380
|
if (!timeOnSiteConfig) return;
|
|
@@ -1875,7 +2388,7 @@ function createTracking(options) {
|
|
|
1875
2388
|
activeGtagIds: gtagIds,
|
|
1876
2389
|
debug
|
|
1877
2390
|
});
|
|
1878
|
-
return attachTimeOnSite(rawClient, timeOnSiteConfig);
|
|
2391
|
+
return attachTimeOnSite(wrapClient(rawClient), timeOnSiteConfig);
|
|
1879
2392
|
}, []);
|
|
1880
2393
|
const multiPageSessionConfig = triggers.automatic.multi_page_session ?? null;
|
|
1881
2394
|
const mpsLastPathRef = useRef(null);
|
|
@@ -1913,7 +2426,7 @@ function createTracking(options) {
|
|
|
1913
2426
|
activeGtagIds: gtagIds,
|
|
1914
2427
|
debug
|
|
1915
2428
|
});
|
|
1916
|
-
rawClient.trackEvent({
|
|
2429
|
+
wrapClient(rawClient).trackEvent({
|
|
1917
2430
|
eventType: "multi_page_session",
|
|
1918
2431
|
metadata: {
|
|
1919
2432
|
page_count: paths.size,
|
|
@@ -1938,13 +2451,14 @@ function createTracking(options) {
|
|
|
1938
2451
|
activeGtagIds: gtagIds,
|
|
1939
2452
|
debug
|
|
1940
2453
|
});
|
|
2454
|
+
const detectorClient = wrapClient(rawClient);
|
|
1941
2455
|
const scrollDepth = triggers.automatic.scroll_depth;
|
|
1942
2456
|
if (scrollDepth) {
|
|
1943
|
-
detachers.push(attachScrollDepth(
|
|
2457
|
+
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
1944
2458
|
}
|
|
1945
2459
|
const formStart = triggers.automatic.form_start;
|
|
1946
2460
|
if (formStart) {
|
|
1947
|
-
detachers.push(attachFormStart(
|
|
2461
|
+
detachers.push(attachFormStart(detectorClient, formStart));
|
|
1948
2462
|
}
|
|
1949
2463
|
return () => {
|
|
1950
2464
|
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
@@ -1952,7 +2466,7 @@ function createTracking(options) {
|
|
|
1952
2466
|
}
|
|
1953
2467
|
};
|
|
1954
2468
|
}, []);
|
|
1955
|
-
return /* @__PURE__ */
|
|
2469
|
+
return /* @__PURE__ */ jsx5(TrackingContext.Provider, { value: client, children: /* @__PURE__ */ jsx5(PhoneConfigProvider, { value: phone ?? null, children }) });
|
|
1956
2470
|
}
|
|
1957
2471
|
function useTracking() {
|
|
1958
2472
|
const client = useContext2(TrackingContext);
|
|
@@ -1966,6 +2480,7 @@ function createTracking(options) {
|
|
|
1966
2480
|
return { TrackingProvider, useTracking };
|
|
1967
2481
|
}
|
|
1968
2482
|
export {
|
|
2483
|
+
AdPlatformTracking,
|
|
1969
2484
|
AranovaApiError,
|
|
1970
2485
|
ConsentBanner,
|
|
1971
2486
|
DEFAULT_PHONE_COUNTRY,
|
|
@@ -1991,6 +2506,7 @@ export {
|
|
|
1991
2506
|
parsePhone,
|
|
1992
2507
|
phoneField,
|
|
1993
2508
|
resetConsent,
|
|
2509
|
+
resolveConversionConfig,
|
|
1994
2510
|
saleCreateSchema,
|
|
1995
2511
|
saleItemSchema,
|
|
1996
2512
|
saleServiceSchema,
|