@aranova/tracking-react 0.16.2 → 0.17.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 +27 -0
- package/dist/index.d.mts +40 -5
- package/dist/index.d.ts +40 -5
- package/dist/index.js +111 -45
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +111 -45
- package/dist/index.mjs.map +1 -1
- package/dist/phone.js +52 -43
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +52 -43
- package/dist/phone.mjs.map +1 -1
- package/dist/{sales-Bq7H-Vym.d.mts → sales-C3jFBx08.d.mts} +10 -0
- package/dist/{sales-Bq7H-Vym.d.ts → sales-C3jFBx08.d.ts} +10 -0
- package/dist/sales.d.mts +1 -1
- package/dist/sales.d.ts +1 -1
- package/dist/sales.js +7 -2
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +7 -2
- package/dist/sales.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -758,8 +758,8 @@ function thresholdMet(goal, eventType, metadata) {
|
|
|
758
758
|
return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
|
|
759
759
|
case "page_view":
|
|
760
760
|
case "form_start":
|
|
761
|
+
case "phone_click":
|
|
761
762
|
return true;
|
|
762
|
-
// no threshold — fire whenever the detector emits
|
|
763
763
|
default:
|
|
764
764
|
return false;
|
|
765
765
|
}
|
|
@@ -1418,7 +1418,11 @@ var phoneClickMetadataSchema = z8.object({
|
|
|
1418
1418
|
}).strict(),
|
|
1419
1419
|
section: z8.string().nullable().optional()
|
|
1420
1420
|
}).strict();
|
|
1421
|
-
var phoneClickConfigSchema = z8.object({
|
|
1421
|
+
var phoneClickConfigSchema = z8.object({
|
|
1422
|
+
autoCapture: z8.object({
|
|
1423
|
+
selector: z8.string().optional()
|
|
1424
|
+
}).strict().optional()
|
|
1425
|
+
}).strict();
|
|
1422
1426
|
|
|
1423
1427
|
// ../tracking-core/src/events/scroll-depth.ts
|
|
1424
1428
|
import { z as z9 } from "zod";
|
|
@@ -2054,6 +2058,99 @@ function attachCtaClickCapture(client, config) {
|
|
|
2054
2058
|
};
|
|
2055
2059
|
}
|
|
2056
2060
|
|
|
2061
|
+
// ../tracking-core/src/phone.ts
|
|
2062
|
+
import { AsYouType, parsePhoneNumberFromString } from "libphonenumber-js";
|
|
2063
|
+
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
2064
|
+
function parsePhone(raw, country) {
|
|
2065
|
+
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
2066
|
+
const parsed = parsePhoneNumberFromString(raw ?? "", region);
|
|
2067
|
+
if (!parsed) {
|
|
2068
|
+
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
2069
|
+
}
|
|
2070
|
+
const isValid = parsed.isValid();
|
|
2071
|
+
return {
|
|
2072
|
+
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
2073
|
+
// (e.g. too few digits) still parses but must not be transmitted.
|
|
2074
|
+
e164: isValid ? parsed.number : null,
|
|
2075
|
+
national: parsed.formatNational(),
|
|
2076
|
+
international: parsed.formatInternational(),
|
|
2077
|
+
country: parsed.country ?? region,
|
|
2078
|
+
isValid
|
|
2079
|
+
};
|
|
2080
|
+
}
|
|
2081
|
+
function toE164(raw, country) {
|
|
2082
|
+
return parsePhone(raw, country).e164;
|
|
2083
|
+
}
|
|
2084
|
+
function formatPhone(value, format = "national", country) {
|
|
2085
|
+
const parsed = parsePhone(value, country);
|
|
2086
|
+
if (typeof format === "function") return format(parsed);
|
|
2087
|
+
switch (format) {
|
|
2088
|
+
case "international":
|
|
2089
|
+
return parsed.international || value;
|
|
2090
|
+
case "e164":
|
|
2091
|
+
return parsed.e164 ?? value;
|
|
2092
|
+
case "national":
|
|
2093
|
+
default:
|
|
2094
|
+
return parsed.national || value;
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
function formatPhoneAsTyped(raw, country) {
|
|
2098
|
+
return new AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
2099
|
+
}
|
|
2100
|
+
|
|
2101
|
+
// ../tracking-core/src/triggers/phone-click-capture.ts
|
|
2102
|
+
var DEFAULT_TEL_SELECTOR = 'a[href^="tel:"]';
|
|
2103
|
+
function safeDecodeURIComponent(value) {
|
|
2104
|
+
try {
|
|
2105
|
+
return decodeURIComponent(value);
|
|
2106
|
+
} catch {
|
|
2107
|
+
return value;
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
function resolvePhoneNumber(el) {
|
|
2111
|
+
const href = el instanceof HTMLAnchorElement ? el.href : el.getAttribute("href") ?? "";
|
|
2112
|
+
const raw = safeDecodeURIComponent(href.replace(/^tel:/i, "").split(";")[0]).trim();
|
|
2113
|
+
return toE164(raw) ?? raw;
|
|
2114
|
+
}
|
|
2115
|
+
function attachPhoneClickCapture(client, config) {
|
|
2116
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
2117
|
+
return () => {
|
|
2118
|
+
};
|
|
2119
|
+
}
|
|
2120
|
+
const autoCapture = config.autoCapture;
|
|
2121
|
+
if (!autoCapture) {
|
|
2122
|
+
return () => {
|
|
2123
|
+
};
|
|
2124
|
+
}
|
|
2125
|
+
const selector = autoCapture.selector ?? DEFAULT_TEL_SELECTOR;
|
|
2126
|
+
function onClick(event) {
|
|
2127
|
+
const target = event.target;
|
|
2128
|
+
if (!(target instanceof Element)) return;
|
|
2129
|
+
let matched = null;
|
|
2130
|
+
try {
|
|
2131
|
+
matched = target.closest(selector);
|
|
2132
|
+
} catch {
|
|
2133
|
+
return;
|
|
2134
|
+
}
|
|
2135
|
+
if (matched === null) return;
|
|
2136
|
+
const metadata = {
|
|
2137
|
+
phone_number: resolvePhoneNumber(matched),
|
|
2138
|
+
page: { path: window.location.pathname },
|
|
2139
|
+
section: matched.getAttribute("data-aranova-section")
|
|
2140
|
+
};
|
|
2141
|
+
client.trackEvent({
|
|
2142
|
+
eventType: "phone_click",
|
|
2143
|
+
metadata,
|
|
2144
|
+
pageUrl: window.location.href,
|
|
2145
|
+
occurredAt: null
|
|
2146
|
+
});
|
|
2147
|
+
}
|
|
2148
|
+
document.addEventListener("click", onClick, true);
|
|
2149
|
+
return () => {
|
|
2150
|
+
document.removeEventListener("click", onClick, true);
|
|
2151
|
+
};
|
|
2152
|
+
}
|
|
2153
|
+
|
|
2057
2154
|
// ../tracking-core/src/resources/sales/errors.ts
|
|
2058
2155
|
var AranovaApiError = class extends Error {
|
|
2059
2156
|
constructor(message, options) {
|
|
@@ -2341,7 +2438,10 @@ var saleCreateSchema = z12.object({
|
|
|
2341
2438
|
metadata: metadataSchema.nullable().optional(),
|
|
2342
2439
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2343
2440
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2344
|
-
customer_email: customerEmailSchema.nullable().optional()
|
|
2441
|
+
customer_email: customerEmailSchema.nullable().optional(),
|
|
2442
|
+
// CASL consent attestation: the customer agreed to receive SMS. Recorded
|
|
2443
|
+
// with a timestamp server-side; every SMS send path gates on it.
|
|
2444
|
+
sms_consent: z12.boolean().default(false)
|
|
2345
2445
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
2346
2446
|
var saleUpdateSchema = z12.object({
|
|
2347
2447
|
description: z12.string().nullable().optional(),
|
|
@@ -2354,7 +2454,9 @@ var saleUpdateSchema = z12.object({
|
|
|
2354
2454
|
metadata: metadataSchema.nullable().optional(),
|
|
2355
2455
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2356
2456
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2357
|
-
customer_email: customerEmailSchema.nullable().optional()
|
|
2457
|
+
customer_email: customerEmailSchema.nullable().optional(),
|
|
2458
|
+
// NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
|
|
2459
|
+
sms_consent: z12.boolean().optional()
|
|
2358
2460
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: false }));
|
|
2359
2461
|
var TRACKING_RANGES = ["24h", "7d", "30d"];
|
|
2360
2462
|
var NAMED_RANGES = [
|
|
@@ -2376,46 +2478,6 @@ async function fetchServices(config) {
|
|
|
2376
2478
|
return salesRequest(config, "GET", "/services");
|
|
2377
2479
|
}
|
|
2378
2480
|
|
|
2379
|
-
// ../tracking-core/src/phone.ts
|
|
2380
|
-
import { AsYouType, parsePhoneNumberFromString } from "libphonenumber-js";
|
|
2381
|
-
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
2382
|
-
function parsePhone(raw, country) {
|
|
2383
|
-
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
2384
|
-
const parsed = parsePhoneNumberFromString(raw ?? "", region);
|
|
2385
|
-
if (!parsed) {
|
|
2386
|
-
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
2387
|
-
}
|
|
2388
|
-
const isValid = parsed.isValid();
|
|
2389
|
-
return {
|
|
2390
|
-
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
2391
|
-
// (e.g. too few digits) still parses but must not be transmitted.
|
|
2392
|
-
e164: isValid ? parsed.number : null,
|
|
2393
|
-
national: parsed.formatNational(),
|
|
2394
|
-
international: parsed.formatInternational(),
|
|
2395
|
-
country: parsed.country ?? region,
|
|
2396
|
-
isValid
|
|
2397
|
-
};
|
|
2398
|
-
}
|
|
2399
|
-
function toE164(raw, country) {
|
|
2400
|
-
return parsePhone(raw, country).e164;
|
|
2401
|
-
}
|
|
2402
|
-
function formatPhone(value, format = "national", country) {
|
|
2403
|
-
const parsed = parsePhone(value, country);
|
|
2404
|
-
if (typeof format === "function") return format(parsed);
|
|
2405
|
-
switch (format) {
|
|
2406
|
-
case "international":
|
|
2407
|
-
return parsed.international || value;
|
|
2408
|
-
case "e164":
|
|
2409
|
-
return parsed.e164 ?? value;
|
|
2410
|
-
case "national":
|
|
2411
|
-
default:
|
|
2412
|
-
return parsed.national || value;
|
|
2413
|
-
}
|
|
2414
|
-
}
|
|
2415
|
-
function formatPhoneAsTyped(raw, country) {
|
|
2416
|
-
return new AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
2417
|
-
}
|
|
2418
|
-
|
|
2419
2481
|
// ../tracking-core/src/phone-field.ts
|
|
2420
2482
|
function phoneField(name, raw, country) {
|
|
2421
2483
|
return { name, type: "phone", value: toE164(raw, country) };
|
|
@@ -2738,7 +2800,7 @@ function GoogleAdsTracking(props) {
|
|
|
2738
2800
|
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect5, useMemo as useMemo4 } from "react";
|
|
2739
2801
|
|
|
2740
2802
|
// package.json
|
|
2741
|
-
var version = "0.
|
|
2803
|
+
var version = "0.17.1";
|
|
2742
2804
|
|
|
2743
2805
|
// ../tracking-core/src/phone-react.tsx
|
|
2744
2806
|
import {
|
|
@@ -2951,6 +3013,10 @@ function createTracking(options) {
|
|
|
2951
3013
|
if (ctaClick) {
|
|
2952
3014
|
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
2953
3015
|
}
|
|
3016
|
+
const phoneClick = triggers.manual?.phone_click;
|
|
3017
|
+
if (phoneClick) {
|
|
3018
|
+
detachers.push(attachPhoneClickCapture(detectorClient, phoneClick));
|
|
3019
|
+
}
|
|
2954
3020
|
return () => {
|
|
2955
3021
|
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
2956
3022
|
detachers[i]();
|