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