@aranova/tracking-next 0.14.2 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -50
- package/dist/index.d.mts +219 -99
- package/dist/index.d.ts +219 -99
- package/dist/index.js +490 -155
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +484 -155
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.js +88 -135
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +88 -135
- package/dist/middleware.mjs.map +1 -1
- package/dist/{phone-utils-CcU5mwzc.d.mts → phone-utils-DlAQK-gU.d.mts} +127 -6
- package/dist/{phone-utils-CcU5mwzc.d.ts → phone-utils-DlAQK-gU.d.ts} +127 -6
- package/dist/phone.d.mts +1 -1
- package/dist/phone.d.ts +1 -1
- package/dist/phone.js +88 -135
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +88 -135
- package/dist/phone.mjs.map +1 -1
- package/dist/sales.js +33 -29
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +33 -29
- package/dist/sales.mjs.map +1 -1
- package/dist/server.d.mts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +88 -135
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +88 -135
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/server.js
CHANGED
|
@@ -26,25 +26,6 @@ module.exports = __toCommonJS(server_exports);
|
|
|
26
26
|
var import_server_only = require("server-only");
|
|
27
27
|
var import_headers = require("next/headers");
|
|
28
28
|
|
|
29
|
-
// ../tracking-core/src/consent.ts
|
|
30
|
-
var CONSENT_STATE_KEY = "consent_state";
|
|
31
|
-
var grantedListeners = /* @__PURE__ */ new Set();
|
|
32
|
-
function onConsentGranted(listener) {
|
|
33
|
-
grantedListeners.add(listener);
|
|
34
|
-
return () => {
|
|
35
|
-
grantedListeners.delete(listener);
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
function getConsentState() {
|
|
39
|
-
if (typeof window === "undefined") return "pending";
|
|
40
|
-
try {
|
|
41
|
-
const storedState = window.localStorage.getItem(CONSENT_STATE_KEY);
|
|
42
|
-
if (storedState === "granted" || storedState === "denied") return storedState;
|
|
43
|
-
} catch {
|
|
44
|
-
}
|
|
45
|
-
return "pending";
|
|
46
|
-
}
|
|
47
|
-
|
|
48
29
|
// ../tracking-core/src/tracking.ts
|
|
49
30
|
var TRACKING_PARAM_KEYS = [
|
|
50
31
|
"gclid",
|
|
@@ -76,60 +57,6 @@ function getTrackingParamsFromCookieReader(readCookie) {
|
|
|
76
57
|
}, createEmptyTrackingParams());
|
|
77
58
|
}
|
|
78
59
|
|
|
79
|
-
// ../tracking-core/src/gtag.ts
|
|
80
|
-
var SEND_TO_RE = /^AW-[A-Za-z0-9]+\/[A-Za-z0-9_-]+$/;
|
|
81
|
-
function isValidSendTo(sendTo) {
|
|
82
|
-
return SEND_TO_RE.test(sendTo);
|
|
83
|
-
}
|
|
84
|
-
function fireGtagConversion(input) {
|
|
85
|
-
if (typeof window === "undefined" || typeof window.gtag !== "function") return false;
|
|
86
|
-
if (!isValidSendTo(input.sendTo)) return false;
|
|
87
|
-
const params = { send_to: input.sendTo };
|
|
88
|
-
if (input.value != null) params.value = input.value;
|
|
89
|
-
if (input.currency) params.currency = input.currency;
|
|
90
|
-
if (input.transactionId) params.transaction_id = input.transactionId;
|
|
91
|
-
try {
|
|
92
|
-
window.gtag("event", "conversion", params);
|
|
93
|
-
return true;
|
|
94
|
-
} catch {
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// ../tracking-core/src/resources/conversion-firing.ts
|
|
100
|
-
var DEDUP_PREFIX = "_aranova_conv_";
|
|
101
|
-
var pendingQueue = [];
|
|
102
|
-
function dedupKey(input) {
|
|
103
|
-
return `${DEDUP_PREFIX}${input.transactionId ?? ""}:${input.sendTo}`;
|
|
104
|
-
}
|
|
105
|
-
function alreadyFired(input) {
|
|
106
|
-
if (!input.transactionId || typeof window === "undefined") return false;
|
|
107
|
-
try {
|
|
108
|
-
return window.sessionStorage.getItem(dedupKey(input)) !== null;
|
|
109
|
-
} catch {
|
|
110
|
-
return false;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
function markFired(input) {
|
|
114
|
-
if (!input.transactionId || typeof window === "undefined") return;
|
|
115
|
-
try {
|
|
116
|
-
window.sessionStorage.setItem(dedupKey(input), "1");
|
|
117
|
-
} catch {
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
function fireOnce(input) {
|
|
121
|
-
if (alreadyFired(input)) return;
|
|
122
|
-
if (fireGtagConversion(input)) markFired(input);
|
|
123
|
-
}
|
|
124
|
-
function flushPendingConversions() {
|
|
125
|
-
if (getConsentState() !== "granted") return;
|
|
126
|
-
while (pendingQueue.length > 0) {
|
|
127
|
-
const input = pendingQueue.shift();
|
|
128
|
-
if (input) fireOnce(input);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if (typeof window !== "undefined") onConsentGranted(flushPendingConversions);
|
|
132
|
-
|
|
133
60
|
// ../tracking-core/src/session.ts
|
|
134
61
|
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
135
62
|
|
|
@@ -161,9 +88,17 @@ var ctaClickMetadataSchema = import_zod2.z.object({
|
|
|
161
88
|
path: import_zod2.z.string()
|
|
162
89
|
}).strict(),
|
|
163
90
|
section: import_zod2.z.string().nullable().optional(),
|
|
164
|
-
destination_url: import_zod2.z.string().nullable().optional()
|
|
91
|
+
destination_url: import_zod2.z.string().nullable().optional(),
|
|
92
|
+
// Set by auto-capture (and available to manual callers): the link target
|
|
93
|
+
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
94
|
+
href: import_zod2.z.string().nullable().optional(),
|
|
95
|
+
element: import_zod2.z.string().nullable().optional()
|
|
96
|
+
}).strict();
|
|
97
|
+
var ctaClickConfigSchema = import_zod2.z.object({
|
|
98
|
+
autoCapture: import_zod2.z.object({
|
|
99
|
+
selector: import_zod2.z.string().optional()
|
|
100
|
+
}).strict().optional()
|
|
165
101
|
}).strict();
|
|
166
|
-
var ctaClickConfigSchema = import_zod2.z.object({}).strict();
|
|
167
102
|
|
|
168
103
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
169
104
|
var import_zod3 = require("zod");
|
|
@@ -239,31 +174,44 @@ var multiPageSessionConfigSchema = import_zod6.z.object({
|
|
|
239
174
|
pageThreshold: import_zod6.z.number().int().min(2)
|
|
240
175
|
}).strict();
|
|
241
176
|
|
|
242
|
-
// ../tracking-core/src/events/
|
|
177
|
+
// ../tracking-core/src/events/page-exit.ts
|
|
243
178
|
var import_zod7 = require("zod");
|
|
244
|
-
var
|
|
245
|
-
|
|
179
|
+
var pageExitMetadataSchema = import_zod7.z.object({
|
|
180
|
+
dwell_ms: import_zod7.z.number().int().min(0),
|
|
181
|
+
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
182
|
+
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
183
|
+
max_scroll_percent: import_zod7.z.number().int().min(0).max(100).nullable(),
|
|
246
184
|
page: import_zod7.z.object({
|
|
247
185
|
path: import_zod7.z.string()
|
|
248
|
-
}).strict()
|
|
249
|
-
section: import_zod7.z.string().nullable().optional()
|
|
186
|
+
}).strict()
|
|
250
187
|
}).strict();
|
|
251
|
-
var
|
|
188
|
+
var pageExitConfigSchema = import_zod7.z.object({}).strict();
|
|
252
189
|
|
|
253
|
-
// ../tracking-core/src/events/
|
|
190
|
+
// ../tracking-core/src/events/phone-click.ts
|
|
254
191
|
var import_zod8 = require("zod");
|
|
255
|
-
var
|
|
256
|
-
|
|
192
|
+
var phoneClickMetadataSchema = import_zod8.z.object({
|
|
193
|
+
phone_number: import_zod8.z.string(),
|
|
257
194
|
page: import_zod8.z.object({
|
|
258
195
|
path: import_zod8.z.string()
|
|
196
|
+
}).strict(),
|
|
197
|
+
section: import_zod8.z.string().nullable().optional()
|
|
198
|
+
}).strict();
|
|
199
|
+
var phoneClickConfigSchema = import_zod8.z.object({}).strict();
|
|
200
|
+
|
|
201
|
+
// ../tracking-core/src/events/scroll-depth.ts
|
|
202
|
+
var import_zod9 = require("zod");
|
|
203
|
+
var scrollDepthMetadataSchema = import_zod9.z.object({
|
|
204
|
+
depth_percent: import_zod9.z.number().int().min(1).max(100),
|
|
205
|
+
page: import_zod9.z.object({
|
|
206
|
+
path: import_zod9.z.string()
|
|
259
207
|
}).strict()
|
|
260
208
|
}).strict();
|
|
261
|
-
var scrollDepthConfigSchema =
|
|
262
|
-
thresholds:
|
|
209
|
+
var scrollDepthConfigSchema = import_zod9.z.object({
|
|
210
|
+
thresholds: import_zod9.z.array(import_zod9.z.number().int().min(1).max(100)).min(1)
|
|
263
211
|
}).strict();
|
|
264
212
|
|
|
265
213
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
266
|
-
var
|
|
214
|
+
var import_zod10 = require("zod");
|
|
267
215
|
var SPECIFIC_PAGE_NAMES = [
|
|
268
216
|
"contact_page",
|
|
269
217
|
"about_page",
|
|
@@ -274,18 +222,18 @@ var SPECIFIC_PAGE_NAMES = [
|
|
|
274
222
|
"faq_page",
|
|
275
223
|
"testimonials_page"
|
|
276
224
|
];
|
|
277
|
-
var specificPageNameSchema =
|
|
278
|
-
var specificPageVisitMetadataSchema =
|
|
225
|
+
var specificPageNameSchema = import_zod10.z.enum(SPECIFIC_PAGE_NAMES);
|
|
226
|
+
var specificPageVisitMetadataSchema = import_zod10.z.object({
|
|
279
227
|
page_name: specificPageNameSchema,
|
|
280
|
-
page:
|
|
281
|
-
path:
|
|
228
|
+
page: import_zod10.z.object({
|
|
229
|
+
path: import_zod10.z.string()
|
|
282
230
|
}).strict()
|
|
283
231
|
}).strict();
|
|
284
|
-
var specificPageVisitConfigSchema =
|
|
285
|
-
pages:
|
|
286
|
-
|
|
232
|
+
var specificPageVisitConfigSchema = import_zod10.z.object({
|
|
233
|
+
pages: import_zod10.z.array(
|
|
234
|
+
import_zod10.z.object({
|
|
287
235
|
name: specificPageNameSchema,
|
|
288
|
-
pathPattern:
|
|
236
|
+
pathPattern: import_zod10.z.custom((value) => value instanceof RegExp, {
|
|
289
237
|
message: "pathPattern must be a RegExp"
|
|
290
238
|
})
|
|
291
239
|
}).strict()
|
|
@@ -293,15 +241,15 @@ var specificPageVisitConfigSchema = import_zod9.z.object({
|
|
|
293
241
|
}).strict();
|
|
294
242
|
|
|
295
243
|
// ../tracking-core/src/events/time-on-site.ts
|
|
296
|
-
var
|
|
297
|
-
var timeOnSiteMetadataSchema =
|
|
298
|
-
duration_ms:
|
|
299
|
-
page:
|
|
300
|
-
path:
|
|
244
|
+
var import_zod11 = require("zod");
|
|
245
|
+
var timeOnSiteMetadataSchema = import_zod11.z.object({
|
|
246
|
+
duration_ms: import_zod11.z.number().int().nonnegative(),
|
|
247
|
+
page: import_zod11.z.object({
|
|
248
|
+
path: import_zod11.z.string()
|
|
301
249
|
}).strict()
|
|
302
250
|
}).strict();
|
|
303
|
-
var timeOnSiteConfigSchema =
|
|
304
|
-
thresholdSeconds:
|
|
251
|
+
var timeOnSiteConfigSchema = import_zod11.z.object({
|
|
252
|
+
thresholdSeconds: import_zod11.z.number().int().positive()
|
|
305
253
|
}).strict();
|
|
306
254
|
|
|
307
255
|
// ../tracking-core/src/events/registry.ts
|
|
@@ -343,6 +291,11 @@ var EVENT_REGISTRY = {
|
|
|
343
291
|
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
344
292
|
configSchema: sdkHeartbeatConfigSchema
|
|
345
293
|
},
|
|
294
|
+
page_exit: {
|
|
295
|
+
kind: "automatic",
|
|
296
|
+
metadataSchema: pageExitMetadataSchema,
|
|
297
|
+
configSchema: pageExitConfigSchema
|
|
298
|
+
},
|
|
346
299
|
// --- manual triggers ---
|
|
347
300
|
form_submit: {
|
|
348
301
|
kind: "manual",
|
|
@@ -364,42 +317,42 @@ var ALL_AUTOMATIC_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def])
|
|
|
364
317
|
var ALL_MANUAL_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "manual").map(([name]) => name);
|
|
365
318
|
|
|
366
319
|
// ../tracking-core/src/resources/sales/schema.ts
|
|
367
|
-
var
|
|
320
|
+
var import_zod12 = require("zod");
|
|
368
321
|
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
369
322
|
var TRACKING_ENVIRONMENTS = ["production", "development"];
|
|
370
|
-
var currencySchema =
|
|
371
|
-
var centsSchema =
|
|
372
|
-
var quantitySchema =
|
|
373
|
-
var metadataSchema =
|
|
374
|
-
var saleItemSchema =
|
|
375
|
-
external_item_id:
|
|
376
|
-
name:
|
|
377
|
-
category:
|
|
323
|
+
var currencySchema = import_zod12.z.enum(SUPPORTED_CURRENCIES);
|
|
324
|
+
var centsSchema = import_zod12.z.number().int().nonnegative();
|
|
325
|
+
var quantitySchema = import_zod12.z.string().regex(/^\d+(\.\d{1,3})?$/);
|
|
326
|
+
var metadataSchema = import_zod12.z.record(import_zod12.z.unknown());
|
|
327
|
+
var saleItemSchema = import_zod12.z.object({
|
|
328
|
+
external_item_id: import_zod12.z.string().nullable().optional(),
|
|
329
|
+
name: import_zod12.z.string().nullable().optional(),
|
|
330
|
+
category: import_zod12.z.string().nullable().optional(),
|
|
378
331
|
quantity: quantitySchema,
|
|
379
332
|
unit_price_cents: centsSchema,
|
|
380
333
|
// Non-negativity validated on the wire — same contract as the other cents
|
|
381
334
|
// fields — and backstopped by the DB CHECK.
|
|
382
335
|
unit_cost_cents: centsSchema.nullable().optional()
|
|
383
336
|
}).strict();
|
|
384
|
-
var saleServiceSchema =
|
|
385
|
-
service:
|
|
337
|
+
var saleServiceSchema = import_zod12.z.object({
|
|
338
|
+
service: import_zod12.z.string(),
|
|
386
339
|
amount_cents: centsSchema
|
|
387
340
|
}).strict();
|
|
388
|
-
var customerNameSchema =
|
|
389
|
-
var customerPhoneSchema =
|
|
390
|
-
var customerEmailSchema =
|
|
341
|
+
var customerNameSchema = import_zod12.z.string().max(200);
|
|
342
|
+
var customerPhoneSchema = import_zod12.z.string().max(64);
|
|
343
|
+
var customerEmailSchema = import_zod12.z.string().max(320).email();
|
|
391
344
|
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
392
345
|
if (val.services != null) {
|
|
393
346
|
if (val.service != null) {
|
|
394
347
|
ctx.addIssue({
|
|
395
|
-
code:
|
|
348
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
396
349
|
message: "pass either `service` or `services`, not both",
|
|
397
350
|
path: ["services"]
|
|
398
351
|
});
|
|
399
352
|
}
|
|
400
353
|
if (val.services.length === 0) {
|
|
401
354
|
ctx.addIssue({
|
|
402
|
-
code:
|
|
355
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
403
356
|
message: "`services` must not be empty",
|
|
404
357
|
path: ["services"]
|
|
405
358
|
});
|
|
@@ -407,7 +360,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
407
360
|
const keys = val.services.map((s) => s.service);
|
|
408
361
|
if (new Set(keys).size !== keys.length) {
|
|
409
362
|
ctx.addIssue({
|
|
410
|
-
code:
|
|
363
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
411
364
|
message: "`services` must not list the same service more than once",
|
|
412
365
|
path: ["services"]
|
|
413
366
|
});
|
|
@@ -416,7 +369,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
416
369
|
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
417
370
|
if (val.amount_total_cents !== sum) {
|
|
418
371
|
ctx.addIssue({
|
|
419
|
-
code:
|
|
372
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
420
373
|
message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
|
|
421
374
|
path: ["amount_total_cents"]
|
|
422
375
|
});
|
|
@@ -424,37 +377,37 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
424
377
|
}
|
|
425
378
|
} else if (requireAmount && val.amount_total_cents == null) {
|
|
426
379
|
ctx.addIssue({
|
|
427
|
-
code:
|
|
380
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
428
381
|
message: "amount_total_cents is required unless `services` is provided",
|
|
429
382
|
path: ["amount_total_cents"]
|
|
430
383
|
});
|
|
431
384
|
}
|
|
432
385
|
}
|
|
433
|
-
var saleCreateSchema =
|
|
434
|
-
external_id:
|
|
435
|
-
description:
|
|
436
|
-
service:
|
|
437
|
-
services:
|
|
386
|
+
var saleCreateSchema = import_zod12.z.object({
|
|
387
|
+
external_id: import_zod12.z.string().nullable().optional(),
|
|
388
|
+
description: import_zod12.z.string().nullable().optional(),
|
|
389
|
+
service: import_zod12.z.string().nullable().optional(),
|
|
390
|
+
services: import_zod12.z.array(saleServiceSchema).nullable().optional(),
|
|
438
391
|
currency: currencySchema,
|
|
439
392
|
// Optional only because the plural `services` form derives it from the sum
|
|
440
393
|
// (see refineServiceXor); the singular/serviceless path still requires it.
|
|
441
394
|
amount_total_cents: centsSchema.nullable().optional(),
|
|
442
|
-
occurred_at:
|
|
443
|
-
environment:
|
|
444
|
-
items:
|
|
395
|
+
occurred_at: import_zod12.z.string().datetime(),
|
|
396
|
+
environment: import_zod12.z.enum(TRACKING_ENVIRONMENTS).default("production"),
|
|
397
|
+
items: import_zod12.z.array(saleItemSchema).default([]),
|
|
445
398
|
metadata: metadataSchema.nullable().optional(),
|
|
446
399
|
customer_name: customerNameSchema.nullable().optional(),
|
|
447
400
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
448
401
|
customer_email: customerEmailSchema.nullable().optional()
|
|
449
402
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
450
|
-
var saleUpdateSchema =
|
|
451
|
-
description:
|
|
452
|
-
service:
|
|
453
|
-
services:
|
|
403
|
+
var saleUpdateSchema = import_zod12.z.object({
|
|
404
|
+
description: import_zod12.z.string().nullable().optional(),
|
|
405
|
+
service: import_zod12.z.string().nullable().optional(),
|
|
406
|
+
services: import_zod12.z.array(saleServiceSchema).nullable().optional(),
|
|
454
407
|
currency: currencySchema.optional(),
|
|
455
408
|
amount_total_cents: centsSchema.optional(),
|
|
456
|
-
occurred_at:
|
|
457
|
-
items:
|
|
409
|
+
occurred_at: import_zod12.z.string().datetime().optional(),
|
|
410
|
+
items: import_zod12.z.array(saleItemSchema).optional(),
|
|
458
411
|
metadata: metadataSchema.nullable().optional(),
|
|
459
412
|
customer_name: customerNameSchema.nullable().optional(),
|
|
460
413
|
customer_phone: customerPhoneSchema.nullable().optional(),
|