@aranova/tracking-react 0.11.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 +304 -306
- package/dist/index.d.ts +304 -306
- 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.mjs
CHANGED
|
@@ -1333,21 +1333,40 @@ function createSalesClient(config) {
|
|
|
1333
1333
|
return salesRequest(config, "POST", "/sales", body);
|
|
1334
1334
|
},
|
|
1335
1335
|
async list(query) {
|
|
1336
|
-
const { cursor, limit, ...filters } = query ?? {};
|
|
1336
|
+
const { cursor, limit, sort, order, want_total, ...filters } = query ?? {};
|
|
1337
1337
|
return salesRequest(config, "POST", "/sales/query", {
|
|
1338
1338
|
filters,
|
|
1339
1339
|
...limit !== void 0 ? { limit } : {},
|
|
1340
|
-
...cursor !== void 0 ? { cursor } : {}
|
|
1340
|
+
...cursor !== void 0 ? { cursor } : {},
|
|
1341
|
+
...sort !== void 0 ? { sort } : {},
|
|
1342
|
+
...order !== void 0 ? { order } : {},
|
|
1343
|
+
...want_total !== void 0 ? { want_total } : {}
|
|
1341
1344
|
});
|
|
1342
1345
|
},
|
|
1343
1346
|
async summary(query) {
|
|
1344
|
-
const {
|
|
1347
|
+
const {
|
|
1348
|
+
range,
|
|
1349
|
+
include_categories,
|
|
1350
|
+
include_deleted_services,
|
|
1351
|
+
top_n,
|
|
1352
|
+
since,
|
|
1353
|
+
until,
|
|
1354
|
+
timezone,
|
|
1355
|
+
granularity,
|
|
1356
|
+
compare_to,
|
|
1357
|
+
...filters
|
|
1358
|
+
} = query;
|
|
1345
1359
|
return salesRequest(config, "POST", "/sales/summary", {
|
|
1346
1360
|
filters,
|
|
1347
|
-
range,
|
|
1361
|
+
...range !== void 0 ? { range } : {},
|
|
1348
1362
|
...include_categories !== void 0 ? { include_categories } : {},
|
|
1349
1363
|
...include_deleted_services !== void 0 ? { include_deleted_services } : {},
|
|
1350
|
-
...top_n !== void 0 ? { top_n } : {}
|
|
1364
|
+
...top_n !== void 0 ? { top_n } : {},
|
|
1365
|
+
...since !== void 0 ? { since } : {},
|
|
1366
|
+
...until !== void 0 ? { until } : {},
|
|
1367
|
+
...timezone !== void 0 ? { timezone } : {},
|
|
1368
|
+
...granularity !== void 0 ? { granularity } : {},
|
|
1369
|
+
...compare_to !== void 0 ? { compare_to } : {}
|
|
1351
1370
|
});
|
|
1352
1371
|
},
|
|
1353
1372
|
async get(id) {
|
|
@@ -1358,6 +1377,49 @@ function createSalesClient(config) {
|
|
|
1358
1377
|
},
|
|
1359
1378
|
async delete(id) {
|
|
1360
1379
|
await salesRequest(config, "DELETE", `/sales/${id}`);
|
|
1380
|
+
},
|
|
1381
|
+
customers: {
|
|
1382
|
+
async list(query) {
|
|
1383
|
+
const { segment, sort, order, cursor, limit, want_total, ...filters } = query ?? {};
|
|
1384
|
+
return salesRequest(config, "POST", "/customers/query", {
|
|
1385
|
+
filters,
|
|
1386
|
+
...segment !== void 0 ? { segment } : {},
|
|
1387
|
+
...sort !== void 0 ? { sort } : {},
|
|
1388
|
+
...order !== void 0 ? { order } : {},
|
|
1389
|
+
...cursor !== void 0 ? { cursor } : {},
|
|
1390
|
+
...limit !== void 0 ? { limit } : {},
|
|
1391
|
+
...want_total !== void 0 ? { want_total } : {}
|
|
1392
|
+
});
|
|
1393
|
+
},
|
|
1394
|
+
async get(id, options) {
|
|
1395
|
+
const params = new URLSearchParams();
|
|
1396
|
+
if (options?.include_sales !== void 0)
|
|
1397
|
+
params.set("include_sales", String(options.include_sales));
|
|
1398
|
+
if (options?.limit !== void 0) params.set("limit", String(options.limit));
|
|
1399
|
+
if (options?.cursor != null) params.set("cursor", options.cursor);
|
|
1400
|
+
const qs = params.toString();
|
|
1401
|
+
return salesRequest(
|
|
1402
|
+
config,
|
|
1403
|
+
"GET",
|
|
1404
|
+
`/customers/${encodeURIComponent(id)}${qs ? `?${qs}` : ""}`
|
|
1405
|
+
);
|
|
1406
|
+
},
|
|
1407
|
+
async summary(query) {
|
|
1408
|
+
const { range, since, until, timezone, compare_to, ...filters } = query ?? {};
|
|
1409
|
+
return salesRequest(config, "POST", "/customers/summary", {
|
|
1410
|
+
filters,
|
|
1411
|
+
...range !== void 0 ? { range } : {},
|
|
1412
|
+
...since !== void 0 ? { since } : {},
|
|
1413
|
+
...until !== void 0 ? { until } : {},
|
|
1414
|
+
...timezone !== void 0 ? { timezone } : {},
|
|
1415
|
+
...compare_to !== void 0 ? { compare_to } : {}
|
|
1416
|
+
});
|
|
1417
|
+
}
|
|
1418
|
+
},
|
|
1419
|
+
business: {
|
|
1420
|
+
async config() {
|
|
1421
|
+
return salesRequest(config, "GET", "/business/config");
|
|
1422
|
+
}
|
|
1361
1423
|
}
|
|
1362
1424
|
};
|
|
1363
1425
|
}
|
|
@@ -1386,6 +1448,64 @@ function formatMoney(cents, currency, locale) {
|
|
|
1386
1448
|
fromMinor(cents, currency)
|
|
1387
1449
|
);
|
|
1388
1450
|
}
|
|
1451
|
+
function formatDateInTz(iso, timeZone, opts, locale) {
|
|
1452
|
+
const date = new Date(iso);
|
|
1453
|
+
if (Number.isNaN(date.getTime())) return iso;
|
|
1454
|
+
return new Intl.DateTimeFormat(locale, {
|
|
1455
|
+
year: "numeric",
|
|
1456
|
+
month: "short",
|
|
1457
|
+
day: "2-digit",
|
|
1458
|
+
hour: "2-digit",
|
|
1459
|
+
minute: "2-digit",
|
|
1460
|
+
...opts,
|
|
1461
|
+
timeZone
|
|
1462
|
+
}).format(date);
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1465
|
+
// ../tracking-core/src/phone.ts
|
|
1466
|
+
import { AsYouType, parsePhoneNumberFromString } from "libphonenumber-js";
|
|
1467
|
+
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
1468
|
+
function parsePhone(raw, country) {
|
|
1469
|
+
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
1470
|
+
const parsed = parsePhoneNumberFromString(raw ?? "", region);
|
|
1471
|
+
if (!parsed) {
|
|
1472
|
+
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
1473
|
+
}
|
|
1474
|
+
const isValid = parsed.isValid();
|
|
1475
|
+
return {
|
|
1476
|
+
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
1477
|
+
// (e.g. too few digits) still parses but must not be transmitted.
|
|
1478
|
+
e164: isValid ? parsed.number : null,
|
|
1479
|
+
national: parsed.formatNational(),
|
|
1480
|
+
international: parsed.formatInternational(),
|
|
1481
|
+
country: parsed.country ?? region,
|
|
1482
|
+
isValid
|
|
1483
|
+
};
|
|
1484
|
+
}
|
|
1485
|
+
function toE164(raw, country) {
|
|
1486
|
+
return parsePhone(raw, country).e164;
|
|
1487
|
+
}
|
|
1488
|
+
function formatPhone(value, format = "national", country) {
|
|
1489
|
+
const parsed = parsePhone(value, country);
|
|
1490
|
+
if (typeof format === "function") return format(parsed);
|
|
1491
|
+
switch (format) {
|
|
1492
|
+
case "international":
|
|
1493
|
+
return parsed.international || value;
|
|
1494
|
+
case "e164":
|
|
1495
|
+
return parsed.e164 ?? value;
|
|
1496
|
+
case "national":
|
|
1497
|
+
default:
|
|
1498
|
+
return parsed.national || value;
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
function formatPhoneAsTyped(raw, country) {
|
|
1502
|
+
return new AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1505
|
+
// ../tracking-core/src/phone-field.ts
|
|
1506
|
+
function phoneField(name, raw, country) {
|
|
1507
|
+
return { name, type: "phone", value: toE164(raw, country) };
|
|
1508
|
+
}
|
|
1389
1509
|
|
|
1390
1510
|
// src/hooks.ts
|
|
1391
1511
|
function useGclid() {
|
|
@@ -1643,17 +1763,100 @@ function GoogleAdsTracking(props) {
|
|
|
1643
1763
|
|
|
1644
1764
|
// src/factory.tsx
|
|
1645
1765
|
import {
|
|
1646
|
-
createContext,
|
|
1647
|
-
useContext,
|
|
1766
|
+
createContext as createContext2,
|
|
1767
|
+
useContext as useContext2,
|
|
1648
1768
|
useEffect as useEffect4,
|
|
1649
|
-
useMemo as
|
|
1769
|
+
useMemo as useMemo3
|
|
1650
1770
|
} from "react";
|
|
1651
1771
|
|
|
1652
1772
|
// package.json
|
|
1653
|
-
var version = "0.
|
|
1773
|
+
var version = "0.12.0";
|
|
1654
1774
|
|
|
1655
|
-
// src/
|
|
1775
|
+
// ../tracking-core/src/phone-react.tsx
|
|
1776
|
+
import {
|
|
1777
|
+
createContext,
|
|
1778
|
+
forwardRef,
|
|
1779
|
+
useCallback as useCallback2,
|
|
1780
|
+
useContext,
|
|
1781
|
+
useMemo as useMemo2,
|
|
1782
|
+
useState as useState3
|
|
1783
|
+
} from "react";
|
|
1656
1784
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1785
|
+
var PhoneConfigContext = createContext(null);
|
|
1786
|
+
function usePhoneConfig() {
|
|
1787
|
+
const ctx = useContext(PhoneConfigContext);
|
|
1788
|
+
return {
|
|
1789
|
+
defaultCountry: ctx?.defaultCountry ?? DEFAULT_PHONE_COUNTRY,
|
|
1790
|
+
display: ctx?.display ?? "national"
|
|
1791
|
+
};
|
|
1792
|
+
}
|
|
1793
|
+
function usePhoneField(opts = {}) {
|
|
1794
|
+
const cfg = usePhoneConfig();
|
|
1795
|
+
const country = opts.country ?? cfg.defaultCountry;
|
|
1796
|
+
const display = opts.display ?? cfg.display;
|
|
1797
|
+
const { onValueChange } = opts;
|
|
1798
|
+
const [value, setValue] = useState3(() => formatPhoneAsTyped(opts.defaultValue ?? "", country));
|
|
1799
|
+
const [touched, setTouched] = useState3(false);
|
|
1800
|
+
const parsed = useMemo2(() => parsePhone(value, country), [value, country]);
|
|
1801
|
+
const onChange = useCallback2(
|
|
1802
|
+
(event) => {
|
|
1803
|
+
const next = formatPhoneAsTyped(event.target.value, country);
|
|
1804
|
+
setValue(next);
|
|
1805
|
+
onValueChange?.(parsePhone(next, country).e164);
|
|
1806
|
+
},
|
|
1807
|
+
[country, onValueChange]
|
|
1808
|
+
);
|
|
1809
|
+
const onBlur = useCallback2(
|
|
1810
|
+
(_event) => {
|
|
1811
|
+
setTouched(true);
|
|
1812
|
+
setValue((current) => {
|
|
1813
|
+
const p = parsePhone(current, country);
|
|
1814
|
+
return p.isValid ? formatPhone(current, display, country) : current;
|
|
1815
|
+
});
|
|
1816
|
+
},
|
|
1817
|
+
[country, display]
|
|
1818
|
+
);
|
|
1819
|
+
const error = touched && value.length > 0 && !parsed.isValid ? "Enter a valid phone number" : null;
|
|
1820
|
+
return {
|
|
1821
|
+
value,
|
|
1822
|
+
e164: parsed.e164,
|
|
1823
|
+
isValid: parsed.isValid,
|
|
1824
|
+
error,
|
|
1825
|
+
parsed,
|
|
1826
|
+
inputProps: { value, onChange, onBlur, type: "tel", inputMode: "tel", autoComplete: "tel" }
|
|
1827
|
+
};
|
|
1828
|
+
}
|
|
1829
|
+
var PhoneField = forwardRef(function PhoneField2({ country, value, defaultValue, onChange, onE164Change, ...rest }, ref) {
|
|
1830
|
+
const cfg = usePhoneConfig();
|
|
1831
|
+
const resolvedCountry = country ?? cfg.defaultCountry;
|
|
1832
|
+
const isControlled = value !== void 0;
|
|
1833
|
+
const [internal, setInternal] = useState3(
|
|
1834
|
+
() => formatPhoneAsTyped(defaultValue ?? "", resolvedCountry)
|
|
1835
|
+
);
|
|
1836
|
+
const handleChange = (event) => {
|
|
1837
|
+
const formatted = formatPhoneAsTyped(event.target.value, resolvedCountry);
|
|
1838
|
+
event.target.value = formatted;
|
|
1839
|
+
onE164Change?.(parsePhone(formatted, resolvedCountry).e164);
|
|
1840
|
+
if (!isControlled) setInternal(formatted);
|
|
1841
|
+
onChange?.(event);
|
|
1842
|
+
};
|
|
1843
|
+
const shown = isControlled ? formatPhoneAsTyped(value, resolvedCountry) : internal;
|
|
1844
|
+
return /* @__PURE__ */ jsx2(
|
|
1845
|
+
"input",
|
|
1846
|
+
{
|
|
1847
|
+
...rest,
|
|
1848
|
+
ref,
|
|
1849
|
+
type: "tel",
|
|
1850
|
+
inputMode: "tel",
|
|
1851
|
+
autoComplete: "tel",
|
|
1852
|
+
value: shown,
|
|
1853
|
+
onChange: handleChange
|
|
1854
|
+
}
|
|
1855
|
+
);
|
|
1856
|
+
});
|
|
1857
|
+
|
|
1858
|
+
// src/factory.tsx
|
|
1859
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1657
1860
|
var NOOP_CLIENT = {
|
|
1658
1861
|
trackEvent: () => {
|
|
1659
1862
|
},
|
|
@@ -1663,7 +1866,7 @@ var NOOP_CLIENT = {
|
|
|
1663
1866
|
getVisitorId: () => ""
|
|
1664
1867
|
};
|
|
1665
1868
|
function createTracking(options) {
|
|
1666
|
-
const { apiKey, endpoint, triggers, environment, debug } = options;
|
|
1869
|
+
const { apiKey, endpoint, triggers, environment, debug, phone } = options;
|
|
1667
1870
|
if (!apiKey || !endpoint) {
|
|
1668
1871
|
if (apiKey || endpoint) {
|
|
1669
1872
|
console.warn(
|
|
@@ -1672,14 +1875,16 @@ function createTracking(options) {
|
|
|
1672
1875
|
}
|
|
1673
1876
|
const noopTyped = NOOP_CLIENT;
|
|
1674
1877
|
return {
|
|
1675
|
-
|
|
1878
|
+
// Still publish phone config so usePhoneField/<PhoneField> work even when
|
|
1879
|
+
// tracking is disabled (missing apiKey/endpoint).
|
|
1880
|
+
TrackingProvider: ({ children }) => /* @__PURE__ */ jsx3(PhoneConfigContext.Provider, { value: phone ?? null, children }),
|
|
1676
1881
|
useTracking: () => noopTyped
|
|
1677
1882
|
};
|
|
1678
1883
|
}
|
|
1679
|
-
const TrackingContext =
|
|
1884
|
+
const TrackingContext = createContext2(null);
|
|
1680
1885
|
function TrackingProvider({ gtagId, gtagIds, children }) {
|
|
1681
1886
|
const resolvedGtagIds = gtagIds ?? (gtagId ? { default: gtagId } : void 0);
|
|
1682
|
-
const client =
|
|
1887
|
+
const client = useMemo3(
|
|
1683
1888
|
() => createTypedClient(
|
|
1684
1889
|
getOrCreateTrackingClient({
|
|
1685
1890
|
apiKey,
|
|
@@ -1697,7 +1902,7 @@ function createTracking(options) {
|
|
|
1697
1902
|
),
|
|
1698
1903
|
[]
|
|
1699
1904
|
);
|
|
1700
|
-
const gtagIdsKey =
|
|
1905
|
+
const gtagIdsKey = useMemo3(() => gtagIds ? JSON.stringify(gtagIds) : "", [gtagIds]);
|
|
1701
1906
|
useEffect4(() => {
|
|
1702
1907
|
if (gtagIds && Object.keys(gtagIds).length > 0) {
|
|
1703
1908
|
bootstrapMultipleGtags(gtagIds);
|
|
@@ -1745,10 +1950,10 @@ function createTracking(options) {
|
|
|
1745
1950
|
}
|
|
1746
1951
|
};
|
|
1747
1952
|
}, []);
|
|
1748
|
-
return /* @__PURE__ */
|
|
1953
|
+
return /* @__PURE__ */ jsx3(TrackingContext.Provider, { value: client, children: /* @__PURE__ */ jsx3(PhoneConfigContext.Provider, { value: phone ?? null, children }) });
|
|
1749
1954
|
}
|
|
1750
1955
|
function useTracking() {
|
|
1751
|
-
const client =
|
|
1956
|
+
const client = useContext2(TrackingContext);
|
|
1752
1957
|
if (client === null) {
|
|
1753
1958
|
throw new Error(
|
|
1754
1959
|
"useTracking must be called inside a <TrackingProvider> returned by createTracking()"
|
|
@@ -1761,7 +1966,10 @@ function createTracking(options) {
|
|
|
1761
1966
|
export {
|
|
1762
1967
|
AranovaApiError,
|
|
1763
1968
|
ConsentBanner,
|
|
1969
|
+
DEFAULT_PHONE_COUNTRY,
|
|
1764
1970
|
GoogleAdsTracking,
|
|
1971
|
+
PhoneConfigContext,
|
|
1972
|
+
PhoneField,
|
|
1765
1973
|
TRACKING_PARAM_KEYS,
|
|
1766
1974
|
captureTrackingParamsFromLocation,
|
|
1767
1975
|
createSalesClient,
|
|
@@ -1770,15 +1978,23 @@ export {
|
|
|
1770
1978
|
createTrackingEventCreatePayload,
|
|
1771
1979
|
createTrackingSessionUpsertPayload,
|
|
1772
1980
|
fetchServices,
|
|
1981
|
+
formatDateInTz,
|
|
1773
1982
|
formatMoney,
|
|
1983
|
+
formatPhone,
|
|
1984
|
+
formatPhoneAsTyped,
|
|
1774
1985
|
fromMinor,
|
|
1775
1986
|
getConsentState,
|
|
1987
|
+
parsePhone,
|
|
1988
|
+
phoneField,
|
|
1776
1989
|
resetConsent,
|
|
1777
1990
|
setConsentState,
|
|
1991
|
+
toE164,
|
|
1778
1992
|
toMinor,
|
|
1779
1993
|
useConsent,
|
|
1780
1994
|
useConsentState,
|
|
1781
1995
|
useGclid,
|
|
1996
|
+
usePhoneConfig,
|
|
1997
|
+
usePhoneField,
|
|
1782
1998
|
useTrackingParams
|
|
1783
1999
|
};
|
|
1784
2000
|
//# sourceMappingURL=index.mjs.map
|