@aranova/tracking-react 0.10.0 → 0.12.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 +35 -24
- package/dist/index.d.mts +469 -316
- package/dist/index.d.ts +469 -316
- package/dist/index.js +237 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +233 -17
- package/dist/index.mjs.map +1 -1
- package/dist/phone-utils-CVX7JmqB.d.mts +343 -0
- package/dist/phone-utils-CVX7JmqB.d.ts +343 -0
- package/dist/phone.d.mts +3 -0
- package/dist/phone.d.ts +3 -0
- package/dist/phone.js +318 -0
- package/dist/phone.js.map +1 -0
- package/dist/phone.mjs +286 -0
- package/dist/phone.mjs.map +1 -0
- package/package.json +7 -1
package/dist/index.js
CHANGED
|
@@ -22,7 +22,10 @@ var src_exports = {};
|
|
|
22
22
|
__export(src_exports, {
|
|
23
23
|
AranovaApiError: () => AranovaApiError,
|
|
24
24
|
ConsentBanner: () => ConsentBanner,
|
|
25
|
+
DEFAULT_PHONE_COUNTRY: () => DEFAULT_PHONE_COUNTRY,
|
|
25
26
|
GoogleAdsTracking: () => GoogleAdsTracking,
|
|
27
|
+
PhoneConfigContext: () => PhoneConfigContext,
|
|
28
|
+
PhoneField: () => PhoneField,
|
|
26
29
|
TRACKING_PARAM_KEYS: () => TRACKING_PARAM_KEYS,
|
|
27
30
|
captureTrackingParamsFromLocation: () => captureTrackingParamsFromLocation,
|
|
28
31
|
createSalesClient: () => createSalesClient,
|
|
@@ -31,15 +34,23 @@ __export(src_exports, {
|
|
|
31
34
|
createTrackingEventCreatePayload: () => createTrackingEventCreatePayload,
|
|
32
35
|
createTrackingSessionUpsertPayload: () => createTrackingSessionUpsertPayload,
|
|
33
36
|
fetchServices: () => fetchServices,
|
|
37
|
+
formatDateInTz: () => formatDateInTz,
|
|
34
38
|
formatMoney: () => formatMoney,
|
|
39
|
+
formatPhone: () => formatPhone,
|
|
40
|
+
formatPhoneAsTyped: () => formatPhoneAsTyped,
|
|
35
41
|
fromMinor: () => fromMinor,
|
|
36
42
|
getConsentState: () => getConsentState,
|
|
43
|
+
parsePhone: () => parsePhone,
|
|
44
|
+
phoneField: () => phoneField,
|
|
37
45
|
resetConsent: () => resetConsent,
|
|
38
46
|
setConsentState: () => setConsentState,
|
|
47
|
+
toE164: () => toE164,
|
|
39
48
|
toMinor: () => toMinor,
|
|
40
49
|
useConsent: () => useConsent,
|
|
41
50
|
useConsentState: () => useConsentState,
|
|
42
51
|
useGclid: () => useGclid,
|
|
52
|
+
usePhoneConfig: () => usePhoneConfig,
|
|
53
|
+
usePhoneField: () => usePhoneField,
|
|
43
54
|
useTrackingParams: () => useTrackingParams
|
|
44
55
|
});
|
|
45
56
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -1379,21 +1390,40 @@ function createSalesClient(config) {
|
|
|
1379
1390
|
return salesRequest(config, "POST", "/sales", body);
|
|
1380
1391
|
},
|
|
1381
1392
|
async list(query) {
|
|
1382
|
-
const { cursor, limit, ...filters } = query ?? {};
|
|
1393
|
+
const { cursor, limit, sort, order, want_total, ...filters } = query ?? {};
|
|
1383
1394
|
return salesRequest(config, "POST", "/sales/query", {
|
|
1384
1395
|
filters,
|
|
1385
1396
|
...limit !== void 0 ? { limit } : {},
|
|
1386
|
-
...cursor !== void 0 ? { cursor } : {}
|
|
1397
|
+
...cursor !== void 0 ? { cursor } : {},
|
|
1398
|
+
...sort !== void 0 ? { sort } : {},
|
|
1399
|
+
...order !== void 0 ? { order } : {},
|
|
1400
|
+
...want_total !== void 0 ? { want_total } : {}
|
|
1387
1401
|
});
|
|
1388
1402
|
},
|
|
1389
1403
|
async summary(query) {
|
|
1390
|
-
const {
|
|
1404
|
+
const {
|
|
1405
|
+
range,
|
|
1406
|
+
include_categories,
|
|
1407
|
+
include_deleted_services,
|
|
1408
|
+
top_n,
|
|
1409
|
+
since,
|
|
1410
|
+
until,
|
|
1411
|
+
timezone,
|
|
1412
|
+
granularity,
|
|
1413
|
+
compare_to,
|
|
1414
|
+
...filters
|
|
1415
|
+
} = query;
|
|
1391
1416
|
return salesRequest(config, "POST", "/sales/summary", {
|
|
1392
1417
|
filters,
|
|
1393
|
-
range,
|
|
1418
|
+
...range !== void 0 ? { range } : {},
|
|
1394
1419
|
...include_categories !== void 0 ? { include_categories } : {},
|
|
1395
1420
|
...include_deleted_services !== void 0 ? { include_deleted_services } : {},
|
|
1396
|
-
...top_n !== void 0 ? { top_n } : {}
|
|
1421
|
+
...top_n !== void 0 ? { top_n } : {},
|
|
1422
|
+
...since !== void 0 ? { since } : {},
|
|
1423
|
+
...until !== void 0 ? { until } : {},
|
|
1424
|
+
...timezone !== void 0 ? { timezone } : {},
|
|
1425
|
+
...granularity !== void 0 ? { granularity } : {},
|
|
1426
|
+
...compare_to !== void 0 ? { compare_to } : {}
|
|
1397
1427
|
});
|
|
1398
1428
|
},
|
|
1399
1429
|
async get(id) {
|
|
@@ -1404,6 +1434,49 @@ function createSalesClient(config) {
|
|
|
1404
1434
|
},
|
|
1405
1435
|
async delete(id) {
|
|
1406
1436
|
await salesRequest(config, "DELETE", `/sales/${id}`);
|
|
1437
|
+
},
|
|
1438
|
+
customers: {
|
|
1439
|
+
async list(query) {
|
|
1440
|
+
const { segment, sort, order, cursor, limit, want_total, ...filters } = query ?? {};
|
|
1441
|
+
return salesRequest(config, "POST", "/customers/query", {
|
|
1442
|
+
filters,
|
|
1443
|
+
...segment !== void 0 ? { segment } : {},
|
|
1444
|
+
...sort !== void 0 ? { sort } : {},
|
|
1445
|
+
...order !== void 0 ? { order } : {},
|
|
1446
|
+
...cursor !== void 0 ? { cursor } : {},
|
|
1447
|
+
...limit !== void 0 ? { limit } : {},
|
|
1448
|
+
...want_total !== void 0 ? { want_total } : {}
|
|
1449
|
+
});
|
|
1450
|
+
},
|
|
1451
|
+
async get(id, options) {
|
|
1452
|
+
const params = new URLSearchParams();
|
|
1453
|
+
if (options?.include_sales !== void 0)
|
|
1454
|
+
params.set("include_sales", String(options.include_sales));
|
|
1455
|
+
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
1456
|
+
if (options?.cursor != null) params.set("cursor", options.cursor);
|
|
1457
|
+
const qs = params.toString();
|
|
1458
|
+
return salesRequest(
|
|
1459
|
+
config,
|
|
1460
|
+
"GET",
|
|
1461
|
+
`/customers/${encodeURIComponent(id)}${qs ? `?${qs}` : ""}`
|
|
1462
|
+
);
|
|
1463
|
+
},
|
|
1464
|
+
async summary(query) {
|
|
1465
|
+
const { range, since, until, timezone, compare_to, ...filters } = query ?? {};
|
|
1466
|
+
return salesRequest(config, "POST", "/customers/summary", {
|
|
1467
|
+
filters,
|
|
1468
|
+
...range !== void 0 ? { range } : {},
|
|
1469
|
+
...since !== void 0 ? { since } : {},
|
|
1470
|
+
...until !== void 0 ? { until } : {},
|
|
1471
|
+
...timezone !== void 0 ? { timezone } : {},
|
|
1472
|
+
...compare_to !== void 0 ? { compare_to } : {}
|
|
1473
|
+
});
|
|
1474
|
+
}
|
|
1475
|
+
},
|
|
1476
|
+
business: {
|
|
1477
|
+
async config() {
|
|
1478
|
+
return salesRequest(config, "GET", "/business/config");
|
|
1479
|
+
}
|
|
1407
1480
|
}
|
|
1408
1481
|
};
|
|
1409
1482
|
}
|
|
@@ -1432,6 +1505,64 @@ function formatMoney(cents, currency, locale) {
|
|
|
1432
1505
|
fromMinor(cents, currency)
|
|
1433
1506
|
);
|
|
1434
1507
|
}
|
|
1508
|
+
function formatDateInTz(iso, timeZone, opts, locale) {
|
|
1509
|
+
const date = new Date(iso);
|
|
1510
|
+
if (Number.isNaN(date.getTime())) return iso;
|
|
1511
|
+
return new Intl.DateTimeFormat(locale, {
|
|
1512
|
+
year: "numeric",
|
|
1513
|
+
month: "short",
|
|
1514
|
+
day: "2-digit",
|
|
1515
|
+
hour: "2-digit",
|
|
1516
|
+
minute: "2-digit",
|
|
1517
|
+
...opts,
|
|
1518
|
+
timeZone
|
|
1519
|
+
}).format(date);
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1522
|
+
// ../tracking-core/src/phone.ts
|
|
1523
|
+
var import_libphonenumber_js = require("libphonenumber-js");
|
|
1524
|
+
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
1525
|
+
function parsePhone(raw, country) {
|
|
1526
|
+
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
1527
|
+
const parsed = (0, import_libphonenumber_js.parsePhoneNumberFromString)(raw ?? "", region);
|
|
1528
|
+
if (!parsed) {
|
|
1529
|
+
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
1530
|
+
}
|
|
1531
|
+
const isValid = parsed.isValid();
|
|
1532
|
+
return {
|
|
1533
|
+
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
1534
|
+
// (e.g. too few digits) still parses but must not be transmitted.
|
|
1535
|
+
e164: isValid ? parsed.number : null,
|
|
1536
|
+
national: parsed.formatNational(),
|
|
1537
|
+
international: parsed.formatInternational(),
|
|
1538
|
+
country: parsed.country ?? region,
|
|
1539
|
+
isValid
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1542
|
+
function toE164(raw, country) {
|
|
1543
|
+
return parsePhone(raw, country).e164;
|
|
1544
|
+
}
|
|
1545
|
+
function formatPhone(value, format = "national", country) {
|
|
1546
|
+
const parsed = parsePhone(value, country);
|
|
1547
|
+
if (typeof format === "function") return format(parsed);
|
|
1548
|
+
switch (format) {
|
|
1549
|
+
case "international":
|
|
1550
|
+
return parsed.international || value;
|
|
1551
|
+
case "e164":
|
|
1552
|
+
return parsed.e164 ?? value;
|
|
1553
|
+
case "national":
|
|
1554
|
+
default:
|
|
1555
|
+
return parsed.national || value;
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
function formatPhoneAsTyped(raw, country) {
|
|
1559
|
+
return new import_libphonenumber_js.AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
// ../tracking-core/src/phone-field.ts
|
|
1563
|
+
function phoneField(name, raw, country) {
|
|
1564
|
+
return { name, type: "phone", value: toE164(raw, country) };
|
|
1565
|
+
}
|
|
1435
1566
|
|
|
1436
1567
|
// src/hooks.ts
|
|
1437
1568
|
function useGclid() {
|
|
@@ -1688,13 +1819,89 @@ function GoogleAdsTracking(props) {
|
|
|
1688
1819
|
}
|
|
1689
1820
|
|
|
1690
1821
|
// src/factory.tsx
|
|
1691
|
-
var
|
|
1822
|
+
var import_react5 = require("react");
|
|
1692
1823
|
|
|
1693
1824
|
// package.json
|
|
1694
|
-
var version = "0.
|
|
1825
|
+
var version = "0.12.0";
|
|
1695
1826
|
|
|
1696
|
-
// src/
|
|
1827
|
+
// ../tracking-core/src/phone-react.tsx
|
|
1828
|
+
var import_react4 = require("react");
|
|
1697
1829
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
1830
|
+
var PhoneConfigContext = (0, import_react4.createContext)(null);
|
|
1831
|
+
function usePhoneConfig() {
|
|
1832
|
+
const ctx = (0, import_react4.useContext)(PhoneConfigContext);
|
|
1833
|
+
return {
|
|
1834
|
+
defaultCountry: ctx?.defaultCountry ?? DEFAULT_PHONE_COUNTRY,
|
|
1835
|
+
display: ctx?.display ?? "national"
|
|
1836
|
+
};
|
|
1837
|
+
}
|
|
1838
|
+
function usePhoneField(opts = {}) {
|
|
1839
|
+
const cfg = usePhoneConfig();
|
|
1840
|
+
const country = opts.country ?? cfg.defaultCountry;
|
|
1841
|
+
const display = opts.display ?? cfg.display;
|
|
1842
|
+
const { onValueChange } = opts;
|
|
1843
|
+
const [value, setValue] = (0, import_react4.useState)(() => formatPhoneAsTyped(opts.defaultValue ?? "", country));
|
|
1844
|
+
const [touched, setTouched] = (0, import_react4.useState)(false);
|
|
1845
|
+
const parsed = (0, import_react4.useMemo)(() => parsePhone(value, country), [value, country]);
|
|
1846
|
+
const onChange = (0, import_react4.useCallback)(
|
|
1847
|
+
(event) => {
|
|
1848
|
+
const next = formatPhoneAsTyped(event.target.value, country);
|
|
1849
|
+
setValue(next);
|
|
1850
|
+
onValueChange?.(parsePhone(next, country).e164);
|
|
1851
|
+
},
|
|
1852
|
+
[country, onValueChange]
|
|
1853
|
+
);
|
|
1854
|
+
const onBlur = (0, import_react4.useCallback)(
|
|
1855
|
+
(_event) => {
|
|
1856
|
+
setTouched(true);
|
|
1857
|
+
setValue((current) => {
|
|
1858
|
+
const p = parsePhone(current, country);
|
|
1859
|
+
return p.isValid ? formatPhone(current, display, country) : current;
|
|
1860
|
+
});
|
|
1861
|
+
},
|
|
1862
|
+
[country, display]
|
|
1863
|
+
);
|
|
1864
|
+
const error = touched && value.length > 0 && !parsed.isValid ? "Enter a valid phone number" : null;
|
|
1865
|
+
return {
|
|
1866
|
+
value,
|
|
1867
|
+
e164: parsed.e164,
|
|
1868
|
+
isValid: parsed.isValid,
|
|
1869
|
+
error,
|
|
1870
|
+
parsed,
|
|
1871
|
+
inputProps: { value, onChange, onBlur, type: "tel", inputMode: "tel", autoComplete: "tel" }
|
|
1872
|
+
};
|
|
1873
|
+
}
|
|
1874
|
+
var PhoneField = (0, import_react4.forwardRef)(function PhoneField2({ country, value, defaultValue, onChange, onE164Change, ...rest }, ref) {
|
|
1875
|
+
const cfg = usePhoneConfig();
|
|
1876
|
+
const resolvedCountry = country ?? cfg.defaultCountry;
|
|
1877
|
+
const isControlled = value !== void 0;
|
|
1878
|
+
const [internal, setInternal] = (0, import_react4.useState)(
|
|
1879
|
+
() => formatPhoneAsTyped(defaultValue ?? "", resolvedCountry)
|
|
1880
|
+
);
|
|
1881
|
+
const handleChange = (event) => {
|
|
1882
|
+
const formatted = formatPhoneAsTyped(event.target.value, resolvedCountry);
|
|
1883
|
+
event.target.value = formatted;
|
|
1884
|
+
onE164Change?.(parsePhone(formatted, resolvedCountry).e164);
|
|
1885
|
+
if (!isControlled) setInternal(formatted);
|
|
1886
|
+
onChange?.(event);
|
|
1887
|
+
};
|
|
1888
|
+
const shown = isControlled ? formatPhoneAsTyped(value, resolvedCountry) : internal;
|
|
1889
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
1890
|
+
"input",
|
|
1891
|
+
{
|
|
1892
|
+
...rest,
|
|
1893
|
+
ref,
|
|
1894
|
+
type: "tel",
|
|
1895
|
+
inputMode: "tel",
|
|
1896
|
+
autoComplete: "tel",
|
|
1897
|
+
value: shown,
|
|
1898
|
+
onChange: handleChange
|
|
1899
|
+
}
|
|
1900
|
+
);
|
|
1901
|
+
});
|
|
1902
|
+
|
|
1903
|
+
// src/factory.tsx
|
|
1904
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1698
1905
|
var NOOP_CLIENT = {
|
|
1699
1906
|
trackEvent: () => {
|
|
1700
1907
|
},
|
|
@@ -1704,7 +1911,7 @@ var NOOP_CLIENT = {
|
|
|
1704
1911
|
getVisitorId: () => ""
|
|
1705
1912
|
};
|
|
1706
1913
|
function createTracking(options) {
|
|
1707
|
-
const { apiKey, endpoint, triggers, environment, debug } = options;
|
|
1914
|
+
const { apiKey, endpoint, triggers, environment, debug, phone } = options;
|
|
1708
1915
|
if (!apiKey || !endpoint) {
|
|
1709
1916
|
if (apiKey || endpoint) {
|
|
1710
1917
|
console.warn(
|
|
@@ -1713,14 +1920,16 @@ function createTracking(options) {
|
|
|
1713
1920
|
}
|
|
1714
1921
|
const noopTyped = NOOP_CLIENT;
|
|
1715
1922
|
return {
|
|
1716
|
-
|
|
1923
|
+
// Still publish phone config so usePhoneField/<PhoneField> work even when
|
|
1924
|
+
// tracking is disabled (missing apiKey/endpoint).
|
|
1925
|
+
TrackingProvider: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneConfigContext.Provider, { value: phone ?? null, children }),
|
|
1717
1926
|
useTracking: () => noopTyped
|
|
1718
1927
|
};
|
|
1719
1928
|
}
|
|
1720
|
-
const TrackingContext = (0,
|
|
1929
|
+
const TrackingContext = (0, import_react5.createContext)(null);
|
|
1721
1930
|
function TrackingProvider({ gtagId, gtagIds, children }) {
|
|
1722
1931
|
const resolvedGtagIds = gtagIds ?? (gtagId ? { default: gtagId } : void 0);
|
|
1723
|
-
const client = (0,
|
|
1932
|
+
const client = (0, import_react5.useMemo)(
|
|
1724
1933
|
() => createTypedClient(
|
|
1725
1934
|
getOrCreateTrackingClient({
|
|
1726
1935
|
apiKey,
|
|
@@ -1738,15 +1947,15 @@ function createTracking(options) {
|
|
|
1738
1947
|
),
|
|
1739
1948
|
[]
|
|
1740
1949
|
);
|
|
1741
|
-
const gtagIdsKey = (0,
|
|
1742
|
-
(0,
|
|
1950
|
+
const gtagIdsKey = (0, import_react5.useMemo)(() => gtagIds ? JSON.stringify(gtagIds) : "", [gtagIds]);
|
|
1951
|
+
(0, import_react5.useEffect)(() => {
|
|
1743
1952
|
if (gtagIds && Object.keys(gtagIds).length > 0) {
|
|
1744
1953
|
bootstrapMultipleGtags(gtagIds);
|
|
1745
1954
|
} else if (gtagId) {
|
|
1746
1955
|
bootstrapGoogleAdsTracking(gtagId);
|
|
1747
1956
|
}
|
|
1748
1957
|
}, [gtagId, gtagIdsKey]);
|
|
1749
|
-
(0,
|
|
1958
|
+
(0, import_react5.useEffect)(() => {
|
|
1750
1959
|
const detachers = [];
|
|
1751
1960
|
const rawClient = getOrCreateTrackingClient({
|
|
1752
1961
|
apiKey,
|
|
@@ -1786,10 +1995,10 @@ function createTracking(options) {
|
|
|
1786
1995
|
}
|
|
1787
1996
|
};
|
|
1788
1997
|
}, []);
|
|
1789
|
-
return /* @__PURE__ */ (0,
|
|
1998
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TrackingContext.Provider, { value: client, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(PhoneConfigContext.Provider, { value: phone ?? null, children }) });
|
|
1790
1999
|
}
|
|
1791
2000
|
function useTracking() {
|
|
1792
|
-
const client = (0,
|
|
2001
|
+
const client = (0, import_react5.useContext)(TrackingContext);
|
|
1793
2002
|
if (client === null) {
|
|
1794
2003
|
throw new Error(
|
|
1795
2004
|
"useTracking must be called inside a <TrackingProvider> returned by createTracking()"
|
|
@@ -1803,7 +2012,10 @@ function createTracking(options) {
|
|
|
1803
2012
|
0 && (module.exports = {
|
|
1804
2013
|
AranovaApiError,
|
|
1805
2014
|
ConsentBanner,
|
|
2015
|
+
DEFAULT_PHONE_COUNTRY,
|
|
1806
2016
|
GoogleAdsTracking,
|
|
2017
|
+
PhoneConfigContext,
|
|
2018
|
+
PhoneField,
|
|
1807
2019
|
TRACKING_PARAM_KEYS,
|
|
1808
2020
|
captureTrackingParamsFromLocation,
|
|
1809
2021
|
createSalesClient,
|
|
@@ -1812,15 +2024,23 @@ function createTracking(options) {
|
|
|
1812
2024
|
createTrackingEventCreatePayload,
|
|
1813
2025
|
createTrackingSessionUpsertPayload,
|
|
1814
2026
|
fetchServices,
|
|
2027
|
+
formatDateInTz,
|
|
1815
2028
|
formatMoney,
|
|
2029
|
+
formatPhone,
|
|
2030
|
+
formatPhoneAsTyped,
|
|
1816
2031
|
fromMinor,
|
|
1817
2032
|
getConsentState,
|
|
2033
|
+
parsePhone,
|
|
2034
|
+
phoneField,
|
|
1818
2035
|
resetConsent,
|
|
1819
2036
|
setConsentState,
|
|
2037
|
+
toE164,
|
|
1820
2038
|
toMinor,
|
|
1821
2039
|
useConsent,
|
|
1822
2040
|
useConsentState,
|
|
1823
2041
|
useGclid,
|
|
2042
|
+
usePhoneConfig,
|
|
2043
|
+
usePhoneField,
|
|
1824
2044
|
useTrackingParams
|
|
1825
2045
|
});
|
|
1826
2046
|
//# sourceMappingURL=index.js.map
|