@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.js
CHANGED
|
@@ -26,25 +26,6 @@ module.exports = __toCommonJS(middleware_exports);
|
|
|
26
26
|
var import_server_only = require("server-only");
|
|
27
27
|
var import_server = require("next/server");
|
|
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",
|
|
@@ -65,60 +46,6 @@ function getTrackingQueryValues(searchParams) {
|
|
|
65
46
|
}, {});
|
|
66
47
|
}
|
|
67
48
|
|
|
68
|
-
// ../tracking-core/src/gtag.ts
|
|
69
|
-
var SEND_TO_RE = /^AW-[A-Za-z0-9]+\/[A-Za-z0-9_-]+$/;
|
|
70
|
-
function isValidSendTo(sendTo) {
|
|
71
|
-
return SEND_TO_RE.test(sendTo);
|
|
72
|
-
}
|
|
73
|
-
function fireGtagConversion(input) {
|
|
74
|
-
if (typeof window === "undefined" || typeof window.gtag !== "function") return false;
|
|
75
|
-
if (!isValidSendTo(input.sendTo)) return false;
|
|
76
|
-
const params = { send_to: input.sendTo };
|
|
77
|
-
if (input.value != null) params.value = input.value;
|
|
78
|
-
if (input.currency) params.currency = input.currency;
|
|
79
|
-
if (input.transactionId) params.transaction_id = input.transactionId;
|
|
80
|
-
try {
|
|
81
|
-
window.gtag("event", "conversion", params);
|
|
82
|
-
return true;
|
|
83
|
-
} catch {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// ../tracking-core/src/resources/conversion-firing.ts
|
|
89
|
-
var DEDUP_PREFIX = "_aranova_conv_";
|
|
90
|
-
var pendingQueue = [];
|
|
91
|
-
function dedupKey(input) {
|
|
92
|
-
return `${DEDUP_PREFIX}${input.transactionId ?? ""}:${input.sendTo}`;
|
|
93
|
-
}
|
|
94
|
-
function alreadyFired(input) {
|
|
95
|
-
if (!input.transactionId || typeof window === "undefined") return false;
|
|
96
|
-
try {
|
|
97
|
-
return window.sessionStorage.getItem(dedupKey(input)) !== null;
|
|
98
|
-
} catch {
|
|
99
|
-
return false;
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
function markFired(input) {
|
|
103
|
-
if (!input.transactionId || typeof window === "undefined") return;
|
|
104
|
-
try {
|
|
105
|
-
window.sessionStorage.setItem(dedupKey(input), "1");
|
|
106
|
-
} catch {
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
function fireOnce(input) {
|
|
110
|
-
if (alreadyFired(input)) return;
|
|
111
|
-
if (fireGtagConversion(input)) markFired(input);
|
|
112
|
-
}
|
|
113
|
-
function flushPendingConversions() {
|
|
114
|
-
if (getConsentState() !== "granted") return;
|
|
115
|
-
while (pendingQueue.length > 0) {
|
|
116
|
-
const input = pendingQueue.shift();
|
|
117
|
-
if (input) fireOnce(input);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
if (typeof window !== "undefined") onConsentGranted(flushPendingConversions);
|
|
121
|
-
|
|
122
49
|
// ../tracking-core/src/session.ts
|
|
123
50
|
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
124
51
|
|
|
@@ -150,9 +77,17 @@ var ctaClickMetadataSchema = import_zod2.z.object({
|
|
|
150
77
|
path: import_zod2.z.string()
|
|
151
78
|
}).strict(),
|
|
152
79
|
section: import_zod2.z.string().nullable().optional(),
|
|
153
|
-
destination_url: import_zod2.z.string().nullable().optional()
|
|
80
|
+
destination_url: import_zod2.z.string().nullable().optional(),
|
|
81
|
+
// Set by auto-capture (and available to manual callers): the link target
|
|
82
|
+
// and a short element descriptor (tag#id) for tying clicks to specific UI.
|
|
83
|
+
href: import_zod2.z.string().nullable().optional(),
|
|
84
|
+
element: import_zod2.z.string().nullable().optional()
|
|
85
|
+
}).strict();
|
|
86
|
+
var ctaClickConfigSchema = import_zod2.z.object({
|
|
87
|
+
autoCapture: import_zod2.z.object({
|
|
88
|
+
selector: import_zod2.z.string().optional()
|
|
89
|
+
}).strict().optional()
|
|
154
90
|
}).strict();
|
|
155
|
-
var ctaClickConfigSchema = import_zod2.z.object({}).strict();
|
|
156
91
|
|
|
157
92
|
// ../tracking-core/src/events/sdk-heartbeat.ts
|
|
158
93
|
var import_zod3 = require("zod");
|
|
@@ -228,31 +163,44 @@ var multiPageSessionConfigSchema = import_zod6.z.object({
|
|
|
228
163
|
pageThreshold: import_zod6.z.number().int().min(2)
|
|
229
164
|
}).strict();
|
|
230
165
|
|
|
231
|
-
// ../tracking-core/src/events/
|
|
166
|
+
// ../tracking-core/src/events/page-exit.ts
|
|
232
167
|
var import_zod7 = require("zod");
|
|
233
|
-
var
|
|
234
|
-
|
|
168
|
+
var pageExitMetadataSchema = import_zod7.z.object({
|
|
169
|
+
dwell_ms: import_zod7.z.number().int().min(0),
|
|
170
|
+
// null = left without any scroll signal; floor is 0 so a valid 0% is never
|
|
171
|
+
// rejected (a single bad field 422s the whole keepalive beacon batch).
|
|
172
|
+
max_scroll_percent: import_zod7.z.number().int().min(0).max(100).nullable(),
|
|
235
173
|
page: import_zod7.z.object({
|
|
236
174
|
path: import_zod7.z.string()
|
|
237
|
-
}).strict()
|
|
238
|
-
section: import_zod7.z.string().nullable().optional()
|
|
175
|
+
}).strict()
|
|
239
176
|
}).strict();
|
|
240
|
-
var
|
|
177
|
+
var pageExitConfigSchema = import_zod7.z.object({}).strict();
|
|
241
178
|
|
|
242
|
-
// ../tracking-core/src/events/
|
|
179
|
+
// ../tracking-core/src/events/phone-click.ts
|
|
243
180
|
var import_zod8 = require("zod");
|
|
244
|
-
var
|
|
245
|
-
|
|
181
|
+
var phoneClickMetadataSchema = import_zod8.z.object({
|
|
182
|
+
phone_number: import_zod8.z.string(),
|
|
246
183
|
page: import_zod8.z.object({
|
|
247
184
|
path: import_zod8.z.string()
|
|
185
|
+
}).strict(),
|
|
186
|
+
section: import_zod8.z.string().nullable().optional()
|
|
187
|
+
}).strict();
|
|
188
|
+
var phoneClickConfigSchema = import_zod8.z.object({}).strict();
|
|
189
|
+
|
|
190
|
+
// ../tracking-core/src/events/scroll-depth.ts
|
|
191
|
+
var import_zod9 = require("zod");
|
|
192
|
+
var scrollDepthMetadataSchema = import_zod9.z.object({
|
|
193
|
+
depth_percent: import_zod9.z.number().int().min(1).max(100),
|
|
194
|
+
page: import_zod9.z.object({
|
|
195
|
+
path: import_zod9.z.string()
|
|
248
196
|
}).strict()
|
|
249
197
|
}).strict();
|
|
250
|
-
var scrollDepthConfigSchema =
|
|
251
|
-
thresholds:
|
|
198
|
+
var scrollDepthConfigSchema = import_zod9.z.object({
|
|
199
|
+
thresholds: import_zod9.z.array(import_zod9.z.number().int().min(1).max(100)).min(1)
|
|
252
200
|
}).strict();
|
|
253
201
|
|
|
254
202
|
// ../tracking-core/src/events/specific-page-visit.ts
|
|
255
|
-
var
|
|
203
|
+
var import_zod10 = require("zod");
|
|
256
204
|
var SPECIFIC_PAGE_NAMES = [
|
|
257
205
|
"contact_page",
|
|
258
206
|
"about_page",
|
|
@@ -263,18 +211,18 @@ var SPECIFIC_PAGE_NAMES = [
|
|
|
263
211
|
"faq_page",
|
|
264
212
|
"testimonials_page"
|
|
265
213
|
];
|
|
266
|
-
var specificPageNameSchema =
|
|
267
|
-
var specificPageVisitMetadataSchema =
|
|
214
|
+
var specificPageNameSchema = import_zod10.z.enum(SPECIFIC_PAGE_NAMES);
|
|
215
|
+
var specificPageVisitMetadataSchema = import_zod10.z.object({
|
|
268
216
|
page_name: specificPageNameSchema,
|
|
269
|
-
page:
|
|
270
|
-
path:
|
|
217
|
+
page: import_zod10.z.object({
|
|
218
|
+
path: import_zod10.z.string()
|
|
271
219
|
}).strict()
|
|
272
220
|
}).strict();
|
|
273
|
-
var specificPageVisitConfigSchema =
|
|
274
|
-
pages:
|
|
275
|
-
|
|
221
|
+
var specificPageVisitConfigSchema = import_zod10.z.object({
|
|
222
|
+
pages: import_zod10.z.array(
|
|
223
|
+
import_zod10.z.object({
|
|
276
224
|
name: specificPageNameSchema,
|
|
277
|
-
pathPattern:
|
|
225
|
+
pathPattern: import_zod10.z.custom((value) => value instanceof RegExp, {
|
|
278
226
|
message: "pathPattern must be a RegExp"
|
|
279
227
|
})
|
|
280
228
|
}).strict()
|
|
@@ -282,15 +230,15 @@ var specificPageVisitConfigSchema = import_zod9.z.object({
|
|
|
282
230
|
}).strict();
|
|
283
231
|
|
|
284
232
|
// ../tracking-core/src/events/time-on-site.ts
|
|
285
|
-
var
|
|
286
|
-
var timeOnSiteMetadataSchema =
|
|
287
|
-
duration_ms:
|
|
288
|
-
page:
|
|
289
|
-
path:
|
|
233
|
+
var import_zod11 = require("zod");
|
|
234
|
+
var timeOnSiteMetadataSchema = import_zod11.z.object({
|
|
235
|
+
duration_ms: import_zod11.z.number().int().nonnegative(),
|
|
236
|
+
page: import_zod11.z.object({
|
|
237
|
+
path: import_zod11.z.string()
|
|
290
238
|
}).strict()
|
|
291
239
|
}).strict();
|
|
292
|
-
var timeOnSiteConfigSchema =
|
|
293
|
-
thresholdSeconds:
|
|
240
|
+
var timeOnSiteConfigSchema = import_zod11.z.object({
|
|
241
|
+
thresholdSeconds: import_zod11.z.number().int().positive()
|
|
294
242
|
}).strict();
|
|
295
243
|
|
|
296
244
|
// ../tracking-core/src/events/registry.ts
|
|
@@ -332,6 +280,11 @@ var EVENT_REGISTRY = {
|
|
|
332
280
|
metadataSchema: sdkHeartbeatMetadataSchema,
|
|
333
281
|
configSchema: sdkHeartbeatConfigSchema
|
|
334
282
|
},
|
|
283
|
+
page_exit: {
|
|
284
|
+
kind: "automatic",
|
|
285
|
+
metadataSchema: pageExitMetadataSchema,
|
|
286
|
+
configSchema: pageExitConfigSchema
|
|
287
|
+
},
|
|
335
288
|
// --- manual triggers ---
|
|
336
289
|
form_submit: {
|
|
337
290
|
kind: "manual",
|
|
@@ -353,42 +306,42 @@ var ALL_AUTOMATIC_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def])
|
|
|
353
306
|
var ALL_MANUAL_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "manual").map(([name]) => name);
|
|
354
307
|
|
|
355
308
|
// ../tracking-core/src/resources/sales/schema.ts
|
|
356
|
-
var
|
|
309
|
+
var import_zod12 = require("zod");
|
|
357
310
|
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
358
311
|
var TRACKING_ENVIRONMENTS = ["production", "development"];
|
|
359
|
-
var currencySchema =
|
|
360
|
-
var centsSchema =
|
|
361
|
-
var quantitySchema =
|
|
362
|
-
var metadataSchema =
|
|
363
|
-
var saleItemSchema =
|
|
364
|
-
external_item_id:
|
|
365
|
-
name:
|
|
366
|
-
category:
|
|
312
|
+
var currencySchema = import_zod12.z.enum(SUPPORTED_CURRENCIES);
|
|
313
|
+
var centsSchema = import_zod12.z.number().int().nonnegative();
|
|
314
|
+
var quantitySchema = import_zod12.z.string().regex(/^\d+(\.\d{1,3})?$/);
|
|
315
|
+
var metadataSchema = import_zod12.z.record(import_zod12.z.unknown());
|
|
316
|
+
var saleItemSchema = import_zod12.z.object({
|
|
317
|
+
external_item_id: import_zod12.z.string().nullable().optional(),
|
|
318
|
+
name: import_zod12.z.string().nullable().optional(),
|
|
319
|
+
category: import_zod12.z.string().nullable().optional(),
|
|
367
320
|
quantity: quantitySchema,
|
|
368
321
|
unit_price_cents: centsSchema,
|
|
369
322
|
// Non-negativity validated on the wire — same contract as the other cents
|
|
370
323
|
// fields — and backstopped by the DB CHECK.
|
|
371
324
|
unit_cost_cents: centsSchema.nullable().optional()
|
|
372
325
|
}).strict();
|
|
373
|
-
var saleServiceSchema =
|
|
374
|
-
service:
|
|
326
|
+
var saleServiceSchema = import_zod12.z.object({
|
|
327
|
+
service: import_zod12.z.string(),
|
|
375
328
|
amount_cents: centsSchema
|
|
376
329
|
}).strict();
|
|
377
|
-
var customerNameSchema =
|
|
378
|
-
var customerPhoneSchema =
|
|
379
|
-
var customerEmailSchema =
|
|
330
|
+
var customerNameSchema = import_zod12.z.string().max(200);
|
|
331
|
+
var customerPhoneSchema = import_zod12.z.string().max(64);
|
|
332
|
+
var customerEmailSchema = import_zod12.z.string().max(320).email();
|
|
380
333
|
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
381
334
|
if (val.services != null) {
|
|
382
335
|
if (val.service != null) {
|
|
383
336
|
ctx.addIssue({
|
|
384
|
-
code:
|
|
337
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
385
338
|
message: "pass either `service` or `services`, not both",
|
|
386
339
|
path: ["services"]
|
|
387
340
|
});
|
|
388
341
|
}
|
|
389
342
|
if (val.services.length === 0) {
|
|
390
343
|
ctx.addIssue({
|
|
391
|
-
code:
|
|
344
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
392
345
|
message: "`services` must not be empty",
|
|
393
346
|
path: ["services"]
|
|
394
347
|
});
|
|
@@ -396,7 +349,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
396
349
|
const keys = val.services.map((s) => s.service);
|
|
397
350
|
if (new Set(keys).size !== keys.length) {
|
|
398
351
|
ctx.addIssue({
|
|
399
|
-
code:
|
|
352
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
400
353
|
message: "`services` must not list the same service more than once",
|
|
401
354
|
path: ["services"]
|
|
402
355
|
});
|
|
@@ -405,7 +358,7 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
405
358
|
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
406
359
|
if (val.amount_total_cents !== sum) {
|
|
407
360
|
ctx.addIssue({
|
|
408
|
-
code:
|
|
361
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
409
362
|
message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
|
|
410
363
|
path: ["amount_total_cents"]
|
|
411
364
|
});
|
|
@@ -413,37 +366,37 @@ function refineServiceXor(val, ctx, { requireAmount }) {
|
|
|
413
366
|
}
|
|
414
367
|
} else if (requireAmount && val.amount_total_cents == null) {
|
|
415
368
|
ctx.addIssue({
|
|
416
|
-
code:
|
|
369
|
+
code: import_zod12.z.ZodIssueCode.custom,
|
|
417
370
|
message: "amount_total_cents is required unless `services` is provided",
|
|
418
371
|
path: ["amount_total_cents"]
|
|
419
372
|
});
|
|
420
373
|
}
|
|
421
374
|
}
|
|
422
|
-
var saleCreateSchema =
|
|
423
|
-
external_id:
|
|
424
|
-
description:
|
|
425
|
-
service:
|
|
426
|
-
services:
|
|
375
|
+
var saleCreateSchema = import_zod12.z.object({
|
|
376
|
+
external_id: import_zod12.z.string().nullable().optional(),
|
|
377
|
+
description: import_zod12.z.string().nullable().optional(),
|
|
378
|
+
service: import_zod12.z.string().nullable().optional(),
|
|
379
|
+
services: import_zod12.z.array(saleServiceSchema).nullable().optional(),
|
|
427
380
|
currency: currencySchema,
|
|
428
381
|
// Optional only because the plural `services` form derives it from the sum
|
|
429
382
|
// (see refineServiceXor); the singular/serviceless path still requires it.
|
|
430
383
|
amount_total_cents: centsSchema.nullable().optional(),
|
|
431
|
-
occurred_at:
|
|
432
|
-
environment:
|
|
433
|
-
items:
|
|
384
|
+
occurred_at: import_zod12.z.string().datetime(),
|
|
385
|
+
environment: import_zod12.z.enum(TRACKING_ENVIRONMENTS).default("production"),
|
|
386
|
+
items: import_zod12.z.array(saleItemSchema).default([]),
|
|
434
387
|
metadata: metadataSchema.nullable().optional(),
|
|
435
388
|
customer_name: customerNameSchema.nullable().optional(),
|
|
436
389
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
437
390
|
customer_email: customerEmailSchema.nullable().optional()
|
|
438
391
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
439
|
-
var saleUpdateSchema =
|
|
440
|
-
description:
|
|
441
|
-
service:
|
|
442
|
-
services:
|
|
392
|
+
var saleUpdateSchema = import_zod12.z.object({
|
|
393
|
+
description: import_zod12.z.string().nullable().optional(),
|
|
394
|
+
service: import_zod12.z.string().nullable().optional(),
|
|
395
|
+
services: import_zod12.z.array(saleServiceSchema).nullable().optional(),
|
|
443
396
|
currency: currencySchema.optional(),
|
|
444
397
|
amount_total_cents: centsSchema.optional(),
|
|
445
|
-
occurred_at:
|
|
446
|
-
items:
|
|
398
|
+
occurred_at: import_zod12.z.string().datetime().optional(),
|
|
399
|
+
items: import_zod12.z.array(saleItemSchema).optional(),
|
|
447
400
|
metadata: metadataSchema.nullable().optional(),
|
|
448
401
|
customer_name: customerNameSchema.nullable().optional(),
|
|
449
402
|
customer_phone: customerPhoneSchema.nullable().optional(),
|