@aranova/tracking-next 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 +35 -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/middleware.js +15 -6
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +15 -6
- package/dist/middleware.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/dist/server.js +15 -6
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +15 -6
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -702,8 +702,8 @@ function thresholdMet(goal, eventType, metadata) {
|
|
|
702
702
|
return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
|
|
703
703
|
case "page_view":
|
|
704
704
|
case "form_start":
|
|
705
|
+
case "phone_click":
|
|
705
706
|
return true;
|
|
706
|
-
// no threshold — fire whenever the detector emits
|
|
707
707
|
default:
|
|
708
708
|
return false;
|
|
709
709
|
}
|
|
@@ -1324,7 +1324,11 @@ var phoneClickMetadataSchema = z8.object({
|
|
|
1324
1324
|
}).strict(),
|
|
1325
1325
|
section: z8.string().nullable().optional()
|
|
1326
1326
|
}).strict();
|
|
1327
|
-
var phoneClickConfigSchema = z8.object({
|
|
1327
|
+
var phoneClickConfigSchema = z8.object({
|
|
1328
|
+
autoCapture: z8.object({
|
|
1329
|
+
selector: z8.string().optional()
|
|
1330
|
+
}).strict().optional()
|
|
1331
|
+
}).strict();
|
|
1328
1332
|
|
|
1329
1333
|
// ../tracking-core/src/events/scroll-depth.ts
|
|
1330
1334
|
import { z as z9 } from "zod";
|
|
@@ -1825,6 +1829,99 @@ function attachCtaClickCapture(client, config) {
|
|
|
1825
1829
|
};
|
|
1826
1830
|
}
|
|
1827
1831
|
|
|
1832
|
+
// ../tracking-core/src/phone.ts
|
|
1833
|
+
import { AsYouType, parsePhoneNumberFromString } from "libphonenumber-js";
|
|
1834
|
+
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
1835
|
+
function parsePhone(raw, country) {
|
|
1836
|
+
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
1837
|
+
const parsed = parsePhoneNumberFromString(raw ?? "", region);
|
|
1838
|
+
if (!parsed) {
|
|
1839
|
+
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
1840
|
+
}
|
|
1841
|
+
const isValid = parsed.isValid();
|
|
1842
|
+
return {
|
|
1843
|
+
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
1844
|
+
// (e.g. too few digits) still parses but must not be transmitted.
|
|
1845
|
+
e164: isValid ? parsed.number : null,
|
|
1846
|
+
national: parsed.formatNational(),
|
|
1847
|
+
international: parsed.formatInternational(),
|
|
1848
|
+
country: parsed.country ?? region,
|
|
1849
|
+
isValid
|
|
1850
|
+
};
|
|
1851
|
+
}
|
|
1852
|
+
function toE164(raw, country) {
|
|
1853
|
+
return parsePhone(raw, country).e164;
|
|
1854
|
+
}
|
|
1855
|
+
function formatPhone(value, format = "national", country) {
|
|
1856
|
+
const parsed = parsePhone(value, country);
|
|
1857
|
+
if (typeof format === "function") return format(parsed);
|
|
1858
|
+
switch (format) {
|
|
1859
|
+
case "international":
|
|
1860
|
+
return parsed.international || value;
|
|
1861
|
+
case "e164":
|
|
1862
|
+
return parsed.e164 ?? value;
|
|
1863
|
+
case "national":
|
|
1864
|
+
default:
|
|
1865
|
+
return parsed.national || value;
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
function formatPhoneAsTyped(raw, country) {
|
|
1869
|
+
return new AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
// ../tracking-core/src/triggers/phone-click-capture.ts
|
|
1873
|
+
var DEFAULT_TEL_SELECTOR = 'a[href^="tel:"]';
|
|
1874
|
+
function safeDecodeURIComponent(value) {
|
|
1875
|
+
try {
|
|
1876
|
+
return decodeURIComponent(value);
|
|
1877
|
+
} catch {
|
|
1878
|
+
return value;
|
|
1879
|
+
}
|
|
1880
|
+
}
|
|
1881
|
+
function resolvePhoneNumber(el) {
|
|
1882
|
+
const href = el instanceof HTMLAnchorElement ? el.href : el.getAttribute("href") ?? "";
|
|
1883
|
+
const raw = safeDecodeURIComponent(href.replace(/^tel:/i, "").split(";")[0]).trim();
|
|
1884
|
+
return toE164(raw) ?? raw;
|
|
1885
|
+
}
|
|
1886
|
+
function attachPhoneClickCapture(client, config) {
|
|
1887
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
1888
|
+
return () => {
|
|
1889
|
+
};
|
|
1890
|
+
}
|
|
1891
|
+
const autoCapture = config.autoCapture;
|
|
1892
|
+
if (!autoCapture) {
|
|
1893
|
+
return () => {
|
|
1894
|
+
};
|
|
1895
|
+
}
|
|
1896
|
+
const selector = autoCapture.selector ?? DEFAULT_TEL_SELECTOR;
|
|
1897
|
+
function onClick(event) {
|
|
1898
|
+
const target = event.target;
|
|
1899
|
+
if (!(target instanceof Element)) return;
|
|
1900
|
+
let matched = null;
|
|
1901
|
+
try {
|
|
1902
|
+
matched = target.closest(selector);
|
|
1903
|
+
} catch {
|
|
1904
|
+
return;
|
|
1905
|
+
}
|
|
1906
|
+
if (matched === null) return;
|
|
1907
|
+
const metadata = {
|
|
1908
|
+
phone_number: resolvePhoneNumber(matched),
|
|
1909
|
+
page: { path: window.location.pathname },
|
|
1910
|
+
section: matched.getAttribute("data-aranova-section")
|
|
1911
|
+
};
|
|
1912
|
+
client.trackEvent({
|
|
1913
|
+
eventType: "phone_click",
|
|
1914
|
+
metadata,
|
|
1915
|
+
pageUrl: window.location.href,
|
|
1916
|
+
occurredAt: null
|
|
1917
|
+
});
|
|
1918
|
+
}
|
|
1919
|
+
document.addEventListener("click", onClick, true);
|
|
1920
|
+
return () => {
|
|
1921
|
+
document.removeEventListener("click", onClick, true);
|
|
1922
|
+
};
|
|
1923
|
+
}
|
|
1924
|
+
|
|
1828
1925
|
// ../tracking-core/src/resources/sales/errors.ts
|
|
1829
1926
|
var AranovaApiError = class extends Error {
|
|
1830
1927
|
constructor(message, options) {
|
|
@@ -2112,7 +2209,10 @@ var saleCreateSchema = z12.object({
|
|
|
2112
2209
|
metadata: metadataSchema.nullable().optional(),
|
|
2113
2210
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2114
2211
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2115
|
-
customer_email: customerEmailSchema.nullable().optional()
|
|
2212
|
+
customer_email: customerEmailSchema.nullable().optional(),
|
|
2213
|
+
// CASL consent attestation: the customer agreed to receive SMS. Recorded
|
|
2214
|
+
// with a timestamp server-side; every SMS send path gates on it.
|
|
2215
|
+
sms_consent: z12.boolean().default(false)
|
|
2116
2216
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
2117
2217
|
var saleUpdateSchema = z12.object({
|
|
2118
2218
|
description: z12.string().nullable().optional(),
|
|
@@ -2125,7 +2225,9 @@ var saleUpdateSchema = z12.object({
|
|
|
2125
2225
|
metadata: metadataSchema.nullable().optional(),
|
|
2126
2226
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2127
2227
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2128
|
-
customer_email: customerEmailSchema.nullable().optional()
|
|
2228
|
+
customer_email: customerEmailSchema.nullable().optional(),
|
|
2229
|
+
// NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
|
|
2230
|
+
sms_consent: z12.boolean().optional()
|
|
2129
2231
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: false }));
|
|
2130
2232
|
var TRACKING_RANGES = ["24h", "7d", "30d"];
|
|
2131
2233
|
var NAMED_RANGES = [
|
|
@@ -2147,46 +2249,6 @@ async function fetchServices(config) {
|
|
|
2147
2249
|
return salesRequest(config, "GET", "/services");
|
|
2148
2250
|
}
|
|
2149
2251
|
|
|
2150
|
-
// ../tracking-core/src/phone.ts
|
|
2151
|
-
import { AsYouType, parsePhoneNumberFromString } from "libphonenumber-js";
|
|
2152
|
-
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
2153
|
-
function parsePhone(raw, country) {
|
|
2154
|
-
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
2155
|
-
const parsed = parsePhoneNumberFromString(raw ?? "", region);
|
|
2156
|
-
if (!parsed) {
|
|
2157
|
-
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
2158
|
-
}
|
|
2159
|
-
const isValid = parsed.isValid();
|
|
2160
|
-
return {
|
|
2161
|
-
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
2162
|
-
// (e.g. too few digits) still parses but must not be transmitted.
|
|
2163
|
-
e164: isValid ? parsed.number : null,
|
|
2164
|
-
national: parsed.formatNational(),
|
|
2165
|
-
international: parsed.formatInternational(),
|
|
2166
|
-
country: parsed.country ?? region,
|
|
2167
|
-
isValid
|
|
2168
|
-
};
|
|
2169
|
-
}
|
|
2170
|
-
function toE164(raw, country) {
|
|
2171
|
-
return parsePhone(raw, country).e164;
|
|
2172
|
-
}
|
|
2173
|
-
function formatPhone(value, format = "national", country) {
|
|
2174
|
-
const parsed = parsePhone(value, country);
|
|
2175
|
-
if (typeof format === "function") return format(parsed);
|
|
2176
|
-
switch (format) {
|
|
2177
|
-
case "international":
|
|
2178
|
-
return parsed.international || value;
|
|
2179
|
-
case "e164":
|
|
2180
|
-
return parsed.e164 ?? value;
|
|
2181
|
-
case "national":
|
|
2182
|
-
default:
|
|
2183
|
-
return parsed.national || value;
|
|
2184
|
-
}
|
|
2185
|
-
}
|
|
2186
|
-
function formatPhoneAsTyped(raw, country) {
|
|
2187
|
-
return new AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
2188
|
-
}
|
|
2189
|
-
|
|
2190
2252
|
// ../tracking-core/src/phone-field.ts
|
|
2191
2253
|
function phoneField(name, raw, country) {
|
|
2192
2254
|
return { name, type: "phone", value: toE164(raw, country) };
|
|
@@ -2523,7 +2585,7 @@ function GoogleAdsTracking(props) {
|
|
|
2523
2585
|
import { usePathname, useSearchParams } from "next/navigation";
|
|
2524
2586
|
|
|
2525
2587
|
// package.json
|
|
2526
|
-
var version = "0.
|
|
2588
|
+
var version = "0.17.1";
|
|
2527
2589
|
|
|
2528
2590
|
// src/factory.tsx
|
|
2529
2591
|
import {
|
|
@@ -2839,6 +2901,10 @@ function createTracking(options) {
|
|
|
2839
2901
|
if (ctaClick) {
|
|
2840
2902
|
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
2841
2903
|
}
|
|
2904
|
+
const phoneClick = triggers.manual?.phone_click;
|
|
2905
|
+
if (phoneClick) {
|
|
2906
|
+
detachers.push(attachPhoneClickCapture(detectorClient, phoneClick));
|
|
2907
|
+
}
|
|
2842
2908
|
return () => {
|
|
2843
2909
|
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
2844
2910
|
detachers[i]();
|