@aranova/tracking-next 0.11.0 → 0.12.1
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 +79 -71
- package/dist/index.d.mts +137 -722
- package/dist/index.d.ts +137 -722
- package/dist/index.js +408 -66
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +385 -60
- package/dist/index.mjs.map +1 -1
- package/dist/middleware.js +101 -0
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +101 -0
- package/dist/middleware.mjs.map +1 -1
- package/dist/phone-utils-dd1tW7sb.d.mts +344 -0
- package/dist/phone-utils-dd1tW7sb.d.ts +344 -0
- package/dist/phone.d.mts +3 -0
- package/dist/phone.d.ts +3 -0
- package/dist/phone.js +416 -0
- package/dist/phone.js.map +1 -0
- package/dist/phone.mjs +384 -0
- package/dist/phone.mjs.map +1 -0
- package/dist/sales.d.mts +784 -0
- package/dist/sales.d.ts +784 -0
- package/dist/sales.js +400 -0
- package/dist/sales.js.map +1 -0
- package/dist/sales.mjs +359 -0
- package/dist/sales.mjs.map +1 -0
- package/dist/server.d.mts +3 -1
- package/dist/server.d.ts +3 -1
- package/dist/server.js +101 -0
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +101 -0
- package/dist/server.mjs.map +1 -1
- package/package.json +51 -10
- package/dist/types-BPJLgMsG.d.mts +0 -161
- package/dist/types-BPJLgMsG.d.ts +0 -161
package/dist/index.mjs
CHANGED
|
@@ -10,24 +10,20 @@ function buildConsentPayload(state) {
|
|
|
10
10
|
};
|
|
11
11
|
}
|
|
12
12
|
function getConsentState() {
|
|
13
|
-
if (typeof window === "undefined")
|
|
14
|
-
return "pending";
|
|
13
|
+
if (typeof window === "undefined") return "pending";
|
|
15
14
|
const storedState = window.localStorage.getItem(CONSENT_STATE_KEY);
|
|
16
|
-
if (storedState === "granted" || storedState === "denied")
|
|
17
|
-
return storedState;
|
|
15
|
+
if (storedState === "granted" || storedState === "denied") return storedState;
|
|
18
16
|
return "pending";
|
|
19
17
|
}
|
|
20
18
|
function setConsentState(state) {
|
|
21
|
-
if (typeof window === "undefined")
|
|
22
|
-
return;
|
|
19
|
+
if (typeof window === "undefined") return;
|
|
23
20
|
window.localStorage.setItem(CONSENT_STATE_KEY, state);
|
|
24
21
|
window.localStorage.setItem(CONSENT_TIMESTAMP_KEY, (/* @__PURE__ */ new Date()).toISOString());
|
|
25
22
|
if (typeof window.gtag === "function")
|
|
26
23
|
window.gtag("consent", "update", buildConsentPayload(state));
|
|
27
24
|
}
|
|
28
25
|
function resetConsent() {
|
|
29
|
-
if (typeof window === "undefined")
|
|
30
|
-
return;
|
|
26
|
+
if (typeof window === "undefined") return;
|
|
31
27
|
window.localStorage.removeItem(CONSENT_STATE_KEY);
|
|
32
28
|
window.localStorage.removeItem(CONSENT_TIMESTAMP_KEY);
|
|
33
29
|
}
|
|
@@ -168,18 +164,15 @@ function getTrackingQueryValues(searchParams) {
|
|
|
168
164
|
}, {});
|
|
169
165
|
}
|
|
170
166
|
function getCookieValueFromDocument(key) {
|
|
171
|
-
if (typeof document === "undefined")
|
|
172
|
-
return null;
|
|
167
|
+
if (typeof document === "undefined") return null;
|
|
173
168
|
const cookies = document.cookie ? document.cookie.split("; ") : [];
|
|
174
169
|
const match = cookies.find((cookie) => cookie.startsWith(`${key}=`));
|
|
175
|
-
if (!match)
|
|
176
|
-
return null;
|
|
170
|
+
if (!match) return null;
|
|
177
171
|
const [, rawValue = ""] = match.split("=");
|
|
178
172
|
return normalizeTrackingCookieValue(decodeURIComponent(rawValue));
|
|
179
173
|
}
|
|
180
174
|
function setTrackingCookie(key, value, maxAgeSeconds = TRACKING_COOKIE_MAX_AGE_SECONDS) {
|
|
181
|
-
if (typeof document === "undefined")
|
|
182
|
-
return;
|
|
175
|
+
if (typeof document === "undefined") return;
|
|
183
176
|
const encodedValue = encodeURIComponent(value);
|
|
184
177
|
document.cookie = `${key}=${encodedValue}; Max-Age=${maxAgeSeconds}; Path=/; SameSite=Lax`;
|
|
185
178
|
}
|
|
@@ -219,18 +212,15 @@ function writeLocalStorage(key, value) {
|
|
|
219
212
|
}
|
|
220
213
|
}
|
|
221
214
|
function getVisitorId() {
|
|
222
|
-
if (typeof window === "undefined")
|
|
223
|
-
return safeUuid();
|
|
215
|
+
if (typeof window === "undefined") return safeUuid();
|
|
224
216
|
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
225
|
-
if (existing && existing.length > 0)
|
|
226
|
-
return existing;
|
|
217
|
+
if (existing && existing.length > 0) return existing;
|
|
227
218
|
const fresh = safeUuid();
|
|
228
219
|
writeLocalStorage(VISITOR_STORAGE_KEY, fresh);
|
|
229
220
|
return fresh;
|
|
230
221
|
}
|
|
231
222
|
function getOrRotateSessionId(now = Date.now()) {
|
|
232
|
-
if (typeof window === "undefined")
|
|
233
|
-
return { id: safeUuid(), isNew: true };
|
|
223
|
+
if (typeof window === "undefined") return { id: safeUuid(), isNew: true };
|
|
234
224
|
const raw = readLocalStorage(SESSION_STORAGE_KEY);
|
|
235
225
|
if (raw) {
|
|
236
226
|
try {
|
|
@@ -303,8 +293,7 @@ function setLastFiredUrl(url) {
|
|
|
303
293
|
writeSessionStorage(LAST_FIRED_URL_STORAGE_KEY, url);
|
|
304
294
|
}
|
|
305
295
|
function buildPageViewMetadata(referrerOverride) {
|
|
306
|
-
if (typeof window === "undefined" || typeof document === "undefined")
|
|
307
|
-
return null;
|
|
296
|
+
if (typeof window === "undefined" || typeof document === "undefined") return null;
|
|
308
297
|
return pageViewMetadataSchema.parse({
|
|
309
298
|
page: {
|
|
310
299
|
title: document.title || null,
|
|
@@ -317,8 +306,7 @@ function buildPageViewMetadata(referrerOverride) {
|
|
|
317
306
|
});
|
|
318
307
|
}
|
|
319
308
|
function fireManualPageView(client) {
|
|
320
|
-
if (typeof window === "undefined")
|
|
321
|
-
return;
|
|
309
|
+
if (typeof window === "undefined") return;
|
|
322
310
|
const currentHref = window.location.href;
|
|
323
311
|
const previousFiredUrl = getLastFiredUrl();
|
|
324
312
|
const internalReferrer = previousFiredUrl !== null && previousFiredUrl !== currentHref ? previousFiredUrl : null;
|
|
@@ -420,8 +408,7 @@ function buildContext(surface, sdkVersion, packageName, environment, activeGtagI
|
|
|
420
408
|
};
|
|
421
409
|
}
|
|
422
410
|
function readTrackingParams() {
|
|
423
|
-
if (typeof window === "undefined")
|
|
424
|
-
return createEmptyTrackingParams();
|
|
411
|
+
if (typeof window === "undefined") return createEmptyTrackingParams();
|
|
425
412
|
try {
|
|
426
413
|
captureTrackingParamsFromLocation();
|
|
427
414
|
} catch {
|
|
@@ -436,8 +423,7 @@ function consentSnapshot() {
|
|
|
436
423
|
}
|
|
437
424
|
}
|
|
438
425
|
async function postWithFetch(url, body, apiKey, identity, keepalive) {
|
|
439
|
-
if (typeof fetch !== "function")
|
|
440
|
-
return;
|
|
426
|
+
if (typeof fetch !== "function") return;
|
|
441
427
|
try {
|
|
442
428
|
await fetch(url, {
|
|
443
429
|
method: "POST",
|
|
@@ -497,8 +483,7 @@ function createTrackingClient(config) {
|
|
|
497
483
|
const visitorId = getVisitorId();
|
|
498
484
|
const initialSession = getOrRotateSessionId();
|
|
499
485
|
let sessionId = initialSession.id;
|
|
500
|
-
if (typeof window !== "undefined")
|
|
501
|
-
firstPage = window.location.href;
|
|
486
|
+
if (typeof window !== "undefined") firstPage = window.location.href;
|
|
502
487
|
function enqueueHeartbeat() {
|
|
503
488
|
const metadata = buildHeartbeatMetadata(
|
|
504
489
|
config.surface,
|
|
@@ -524,7 +509,13 @@ function createTrackingClient(config) {
|
|
|
524
509
|
}
|
|
525
510
|
sessionId = rotated.id;
|
|
526
511
|
const params = readTrackingParams();
|
|
527
|
-
const context = buildContext(
|
|
512
|
+
const context = buildContext(
|
|
513
|
+
config.surface,
|
|
514
|
+
sdkVersion,
|
|
515
|
+
packageName,
|
|
516
|
+
environment,
|
|
517
|
+
activeGtagIds
|
|
518
|
+
);
|
|
528
519
|
return {
|
|
529
520
|
session_id: sessionId,
|
|
530
521
|
visitor_id: visitorId,
|
|
@@ -541,8 +532,7 @@ function createTrackingClient(config) {
|
|
|
541
532
|
};
|
|
542
533
|
}
|
|
543
534
|
function scheduleFlush() {
|
|
544
|
-
if (flushTimer !== null || destroyed)
|
|
545
|
-
return;
|
|
535
|
+
if (flushTimer !== null || destroyed) return;
|
|
546
536
|
flushTimer = setTimeout(() => {
|
|
547
537
|
flushTimer = null;
|
|
548
538
|
void flush();
|
|
@@ -555,8 +545,7 @@ function createTrackingClient(config) {
|
|
|
555
545
|
}
|
|
556
546
|
}
|
|
557
547
|
async function flush() {
|
|
558
|
-
if (queue.length === 0)
|
|
559
|
-
return;
|
|
548
|
+
if (queue.length === 0) return;
|
|
560
549
|
const events = queue.slice(0, HARD_MAX_BATCH);
|
|
561
550
|
queue = queue.slice(events.length);
|
|
562
551
|
clearScheduledFlush();
|
|
@@ -568,10 +557,8 @@ function createTrackingClient(config) {
|
|
|
568
557
|
await postWithFetch(eventsUrl, serialized, config.apiKey, identityHeaders2, false);
|
|
569
558
|
}
|
|
570
559
|
function trackEvent(input) {
|
|
571
|
-
if (destroyed)
|
|
572
|
-
|
|
573
|
-
if (!input || typeof input.eventType !== "string" || input.eventType.length === 0)
|
|
574
|
-
return;
|
|
560
|
+
if (destroyed) return;
|
|
561
|
+
if (!input || typeof input.eventType !== "string" || input.eventType.length === 0) return;
|
|
575
562
|
const occurredAt = input.occurredAt instanceof Date ? input.occurredAt.toISOString() : typeof input.occurredAt === "string" ? input.occurredAt : (/* @__PURE__ */ new Date()).toISOString();
|
|
576
563
|
queue.push({
|
|
577
564
|
event_type: input.eventType,
|
|
@@ -586,8 +573,7 @@ function createTrackingClient(config) {
|
|
|
586
573
|
}
|
|
587
574
|
}
|
|
588
575
|
function flushOnUnload() {
|
|
589
|
-
if (queue.length === 0)
|
|
590
|
-
return;
|
|
576
|
+
if (queue.length === 0) return;
|
|
591
577
|
const events = queue.slice(0, HARD_MAX_BATCH);
|
|
592
578
|
queue = queue.slice(events.length);
|
|
593
579
|
clearScheduledFlush();
|
|
@@ -1127,21 +1113,40 @@ function createSalesClient(config) {
|
|
|
1127
1113
|
return salesRequest(config, "POST", "/sales", body);
|
|
1128
1114
|
},
|
|
1129
1115
|
async list(query) {
|
|
1130
|
-
const { cursor, limit, ...filters } = query ?? {};
|
|
1116
|
+
const { cursor, limit, sort, order, want_total, ...filters } = query ?? {};
|
|
1131
1117
|
return salesRequest(config, "POST", "/sales/query", {
|
|
1132
1118
|
filters,
|
|
1133
1119
|
...limit !== void 0 ? { limit } : {},
|
|
1134
|
-
...cursor !== void 0 ? { cursor } : {}
|
|
1120
|
+
...cursor !== void 0 ? { cursor } : {},
|
|
1121
|
+
...sort !== void 0 ? { sort } : {},
|
|
1122
|
+
...order !== void 0 ? { order } : {},
|
|
1123
|
+
...want_total !== void 0 ? { want_total } : {}
|
|
1135
1124
|
});
|
|
1136
1125
|
},
|
|
1137
1126
|
async summary(query) {
|
|
1138
|
-
const {
|
|
1127
|
+
const {
|
|
1128
|
+
range,
|
|
1129
|
+
include_categories,
|
|
1130
|
+
include_deleted_services,
|
|
1131
|
+
top_n,
|
|
1132
|
+
since,
|
|
1133
|
+
until,
|
|
1134
|
+
timezone,
|
|
1135
|
+
granularity,
|
|
1136
|
+
compare_to,
|
|
1137
|
+
...filters
|
|
1138
|
+
} = query;
|
|
1139
1139
|
return salesRequest(config, "POST", "/sales/summary", {
|
|
1140
1140
|
filters,
|
|
1141
|
-
range,
|
|
1141
|
+
...range !== void 0 ? { range } : {},
|
|
1142
1142
|
...include_categories !== void 0 ? { include_categories } : {},
|
|
1143
1143
|
...include_deleted_services !== void 0 ? { include_deleted_services } : {},
|
|
1144
|
-
...top_n !== void 0 ? { top_n } : {}
|
|
1144
|
+
...top_n !== void 0 ? { top_n } : {},
|
|
1145
|
+
...since !== void 0 ? { since } : {},
|
|
1146
|
+
...until !== void 0 ? { until } : {},
|
|
1147
|
+
...timezone !== void 0 ? { timezone } : {},
|
|
1148
|
+
...granularity !== void 0 ? { granularity } : {},
|
|
1149
|
+
...compare_to !== void 0 ? { compare_to } : {}
|
|
1145
1150
|
});
|
|
1146
1151
|
},
|
|
1147
1152
|
async get(id) {
|
|
@@ -1152,15 +1157,53 @@ function createSalesClient(config) {
|
|
|
1152
1157
|
},
|
|
1153
1158
|
async delete(id) {
|
|
1154
1159
|
await salesRequest(config, "DELETE", `/sales/${id}`);
|
|
1160
|
+
},
|
|
1161
|
+
customers: {
|
|
1162
|
+
async list(query) {
|
|
1163
|
+
const { segment, sort, order, cursor, limit, want_total, ...filters } = query ?? {};
|
|
1164
|
+
return salesRequest(config, "POST", "/customers/query", {
|
|
1165
|
+
filters,
|
|
1166
|
+
...segment !== void 0 ? { segment } : {},
|
|
1167
|
+
...sort !== void 0 ? { sort } : {},
|
|
1168
|
+
...order !== void 0 ? { order } : {},
|
|
1169
|
+
...cursor !== void 0 ? { cursor } : {},
|
|
1170
|
+
...limit !== void 0 ? { limit } : {},
|
|
1171
|
+
...want_total !== void 0 ? { want_total } : {}
|
|
1172
|
+
});
|
|
1173
|
+
},
|
|
1174
|
+
async get(id, options) {
|
|
1175
|
+
const params = new URLSearchParams();
|
|
1176
|
+
if (options?.include_sales !== void 0)
|
|
1177
|
+
params.set("include_sales", String(options.include_sales));
|
|
1178
|
+
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
1179
|
+
if (options?.cursor != null) params.set("cursor", options.cursor);
|
|
1180
|
+
const qs = params.toString();
|
|
1181
|
+
return salesRequest(
|
|
1182
|
+
config,
|
|
1183
|
+
"GET",
|
|
1184
|
+
`/customers/${encodeURIComponent(id)}${qs ? `?${qs}` : ""}`
|
|
1185
|
+
);
|
|
1186
|
+
},
|
|
1187
|
+
async summary(query) {
|
|
1188
|
+
const { range, since, until, timezone, compare_to, ...filters } = query ?? {};
|
|
1189
|
+
return salesRequest(config, "POST", "/customers/summary", {
|
|
1190
|
+
filters,
|
|
1191
|
+
...range !== void 0 ? { range } : {},
|
|
1192
|
+
...since !== void 0 ? { since } : {},
|
|
1193
|
+
...until !== void 0 ? { until } : {},
|
|
1194
|
+
...timezone !== void 0 ? { timezone } : {},
|
|
1195
|
+
...compare_to !== void 0 ? { compare_to } : {}
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1198
|
+
},
|
|
1199
|
+
business: {
|
|
1200
|
+
async config() {
|
|
1201
|
+
return salesRequest(config, "GET", "/business/config");
|
|
1202
|
+
}
|
|
1155
1203
|
}
|
|
1156
1204
|
};
|
|
1157
1205
|
}
|
|
1158
1206
|
|
|
1159
|
-
// ../tracking-core/src/resources/services.ts
|
|
1160
|
-
async function fetchServices(config) {
|
|
1161
|
-
return salesRequest(config, "GET", "/services");
|
|
1162
|
-
}
|
|
1163
|
-
|
|
1164
1207
|
// ../tracking-core/src/resources/sales/money.ts
|
|
1165
1208
|
var MINOR_UNIT_EXPONENT = {
|
|
1166
1209
|
USD: 2,
|
|
@@ -1180,6 +1223,181 @@ function formatMoney(cents, currency, locale) {
|
|
|
1180
1223
|
fromMinor(cents, currency)
|
|
1181
1224
|
);
|
|
1182
1225
|
}
|
|
1226
|
+
function formatDateInTz(iso, timeZone, opts, locale) {
|
|
1227
|
+
const date = new Date(iso);
|
|
1228
|
+
if (Number.isNaN(date.getTime())) return iso;
|
|
1229
|
+
return new Intl.DateTimeFormat(locale, {
|
|
1230
|
+
year: "numeric",
|
|
1231
|
+
month: "short",
|
|
1232
|
+
day: "2-digit",
|
|
1233
|
+
hour: "2-digit",
|
|
1234
|
+
minute: "2-digit",
|
|
1235
|
+
...opts,
|
|
1236
|
+
timeZone
|
|
1237
|
+
}).format(date);
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
// ../tracking-core/src/resources/sales/schema.ts
|
|
1241
|
+
import { z as z11 } from "zod";
|
|
1242
|
+
var SUPPORTED_CURRENCIES = ["USD", "CAD"];
|
|
1243
|
+
var TRACKING_ENVIRONMENTS = ["production", "development"];
|
|
1244
|
+
var currencySchema = z11.enum(SUPPORTED_CURRENCIES);
|
|
1245
|
+
var centsSchema = z11.number().int().nonnegative();
|
|
1246
|
+
var quantitySchema = z11.string().regex(/^\d+(\.\d{1,3})?$/);
|
|
1247
|
+
var metadataSchema = z11.record(z11.unknown());
|
|
1248
|
+
var saleItemSchema = z11.object({
|
|
1249
|
+
external_item_id: z11.string().nullable().optional(),
|
|
1250
|
+
name: z11.string().nullable().optional(),
|
|
1251
|
+
category: z11.string().nullable().optional(),
|
|
1252
|
+
quantity: quantitySchema,
|
|
1253
|
+
unit_price_cents: centsSchema,
|
|
1254
|
+
// Non-negativity validated on the wire — same contract as the other cents
|
|
1255
|
+
// fields — and backstopped by the DB CHECK.
|
|
1256
|
+
unit_cost_cents: centsSchema.nullable().optional()
|
|
1257
|
+
}).strict();
|
|
1258
|
+
var saleServiceSchema = z11.object({
|
|
1259
|
+
service: z11.string(),
|
|
1260
|
+
amount_cents: centsSchema
|
|
1261
|
+
}).strict();
|
|
1262
|
+
var customerNameSchema = z11.string().max(200);
|
|
1263
|
+
var customerPhoneSchema = z11.string().max(64);
|
|
1264
|
+
var customerEmailSchema = z11.string().max(320).email();
|
|
1265
|
+
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
1266
|
+
if (val.services != null) {
|
|
1267
|
+
if (val.service != null) {
|
|
1268
|
+
ctx.addIssue({
|
|
1269
|
+
code: z11.ZodIssueCode.custom,
|
|
1270
|
+
message: "pass either `service` or `services`, not both",
|
|
1271
|
+
path: ["services"]
|
|
1272
|
+
});
|
|
1273
|
+
}
|
|
1274
|
+
if (val.services.length === 0) {
|
|
1275
|
+
ctx.addIssue({
|
|
1276
|
+
code: z11.ZodIssueCode.custom,
|
|
1277
|
+
message: "`services` must not be empty",
|
|
1278
|
+
path: ["services"]
|
|
1279
|
+
});
|
|
1280
|
+
}
|
|
1281
|
+
const keys = val.services.map((s) => s.service);
|
|
1282
|
+
if (new Set(keys).size !== keys.length) {
|
|
1283
|
+
ctx.addIssue({
|
|
1284
|
+
code: z11.ZodIssueCode.custom,
|
|
1285
|
+
message: "`services` must not list the same service more than once",
|
|
1286
|
+
path: ["services"]
|
|
1287
|
+
});
|
|
1288
|
+
}
|
|
1289
|
+
if (val.amount_total_cents != null) {
|
|
1290
|
+
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
1291
|
+
if (val.amount_total_cents !== sum) {
|
|
1292
|
+
ctx.addIssue({
|
|
1293
|
+
code: z11.ZodIssueCode.custom,
|
|
1294
|
+
message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
|
|
1295
|
+
path: ["amount_total_cents"]
|
|
1296
|
+
});
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
} else if (requireAmount && val.amount_total_cents == null) {
|
|
1300
|
+
ctx.addIssue({
|
|
1301
|
+
code: z11.ZodIssueCode.custom,
|
|
1302
|
+
message: "amount_total_cents is required unless `services` is provided",
|
|
1303
|
+
path: ["amount_total_cents"]
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
var saleCreateSchema = z11.object({
|
|
1308
|
+
external_id: z11.string().nullable().optional(),
|
|
1309
|
+
description: z11.string().nullable().optional(),
|
|
1310
|
+
service: z11.string().nullable().optional(),
|
|
1311
|
+
services: z11.array(saleServiceSchema).nullable().optional(),
|
|
1312
|
+
currency: currencySchema,
|
|
1313
|
+
// Optional only because the plural `services` form derives it from the sum
|
|
1314
|
+
// (see refineServiceXor); the singular/serviceless path still requires it.
|
|
1315
|
+
amount_total_cents: centsSchema.nullable().optional(),
|
|
1316
|
+
occurred_at: z11.string().datetime(),
|
|
1317
|
+
environment: z11.enum(TRACKING_ENVIRONMENTS).default("production"),
|
|
1318
|
+
items: z11.array(saleItemSchema).default([]),
|
|
1319
|
+
metadata: metadataSchema.nullable().optional(),
|
|
1320
|
+
customer_name: customerNameSchema.nullable().optional(),
|
|
1321
|
+
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
1322
|
+
customer_email: customerEmailSchema.nullable().optional()
|
|
1323
|
+
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
1324
|
+
var saleUpdateSchema = z11.object({
|
|
1325
|
+
description: z11.string().nullable().optional(),
|
|
1326
|
+
service: z11.string().nullable().optional(),
|
|
1327
|
+
services: z11.array(saleServiceSchema).nullable().optional(),
|
|
1328
|
+
currency: currencySchema.optional(),
|
|
1329
|
+
amount_total_cents: centsSchema.optional(),
|
|
1330
|
+
occurred_at: z11.string().datetime().optional(),
|
|
1331
|
+
items: z11.array(saleItemSchema).optional(),
|
|
1332
|
+
metadata: metadataSchema.nullable().optional(),
|
|
1333
|
+
customer_name: customerNameSchema.nullable().optional(),
|
|
1334
|
+
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
1335
|
+
customer_email: customerEmailSchema.nullable().optional()
|
|
1336
|
+
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: false }));
|
|
1337
|
+
var TRACKING_RANGES = ["24h", "7d", "30d"];
|
|
1338
|
+
var NAMED_RANGES = [
|
|
1339
|
+
"today",
|
|
1340
|
+
"yesterday",
|
|
1341
|
+
"wtd",
|
|
1342
|
+
"mtd",
|
|
1343
|
+
"qtd",
|
|
1344
|
+
"ytd",
|
|
1345
|
+
"24h",
|
|
1346
|
+
"7d",
|
|
1347
|
+
"30d",
|
|
1348
|
+
"90d",
|
|
1349
|
+
"custom"
|
|
1350
|
+
];
|
|
1351
|
+
|
|
1352
|
+
// ../tracking-core/src/resources/services.ts
|
|
1353
|
+
async function fetchServices(config) {
|
|
1354
|
+
return salesRequest(config, "GET", "/services");
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
// ../tracking-core/src/phone.ts
|
|
1358
|
+
import { AsYouType, parsePhoneNumberFromString } from "libphonenumber-js";
|
|
1359
|
+
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
1360
|
+
function parsePhone(raw, country) {
|
|
1361
|
+
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
1362
|
+
const parsed = parsePhoneNumberFromString(raw ?? "", region);
|
|
1363
|
+
if (!parsed) {
|
|
1364
|
+
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
1365
|
+
}
|
|
1366
|
+
const isValid = parsed.isValid();
|
|
1367
|
+
return {
|
|
1368
|
+
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
1369
|
+
// (e.g. too few digits) still parses but must not be transmitted.
|
|
1370
|
+
e164: isValid ? parsed.number : null,
|
|
1371
|
+
national: parsed.formatNational(),
|
|
1372
|
+
international: parsed.formatInternational(),
|
|
1373
|
+
country: parsed.country ?? region,
|
|
1374
|
+
isValid
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1377
|
+
function toE164(raw, country) {
|
|
1378
|
+
return parsePhone(raw, country).e164;
|
|
1379
|
+
}
|
|
1380
|
+
function formatPhone(value, format = "national", country) {
|
|
1381
|
+
const parsed = parsePhone(value, country);
|
|
1382
|
+
if (typeof format === "function") return format(parsed);
|
|
1383
|
+
switch (format) {
|
|
1384
|
+
case "international":
|
|
1385
|
+
return parsed.international || value;
|
|
1386
|
+
case "e164":
|
|
1387
|
+
return parsed.e164 ?? value;
|
|
1388
|
+
case "national":
|
|
1389
|
+
default:
|
|
1390
|
+
return parsed.national || value;
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1393
|
+
function formatPhoneAsTyped(raw, country) {
|
|
1394
|
+
return new AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
// ../tracking-core/src/phone-field.ts
|
|
1398
|
+
function phoneField(name, raw, country) {
|
|
1399
|
+
return { name, type: "phone", value: toE164(raw, country) };
|
|
1400
|
+
}
|
|
1183
1401
|
|
|
1184
1402
|
// src/ConsentBanner.tsx
|
|
1185
1403
|
import { useEffect as useEffect2, useState as useState2 } from "react";
|
|
@@ -1448,19 +1666,108 @@ function GoogleAdsTracking(props) {
|
|
|
1448
1666
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
1449
1667
|
|
|
1450
1668
|
// package.json
|
|
1451
|
-
var version = "0.
|
|
1669
|
+
var version = "0.12.1";
|
|
1452
1670
|
|
|
1453
1671
|
// src/factory.tsx
|
|
1672
|
+
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect3, useMemo as useMemo2, useRef } from "react";
|
|
1673
|
+
|
|
1674
|
+
// ../tracking-core/src/phone-react.tsx
|
|
1454
1675
|
import {
|
|
1455
1676
|
createContext,
|
|
1677
|
+
forwardRef,
|
|
1678
|
+
useCallback as useCallback2,
|
|
1456
1679
|
useContext,
|
|
1457
|
-
useEffect as useEffect3,
|
|
1458
1680
|
useMemo,
|
|
1459
|
-
|
|
1681
|
+
useState as useState3
|
|
1460
1682
|
} from "react";
|
|
1461
1683
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1684
|
+
var _phoneConfigContext;
|
|
1685
|
+
function phoneConfigContext() {
|
|
1686
|
+
return _phoneConfigContext ?? (_phoneConfigContext = createContext(null));
|
|
1687
|
+
}
|
|
1688
|
+
function PhoneConfigProvider({
|
|
1689
|
+
value,
|
|
1690
|
+
children
|
|
1691
|
+
}) {
|
|
1692
|
+
const Ctx = phoneConfigContext();
|
|
1693
|
+
return /* @__PURE__ */ jsx3(Ctx.Provider, { value, children });
|
|
1694
|
+
}
|
|
1695
|
+
function usePhoneConfig() {
|
|
1696
|
+
const ctx = useContext(phoneConfigContext());
|
|
1697
|
+
return {
|
|
1698
|
+
defaultCountry: ctx?.defaultCountry ?? DEFAULT_PHONE_COUNTRY,
|
|
1699
|
+
display: ctx?.display ?? "national"
|
|
1700
|
+
};
|
|
1701
|
+
}
|
|
1702
|
+
function usePhoneField(opts = {}) {
|
|
1703
|
+
const cfg = usePhoneConfig();
|
|
1704
|
+
const country = opts.country ?? cfg.defaultCountry;
|
|
1705
|
+
const display = opts.display ?? cfg.display;
|
|
1706
|
+
const { onValueChange } = opts;
|
|
1707
|
+
const [value, setValue] = useState3(() => formatPhoneAsTyped(opts.defaultValue ?? "", country));
|
|
1708
|
+
const [touched, setTouched] = useState3(false);
|
|
1709
|
+
const parsed = useMemo(() => parsePhone(value, country), [value, country]);
|
|
1710
|
+
const onChange = useCallback2(
|
|
1711
|
+
(event) => {
|
|
1712
|
+
const next = formatPhoneAsTyped(event.target.value, country);
|
|
1713
|
+
setValue(next);
|
|
1714
|
+
onValueChange?.(parsePhone(next, country).e164);
|
|
1715
|
+
},
|
|
1716
|
+
[country, onValueChange]
|
|
1717
|
+
);
|
|
1718
|
+
const onBlur = useCallback2(
|
|
1719
|
+
(_event) => {
|
|
1720
|
+
setTouched(true);
|
|
1721
|
+
setValue((current) => {
|
|
1722
|
+
const p = parsePhone(current, country);
|
|
1723
|
+
return p.isValid ? formatPhone(current, display, country) : current;
|
|
1724
|
+
});
|
|
1725
|
+
},
|
|
1726
|
+
[country, display]
|
|
1727
|
+
);
|
|
1728
|
+
const error = touched && value.length > 0 && !parsed.isValid ? "Enter a valid phone number" : null;
|
|
1729
|
+
return {
|
|
1730
|
+
value,
|
|
1731
|
+
e164: parsed.e164,
|
|
1732
|
+
isValid: parsed.isValid,
|
|
1733
|
+
error,
|
|
1734
|
+
parsed,
|
|
1735
|
+
inputProps: { value, onChange, onBlur, type: "tel", inputMode: "tel", autoComplete: "tel" }
|
|
1736
|
+
};
|
|
1737
|
+
}
|
|
1738
|
+
var PhoneField = forwardRef(function PhoneField2({ country, value, defaultValue, onChange, onE164Change, ...rest }, ref) {
|
|
1739
|
+
const cfg = usePhoneConfig();
|
|
1740
|
+
const resolvedCountry = country ?? cfg.defaultCountry;
|
|
1741
|
+
const isControlled = value !== void 0;
|
|
1742
|
+
const [internal, setInternal] = useState3(
|
|
1743
|
+
() => formatPhoneAsTyped(defaultValue ?? "", resolvedCountry)
|
|
1744
|
+
);
|
|
1745
|
+
const handleChange = (event) => {
|
|
1746
|
+
const formatted = formatPhoneAsTyped(event.target.value, resolvedCountry);
|
|
1747
|
+
event.target.value = formatted;
|
|
1748
|
+
onE164Change?.(parsePhone(formatted, resolvedCountry).e164);
|
|
1749
|
+
if (!isControlled) setInternal(formatted);
|
|
1750
|
+
onChange?.(event);
|
|
1751
|
+
};
|
|
1752
|
+
const shown = isControlled ? formatPhoneAsTyped(value, resolvedCountry) : internal;
|
|
1753
|
+
return /* @__PURE__ */ jsx3(
|
|
1754
|
+
"input",
|
|
1755
|
+
{
|
|
1756
|
+
...rest,
|
|
1757
|
+
ref,
|
|
1758
|
+
type: "tel",
|
|
1759
|
+
inputMode: "tel",
|
|
1760
|
+
autoComplete: "tel",
|
|
1761
|
+
value: shown,
|
|
1762
|
+
onChange: handleChange
|
|
1763
|
+
}
|
|
1764
|
+
);
|
|
1765
|
+
});
|
|
1766
|
+
|
|
1767
|
+
// src/factory.tsx
|
|
1768
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
1462
1769
|
function createTracking(options) {
|
|
1463
|
-
const { apiKey, endpoint, triggers, environment, gtagIds, debug } = options;
|
|
1770
|
+
const { apiKey, endpoint, triggers, environment, gtagIds, debug, phone } = options;
|
|
1464
1771
|
if (!apiKey || !endpoint) {
|
|
1465
1772
|
if (apiKey || endpoint) {
|
|
1466
1773
|
console.warn(
|
|
@@ -1476,17 +1783,17 @@ function createTracking(options) {
|
|
|
1476
1783
|
getVisitorId: () => ""
|
|
1477
1784
|
};
|
|
1478
1785
|
return {
|
|
1479
|
-
TrackingProvider: ({ children }) => children,
|
|
1786
|
+
TrackingProvider: ({ children }) => /* @__PURE__ */ jsx4(PhoneConfigProvider, { value: phone ?? null, children }),
|
|
1480
1787
|
useTracking: () => noopClient
|
|
1481
1788
|
};
|
|
1482
1789
|
}
|
|
1483
|
-
const TrackingContext =
|
|
1790
|
+
const TrackingContext = createContext2(null);
|
|
1484
1791
|
const specificPageVisitConfig = triggers.automatic.specific_page_visit ?? null;
|
|
1485
1792
|
const timeOnSiteConfig = triggers.automatic.time_on_site ?? null;
|
|
1486
1793
|
function TrackingProvider({ children }) {
|
|
1487
1794
|
const pathname = usePathname();
|
|
1488
1795
|
const searchParams = useSearchParams();
|
|
1489
|
-
const client =
|
|
1796
|
+
const client = useMemo2(
|
|
1490
1797
|
() => createTypedClient(
|
|
1491
1798
|
getOrCreateTrackingClient({
|
|
1492
1799
|
apiKey,
|
|
@@ -1645,10 +1952,10 @@ function createTracking(options) {
|
|
|
1645
1952
|
}
|
|
1646
1953
|
};
|
|
1647
1954
|
}, []);
|
|
1648
|
-
return /* @__PURE__ */
|
|
1955
|
+
return /* @__PURE__ */ jsx4(TrackingContext.Provider, { value: client, children: /* @__PURE__ */ jsx4(PhoneConfigProvider, { value: phone ?? null, children }) });
|
|
1649
1956
|
}
|
|
1650
1957
|
function useTracking() {
|
|
1651
|
-
const client =
|
|
1958
|
+
const client = useContext2(TrackingContext);
|
|
1652
1959
|
if (client === null) {
|
|
1653
1960
|
throw new Error(
|
|
1654
1961
|
"useTracking must be called inside a <TrackingProvider> returned by createTracking()"
|
|
@@ -1661,8 +1968,13 @@ function createTracking(options) {
|
|
|
1661
1968
|
export {
|
|
1662
1969
|
AranovaApiError,
|
|
1663
1970
|
ConsentBanner,
|
|
1971
|
+
DEFAULT_PHONE_COUNTRY,
|
|
1664
1972
|
GoogleAdsTracking,
|
|
1973
|
+
NAMED_RANGES,
|
|
1974
|
+
PhoneField,
|
|
1975
|
+
SUPPORTED_CURRENCIES,
|
|
1665
1976
|
TRACKING_PARAM_KEYS,
|
|
1977
|
+
TRACKING_RANGES,
|
|
1666
1978
|
captureTrackingParamsFromLocation,
|
|
1667
1979
|
createSalesClient,
|
|
1668
1980
|
createTracking,
|
|
@@ -1670,15 +1982,28 @@ export {
|
|
|
1670
1982
|
createTrackingEventCreatePayload,
|
|
1671
1983
|
createTrackingSessionUpsertPayload,
|
|
1672
1984
|
fetchServices,
|
|
1985
|
+
formatDateInTz,
|
|
1673
1986
|
formatMoney,
|
|
1987
|
+
formatPhone,
|
|
1988
|
+
formatPhoneAsTyped,
|
|
1674
1989
|
fromMinor,
|
|
1675
1990
|
getConsentState,
|
|
1991
|
+
parsePhone,
|
|
1992
|
+
phoneField,
|
|
1676
1993
|
resetConsent,
|
|
1994
|
+
saleCreateSchema,
|
|
1995
|
+
saleItemSchema,
|
|
1996
|
+
saleServiceSchema,
|
|
1997
|
+
saleUpdateSchema,
|
|
1998
|
+
salesRequest,
|
|
1677
1999
|
setConsentState,
|
|
2000
|
+
toE164,
|
|
1678
2001
|
toMinor,
|
|
1679
2002
|
useConsent,
|
|
1680
2003
|
useConsentState,
|
|
1681
2004
|
useGclid,
|
|
2005
|
+
usePhoneConfig,
|
|
2006
|
+
usePhoneField,
|
|
1682
2007
|
useTrackingParams
|
|
1683
2008
|
};
|
|
1684
2009
|
//# sourceMappingURL=index.mjs.map
|