@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.mjs
CHANGED
|
@@ -2,25 +2,6 @@
|
|
|
2
2
|
import "server-only";
|
|
3
3
|
import { cookies } from "next/headers";
|
|
4
4
|
|
|
5
|
-
// ../tracking-core/src/consent.ts
|
|
6
|
-
var CONSENT_STATE_KEY = "consent_state";
|
|
7
|
-
var grantedListeners = /* @__PURE__ */ new Set();
|
|
8
|
-
function onConsentGranted(listener) {
|
|
9
|
-
grantedListeners.add(listener);
|
|
10
|
-
return () => {
|
|
11
|
-
grantedListeners.delete(listener);
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
function getConsentState() {
|
|
15
|
-
if (typeof window === "undefined") return "pending";
|
|
16
|
-
try {
|
|
17
|
-
const storedState = window.localStorage.getItem(CONSENT_STATE_KEY);
|
|
18
|
-
if (storedState === "granted" || storedState === "denied") return storedState;
|
|
19
|
-
} catch {
|
|
20
|
-
}
|
|
21
|
-
return "pending";
|
|
22
|
-
}
|
|
23
|
-
|
|
24
5
|
// ../tracking-core/src/tracking.ts
|
|
25
6
|
var TRACKING_PARAM_KEYS = [
|
|
26
7
|
"gclid",
|
|
@@ -52,60 +33,6 @@ function getTrackingParamsFromCookieReader(readCookie) {
|
|
|
52
33
|
}, createEmptyTrackingParams());
|
|
53
34
|
}
|
|
54
35
|
|
|
55
|
-
// ../tracking-core/src/gtag.ts
|
|
56
|
-
var SEND_TO_RE = /^AW-[A-Za-z0-9]+\/[A-Za-z0-9_-]+$/;
|
|
57
|
-
function isValidSendTo(sendTo) {
|
|
58
|
-
return SEND_TO_RE.test(sendTo);
|
|
59
|
-
}
|
|
60
|
-
function fireGtagConversion(input) {
|
|
61
|
-
if (typeof window === "undefined" || typeof window.gtag !== "function") return false;
|
|
62
|
-
if (!isValidSendTo(input.sendTo)) return false;
|
|
63
|
-
const params = { send_to: input.sendTo };
|
|
64
|
-
if (input.value != null) params.value = input.value;
|
|
65
|
-
if (input.currency) params.currency = input.currency;
|
|
66
|
-
if (input.transactionId) params.transaction_id = input.transactionId;
|
|
67
|
-
try {
|
|
68
|
-
window.gtag("event", "conversion", params);
|
|
69
|
-
return true;
|
|
70
|
-
} catch {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// ../tracking-core/src/resources/conversion-firing.ts
|
|
76
|
-
var DEDUP_PREFIX = "_aranova_conv_";
|
|
77
|
-
var pendingQueue = [];
|
|
78
|
-
function dedupKey(input) {
|
|
79
|
-
return `${DEDUP_PREFIX}${input.transactionId ?? ""}:${input.sendTo}`;
|
|
80
|
-
}
|
|
81
|
-
function alreadyFired(input) {
|
|
82
|
-
if (!input.transactionId || typeof window === "undefined") return false;
|
|
83
|
-
try {
|
|
84
|
-
return window.sessionStorage.getItem(dedupKey(input)) !== null;
|
|
85
|
-
} catch {
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
function markFired(input) {
|
|
90
|
-
if (!input.transactionId || typeof window === "undefined") return;
|
|
91
|
-
try {
|
|
92
|
-
window.sessionStorage.setItem(dedupKey(input), "1");
|
|
93
|
-
} catch {
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
function fireOnce(input) {
|
|
97
|
-
if (alreadyFired(input)) return;
|
|
98
|
-
if (fireGtagConversion(input)) markFired(input);
|
|
99
|
-
}
|
|
100
|
-
function flushPendingConversions() {
|
|
101
|
-
if (getConsentState() !== "granted") return;
|
|
102
|
-
while (pendingQueue.length > 0) {
|
|
103
|
-
const input = pendingQueue.shift();
|
|
104
|
-
if (input) fireOnce(input);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
if (typeof window !== "undefined") onConsentGranted(flushPendingConversions);
|
|
108
|
-
|
|
109
36
|
// ../tracking-core/src/session.ts
|
|
110
37
|
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
111
38
|
|
|
@@ -137,9 +64,17 @@ var ctaClickMetadataSchema = z2.object({
|
|
|
137
64
|
path: z2.string()
|
|
138
65
|
}).strict(),
|
|
139
66
|
section: z2.string().nullable().optional(),
|
|
140
|
-
destination_url: z2.string().nullable().optional()
|
|
67
|
+
destination_url: z2.string().nullable().optional(),
|
|
68
|
+
// Set by auto-capture (and available to manual callers): the link target
|
|
69
|
+
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
70
|
+
href: z2.string().nullable().optional(),
|
|
71
|
+
element: z2.string().nullable().optional()
|
|
72
|
+
}).strict();
|
|
73
|
+
var ctaClickConfigSchema = z2.object({
|
|
74
|
+
autoCapture: z2.object({
|
|
75
|
+
selector: z2.string().optional()
|
|
76
|
+
}).strict().optional()
|
|
141
77
|
}).strict();
|
|
142
|
-
var ctaClickConfigSchema = z2.object({}).strict();
|
|
143
78
|
|
|
144
79
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
145
80
|
import { z as z3 } from "zod";
|
|
@@ -215,31 +150,44 @@ var multiPageSessionConfigSchema = z6.object({
|
|
|
215
150
|
pageThreshold: z6.number().int().min(2)
|
|
216
151
|
}).strict();
|
|
217
152
|
|
|
218
|
-
// ../tracking-core/src/events/
|
|
153
|
+
// ../tracking-core/src/events/page-exit.ts
|
|
219
154
|
import { z as z7 } from "zod";
|
|
220
|
-
var
|
|
221
|
-
|
|
155
|
+
var pageExitMetadataSchema = z7.object({
|
|
156
|
+
dwell_ms: z7.number().int().min(0),
|
|
157
|
+
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
158
|
+
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
159
|
+
max_scroll_percent: z7.number().int().min(0).max(100).nullable(),
|
|
222
160
|
page: z7.object({
|
|
223
161
|
path: z7.string()
|
|
224
|
-
}).strict()
|
|
225
|
-
section: z7.string().nullable().optional()
|
|
162
|
+
}).strict()
|
|
226
163
|
}).strict();
|
|
227
|
-
var
|
|
164
|
+
var pageExitConfigSchema = z7.object({}).strict();
|
|
228
165
|
|
|
229
|
-
// ../tracking-core/src/events/
|
|
166
|
+
// ../tracking-core/src/events/phone-click.ts
|
|
230
167
|
import { z as z8 } from "zod";
|
|
231
|
-
var
|
|
232
|
-
|
|
168
|
+
var phoneClickMetadataSchema = z8.object({
|
|
169
|
+
phone_number: z8.string(),
|
|
233
170
|
page: z8.object({
|
|
234
171
|
path: z8.string()
|
|
172
|
+
}).strict(),
|
|
173
|
+
section: z8.string().nullable().optional()
|
|
174
|
+
}).strict();
|
|
175
|
+
var phoneClickConfigSchema = z8.object({}).strict();
|
|
176
|
+
|
|
177
|
+
// ../tracking-core/src/events/scroll-depth.ts
|
|
178
|
+
import { z as z9 } from "zod";
|
|
179
|
+
var scrollDepthMetadataSchema = z9.object({
|
|
180
|
+
depth_percent: z9.number().int().min(1).max(100),
|
|
181
|
+
page: z9.object({
|
|
182
|
+
path: z9.string()
|
|
235
183
|
}).strict()
|
|
236
184
|
}).strict();
|
|
237
|
-
var scrollDepthConfigSchema =
|
|
238
|
-
thresholds:
|
|
185
|
+
var scrollDepthConfigSchema = z9.object({
|
|
186
|
+
thresholds: z9.array(z9.number().int().min(1).max(100)).min(1)
|
|
239
187
|
}).strict();
|
|
240
188
|
|
|
241
189
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
242
|
-
import { z as
|
|
190
|
+
import { z as z10 } from "zod";
|
|
243
191
|
var SPECIFIC_PAGE_NAMES = [
|
|
244
192
|
"contact_page",
|
|
245
193
|
"about_page",
|
|
@@ -250,18 +198,18 @@ var SPECIFIC_PAGE_NAMES = [
|
|
|
250
198
|
"faq_page",
|
|
251
199
|
"testimonials_page"
|
|
252
200
|
];
|
|
253
|
-
var specificPageNameSchema =
|
|
254
|
-
var specificPageVisitMetadataSchema =
|
|
201
|
+
var specificPageNameSchema = z10.enum(SPECIFIC_PAGE_NAMES);
|
|
202
|
+
var specificPageVisitMetadataSchema = z10.object({
|
|
255
203
|
page_name: specificPageNameSchema,
|
|
256
|
-
page:
|
|
257
|
-
path:
|
|
204
|
+
page: z10.object({
|
|
205
|
+
path: z10.string()
|
|
258
206
|
}).strict()
|
|
259
207
|
}).strict();
|
|
260
|
-
var specificPageVisitConfigSchema =
|
|
261
|
-
pages:
|
|
262
|
-
|
|
208
|
+
var specificPageVisitConfigSchema = z10.object({
|
|
209
|
+
pages: z10.array(
|
|
210
|
+
z10.object({
|
|
263
211
|
name: specificPageNameSchema,
|
|
264
|
-
pathPattern:
|
|
212
|
+
pathPattern: z10.custom((value) => value instanceof RegExp, {
|
|
265
213
|
message: "pathPattern must be a RegExp"
|
|
266
214
|
})
|
|
267
215
|
}).strict()
|
|
@@ -269,15 +217,15 @@ var specificPageVisitConfigSchema = z9.object({
|
|
|
269
217
|
}).strict();
|
|
270
218
|
|
|
271
219
|
// ../tracking-core/src/events/time-on-site.ts
|
|
272
|
-
import { z as
|
|
273
|
-
var timeOnSiteMetadataSchema =
|
|
274
|
-
duration_ms:
|
|
275
|
-
page:
|
|
276
|
-
path:
|
|
220
|
+
import { z as z11 } from "zod";
|
|
221
|
+
var timeOnSiteMetadataSchema = z11.object({
|
|
222
|
+
duration_ms: z11.number().int().nonnegative(),
|
|
223
|
+
page: z11.object({
|
|
224
|
+
path: z11.string()
|
|
277
225
|
}).strict()
|
|
278
226
|
}).strict();
|
|
279
|
-
var timeOnSiteConfigSchema =
|
|
280
|
-
thresholdSeconds:
|
|
227
|
+
var timeOnSiteConfigSchema = z11.object({
|
|
228
|
+
thresholdSeconds: z11.number().int().positive()
|
|
281
229
|
}).strict();
|
|
282
230
|
|
|
283
231
|
// ../tracking-core/src/events/registry.ts
|
|
@@ -319,6 +267,11 @@ var EVENT_REGISTRY = {
|
|
|
319
267
|
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
320
268
|
configSchema: sdkHeartbeatConfigSchema
|
|
321
269
|
},
|
|
270
|
+
page_exit: {
|
|
271
|
+
kind: "automatic",
|
|
272
|
+
metadataSchema: pageExitMetadataSchema,
|
|
273
|
+
configSchema: pageExitConfigSchema
|
|
274
|
+
},
|
|
322
275
|
// --- manual triggers ---
|
|
323
276
|
form_submit: {
|
|
324
277
|
kind: "manual",
|
|
@@ -340,42 +293,42 @@ var ALL_AUTOMATIC_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def])
|
|
|
340
293
|
var ALL_MANUAL_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "manual").map(([name]) => name);
|
|
341
294
|
|
|
342
295
|
// ../tracking-core/src/resources/sales/schema.ts
|
|
343
|
-
import { z as
|
|
296
|
+
import { z as z12 } from "zod";
|
|
344
297
|
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
345
298
|
var TRACKING_ENVIRONMENTS = ["production", "development"];
|
|
346
|
-
var currencySchema =
|
|
347
|
-
var centsSchema =
|
|
348
|
-
var quantitySchema =
|
|
349
|
-
var metadataSchema =
|
|
350
|
-
var saleItemSchema =
|
|
351
|
-
external_item_id:
|
|
352
|
-
name:
|
|
353
|
-
category:
|
|
299
|
+
var currencySchema = z12.enum(SUPPORTED_CURRENCIES);
|
|
300
|
+
var centsSchema = z12.number().int().nonnegative();
|
|
301
|
+
var quantitySchema = z12.string().regex(/^\d+(\.\d{1,3})?$/);
|
|
302
|
+
var metadataSchema = z12.record(z12.unknown());
|
|
303
|
+
var saleItemSchema = z12.object({
|
|
304
|
+
external_item_id: z12.string().nullable().optional(),
|
|
305
|
+
name: z12.string().nullable().optional(),
|
|
306
|
+
category: z12.string().nullable().optional(),
|
|
354
307
|
quantity: quantitySchema,
|
|
355
308
|
unit_price_cents: centsSchema,
|
|
356
309
|
// Non-negativity validated on the wire — same contract as the other cents
|
|
357
310
|
// fields — and backstopped by the DB CHECK.
|
|
358
311
|
unit_cost_cents: centsSchema.nullable().optional()
|
|
359
312
|
}).strict();
|
|
360
|
-
var saleServiceSchema =
|
|
361
|
-
service:
|
|
313
|
+
var saleServiceSchema = z12.object({
|
|
314
|
+
service: z12.string(),
|
|
362
315
|
amount_cents: centsSchema
|
|
363
316
|
}).strict();
|
|
364
|
-
var customerNameSchema =
|
|
365
|
-
var customerPhoneSchema =
|
|
366
|
-
var customerEmailSchema =
|
|
317
|
+
var customerNameSchema = z12.string().max(200);
|
|
318
|
+
var customerPhoneSchema = z12.string().max(64);
|
|
319
|
+
var customerEmailSchema = z12.string().max(320).email();
|
|
367
320
|
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
368
321
|
if (val.services != null) {
|
|
369
322
|
if (val.service != null) {
|
|
370
323
|
ctx.addIssue({
|
|
371
|
-
code:
|
|
324
|
+
code: z12.ZodIssueCode.custom,
|
|
372
325
|
message: "pass either `service` or `services`, not both",
|
|
373
326
|
path: ["services"]
|
|
374
327
|
});
|
|
375
328
|
}
|
|
376
329
|
if (val.services.length === 0) {
|
|
377
330
|
ctx.addIssue({
|
|
378
|
-
code:
|
|
331
|
+
code: z12.ZodIssueCode.custom,
|
|
379
332
|
message: "`services` must not be empty",
|
|
380
333
|
path: ["services"]
|
|
381
334
|
});
|
|
@@ -383,7 +336,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
383
336
|
const keys = val.services.map((s) => s.service);
|
|
384
337
|
if (new Set(keys).size !== keys.length) {
|
|
385
338
|
ctx.addIssue({
|
|
386
|
-
code:
|
|
339
|
+
code: z12.ZodIssueCode.custom,
|
|
387
340
|
message: "`services` must not list the same service more than once",
|
|
388
341
|
path: ["services"]
|
|
389
342
|
});
|
|
@@ -392,7 +345,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
392
345
|
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
393
346
|
if (val.amount_total_cents !== sum) {
|
|
394
347
|
ctx.addIssue({
|
|
395
|
-
code:
|
|
348
|
+
code: z12.ZodIssueCode.custom,
|
|
396
349
|
message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
|
|
397
350
|
path: ["amount_total_cents"]
|
|
398
351
|
});
|
|
@@ -400,37 +353,37 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
400
353
|
}
|
|
401
354
|
} else if (requireAmount && val.amount_total_cents == null) {
|
|
402
355
|
ctx.addIssue({
|
|
403
|
-
code:
|
|
356
|
+
code: z12.ZodIssueCode.custom,
|
|
404
357
|
message: "amount_total_cents is required unless `services` is provided",
|
|
405
358
|
path: ["amount_total_cents"]
|
|
406
359
|
});
|
|
407
360
|
}
|
|
408
361
|
}
|
|
409
|
-
var saleCreateSchema =
|
|
410
|
-
external_id:
|
|
411
|
-
description:
|
|
412
|
-
service:
|
|
413
|
-
services:
|
|
362
|
+
var saleCreateSchema = z12.object({
|
|
363
|
+
external_id: z12.string().nullable().optional(),
|
|
364
|
+
description: z12.string().nullable().optional(),
|
|
365
|
+
service: z12.string().nullable().optional(),
|
|
366
|
+
services: z12.array(saleServiceSchema).nullable().optional(),
|
|
414
367
|
currency: currencySchema,
|
|
415
368
|
// Optional only because the plural `services` form derives it from the sum
|
|
416
369
|
// (see refineServiceXor); the singular/serviceless path still requires it.
|
|
417
370
|
amount_total_cents: centsSchema.nullable().optional(),
|
|
418
|
-
occurred_at:
|
|
419
|
-
environment:
|
|
420
|
-
items:
|
|
371
|
+
occurred_at: z12.string().datetime(),
|
|
372
|
+
environment: z12.enum(TRACKING_ENVIRONMENTS).default("production"),
|
|
373
|
+
items: z12.array(saleItemSchema).default([]),
|
|
421
374
|
metadata: metadataSchema.nullable().optional(),
|
|
422
375
|
customer_name: customerNameSchema.nullable().optional(),
|
|
423
376
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
424
377
|
customer_email: customerEmailSchema.nullable().optional()
|
|
425
378
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
426
|
-
var saleUpdateSchema =
|
|
427
|
-
description:
|
|
428
|
-
service:
|
|
429
|
-
services:
|
|
379
|
+
var saleUpdateSchema = z12.object({
|
|
380
|
+
description: z12.string().nullable().optional(),
|
|
381
|
+
service: z12.string().nullable().optional(),
|
|
382
|
+
services: z12.array(saleServiceSchema).nullable().optional(),
|
|
430
383
|
currency: currencySchema.optional(),
|
|
431
384
|
amount_total_cents: centsSchema.optional(),
|
|
432
|
-
occurred_at:
|
|
433
|
-
items:
|
|
385
|
+
occurred_at: z12.string().datetime().optional(),
|
|
386
|
+
items: z12.array(saleItemSchema).optional(),
|
|
434
387
|
metadata: metadataSchema.nullable().optional(),
|
|
435
388
|
customer_name: customerNameSchema.nullable().optional(),
|
|
436
389
|
customer_phone: customerPhoneSchema.nullable().optional(),
|