@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.js
CHANGED
|
@@ -30,6 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var src_exports = {};
|
|
32
32
|
__export(src_exports, {
|
|
33
|
+
AdPlatformTracking: () => AdPlatformTracking,
|
|
33
34
|
AranovaApiError: () => AranovaApiError,
|
|
34
35
|
ConsentBanner: () => ConsentBanner,
|
|
35
36
|
DEFAULT_PHONE_COUNTRY: () => DEFAULT_PHONE_COUNTRY,
|
|
@@ -55,6 +56,7 @@ __export(src_exports, {
|
|
|
55
56
|
parsePhone: () => parsePhone,
|
|
56
57
|
phoneField: () => phoneField,
|
|
57
58
|
resetConsent: () => resetConsent,
|
|
59
|
+
resolveConversionConfig: () => resolveConversionConfig,
|
|
58
60
|
saleCreateSchema: () => saleCreateSchema,
|
|
59
61
|
saleItemSchema: () => saleItemSchema,
|
|
60
62
|
saleServiceSchema: () => saleServiceSchema,
|
|
@@ -75,6 +77,13 @@ module.exports = __toCommonJS(src_exports);
|
|
|
75
77
|
// ../tracking-core/src/consent.ts
|
|
76
78
|
var CONSENT_STATE_KEY = "consent_state";
|
|
77
79
|
var CONSENT_TIMESTAMP_KEY = "consent_timestamp";
|
|
80
|
+
var grantedListeners = /* @__PURE__ */ new Set();
|
|
81
|
+
function onConsentGranted(listener) {
|
|
82
|
+
grantedListeners.add(listener);
|
|
83
|
+
return () => {
|
|
84
|
+
grantedListeners.delete(listener);
|
|
85
|
+
};
|
|
86
|
+
}
|
|
78
87
|
function buildConsentPayload(state) {
|
|
79
88
|
return {
|
|
80
89
|
ad_storage: state,
|
|
@@ -85,62 +94,142 @@ function buildConsentPayload(state) {
|
|
|
85
94
|
}
|
|
86
95
|
function getConsentState() {
|
|
87
96
|
if (typeof window === "undefined") return "pending";
|
|
88
|
-
|
|
89
|
-
|
|
97
|
+
try {
|
|
98
|
+
const storedState = window.localStorage.getItem(CONSENT_STATE_KEY);
|
|
99
|
+
if (storedState === "granted" || storedState === "denied") return storedState;
|
|
100
|
+
} catch {
|
|
101
|
+
}
|
|
90
102
|
return "pending";
|
|
91
103
|
}
|
|
92
104
|
function setConsentState(state) {
|
|
93
105
|
if (typeof window === "undefined") return;
|
|
94
|
-
|
|
95
|
-
|
|
106
|
+
try {
|
|
107
|
+
window.localStorage.setItem(CONSENT_STATE_KEY, state);
|
|
108
|
+
window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, (/* @__PURE__ */ new Date()).toISOString());
|
|
109
|
+
} catch {
|
|
110
|
+
}
|
|
96
111
|
if (typeof window.gtag === "function")
|
|
97
112
|
window.gtag("consent", "update", buildConsentPayload(state));
|
|
113
|
+
if (typeof window.fbq === "function")
|
|
114
|
+
window.fbq("consent", state === "granted" ? "grant" : "revoke");
|
|
115
|
+
if (state === "granted") {
|
|
116
|
+
for (const listener of grantedListeners) {
|
|
117
|
+
try {
|
|
118
|
+
listener();
|
|
119
|
+
} catch {
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
98
123
|
}
|
|
99
124
|
function resetConsent() {
|
|
100
125
|
if (typeof window === "undefined") return;
|
|
101
|
-
|
|
102
|
-
|
|
126
|
+
try {
|
|
127
|
+
window.localStorage.removeItem(CONSENT_STATE_KEY);
|
|
128
|
+
window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
|
|
129
|
+
} catch {
|
|
130
|
+
}
|
|
103
131
|
}
|
|
104
132
|
|
|
105
|
-
// ../tracking-core/src/
|
|
106
|
-
|
|
133
|
+
// ../tracking-core/src/tracking.ts
|
|
134
|
+
var TRACKING_COOKIE_MAX_AGE_SECONDS = 7776e3;
|
|
135
|
+
var TRACKING_PARAM_KEYS = [
|
|
136
|
+
"gclid",
|
|
137
|
+
"fbclid",
|
|
138
|
+
"utm_source",
|
|
139
|
+
"utm_medium",
|
|
140
|
+
"utm_campaign",
|
|
141
|
+
"utm_term",
|
|
142
|
+
"utm_content"
|
|
143
|
+
];
|
|
144
|
+
function createEmptyTrackingParams() {
|
|
107
145
|
return {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
active_gtag_ids: input.activeGtagIds ?? null
|
|
146
|
+
gclid: null,
|
|
147
|
+
fbclid: null,
|
|
148
|
+
utm_source: null,
|
|
149
|
+
utm_medium: null,
|
|
150
|
+
utm_campaign: null,
|
|
151
|
+
utm_term: null,
|
|
152
|
+
utm_content: null
|
|
116
153
|
};
|
|
117
154
|
}
|
|
118
|
-
function
|
|
119
|
-
return
|
|
120
|
-
session_id: input.sessionId,
|
|
121
|
-
visitor_id: input.visitorId ?? null,
|
|
122
|
-
gclid: trackingParams.gclid,
|
|
123
|
-
fbclid: trackingParams.fbclid,
|
|
124
|
-
utm_source: trackingParams.utm_source,
|
|
125
|
-
utm_medium: trackingParams.utm_medium,
|
|
126
|
-
utm_campaign: trackingParams.utm_campaign,
|
|
127
|
-
utm_term: trackingParams.utm_term,
|
|
128
|
-
utm_content: trackingParams.utm_content,
|
|
129
|
-
first_page: input.firstPage ?? null,
|
|
130
|
-
consent_state: input.consentState ?? null,
|
|
131
|
-
context
|
|
132
|
-
};
|
|
155
|
+
function normalizeTrackingCookieValue(value) {
|
|
156
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
133
157
|
}
|
|
134
|
-
function
|
|
135
|
-
return {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
158
|
+
function getTrackingParamsFromCookieReader(readCookie) {
|
|
159
|
+
return TRACKING_PARAM_KEYS.reduce((params, key) => {
|
|
160
|
+
params[key] = normalizeTrackingCookieValue(readCookie(key));
|
|
161
|
+
return params;
|
|
162
|
+
}, createEmptyTrackingParams());
|
|
163
|
+
}
|
|
164
|
+
function getTrackingQueryValues(searchParams) {
|
|
165
|
+
return TRACKING_PARAM_KEYS.reduce((params, key) => {
|
|
166
|
+
const value = searchParams.get(key);
|
|
167
|
+
if (typeof value === "string" && value.trim().length > 0) {
|
|
168
|
+
params[key] = value;
|
|
169
|
+
}
|
|
170
|
+
return params;
|
|
171
|
+
}, {});
|
|
172
|
+
}
|
|
173
|
+
var FALLBACK_STORAGE_PREFIX = "_aranova_track_";
|
|
174
|
+
function fallbackKey(name) {
|
|
175
|
+
return `${FALLBACK_STORAGE_PREFIX}${name}`;
|
|
176
|
+
}
|
|
177
|
+
function persistCookieValue(name, value, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
|
|
178
|
+
const encoded = encodeURIComponent(value);
|
|
179
|
+
if (typeof document !== "undefined") {
|
|
180
|
+
try {
|
|
181
|
+
document.cookie = `${name}=${encoded}; Max-Age=${maxAgeSeconds}; Path=/; SameSite=Lax`;
|
|
182
|
+
} catch {
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (typeof window !== "undefined") {
|
|
186
|
+
try {
|
|
187
|
+
window.localStorage.setItem(fallbackKey(name), encoded);
|
|
188
|
+
} catch {
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function readCookieValue(name) {
|
|
193
|
+
if (typeof document !== "undefined") {
|
|
194
|
+
const cookies = document.cookie ? document.cookie.split("; ") : [];
|
|
195
|
+
const match = cookies.find((cookie) => cookie.startsWith(`${name}=`));
|
|
196
|
+
if (match) {
|
|
197
|
+
const [, rawValue = ""] = match.split("=");
|
|
198
|
+
return normalizeTrackingCookieValue(decodeURIComponent(rawValue));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (typeof window !== "undefined") {
|
|
202
|
+
try {
|
|
203
|
+
const stored = window.localStorage.getItem(fallbackKey(name));
|
|
204
|
+
if (stored) return normalizeTrackingCookieValue(decodeURIComponent(stored));
|
|
205
|
+
} catch {
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
function getCookieValueFromDocument(key) {
|
|
211
|
+
return readCookieValue(key);
|
|
212
|
+
}
|
|
213
|
+
function setTrackingCookie(key, value, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
|
|
214
|
+
persistCookieValue(key, value, maxAgeSeconds);
|
|
215
|
+
}
|
|
216
|
+
function mergeTrackingParams(primary, fallback) {
|
|
217
|
+
return TRACKING_PARAM_KEYS.reduce((merged, key) => {
|
|
218
|
+
merged[key] = primary[key] ?? fallback[key];
|
|
219
|
+
return merged;
|
|
220
|
+
}, createEmptyTrackingParams());
|
|
221
|
+
}
|
|
222
|
+
function persistTrackingParamsFromSearchParams(searchParams, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
|
|
223
|
+
const trackingValues = getTrackingQueryValues(searchParams);
|
|
224
|
+
Object.entries(trackingValues).forEach(([key, value]) => {
|
|
225
|
+
setTrackingCookie(key, value, maxAgeSeconds);
|
|
226
|
+
});
|
|
227
|
+
return trackingValues;
|
|
228
|
+
}
|
|
229
|
+
function captureTrackingParamsFromLocation(url = typeof window === "undefined" ? "" : window.location.href, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
|
|
230
|
+
const resolvedUrl = typeof window === "undefined" ? new URL(url || "https://example.invalid") : new URL(url, window.location.origin);
|
|
231
|
+
persistTrackingParamsFromSearchParams(resolvedUrl.searchParams, maxAgeSeconds);
|
|
232
|
+
return getTrackingParamsFromCookieReader(getCookieValueFromDocument);
|
|
144
233
|
}
|
|
145
234
|
|
|
146
235
|
// ../tracking-core/src/gtag.ts
|
|
@@ -174,17 +263,37 @@ gtag('config', '${gtagId}');
|
|
|
174
263
|
}
|
|
175
264
|
function createConsentRestoreScript() {
|
|
176
265
|
return `
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
window.gtag('
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
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) {}
|
|
186
277
|
`.trim();
|
|
187
278
|
}
|
|
279
|
+
var SEND_TO_RE = /^AW-[A-Za-z0-9]+\/[A-Za-z0-9_-]+$/;
|
|
280
|
+
function isValidSendTo(sendTo) {
|
|
281
|
+
return SEND_TO_RE.test(sendTo);
|
|
282
|
+
}
|
|
283
|
+
function fireGtagConversion(input) {
|
|
284
|
+
if (typeof window === "undefined" || typeof window.gtag !== "function") return false;
|
|
285
|
+
if (!isValidSendTo(input.sendTo)) return false;
|
|
286
|
+
const params = { send_to: input.sendTo };
|
|
287
|
+
if (input.value != null) params.value = input.value;
|
|
288
|
+
if (input.currency) params.currency = input.currency;
|
|
289
|
+
if (input.transactionId) params.transaction_id = input.transactionId;
|
|
290
|
+
try {
|
|
291
|
+
window.gtag("event", "conversion", params);
|
|
292
|
+
return true;
|
|
293
|
+
} catch {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
188
297
|
function createGtagInitScriptMulti(gtagIds) {
|
|
189
298
|
const safeIds = gtagIds.filter(isValidGtagId);
|
|
190
299
|
const configs = safeIds.map((id) => `gtag('config', '${id}');`).join("\n");
|
|
@@ -197,70 +306,403 @@ ${configs}
|
|
|
197
306
|
`.trim();
|
|
198
307
|
}
|
|
199
308
|
|
|
200
|
-
// ../tracking-core/src/
|
|
201
|
-
var
|
|
202
|
-
var
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
"
|
|
210
|
-
|
|
211
|
-
|
|
309
|
+
// ../tracking-core/src/fbq.ts
|
|
310
|
+
var FB_EVENTS_SCRIPT_HOST = "https://connect.facebook.net/en_US/fbevents.js";
|
|
311
|
+
var FBC_COOKIE = "_fbc";
|
|
312
|
+
var FBP_COOKIE = "_fbp";
|
|
313
|
+
var META_PIXEL_ID_PATTERN = /^\d{15,16}$/;
|
|
314
|
+
function isValidMetaPixelId(id) {
|
|
315
|
+
return META_PIXEL_ID_PATTERN.test(id);
|
|
316
|
+
}
|
|
317
|
+
function computeFbSubdomainIndex(hostname) {
|
|
318
|
+
const labels = hostname.split(".").filter(Boolean);
|
|
319
|
+
return Math.max(0, labels.length - 1);
|
|
320
|
+
}
|
|
321
|
+
function buildFbc(fbclid, now, hostname) {
|
|
322
|
+
const host = hostname ?? (typeof window === "undefined" ? "" : window.location.hostname);
|
|
323
|
+
return `fb.${computeFbSubdomainIndex(host)}.${now}.${fbclid}`;
|
|
324
|
+
}
|
|
325
|
+
function getFbcCookie() {
|
|
326
|
+
return readCookieValue(FBC_COOKIE);
|
|
327
|
+
}
|
|
328
|
+
function getFbpCookie() {
|
|
329
|
+
return readCookieValue(FBP_COOKIE);
|
|
330
|
+
}
|
|
331
|
+
function readFbclidFromUrl() {
|
|
332
|
+
if (typeof window === "undefined") return null;
|
|
333
|
+
try {
|
|
334
|
+
const value = new URL(window.location.href).searchParams.get("fbclid");
|
|
335
|
+
return value && value.trim().length > 0 ? value : null;
|
|
336
|
+
} catch {
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
function captureFbc(now = typeof Date === "undefined" ? 0 : Date.now()) {
|
|
341
|
+
if (typeof window === "undefined") return;
|
|
342
|
+
if (getFbcCookie()) return;
|
|
343
|
+
const fbclid = readFbclidFromUrl() ?? readCookieValue("fbclid");
|
|
344
|
+
if (!fbclid) return;
|
|
345
|
+
persistCookieValue(FBC_COOKIE, buildFbc(fbclid, now), TRACKING_COOKIE_MAX_AGE_SECONDS);
|
|
346
|
+
}
|
|
347
|
+
function fbqStubScript() {
|
|
348
|
+
return `
|
|
349
|
+
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
|
|
350
|
+
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
|
|
351
|
+
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
|
|
352
|
+
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
|
|
353
|
+
document,'script','${FB_EVENTS_SCRIPT_HOST}');`.trim();
|
|
354
|
+
}
|
|
355
|
+
function createMetaConsentDefaultScript() {
|
|
356
|
+
return `${fbqStubScript()}
|
|
357
|
+
fbq('consent', 'revoke');`;
|
|
358
|
+
}
|
|
359
|
+
function createMetaPixelInitScript(pixelId) {
|
|
360
|
+
if (!isValidMetaPixelId(pixelId)) return "";
|
|
361
|
+
return `fbq('init', '${pixelId}');
|
|
362
|
+
fbq('track', 'PageView');`;
|
|
363
|
+
}
|
|
364
|
+
function createMetaPixelInitScriptMulti(pixelIds) {
|
|
365
|
+
const inits = pixelIds.filter(isValidMetaPixelId).map((id) => `fbq('init', '${id}');`);
|
|
366
|
+
if (inits.length === 0) return "";
|
|
367
|
+
return `${inits.join("\n")}
|
|
368
|
+
fbq('track', 'PageView');`;
|
|
369
|
+
}
|
|
370
|
+
function createMetaConsentRestoreScript() {
|
|
371
|
+
return `
|
|
372
|
+
try {
|
|
373
|
+
var consentState = window.localStorage.getItem('consent_state');
|
|
374
|
+
if (window.fbq && (consentState === 'granted' || consentState === 'denied')) {
|
|
375
|
+
window.fbq('consent', consentState === 'granted' ? 'grant' : 'revoke');
|
|
376
|
+
}
|
|
377
|
+
} catch (e) {}`.trim();
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// ../tracking-core/src/payloads.ts
|
|
381
|
+
function createTrackingClientContext(surface, input = {}) {
|
|
212
382
|
return {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
383
|
+
surface,
|
|
384
|
+
sdk_version: input.sdkVersion ?? null,
|
|
385
|
+
package_name: input.packageName ?? null,
|
|
386
|
+
site_origin: input.siteOrigin ?? (typeof window === "undefined" ? null : window.location.origin),
|
|
387
|
+
page_title: input.pageTitle ?? (typeof document === "undefined" ? null : document.title || null),
|
|
388
|
+
referrer: input.referrer ?? (typeof document === "undefined" ? null : document.referrer || null),
|
|
389
|
+
environment: input.environment ?? "production",
|
|
390
|
+
active_gtag_ids: input.activeGtagIds ?? null
|
|
220
391
|
};
|
|
221
392
|
}
|
|
222
|
-
function
|
|
223
|
-
return
|
|
393
|
+
function createTrackingSessionUpsertPayload(trackingParams, input, context) {
|
|
394
|
+
return {
|
|
395
|
+
session_id: input.sessionId,
|
|
396
|
+
visitor_id: input.visitorId ?? null,
|
|
397
|
+
gclid: trackingParams.gclid,
|
|
398
|
+
fbclid: trackingParams.fbclid,
|
|
399
|
+
fbc: getFbcCookie(),
|
|
400
|
+
fbp: getFbpCookie(),
|
|
401
|
+
utm_source: trackingParams.utm_source,
|
|
402
|
+
utm_medium: trackingParams.utm_medium,
|
|
403
|
+
utm_campaign: trackingParams.utm_campaign,
|
|
404
|
+
utm_term: trackingParams.utm_term,
|
|
405
|
+
utm_content: trackingParams.utm_content,
|
|
406
|
+
first_page: input.firstPage ?? null,
|
|
407
|
+
consent_state: input.consentState ?? null,
|
|
408
|
+
context
|
|
409
|
+
};
|
|
224
410
|
}
|
|
225
|
-
function
|
|
226
|
-
return
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
411
|
+
function createTrackingEventCreatePayload(trackingParams, input, context) {
|
|
412
|
+
return {
|
|
413
|
+
session_id: input.sessionId,
|
|
414
|
+
event_type: input.eventType,
|
|
415
|
+
gclid: trackingParams.gclid,
|
|
416
|
+
fbclid: trackingParams.fbclid,
|
|
417
|
+
fbc: getFbcCookie(),
|
|
418
|
+
fbp: getFbpCookie(),
|
|
419
|
+
page_url: input.pageUrl ?? (typeof window === "undefined" ? null : window.location.href),
|
|
420
|
+
metadata: input.metadata ?? null,
|
|
421
|
+
context
|
|
422
|
+
};
|
|
230
423
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
424
|
+
|
|
425
|
+
// ../tracking-core/src/resources/conversion-firing.ts
|
|
426
|
+
var DEDUP_PREFIX = "_aranova_conv_";
|
|
427
|
+
var MAX_PENDING = 100;
|
|
428
|
+
var pendingQueue = [];
|
|
429
|
+
function dedupKey(input) {
|
|
430
|
+
return `${DEDUP_PREFIX}${input.transactionId ?? ""}:${input.sendTo}`;
|
|
431
|
+
}
|
|
432
|
+
function alreadyFired(input) {
|
|
433
|
+
if (!input.transactionId || typeof window === "undefined") return false;
|
|
434
|
+
try {
|
|
435
|
+
return window.sessionStorage.getItem(dedupKey(input)) !== null;
|
|
436
|
+
} catch {
|
|
437
|
+
return false;
|
|
438
|
+
}
|
|
239
439
|
}
|
|
240
|
-
function
|
|
241
|
-
if (typeof
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
return normalizeTrackingCookieValue(decodeURIComponent(rawValue));
|
|
440
|
+
function markFired(input) {
|
|
441
|
+
if (!input.transactionId || typeof window === "undefined") return;
|
|
442
|
+
try {
|
|
443
|
+
window.sessionStorage.setItem(dedupKey(input), "1");
|
|
444
|
+
} catch {
|
|
445
|
+
}
|
|
247
446
|
}
|
|
248
|
-
function
|
|
249
|
-
if (
|
|
250
|
-
|
|
251
|
-
|
|
447
|
+
function fireOnce(input) {
|
|
448
|
+
if (alreadyFired(input)) return;
|
|
449
|
+
if (fireGtagConversion(input)) markFired(input);
|
|
450
|
+
}
|
|
451
|
+
function fireConversionWithConsent(input) {
|
|
452
|
+
const state = getConsentState();
|
|
453
|
+
if (state === "denied") return;
|
|
454
|
+
if (state === "pending") {
|
|
455
|
+
if (pendingQueue.length >= MAX_PENDING) pendingQueue.shift();
|
|
456
|
+
pendingQueue.push(input);
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
fireOnce(input);
|
|
252
460
|
}
|
|
253
|
-
function
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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
|
+
|
|
470
|
+
// ../tracking-core/src/resources/conversion-config.ts
|
|
471
|
+
function isStringMap(value) {
|
|
472
|
+
return typeof value === "object" && value !== null && Object.values(value).every((v) => typeof v === "string");
|
|
473
|
+
}
|
|
474
|
+
function parseFiring(value) {
|
|
475
|
+
if (!value || typeof value !== "object") return null;
|
|
476
|
+
const f = value;
|
|
477
|
+
if (typeof f.send_to !== "string") return null;
|
|
478
|
+
return {
|
|
479
|
+
send_to: f.send_to,
|
|
480
|
+
value_cents: typeof f.value_cents === "number" ? f.value_cents : null,
|
|
481
|
+
currency: typeof f.currency === "string" ? f.currency : null
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
function parseTrigger(value) {
|
|
485
|
+
if (!value || typeof value !== "object") return null;
|
|
486
|
+
const t = value;
|
|
487
|
+
if (typeof t.event_type !== "string") return null;
|
|
488
|
+
const spec = { event_type: t.event_type };
|
|
489
|
+
if (typeof t.threshold_percent === "number") spec.threshold_percent = t.threshold_percent;
|
|
490
|
+
if (typeof t.threshold_seconds === "number") spec.threshold_seconds = t.threshold_seconds;
|
|
491
|
+
if (typeof t.page_threshold === "number") spec.page_threshold = t.page_threshold;
|
|
492
|
+
if (typeof t.page_name === "string") spec.page_name = t.page_name;
|
|
493
|
+
return spec;
|
|
494
|
+
}
|
|
495
|
+
function parseConversionConfig(raw) {
|
|
496
|
+
if (!raw || typeof raw !== "object") return null;
|
|
497
|
+
const obj = raw;
|
|
498
|
+
const servicesRaw = Array.isArray(obj.services) ? obj.services : [];
|
|
499
|
+
const services = servicesRaw.flatMap((entry) => {
|
|
500
|
+
if (!entry || typeof entry !== "object") return [];
|
|
501
|
+
const s = entry;
|
|
502
|
+
if (typeof s.key !== "string") return [];
|
|
503
|
+
return [
|
|
504
|
+
{
|
|
505
|
+
key: s.key,
|
|
506
|
+
label: typeof s.label === "string" ? s.label : void 0,
|
|
507
|
+
firing: parseFiring(s.firing)
|
|
508
|
+
}
|
|
509
|
+
];
|
|
257
510
|
});
|
|
258
|
-
|
|
511
|
+
const goalsRaw = Array.isArray(obj.goals) ? obj.goals : null;
|
|
512
|
+
const goals = goalsRaw ? goalsRaw.flatMap((entry) => {
|
|
513
|
+
if (!entry || typeof entry !== "object") return [];
|
|
514
|
+
const g = entry;
|
|
515
|
+
if (typeof g.key !== "string") return [];
|
|
516
|
+
return [
|
|
517
|
+
{
|
|
518
|
+
key: g.key,
|
|
519
|
+
label: typeof g.label === "string" ? g.label : void 0,
|
|
520
|
+
kind: g.kind === "event" ? "event" : "sale",
|
|
521
|
+
trigger: parseTrigger(g.trigger),
|
|
522
|
+
firing: parseFiring(g.firing)
|
|
523
|
+
}
|
|
524
|
+
];
|
|
525
|
+
}) : services.map((s) => ({
|
|
526
|
+
key: s.key,
|
|
527
|
+
label: s.label,
|
|
528
|
+
kind: "sale",
|
|
529
|
+
trigger: null,
|
|
530
|
+
firing: s.firing
|
|
531
|
+
}));
|
|
532
|
+
return {
|
|
533
|
+
schema_version: typeof obj.schema_version === "number" ? obj.schema_version : 1,
|
|
534
|
+
config_version: typeof obj.config_version === "number" ? obj.config_version : 0,
|
|
535
|
+
business_id: typeof obj.business_id === "string" ? obj.business_id : void 0,
|
|
536
|
+
customer_id: typeof obj.customer_id === "string" ? obj.customer_id : null,
|
|
537
|
+
environment: typeof obj.environment === "string" ? obj.environment : void 0,
|
|
538
|
+
gtag_ids: isStringMap(obj.gtag_ids) ? obj.gtag_ids : {},
|
|
539
|
+
meta_pixel_ids: isStringMap(obj.meta_pixel_ids) ? obj.meta_pixel_ids : {},
|
|
540
|
+
services,
|
|
541
|
+
goals
|
|
542
|
+
};
|
|
259
543
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
544
|
+
var CACHE_PREFIX = "_aranova_cfg_";
|
|
545
|
+
function cacheKey(url) {
|
|
546
|
+
return `${CACHE_PREFIX}${url}`;
|
|
547
|
+
}
|
|
548
|
+
function readCache(url) {
|
|
549
|
+
if (typeof window === "undefined") return null;
|
|
550
|
+
try {
|
|
551
|
+
const raw = window.sessionStorage.getItem(cacheKey(url));
|
|
552
|
+
if (!raw) return null;
|
|
553
|
+
const parsed = JSON.parse(raw);
|
|
554
|
+
const config = parseConversionConfig(parsed.config);
|
|
555
|
+
if (!config) return null;
|
|
556
|
+
return {
|
|
557
|
+
etag: typeof parsed.etag === "string" ? parsed.etag : null,
|
|
558
|
+
config
|
|
559
|
+
};
|
|
560
|
+
} catch {
|
|
561
|
+
return null;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
function writeCache(url, entry) {
|
|
565
|
+
if (typeof window === "undefined") return;
|
|
566
|
+
try {
|
|
567
|
+
window.sessionStorage.setItem(cacheKey(url), JSON.stringify(entry));
|
|
568
|
+
} catch {
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
function resolveConversionConfig(options) {
|
|
572
|
+
const cached = readCache(options.cdnUrl);
|
|
573
|
+
let current = cached?.config ?? options.baked ?? null;
|
|
574
|
+
let etag = cached?.etag ?? null;
|
|
575
|
+
const goalsByKey = /* @__PURE__ */ new Map();
|
|
576
|
+
function rebuildIndex() {
|
|
577
|
+
goalsByKey.clear();
|
|
578
|
+
for (const goal of current?.goals ?? []) {
|
|
579
|
+
goalsByKey.set(goal.key, goal);
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
function adopt(next, nextEtag) {
|
|
583
|
+
if (!next) return;
|
|
584
|
+
if (current && next.config_version <= current.config_version) return;
|
|
585
|
+
current = next;
|
|
586
|
+
etag = nextEtag;
|
|
587
|
+
rebuildIndex();
|
|
588
|
+
writeCache(options.cdnUrl, { etag, config: next });
|
|
589
|
+
}
|
|
590
|
+
async function revalidate() {
|
|
591
|
+
if (typeof window === "undefined") return;
|
|
592
|
+
try {
|
|
593
|
+
const doFetch = options.fetchImpl ?? globalThis.fetch;
|
|
594
|
+
if (!doFetch) return;
|
|
595
|
+
const headers = {};
|
|
596
|
+
if (etag) headers["If-None-Match"] = etag;
|
|
597
|
+
const response = await doFetch(options.cdnUrl, {
|
|
598
|
+
method: "GET",
|
|
599
|
+
headers
|
|
600
|
+
});
|
|
601
|
+
if (response.status === 304 || !response.ok) return;
|
|
602
|
+
adopt(parseConversionConfig(await response.json()), response.headers.get("ETag"));
|
|
603
|
+
} catch {
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
rebuildIndex();
|
|
607
|
+
void revalidate();
|
|
608
|
+
return {
|
|
609
|
+
getFiring: (key) => goalsByKey.get(key)?.firing ?? null,
|
|
610
|
+
getGoal: (key) => goalsByKey.get(key) ?? null,
|
|
611
|
+
listGoals: () => [...goalsByKey.values()],
|
|
612
|
+
current: () => current,
|
|
613
|
+
revalidate
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
// ../tracking-core/src/resources/sales/money.ts
|
|
618
|
+
var MINOR_UNIT_EXPONENT = {
|
|
619
|
+
USD: 2,
|
|
620
|
+
CAD: 2
|
|
621
|
+
};
|
|
622
|
+
function exponentFor(currency) {
|
|
623
|
+
return MINOR_UNIT_EXPONENT[currency] ?? 2;
|
|
624
|
+
}
|
|
625
|
+
function toMinor(amount, currency) {
|
|
626
|
+
return Math.round(amount * 10 ** exponentFor(currency));
|
|
627
|
+
}
|
|
628
|
+
function fromMinor(cents, currency) {
|
|
629
|
+
return cents / 10 ** exponentFor(currency);
|
|
630
|
+
}
|
|
631
|
+
function formatMoney(cents, currency, locale) {
|
|
632
|
+
return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
|
|
633
|
+
fromMinor(cents, currency)
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
function formatDateInTz(iso, timeZone, opts, locale) {
|
|
637
|
+
const date = new Date(iso);
|
|
638
|
+
if (Number.isNaN(date.getTime())) return iso;
|
|
639
|
+
return new Intl.DateTimeFormat(locale, {
|
|
640
|
+
year: "numeric",
|
|
641
|
+
month: "short",
|
|
642
|
+
day: "2-digit",
|
|
643
|
+
hour: "2-digit",
|
|
644
|
+
minute: "2-digit",
|
|
645
|
+
...opts,
|
|
646
|
+
timeZone
|
|
647
|
+
}).format(date);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
// ../tracking-core/src/resources/conversion-autofire.ts
|
|
651
|
+
function thresholdMet(goal, eventType, metadata) {
|
|
652
|
+
const t = goal.trigger;
|
|
653
|
+
if (!t || t.event_type !== eventType) return false;
|
|
654
|
+
switch (eventType) {
|
|
655
|
+
case "scroll_depth":
|
|
656
|
+
return typeof metadata.depth_percent === "number" && t.threshold_percent != null && metadata.depth_percent >= t.threshold_percent;
|
|
657
|
+
case "time_on_site":
|
|
658
|
+
return typeof metadata.duration_ms === "number" && t.threshold_seconds != null && metadata.duration_ms >= t.threshold_seconds * 1e3;
|
|
659
|
+
case "multi_page_session":
|
|
660
|
+
return typeof metadata.page_count === "number" && t.page_threshold != null && metadata.page_count >= t.page_threshold;
|
|
661
|
+
case "specific_page_visit":
|
|
662
|
+
return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
|
|
663
|
+
case "page_view":
|
|
664
|
+
case "form_start":
|
|
665
|
+
return true;
|
|
666
|
+
// no threshold — fire whenever the detector emits
|
|
667
|
+
default:
|
|
668
|
+
return false;
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
function currentPath() {
|
|
672
|
+
return typeof window === "undefined" ? "" : window.location.pathname;
|
|
673
|
+
}
|
|
674
|
+
function createConversionAutoFire(store) {
|
|
675
|
+
return {
|
|
676
|
+
onAutomaticEvent(eventType, metadata) {
|
|
677
|
+
for (const goal of store.listGoals()) {
|
|
678
|
+
if (goal.kind !== "event" || !goal.firing) continue;
|
|
679
|
+
if (!thresholdMet(goal, eventType, metadata)) continue;
|
|
680
|
+
const firing = goal.firing;
|
|
681
|
+
const cents = firing.value_cents ?? null;
|
|
682
|
+
const currency = firing.currency ?? null;
|
|
683
|
+
fireConversionWithConsent({
|
|
684
|
+
sendTo: firing.send_to,
|
|
685
|
+
value: cents != null && currency ? fromMinor(cents, currency) : null,
|
|
686
|
+
currency,
|
|
687
|
+
// Page-scoped txn id → fire once per (goal, path) per session; engagement conversions
|
|
688
|
+
// shouldn't re-fire as the visitor scrolls back and forth or re-enters a page.
|
|
689
|
+
transactionId: `auto:${goal.key}:${currentPath()}`
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
}
|
|
695
|
+
function withConversionAutoFire(client, autoFire) {
|
|
696
|
+
return {
|
|
697
|
+
...client,
|
|
698
|
+
trackEvent: (input) => {
|
|
699
|
+
client.trackEvent(input);
|
|
700
|
+
try {
|
|
701
|
+
autoFire.onAutomaticEvent(input.eventType, input.metadata ?? {});
|
|
702
|
+
} catch {
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
};
|
|
264
706
|
}
|
|
265
707
|
|
|
266
708
|
// ../tracking-core/src/session.ts
|
|
@@ -553,11 +995,22 @@ function createTrackingClient(config) {
|
|
|
553
995
|
let queue = [];
|
|
554
996
|
let flushTimer = null;
|
|
555
997
|
let firstPage = null;
|
|
998
|
+
let initialParams = createEmptyTrackingParams();
|
|
556
999
|
let destroyed = false;
|
|
557
1000
|
const visitorId = getVisitorId();
|
|
558
1001
|
const initialSession = getOrRotateSessionId();
|
|
559
1002
|
let sessionId = initialSession.id;
|
|
560
|
-
if (typeof window !== "undefined")
|
|
1003
|
+
if (typeof window !== "undefined") {
|
|
1004
|
+
firstPage = window.location.href;
|
|
1005
|
+
try {
|
|
1006
|
+
initialParams = captureTrackingParamsFromLocation();
|
|
1007
|
+
} catch {
|
|
1008
|
+
}
|
|
1009
|
+
try {
|
|
1010
|
+
captureFbc();
|
|
1011
|
+
} catch {
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
561
1014
|
function enqueueHeartbeat() {
|
|
562
1015
|
const metadata = buildHeartbeatMetadata(
|
|
563
1016
|
config.surface,
|
|
@@ -582,7 +1035,7 @@ function createTrackingClient(config) {
|
|
|
582
1035
|
enqueueHeartbeat();
|
|
583
1036
|
}
|
|
584
1037
|
sessionId = rotated.id;
|
|
585
|
-
const params = readTrackingParams();
|
|
1038
|
+
const params = mergeTrackingParams(readTrackingParams(), initialParams);
|
|
586
1039
|
const context = buildContext(
|
|
587
1040
|
config.surface,
|
|
588
1041
|
sdkVersion,
|
|
@@ -595,6 +1048,8 @@ function createTrackingClient(config) {
|
|
|
595
1048
|
visitor_id: visitorId,
|
|
596
1049
|
gclid: params.gclid,
|
|
597
1050
|
fbclid: params.fbclid,
|
|
1051
|
+
fbc: getFbcCookie(),
|
|
1052
|
+
fbp: getFbpCookie(),
|
|
598
1053
|
utm_source: params.utm_source,
|
|
599
1054
|
utm_medium: params.utm_medium,
|
|
600
1055
|
utm_campaign: params.utm_campaign,
|
|
@@ -986,7 +1441,7 @@ function attachScrollDepth(client, config) {
|
|
|
986
1441
|
}
|
|
987
1442
|
const thresholds = new Set(config.thresholds);
|
|
988
1443
|
let firedForPath = /* @__PURE__ */ new Set();
|
|
989
|
-
let
|
|
1444
|
+
let currentPath2 = window.location.pathname;
|
|
990
1445
|
let rafId = null;
|
|
991
1446
|
function getScrollPercent() {
|
|
992
1447
|
const doc = document.documentElement;
|
|
@@ -1005,7 +1460,7 @@ function attachScrollDepth(client, config) {
|
|
|
1005
1460
|
eventType: "scroll_depth",
|
|
1006
1461
|
metadata: {
|
|
1007
1462
|
depth_percent: threshold,
|
|
1008
|
-
page: { path:
|
|
1463
|
+
page: { path: currentPath2 }
|
|
1009
1464
|
},
|
|
1010
1465
|
pageUrl: window.location.href,
|
|
1011
1466
|
occurredAt: null
|
|
@@ -1022,8 +1477,8 @@ function attachScrollDepth(client, config) {
|
|
|
1022
1477
|
}
|
|
1023
1478
|
function resetIfPathChanged() {
|
|
1024
1479
|
const newPath = window.location.pathname;
|
|
1025
|
-
if (newPath ===
|
|
1026
|
-
|
|
1480
|
+
if (newPath === currentPath2) return;
|
|
1481
|
+
currentPath2 = newPath;
|
|
1027
1482
|
firedForPath = /* @__PURE__ */ new Set();
|
|
1028
1483
|
setTimeout(checkThresholds, 0);
|
|
1029
1484
|
}
|
|
@@ -1059,7 +1514,7 @@ function attachFormStart(client, config) {
|
|
|
1059
1514
|
}
|
|
1060
1515
|
const selector = config.selector ?? "form";
|
|
1061
1516
|
let firedForms = /* @__PURE__ */ new Set();
|
|
1062
|
-
let
|
|
1517
|
+
let currentPath2 = window.location.pathname;
|
|
1063
1518
|
function getFormKey(form) {
|
|
1064
1519
|
if (form.id) return `id:${form.id}`;
|
|
1065
1520
|
const explicitAction = form.getAttribute("action");
|
|
@@ -1090,8 +1545,8 @@ function attachFormStart(client, config) {
|
|
|
1090
1545
|
}
|
|
1091
1546
|
function resetIfPathChanged() {
|
|
1092
1547
|
const newPath = window.location.pathname;
|
|
1093
|
-
if (newPath ===
|
|
1094
|
-
|
|
1548
|
+
if (newPath === currentPath2) return;
|
|
1549
|
+
currentPath2 = newPath;
|
|
1095
1550
|
firedForms = /* @__PURE__ */ new Set();
|
|
1096
1551
|
}
|
|
1097
1552
|
const originalPushState = history.pushState.bind(history);
|
|
@@ -1170,21 +1625,64 @@ async function salesRequest(config, method, path, body) {
|
|
|
1170
1625
|
}
|
|
1171
1626
|
|
|
1172
1627
|
// ../tracking-core/src/resources/sales/client.ts
|
|
1628
|
+
function fireRecordedConversions(firing, input, recorded, sale, currency) {
|
|
1629
|
+
if (!firing) return;
|
|
1630
|
+
const txnBase = input.external_id ?? sale.id;
|
|
1631
|
+
for (const item of recorded) {
|
|
1632
|
+
if (!item.service) continue;
|
|
1633
|
+
const config = firing.getFiring(item.service);
|
|
1634
|
+
if (!config) continue;
|
|
1635
|
+
const cents = item.amount_cents ?? config.value_cents ?? null;
|
|
1636
|
+
fireConversionWithConsent({
|
|
1637
|
+
sendTo: config.send_to,
|
|
1638
|
+
value: cents != null ? fromMinor(cents, currency) : null,
|
|
1639
|
+
currency: config.currency ?? currency,
|
|
1640
|
+
transactionId: `${txnBase}:${item.service}`
|
|
1641
|
+
});
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1173
1644
|
function createSalesClient(config) {
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1645
|
+
async function record(input) {
|
|
1646
|
+
const currency = input.currency ?? config.defaultCurrency;
|
|
1647
|
+
if (!currency) {
|
|
1648
|
+
throw new Error(
|
|
1649
|
+
"record: `currency` is required (pass it on the sale or set config.defaultCurrency)"
|
|
1650
|
+
);
|
|
1651
|
+
}
|
|
1652
|
+
const body = {
|
|
1653
|
+
...input,
|
|
1654
|
+
currency,
|
|
1655
|
+
occurred_at: input.occurred_at ?? (/* @__PURE__ */ new Date()).toISOString()
|
|
1656
|
+
};
|
|
1657
|
+
const sale = await salesRequest(config, "POST", "/sales", body);
|
|
1658
|
+
const recorded = input.services?.length ? input.services.map((s) => ({
|
|
1659
|
+
service: s.service,
|
|
1660
|
+
amount_cents: s.amount_cents
|
|
1661
|
+
})) : [
|
|
1662
|
+
{
|
|
1663
|
+
service: input.service,
|
|
1664
|
+
amount_cents: input.amount_total_cents ?? null
|
|
1181
1665
|
}
|
|
1182
|
-
|
|
1183
|
-
|
|
1666
|
+
];
|
|
1667
|
+
fireRecordedConversions(config.firing, input, recorded, sale, currency);
|
|
1668
|
+
return sale;
|
|
1669
|
+
}
|
|
1670
|
+
return {
|
|
1671
|
+
record,
|
|
1672
|
+
// recordSale is the intent-revealing alias — same behavior, clearer call site.
|
|
1673
|
+
recordSale: record,
|
|
1674
|
+
trackConversion(key, options) {
|
|
1675
|
+
const firing = config.firing?.getFiring(key);
|
|
1676
|
+
if (!firing) return;
|
|
1677
|
+
const currency = firing.currency ?? options?.currency ?? config.defaultCurrency ?? null;
|
|
1678
|
+
const cents = firing.value_cents ?? null;
|
|
1679
|
+
const value = options?.value ?? (cents != null && currency ? fromMinor(cents, currency) : null);
|
|
1680
|
+
fireConversionWithConsent({
|
|
1681
|
+
sendTo: firing.send_to,
|
|
1682
|
+
value,
|
|
1184
1683
|
currency,
|
|
1185
|
-
|
|
1186
|
-
};
|
|
1187
|
-
return salesRequest(config, "POST", "/sales", body);
|
|
1684
|
+
transactionId: options?.transactionId ?? null
|
|
1685
|
+
});
|
|
1188
1686
|
},
|
|
1189
1687
|
async list(query) {
|
|
1190
1688
|
const { cursor, limit, sort, order, want_total, ...filters } = query ?? {};
|
|
@@ -1278,39 +1776,6 @@ function createSalesClient(config) {
|
|
|
1278
1776
|
};
|
|
1279
1777
|
}
|
|
1280
1778
|
|
|
1281
|
-
// ../tracking-core/src/resources/sales/money.ts
|
|
1282
|
-
var MINOR_UNIT_EXPONENT = {
|
|
1283
|
-
USD: 2,
|
|
1284
|
-
CAD: 2
|
|
1285
|
-
};
|
|
1286
|
-
function exponentFor(currency) {
|
|
1287
|
-
return MINOR_UNIT_EXPONENT[currency] ?? 2;
|
|
1288
|
-
}
|
|
1289
|
-
function toMinor(amount, currency) {
|
|
1290
|
-
return Math.round(amount * 10 ** exponentFor(currency));
|
|
1291
|
-
}
|
|
1292
|
-
function fromMinor(cents, currency) {
|
|
1293
|
-
return cents / 10 ** exponentFor(currency);
|
|
1294
|
-
}
|
|
1295
|
-
function formatMoney(cents, currency, locale) {
|
|
1296
|
-
return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
|
|
1297
|
-
fromMinor(cents, currency)
|
|
1298
|
-
);
|
|
1299
|
-
}
|
|
1300
|
-
function formatDateInTz(iso, timeZone, opts, locale) {
|
|
1301
|
-
const date = new Date(iso);
|
|
1302
|
-
if (Number.isNaN(date.getTime())) return iso;
|
|
1303
|
-
return new Intl.DateTimeFormat(locale, {
|
|
1304
|
-
year: "numeric",
|
|
1305
|
-
month: "short",
|
|
1306
|
-
day: "2-digit",
|
|
1307
|
-
hour: "2-digit",
|
|
1308
|
-
minute: "2-digit",
|
|
1309
|
-
...opts,
|
|
1310
|
-
timeZone
|
|
1311
|
-
}).format(date);
|
|
1312
|
-
}
|
|
1313
|
-
|
|
1314
1779
|
// ../tracking-core/src/resources/sales/schema.ts
|
|
1315
1780
|
var import_zod11 = require("zod");
|
|
1316
1781
|
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
@@ -1713,26 +2178,61 @@ var ANIMATION_KEYFRAMES = `
|
|
|
1713
2178
|
}
|
|
1714
2179
|
`;
|
|
1715
2180
|
|
|
1716
|
-
// src/
|
|
2181
|
+
// src/AdPlatformTracking.tsx
|
|
1717
2182
|
var import_script = __toESM(require("next/script"));
|
|
1718
2183
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
2184
|
+
function AdPlatformTracking({
|
|
2185
|
+
gtagId,
|
|
2186
|
+
gtagIds,
|
|
2187
|
+
metaPixelId,
|
|
2188
|
+
metaPixelIds
|
|
2189
|
+
}) {
|
|
2190
|
+
const gtagAll = gtagIds ? Object.values(gtagIds).filter((id) => id != null) : gtagId ? [gtagId] : [];
|
|
2191
|
+
const metaAll = metaPixelIds ? Object.values(metaPixelIds).filter((id) => id != null) : metaPixelId ? [metaPixelId] : [];
|
|
2192
|
+
const gtagLoaderId = gtagAll[0];
|
|
2193
|
+
const gtagInitScript = gtagAll.length === 1 ? createGtagInitScript(gtagAll[0]) : createGtagInitScriptMulti(gtagAll);
|
|
2194
|
+
const metaInitScript = metaAll.length === 1 ? createMetaPixelInitScript(metaAll[0]) : createMetaPixelInitScriptMulti(metaAll);
|
|
2195
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
2196
|
+
gtagLoaderId ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
2197
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "consent-default", strategy: "beforeInteractive", children: createConsentDefaultScript() }),
|
|
2198
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2199
|
+
import_script.default,
|
|
2200
|
+
{
|
|
2201
|
+
src: `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(gtagLoaderId)}`,
|
|
2202
|
+
strategy: "afterInteractive"
|
|
2203
|
+
}
|
|
2204
|
+
),
|
|
2205
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "gtag-init", strategy: "afterInteractive", children: gtagInitScript }),
|
|
2206
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "consent-restore", strategy: "afterInteractive", children: createConsentRestoreScript() })
|
|
2207
|
+
] }) : null,
|
|
2208
|
+
metaAll.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
2209
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "meta-pixel-base", strategy: "afterInteractive", children: createMetaConsentDefaultScript() }),
|
|
2210
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "meta-pixel-init", strategy: "afterInteractive", children: metaInitScript }),
|
|
2211
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_script.default, { id: "meta-pixel-consent-restore", strategy: "afterInteractive", children: createMetaConsentRestoreScript() })
|
|
2212
|
+
] }) : null
|
|
2213
|
+
] });
|
|
2214
|
+
}
|
|
2215
|
+
|
|
2216
|
+
// src/GoogleAdsTracking.tsx
|
|
2217
|
+
var import_script2 = __toESM(require("next/script"));
|
|
2218
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1719
2219
|
function GoogleAdsTracking(props) {
|
|
1720
2220
|
const { gtagId, gtagIds } = props;
|
|
1721
2221
|
const allIds = gtagIds ? Object.values(gtagIds).filter((id) => id != null) : gtagId ? [gtagId] : [];
|
|
1722
2222
|
if (allIds.length === 0) return null;
|
|
1723
2223
|
const loaderId = allIds[0];
|
|
1724
2224
|
const initScript = allIds.length === 1 ? createGtagInitScript(loaderId) : createGtagInitScriptMulti(allIds);
|
|
1725
|
-
return /* @__PURE__ */ (0,
|
|
1726
|
-
/* @__PURE__ */ (0,
|
|
1727
|
-
/* @__PURE__ */ (0,
|
|
1728
|
-
|
|
2225
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
2226
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_script2.default, { id: "consent-default", strategy: "beforeInteractive", children: createConsentDefaultScript() }),
|
|
2227
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
2228
|
+
import_script2.default,
|
|
1729
2229
|
{
|
|
1730
2230
|
src: `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(loaderId)}`,
|
|
1731
2231
|
strategy: "afterInteractive"
|
|
1732
2232
|
}
|
|
1733
2233
|
),
|
|
1734
|
-
/* @__PURE__ */ (0,
|
|
1735
|
-
/* @__PURE__ */ (0,
|
|
2234
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_script2.default, { id: "gtag-init", strategy: "afterInteractive", children: initScript }),
|
|
2235
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_script2.default, { id: "consent-restore", strategy: "afterInteractive", children: createConsentRestoreScript() })
|
|
1736
2236
|
] });
|
|
1737
2237
|
}
|
|
1738
2238
|
|
|
@@ -1740,14 +2240,14 @@ function GoogleAdsTracking(props) {
|
|
|
1740
2240
|
var import_navigation = require("next/navigation");
|
|
1741
2241
|
|
|
1742
2242
|
// package.json
|
|
1743
|
-
var version = "0.
|
|
2243
|
+
var version = "0.14.0";
|
|
1744
2244
|
|
|
1745
2245
|
// src/factory.tsx
|
|
1746
2246
|
var import_react4 = require("react");
|
|
1747
2247
|
|
|
1748
2248
|
// ../tracking-core/src/phone-react.tsx
|
|
1749
2249
|
var import_react3 = require("react");
|
|
1750
|
-
var
|
|
2250
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1751
2251
|
var _phoneConfigContext;
|
|
1752
2252
|
function phoneConfigContext() {
|
|
1753
2253
|
return _phoneConfigContext ?? (_phoneConfigContext = (0, import_react3.createContext)(null));
|
|
@@ -1757,7 +2257,7 @@ function PhoneConfigProvider({
|
|
|
1757
2257
|
children
|
|
1758
2258
|
}) {
|
|
1759
2259
|
const Ctx = phoneConfigContext();
|
|
1760
|
-
return /* @__PURE__ */ (0,
|
|
2260
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Ctx.Provider, { value, children });
|
|
1761
2261
|
}
|
|
1762
2262
|
function usePhoneConfig() {
|
|
1763
2263
|
const ctx = (0, import_react3.useContext)(phoneConfigContext());
|
|
@@ -1817,7 +2317,7 @@ var PhoneField = (0, import_react3.forwardRef)(function PhoneField2({ country, v
|
|
|
1817
2317
|
onChange?.(event);
|
|
1818
2318
|
};
|
|
1819
2319
|
const shown = isControlled ? formatPhoneAsTyped(value, resolvedCountry) : internal;
|
|
1820
|
-
return /* @__PURE__ */ (0,
|
|
2320
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1821
2321
|
"input",
|
|
1822
2322
|
{
|
|
1823
2323
|
...rest,
|
|
@@ -1832,9 +2332,9 @@ var PhoneField = (0, import_react3.forwardRef)(function PhoneField2({ country, v
|
|
|
1832
2332
|
});
|
|
1833
2333
|
|
|
1834
2334
|
// src/factory.tsx
|
|
1835
|
-
var
|
|
2335
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1836
2336
|
function createTracking(options) {
|
|
1837
|
-
const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone } = options;
|
|
2337
|
+
const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone, conversionConfig } = options;
|
|
1838
2338
|
if (!apiKey || !endpoint) {
|
|
1839
2339
|
if (apiKey || endpoint) {
|
|
1840
2340
|
console.warn(
|
|
@@ -1850,7 +2350,7 @@ function createTracking(options) {
|
|
|
1850
2350
|
getVisitorId: () => ""
|
|
1851
2351
|
};
|
|
1852
2352
|
return {
|
|
1853
|
-
TrackingProvider: ({ children }) => /* @__PURE__ */ (0,
|
|
2353
|
+
TrackingProvider: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PhoneConfigProvider, { value: phone ?? null, children }),
|
|
1854
2354
|
useTracking: () => noopClient
|
|
1855
2355
|
};
|
|
1856
2356
|
}
|
|
@@ -1878,6 +2378,17 @@ function createTracking(options) {
|
|
|
1878
2378
|
),
|
|
1879
2379
|
[]
|
|
1880
2380
|
);
|
|
2381
|
+
const conversionStore = (0, import_react4.useMemo)(
|
|
2382
|
+
() => conversionConfig ? resolveConversionConfig({
|
|
2383
|
+
cdnUrl: conversionConfig.cdnUrl,
|
|
2384
|
+
baked: conversionConfig.baked
|
|
2385
|
+
}) : null,
|
|
2386
|
+
[]
|
|
2387
|
+
);
|
|
2388
|
+
const wrapClient = (0, import_react4.useMemo)(() => {
|
|
2389
|
+
const autoFire = conversionStore ? createConversionAutoFire(conversionStore) : null;
|
|
2390
|
+
return (c) => autoFire ? withConversionAutoFire(c, autoFire) : c;
|
|
2391
|
+
}, [conversionStore]);
|
|
1881
2392
|
(0, import_react4.useEffect)(() => {
|
|
1882
2393
|
const rawClient = getOrCreateTrackingClient({
|
|
1883
2394
|
apiKey,
|
|
@@ -1889,7 +2400,7 @@ function createTracking(options) {
|
|
|
1889
2400
|
activeGtagIds: gtagIds,
|
|
1890
2401
|
debug
|
|
1891
2402
|
});
|
|
1892
|
-
fireManualPageView(rawClient);
|
|
2403
|
+
fireManualPageView(wrapClient(rawClient));
|
|
1893
2404
|
}, [pathname, searchParams]);
|
|
1894
2405
|
const firedPagesRef = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
|
|
1895
2406
|
(0, import_react4.useEffect)(() => {
|
|
@@ -1904,14 +2415,18 @@ function createTracking(options) {
|
|
|
1904
2415
|
activeGtagIds: gtagIds,
|
|
1905
2416
|
debug
|
|
1906
2417
|
});
|
|
2418
|
+
const detectorClient = wrapClient(rawClient);
|
|
1907
2419
|
for (const { name, pathPattern } of specificPageVisitConfig.pages) {
|
|
1908
2420
|
if (!pathPattern.test(pathname)) continue;
|
|
1909
2421
|
const key = `${name}:${pathname}`;
|
|
1910
2422
|
if (firedPagesRef.current.has(key)) continue;
|
|
1911
2423
|
firedPagesRef.current.add(key);
|
|
1912
|
-
|
|
2424
|
+
detectorClient.trackEvent({
|
|
1913
2425
|
eventType: "specific_page_visit",
|
|
1914
|
-
metadata: {
|
|
2426
|
+
metadata: {
|
|
2427
|
+
page_name: name,
|
|
2428
|
+
page: { path: pathname }
|
|
2429
|
+
},
|
|
1915
2430
|
pageUrl: null,
|
|
1916
2431
|
occurredAt: null
|
|
1917
2432
|
});
|
|
@@ -1928,7 +2443,7 @@ function createTracking(options) {
|
|
|
1928
2443
|
activeGtagIds: gtagIds,
|
|
1929
2444
|
debug
|
|
1930
2445
|
});
|
|
1931
|
-
return attachBfcacheRestore(rawClient);
|
|
2446
|
+
return attachBfcacheRestore(wrapClient(rawClient));
|
|
1932
2447
|
}, []);
|
|
1933
2448
|
(0, import_react4.useEffect)(() => {
|
|
1934
2449
|
if (!timeOnSiteConfig) return;
|
|
@@ -1942,7 +2457,7 @@ function createTracking(options) {
|
|
|
1942
2457
|
activeGtagIds: gtagIds,
|
|
1943
2458
|
debug
|
|
1944
2459
|
});
|
|
1945
|
-
return attachTimeOnSite(rawClient, timeOnSiteConfig);
|
|
2460
|
+
return attachTimeOnSite(wrapClient(rawClient), timeOnSiteConfig);
|
|
1946
2461
|
}, []);
|
|
1947
2462
|
const multiPageSessionConfig = triggers.automatic.multi_page_session ?? null;
|
|
1948
2463
|
const mpsLastPathRef = (0, import_react4.useRef)(null);
|
|
@@ -1980,7 +2495,7 @@ function createTracking(options) {
|
|
|
1980
2495
|
activeGtagIds: gtagIds,
|
|
1981
2496
|
debug
|
|
1982
2497
|
});
|
|
1983
|
-
rawClient.trackEvent({
|
|
2498
|
+
wrapClient(rawClient).trackEvent({
|
|
1984
2499
|
eventType: "multi_page_session",
|
|
1985
2500
|
metadata: {
|
|
1986
2501
|
page_count: paths.size,
|
|
@@ -2005,13 +2520,14 @@ function createTracking(options) {
|
|
|
2005
2520
|
activeGtagIds: gtagIds,
|
|
2006
2521
|
debug
|
|
2007
2522
|
});
|
|
2523
|
+
const detectorClient = wrapClient(rawClient);
|
|
2008
2524
|
const scrollDepth = triggers.automatic.scroll_depth;
|
|
2009
2525
|
if (scrollDepth) {
|
|
2010
|
-
detachers.push(attachScrollDepth(
|
|
2526
|
+
detachers.push(attachScrollDepth(detectorClient, scrollDepth));
|
|
2011
2527
|
}
|
|
2012
2528
|
const formStart = triggers.automatic.form_start;
|
|
2013
2529
|
if (formStart) {
|
|
2014
|
-
detachers.push(attachFormStart(
|
|
2530
|
+
detachers.push(attachFormStart(detectorClient, formStart));
|
|
2015
2531
|
}
|
|
2016
2532
|
return () => {
|
|
2017
2533
|
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
@@ -2019,7 +2535,7 @@ function createTracking(options) {
|
|
|
2019
2535
|
}
|
|
2020
2536
|
};
|
|
2021
2537
|
}, []);
|
|
2022
|
-
return /* @__PURE__ */ (0,
|
|
2538
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(TrackingContext.Provider, { value: client, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PhoneConfigProvider, { value: phone ?? null, children }) });
|
|
2023
2539
|
}
|
|
2024
2540
|
function useTracking() {
|
|
2025
2541
|
const client = (0, import_react4.useContext)(TrackingContext);
|
|
@@ -2034,6 +2550,7 @@ function createTracking(options) {
|
|
|
2034
2550
|
}
|
|
2035
2551
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2036
2552
|
0 && (module.exports = {
|
|
2553
|
+
AdPlatformTracking,
|
|
2037
2554
|
AranovaApiError,
|
|
2038
2555
|
ConsentBanner,
|
|
2039
2556
|
DEFAULT_PHONE_COUNTRY,
|
|
@@ -2059,6 +2576,7 @@ function createTracking(options) {
|
|
|
2059
2576
|
parsePhone,
|
|
2060
2577
|
phoneField,
|
|
2061
2578
|
resetConsent,
|
|
2579
|
+
resolveConversionConfig,
|
|
2062
2580
|
saleCreateSchema,
|
|
2063
2581
|
saleItemSchema,
|
|
2064
2582
|
saleServiceSchema,
|