@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.
@@ -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/phone-click.ts
166
+ // ../tracking-core/src/events/page-exit.ts
232
167
  var import_zod7 = require("zod");
233
- var phoneClickMetadataSchema = import_zod7.z.object({
234
- phone_number: import_zod7.z.string(),
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 phoneClickConfigSchema = import_zod7.z.object({}).strict();
177
+ var pageExitConfigSchema = import_zod7.z.object({}).strict();
241
178
 
242
- // ../tracking-core/src/events/scroll-depth.ts
179
+ // ../tracking-core/src/events/phone-click.ts
243
180
  var import_zod8 = require("zod");
244
- var scrollDepthMetadataSchema = import_zod8.z.object({
245
- depth_percent: import_zod8.z.number().int().min(1).max(100),
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 = import_zod8.z.object({
251
- thresholds: import_zod8.z.array(import_zod8.z.number().int().min(1).max(100)).min(1)
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 import_zod9 = require("zod");
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 = import_zod9.z.enum(SPECIFIC_PAGE_NAMES);
267
- var specificPageVisitMetadataSchema = import_zod9.z.object({
214
+ var specificPageNameSchema = import_zod10.z.enum(SPECIFIC_PAGE_NAMES);
215
+ var specificPageVisitMetadataSchema = import_zod10.z.object({
268
216
  page_name: specificPageNameSchema,
269
- page: import_zod9.z.object({
270
- path: import_zod9.z.string()
217
+ page: import_zod10.z.object({
218
+ path: import_zod10.z.string()
271
219
  }).strict()
272
220
  }).strict();
273
- var specificPageVisitConfigSchema = import_zod9.z.object({
274
- pages: import_zod9.z.array(
275
- import_zod9.z.object({
221
+ var specificPageVisitConfigSchema = import_zod10.z.object({
222
+ pages: import_zod10.z.array(
223
+ import_zod10.z.object({
276
224
  name: specificPageNameSchema,
277
- pathPattern: import_zod9.z.custom((value) => value instanceof RegExp, {
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 import_zod10 = require("zod");
286
- var timeOnSiteMetadataSchema = import_zod10.z.object({
287
- duration_ms: import_zod10.z.number().int().nonnegative(),
288
- page: import_zod10.z.object({
289
- path: import_zod10.z.string()
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 = import_zod10.z.object({
293
- thresholdSeconds: import_zod10.z.number().int().positive()
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 import_zod11 = require("zod");
309
+ var import_zod12 = require("zod");
357
310
  var SUPPORTED_CURRENCIES = ["USD", "CAD"];
358
311
  var TRACKING_ENVIRONMENTS = ["production", "development"];
359
- var currencySchema = import_zod11.z.enum(SUPPORTED_CURRENCIES);
360
- var centsSchema = import_zod11.z.number().int().nonnegative();
361
- var quantitySchema = import_zod11.z.string().regex(/^\d+(\.\d{1,3})?$/);
362
- var metadataSchema = import_zod11.z.record(import_zod11.z.unknown());
363
- var saleItemSchema = import_zod11.z.object({
364
- external_item_id: import_zod11.z.string().nullable().optional(),
365
- name: import_zod11.z.string().nullable().optional(),
366
- category: import_zod11.z.string().nullable().optional(),
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 = import_zod11.z.object({
374
- service: import_zod11.z.string(),
326
+ var saleServiceSchema = import_zod12.z.object({
327
+ service: import_zod12.z.string(),
375
328
  amount_cents: centsSchema
376
329
  }).strict();
377
- var customerNameSchema = import_zod11.z.string().max(200);
378
- var customerPhoneSchema = import_zod11.z.string().max(64);
379
- var customerEmailSchema = import_zod11.z.string().max(320).email();
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: import_zod11.z.ZodIssueCode.custom,
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: import_zod11.z.ZodIssueCode.custom,
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: import_zod11.z.ZodIssueCode.custom,
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: import_zod11.z.ZodIssueCode.custom,
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: import_zod11.z.ZodIssueCode.custom,
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 = import_zod11.z.object({
423
- external_id: import_zod11.z.string().nullable().optional(),
424
- description: import_zod11.z.string().nullable().optional(),
425
- service: import_zod11.z.string().nullable().optional(),
426
- services: import_zod11.z.array(saleServiceSchema).nullable().optional(),
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: import_zod11.z.string().datetime(),
432
- environment: import_zod11.z.enum(TRACKING_ENVIRONMENTS).default("production"),
433
- items: import_zod11.z.array(saleItemSchema).default([]),
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 = import_zod11.z.object({
440
- description: import_zod11.z.string().nullable().optional(),
441
- service: import_zod11.z.string().nullable().optional(),
442
- services: import_zod11.z.array(saleServiceSchema).nullable().optional(),
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: import_zod11.z.string().datetime().optional(),
446
- items: import_zod11.z.array(saleItemSchema).optional(),
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(),