@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/README.md
CHANGED
|
@@ -111,6 +111,33 @@ export function LeadForm() {
|
|
|
111
111
|
|
|
112
112
|
`fields[].value` can be any JSON value: string, number, boolean, null, array, or object. Values must be JSON-serializable because events are stored as JSONB. Only send reviewed, allowlisted, non-sensitive values; do not send names, emails, phone numbers entered by the visitor, addresses, payment data, medical details, passwords, file contents, or free-text messages.
|
|
113
113
|
|
|
114
|
+
### Phone clicks (`tel:` taps) — manual or auto-capture
|
|
115
|
+
|
|
116
|
+
Opt into **auto-capture** and every `tel:` link is tracked with no per-link code. Add
|
|
117
|
+
`autoCapture` to the `phone_click` registration — a single delegated click listener does the rest:
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
manual: {
|
|
121
|
+
phone_click: { autoCapture: {} }, // default selector: a[href^="tel:"]
|
|
122
|
+
// or narrow it: { autoCapture: { selector: "a.call" } }
|
|
123
|
+
},
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
<a href="tel:+14165550199" data-aranova-section="header">
|
|
128
|
+
(416) 555-0199
|
|
129
|
+
</a>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
The number is read from the `href` (normalized to E.164); `section` comes from an optional
|
|
133
|
+
`data-aranova-section`. **Unlike `cta_click`, a `phone_click` also fires the Google Ads
|
|
134
|
+
conversion** for a linked phone-call goal (a `CLICK_TO_CALL` action) — auto-fired the moment the
|
|
135
|
+
tap is captured, so you never call `trackConversion` (firing needs the sales client wired with the
|
|
136
|
+
same config; see below).
|
|
137
|
+
|
|
138
|
+
Prefer to instrument links yourself? Fire it from a click handler — this fires the conversion the
|
|
139
|
+
same way:
|
|
140
|
+
|
|
114
141
|
```tsx
|
|
115
142
|
tracking.trackEvent("phone_click", {
|
|
116
143
|
phone_number: "+14165550199",
|
package/dist/index.d.mts
CHANGED
|
@@ -2,8 +2,8 @@ import * as react from 'react';
|
|
|
2
2
|
import { ReactNode, CSSProperties, InputHTMLAttributes, ChangeEvent, FocusEvent } from 'react';
|
|
3
3
|
import { T as TrackingParams, a as TrackingInstallSurface, b as TrackingEnvironment, c as TrackingClientContext, d as TrackingEventCreatePayload, e as TrackingSessionUpsertPayload, F as FormSubmitConfig, f as FormSubmitMetadata, G as GtagEnvironmentMap, M as MetaPixelEnvironmentMap, C as ConsentState, g as ConsentChoiceState, h as ConsentSource, P as PhoneConfig, i as ParsedPhone, j as PhoneDisplayFormat } from './phone-utils-DlAQK-gU.mjs';
|
|
4
4
|
export { k as ConsentChoice, D as DEFAULT_DECLINE_TTL_DAYS, l as DEFAULT_PHONE_COUNTRY, J as JsonValue, S as SetConsentOptions, m as TrackedField, n as TrackingInitConfig, o as formSubmitConfigSchema, p as formSubmitMetadataSchema, q as formatPhone, r as formatPhoneAsTyped, s as getConsentChoice, t as getConsentState, u as jsonValueSchema, v as onConsentChange, w as optIn, x as optOut, y as parsePhone, z as phoneField, A as resetConsent, B as setConsentState, E as toE164 } from './phone-utils-DlAQK-gU.mjs';
|
|
5
|
-
import { C as ConversionConfig } from './sales-
|
|
6
|
-
export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, c as CompareTo, d as ConversionConfigStore, e as CurrencyRevenue, f as CustomerCurrencyDelta, g as CustomerCurrencyTotal, h as CustomerGetOptions, i as CustomerGetResult, j as CustomerKpis, k as CustomerKpisDeltas, l as CustomerKpisPrevious, m as CustomerListPage, n as CustomerListQuery, o as CustomerProfile, p as CustomerSegment, q as CustomerSegmentCount, r as CustomerSortField, s as CustomerSummary, t as CustomerSummaryQuery, D as DistinctCustomersByCurrency, G as Granularity, N as NAMED_RANGES, u as NamedRange, P as PublicServiceItem, S as SUPPORTED_CURRENCIES, v as Sale, w as SaleCursorPage, x as SaleFilters, y as SaleInput, z as SaleItem, E as SaleItemInput, F as SaleKeysetSortField, H as SaleListPage, I as SaleListQuery, J as SaleListQueryV2, K as SaleService, L as SaleServiceInput, M as SaleSortField, O as SaleSortOrder, Q as SaleSummary, R as SaleSummaryPrevious, T as SaleSummaryQuery, U as SaleSummaryQueryV2, V as SaleSummaryV2, W as SaleUpdateInput, X as SalesBusinessClient, Y as SalesCategoryBreakdown, Z as SalesClient, _ as SalesClientConfig, $ as SalesCustomersClient, a0 as SalesServiceBreakdown, a1 as SalesTransportConfig, a2 as SalesTrendPoint, a3 as SummaryCurrencyDelta, a4 as SummaryDeltas, a5 as SummaryWindow, a6 as SupportedCurrency, a7 as TRACKING_RANGES, a8 as TrackingOverviewRange, a9 as createSalesClient, aa as fetchServices, ab as formatDateInTz, ac as formatMoney, ad as fromMinor, ae as resolveConversionConfig, af as saleCreateSchema, ag as saleItemSchema, ah as saleServiceSchema, ai as saleUpdateSchema, aj as salesRequest, ak as toMinor } from './sales-
|
|
5
|
+
import { C as ConversionConfig } from './sales-C3jFBx08.mjs';
|
|
6
|
+
export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, c as CompareTo, d as ConversionConfigStore, e as CurrencyRevenue, f as CustomerCurrencyDelta, g as CustomerCurrencyTotal, h as CustomerGetOptions, i as CustomerGetResult, j as CustomerKpis, k as CustomerKpisDeltas, l as CustomerKpisPrevious, m as CustomerListPage, n as CustomerListQuery, o as CustomerProfile, p as CustomerSegment, q as CustomerSegmentCount, r as CustomerSortField, s as CustomerSummary, t as CustomerSummaryQuery, D as DistinctCustomersByCurrency, G as Granularity, N as NAMED_RANGES, u as NamedRange, P as PublicServiceItem, S as SUPPORTED_CURRENCIES, v as Sale, w as SaleCursorPage, x as SaleFilters, y as SaleInput, z as SaleItem, E as SaleItemInput, F as SaleKeysetSortField, H as SaleListPage, I as SaleListQuery, J as SaleListQueryV2, K as SaleService, L as SaleServiceInput, M as SaleSortField, O as SaleSortOrder, Q as SaleSummary, R as SaleSummaryPrevious, T as SaleSummaryQuery, U as SaleSummaryQueryV2, V as SaleSummaryV2, W as SaleUpdateInput, X as SalesBusinessClient, Y as SalesCategoryBreakdown, Z as SalesClient, _ as SalesClientConfig, $ as SalesCustomersClient, a0 as SalesServiceBreakdown, a1 as SalesTransportConfig, a2 as SalesTrendPoint, a3 as SummaryCurrencyDelta, a4 as SummaryDeltas, a5 as SummaryWindow, a6 as SupportedCurrency, a7 as TRACKING_RANGES, a8 as TrackingOverviewRange, a9 as createSalesClient, aa as fetchServices, ab as formatDateInTz, ac as formatMoney, ad as fromMinor, ae as resolveConversionConfig, af as saleCreateSchema, ag as saleItemSchema, ah as saleServiceSchema, ai as saleUpdateSchema, aj as salesRequest, ak as toMinor } from './sales-C3jFBx08.mjs';
|
|
7
7
|
import * as src from 'src';
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
import { CountryCode } from 'libphonenumber-js';
|
|
@@ -483,9 +483,28 @@ type PhoneClickMetadata = z.infer<typeof phoneClickMetadataSchema>;
|
|
|
483
483
|
/**
|
|
484
484
|
* Registration config for `phone_click`.
|
|
485
485
|
*
|
|
486
|
-
*
|
|
486
|
+
* The event stays manually fireable; `autoCapture` additionally attaches a
|
|
487
|
+
* delegated click listener that fires it for any `tel:` link matching
|
|
488
|
+
* `selector` (default `a[href^="tel:"]`) — link your phone number, get the
|
|
489
|
+
* analytics event (and, for a linked phone-click goal, the conversion) for free.
|
|
487
490
|
*/
|
|
488
|
-
declare const phoneClickConfigSchema: z.ZodObject<{
|
|
491
|
+
declare const phoneClickConfigSchema: z.ZodObject<{
|
|
492
|
+
autoCapture: z.ZodOptional<z.ZodObject<{
|
|
493
|
+
selector: z.ZodOptional<z.ZodString>;
|
|
494
|
+
}, "strict", z.ZodTypeAny, {
|
|
495
|
+
selector?: string | undefined;
|
|
496
|
+
}, {
|
|
497
|
+
selector?: string | undefined;
|
|
498
|
+
}>>;
|
|
499
|
+
}, "strict", z.ZodTypeAny, {
|
|
500
|
+
autoCapture?: {
|
|
501
|
+
selector?: string | undefined;
|
|
502
|
+
} | undefined;
|
|
503
|
+
}, {
|
|
504
|
+
autoCapture?: {
|
|
505
|
+
selector?: string | undefined;
|
|
506
|
+
} | undefined;
|
|
507
|
+
}>;
|
|
489
508
|
type PhoneClickConfig = z.infer<typeof phoneClickConfigSchema>;
|
|
490
509
|
|
|
491
510
|
/**
|
|
@@ -1041,7 +1060,23 @@ declare const EVENT_REGISTRY: {
|
|
|
1041
1060
|
phone_number: string;
|
|
1042
1061
|
section?: string | null | undefined;
|
|
1043
1062
|
}>;
|
|
1044
|
-
readonly configSchema: z.ZodObject<{
|
|
1063
|
+
readonly configSchema: z.ZodObject<{
|
|
1064
|
+
autoCapture: z.ZodOptional<z.ZodObject<{
|
|
1065
|
+
selector: z.ZodOptional<z.ZodString>;
|
|
1066
|
+
}, "strict", z.ZodTypeAny, {
|
|
1067
|
+
selector?: string | undefined;
|
|
1068
|
+
}, {
|
|
1069
|
+
selector?: string | undefined;
|
|
1070
|
+
}>>;
|
|
1071
|
+
}, "strict", z.ZodTypeAny, {
|
|
1072
|
+
autoCapture?: {
|
|
1073
|
+
selector?: string | undefined;
|
|
1074
|
+
} | undefined;
|
|
1075
|
+
}, {
|
|
1076
|
+
autoCapture?: {
|
|
1077
|
+
selector?: string | undefined;
|
|
1078
|
+
} | undefined;
|
|
1079
|
+
}>;
|
|
1045
1080
|
};
|
|
1046
1081
|
readonly cta_click: {
|
|
1047
1082
|
readonly kind: "manual";
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ import * as react from 'react';
|
|
|
2
2
|
import { ReactNode, CSSProperties, InputHTMLAttributes, ChangeEvent, FocusEvent } from 'react';
|
|
3
3
|
import { T as TrackingParams, a as TrackingInstallSurface, b as TrackingEnvironment, c as TrackingClientContext, d as TrackingEventCreatePayload, e as TrackingSessionUpsertPayload, F as FormSubmitConfig, f as FormSubmitMetadata, G as GtagEnvironmentMap, M as MetaPixelEnvironmentMap, C as ConsentState, g as ConsentChoiceState, h as ConsentSource, P as PhoneConfig, i as ParsedPhone, j as PhoneDisplayFormat } from './phone-utils-DlAQK-gU.js';
|
|
4
4
|
export { k as ConsentChoice, D as DEFAULT_DECLINE_TTL_DAYS, l as DEFAULT_PHONE_COUNTRY, J as JsonValue, S as SetConsentOptions, m as TrackedField, n as TrackingInitConfig, o as formSubmitConfigSchema, p as formSubmitMetadataSchema, q as formatPhone, r as formatPhoneAsTyped, s as getConsentChoice, t as getConsentState, u as jsonValueSchema, v as onConsentChange, w as optIn, x as optOut, y as parsePhone, z as phoneField, A as resetConsent, B as setConsentState, E as toE164 } from './phone-utils-DlAQK-gU.js';
|
|
5
|
-
import { C as ConversionConfig } from './sales-
|
|
6
|
-
export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, c as CompareTo, d as ConversionConfigStore, e as CurrencyRevenue, f as CustomerCurrencyDelta, g as CustomerCurrencyTotal, h as CustomerGetOptions, i as CustomerGetResult, j as CustomerKpis, k as CustomerKpisDeltas, l as CustomerKpisPrevious, m as CustomerListPage, n as CustomerListQuery, o as CustomerProfile, p as CustomerSegment, q as CustomerSegmentCount, r as CustomerSortField, s as CustomerSummary, t as CustomerSummaryQuery, D as DistinctCustomersByCurrency, G as Granularity, N as NAMED_RANGES, u as NamedRange, P as PublicServiceItem, S as SUPPORTED_CURRENCIES, v as Sale, w as SaleCursorPage, x as SaleFilters, y as SaleInput, z as SaleItem, E as SaleItemInput, F as SaleKeysetSortField, H as SaleListPage, I as SaleListQuery, J as SaleListQueryV2, K as SaleService, L as SaleServiceInput, M as SaleSortField, O as SaleSortOrder, Q as SaleSummary, R as SaleSummaryPrevious, T as SaleSummaryQuery, U as SaleSummaryQueryV2, V as SaleSummaryV2, W as SaleUpdateInput, X as SalesBusinessClient, Y as SalesCategoryBreakdown, Z as SalesClient, _ as SalesClientConfig, $ as SalesCustomersClient, a0 as SalesServiceBreakdown, a1 as SalesTransportConfig, a2 as SalesTrendPoint, a3 as SummaryCurrencyDelta, a4 as SummaryDeltas, a5 as SummaryWindow, a6 as SupportedCurrency, a7 as TRACKING_RANGES, a8 as TrackingOverviewRange, a9 as createSalesClient, aa as fetchServices, ab as formatDateInTz, ac as formatMoney, ad as fromMinor, ae as resolveConversionConfig, af as saleCreateSchema, ag as saleItemSchema, ah as saleServiceSchema, ai as saleUpdateSchema, aj as salesRequest, ak as toMinor } from './sales-
|
|
5
|
+
import { C as ConversionConfig } from './sales-C3jFBx08.js';
|
|
6
|
+
export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, c as CompareTo, d as ConversionConfigStore, e as CurrencyRevenue, f as CustomerCurrencyDelta, g as CustomerCurrencyTotal, h as CustomerGetOptions, i as CustomerGetResult, j as CustomerKpis, k as CustomerKpisDeltas, l as CustomerKpisPrevious, m as CustomerListPage, n as CustomerListQuery, o as CustomerProfile, p as CustomerSegment, q as CustomerSegmentCount, r as CustomerSortField, s as CustomerSummary, t as CustomerSummaryQuery, D as DistinctCustomersByCurrency, G as Granularity, N as NAMED_RANGES, u as NamedRange, P as PublicServiceItem, S as SUPPORTED_CURRENCIES, v as Sale, w as SaleCursorPage, x as SaleFilters, y as SaleInput, z as SaleItem, E as SaleItemInput, F as SaleKeysetSortField, H as SaleListPage, I as SaleListQuery, J as SaleListQueryV2, K as SaleService, L as SaleServiceInput, M as SaleSortField, O as SaleSortOrder, Q as SaleSummary, R as SaleSummaryPrevious, T as SaleSummaryQuery, U as SaleSummaryQueryV2, V as SaleSummaryV2, W as SaleUpdateInput, X as SalesBusinessClient, Y as SalesCategoryBreakdown, Z as SalesClient, _ as SalesClientConfig, $ as SalesCustomersClient, a0 as SalesServiceBreakdown, a1 as SalesTransportConfig, a2 as SalesTrendPoint, a3 as SummaryCurrencyDelta, a4 as SummaryDeltas, a5 as SummaryWindow, a6 as SupportedCurrency, a7 as TRACKING_RANGES, a8 as TrackingOverviewRange, a9 as createSalesClient, aa as fetchServices, ab as formatDateInTz, ac as formatMoney, ad as fromMinor, ae as resolveConversionConfig, af as saleCreateSchema, ag as saleItemSchema, ah as saleServiceSchema, ai as saleUpdateSchema, aj as salesRequest, ak as toMinor } from './sales-C3jFBx08.js';
|
|
7
7
|
import * as src from 'src';
|
|
8
8
|
import { z } from 'zod';
|
|
9
9
|
import { CountryCode } from 'libphonenumber-js';
|
|
@@ -483,9 +483,28 @@ type PhoneClickMetadata = z.infer<typeof phoneClickMetadataSchema>;
|
|
|
483
483
|
/**
|
|
484
484
|
* Registration config for `phone_click`.
|
|
485
485
|
*
|
|
486
|
-
*
|
|
486
|
+
* The event stays manually fireable; `autoCapture` additionally attaches a
|
|
487
|
+
* delegated click listener that fires it for any `tel:` link matching
|
|
488
|
+
* `selector` (default `a[href^="tel:"]`) — link your phone number, get the
|
|
489
|
+
* analytics event (and, for a linked phone-click goal, the conversion) for free.
|
|
487
490
|
*/
|
|
488
|
-
declare const phoneClickConfigSchema: z.ZodObject<{
|
|
491
|
+
declare const phoneClickConfigSchema: z.ZodObject<{
|
|
492
|
+
autoCapture: z.ZodOptional<z.ZodObject<{
|
|
493
|
+
selector: z.ZodOptional<z.ZodString>;
|
|
494
|
+
}, "strict", z.ZodTypeAny, {
|
|
495
|
+
selector?: string | undefined;
|
|
496
|
+
}, {
|
|
497
|
+
selector?: string | undefined;
|
|
498
|
+
}>>;
|
|
499
|
+
}, "strict", z.ZodTypeAny, {
|
|
500
|
+
autoCapture?: {
|
|
501
|
+
selector?: string | undefined;
|
|
502
|
+
} | undefined;
|
|
503
|
+
}, {
|
|
504
|
+
autoCapture?: {
|
|
505
|
+
selector?: string | undefined;
|
|
506
|
+
} | undefined;
|
|
507
|
+
}>;
|
|
489
508
|
type PhoneClickConfig = z.infer<typeof phoneClickConfigSchema>;
|
|
490
509
|
|
|
491
510
|
/**
|
|
@@ -1041,7 +1060,23 @@ declare const EVENT_REGISTRY: {
|
|
|
1041
1060
|
phone_number: string;
|
|
1042
1061
|
section?: string | null | undefined;
|
|
1043
1062
|
}>;
|
|
1044
|
-
readonly configSchema: z.ZodObject<{
|
|
1063
|
+
readonly configSchema: z.ZodObject<{
|
|
1064
|
+
autoCapture: z.ZodOptional<z.ZodObject<{
|
|
1065
|
+
selector: z.ZodOptional<z.ZodString>;
|
|
1066
|
+
}, "strict", z.ZodTypeAny, {
|
|
1067
|
+
selector?: string | undefined;
|
|
1068
|
+
}, {
|
|
1069
|
+
selector?: string | undefined;
|
|
1070
|
+
}>>;
|
|
1071
|
+
}, "strict", z.ZodTypeAny, {
|
|
1072
|
+
autoCapture?: {
|
|
1073
|
+
selector?: string | undefined;
|
|
1074
|
+
} | undefined;
|
|
1075
|
+
}, {
|
|
1076
|
+
autoCapture?: {
|
|
1077
|
+
selector?: string | undefined;
|
|
1078
|
+
} | undefined;
|
|
1079
|
+
}>;
|
|
1045
1080
|
};
|
|
1046
1081
|
readonly cta_click: {
|
|
1047
1082
|
readonly kind: "manual";
|
package/dist/index.js
CHANGED
|
@@ -830,8 +830,8 @@ function thresholdMet(goal, eventType, metadata) {
|
|
|
830
830
|
return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
|
|
831
831
|
case "page_view":
|
|
832
832
|
case "form_start":
|
|
833
|
+
case "phone_click":
|
|
833
834
|
return true;
|
|
834
|
-
// no threshold — fire whenever the detector emits
|
|
835
835
|
default:
|
|
836
836
|
return false;
|
|
837
837
|
}
|
|
@@ -1490,7 +1490,11 @@ var phoneClickMetadataSchema = import_zod8.z.object({
|
|
|
1490
1490
|
}).strict(),
|
|
1491
1491
|
section: import_zod8.z.string().nullable().optional()
|
|
1492
1492
|
}).strict();
|
|
1493
|
-
var phoneClickConfigSchema = import_zod8.z.object({
|
|
1493
|
+
var phoneClickConfigSchema = import_zod8.z.object({
|
|
1494
|
+
autoCapture: import_zod8.z.object({
|
|
1495
|
+
selector: import_zod8.z.string().optional()
|
|
1496
|
+
}).strict().optional()
|
|
1497
|
+
}).strict();
|
|
1494
1498
|
|
|
1495
1499
|
// ../tracking-core/src/events/scroll-depth.ts
|
|
1496
1500
|
var import_zod9 = require("zod");
|
|
@@ -2126,6 +2130,99 @@ function attachCtaClickCapture(client, config) {
|
|
|
2126
2130
|
};
|
|
2127
2131
|
}
|
|
2128
2132
|
|
|
2133
|
+
// ../tracking-core/src/phone.ts
|
|
2134
|
+
var import_libphonenumber_js = require("libphonenumber-js");
|
|
2135
|
+
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
2136
|
+
function parsePhone(raw, country) {
|
|
2137
|
+
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
2138
|
+
const parsed = (0, import_libphonenumber_js.parsePhoneNumberFromString)(raw ?? "", region);
|
|
2139
|
+
if (!parsed) {
|
|
2140
|
+
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
2141
|
+
}
|
|
2142
|
+
const isValid = parsed.isValid();
|
|
2143
|
+
return {
|
|
2144
|
+
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
2145
|
+
// (e.g. too few digits) still parses but must not be transmitted.
|
|
2146
|
+
e164: isValid ? parsed.number : null,
|
|
2147
|
+
national: parsed.formatNational(),
|
|
2148
|
+
international: parsed.formatInternational(),
|
|
2149
|
+
country: parsed.country ?? region,
|
|
2150
|
+
isValid
|
|
2151
|
+
};
|
|
2152
|
+
}
|
|
2153
|
+
function toE164(raw, country) {
|
|
2154
|
+
return parsePhone(raw, country).e164;
|
|
2155
|
+
}
|
|
2156
|
+
function formatPhone(value, format = "national", country) {
|
|
2157
|
+
const parsed = parsePhone(value, country);
|
|
2158
|
+
if (typeof format === "function") return format(parsed);
|
|
2159
|
+
switch (format) {
|
|
2160
|
+
case "international":
|
|
2161
|
+
return parsed.international || value;
|
|
2162
|
+
case "e164":
|
|
2163
|
+
return parsed.e164 ?? value;
|
|
2164
|
+
case "national":
|
|
2165
|
+
default:
|
|
2166
|
+
return parsed.national || value;
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2169
|
+
function formatPhoneAsTyped(raw, country) {
|
|
2170
|
+
return new import_libphonenumber_js.AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
// ../tracking-core/src/triggers/phone-click-capture.ts
|
|
2174
|
+
var DEFAULT_TEL_SELECTOR = 'a[href^="tel:"]';
|
|
2175
|
+
function safeDecodeURIComponent(value) {
|
|
2176
|
+
try {
|
|
2177
|
+
return decodeURIComponent(value);
|
|
2178
|
+
} catch {
|
|
2179
|
+
return value;
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2182
|
+
function resolvePhoneNumber(el) {
|
|
2183
|
+
const href = el instanceof HTMLAnchorElement ? el.href : el.getAttribute("href") ?? "";
|
|
2184
|
+
const raw = safeDecodeURIComponent(href.replace(/^tel:/i, "").split(";")[0]).trim();
|
|
2185
|
+
return toE164(raw) ?? raw;
|
|
2186
|
+
}
|
|
2187
|
+
function attachPhoneClickCapture(client, config) {
|
|
2188
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
2189
|
+
return () => {
|
|
2190
|
+
};
|
|
2191
|
+
}
|
|
2192
|
+
const autoCapture = config.autoCapture;
|
|
2193
|
+
if (!autoCapture) {
|
|
2194
|
+
return () => {
|
|
2195
|
+
};
|
|
2196
|
+
}
|
|
2197
|
+
const selector = autoCapture.selector ?? DEFAULT_TEL_SELECTOR;
|
|
2198
|
+
function onClick(event) {
|
|
2199
|
+
const target = event.target;
|
|
2200
|
+
if (!(target instanceof Element)) return;
|
|
2201
|
+
let matched = null;
|
|
2202
|
+
try {
|
|
2203
|
+
matched = target.closest(selector);
|
|
2204
|
+
} catch {
|
|
2205
|
+
return;
|
|
2206
|
+
}
|
|
2207
|
+
if (matched === null) return;
|
|
2208
|
+
const metadata = {
|
|
2209
|
+
phone_number: resolvePhoneNumber(matched),
|
|
2210
|
+
page: { path: window.location.pathname },
|
|
2211
|
+
section: matched.getAttribute("data-aranova-section")
|
|
2212
|
+
};
|
|
2213
|
+
client.trackEvent({
|
|
2214
|
+
eventType: "phone_click",
|
|
2215
|
+
metadata,
|
|
2216
|
+
pageUrl: window.location.href,
|
|
2217
|
+
occurredAt: null
|
|
2218
|
+
});
|
|
2219
|
+
}
|
|
2220
|
+
document.addEventListener("click", onClick, true);
|
|
2221
|
+
return () => {
|
|
2222
|
+
document.removeEventListener("click", onClick, true);
|
|
2223
|
+
};
|
|
2224
|
+
}
|
|
2225
|
+
|
|
2129
2226
|
// ../tracking-core/src/resources/sales/errors.ts
|
|
2130
2227
|
var AranovaApiError = class extends Error {
|
|
2131
2228
|
constructor(message, options) {
|
|
@@ -2413,7 +2510,10 @@ var saleCreateSchema = import_zod12.z.object({
|
|
|
2413
2510
|
metadata: metadataSchema.nullable().optional(),
|
|
2414
2511
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2415
2512
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2416
|
-
customer_email: customerEmailSchema.nullable().optional()
|
|
2513
|
+
customer_email: customerEmailSchema.nullable().optional(),
|
|
2514
|
+
// CASL consent attestation: the customer agreed to receive SMS. Recorded
|
|
2515
|
+
// with a timestamp server-side; every SMS send path gates on it.
|
|
2516
|
+
sms_consent: import_zod12.z.boolean().default(false)
|
|
2417
2517
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
2418
2518
|
var saleUpdateSchema = import_zod12.z.object({
|
|
2419
2519
|
description: import_zod12.z.string().nullable().optional(),
|
|
@@ -2426,7 +2526,9 @@ var saleUpdateSchema = import_zod12.z.object({
|
|
|
2426
2526
|
metadata: metadataSchema.nullable().optional(),
|
|
2427
2527
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2428
2528
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2429
|
-
customer_email: customerEmailSchema.nullable().optional()
|
|
2529
|
+
customer_email: customerEmailSchema.nullable().optional(),
|
|
2530
|
+
// NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
|
|
2531
|
+
sms_consent: import_zod12.z.boolean().optional()
|
|
2430
2532
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: false }));
|
|
2431
2533
|
var TRACKING_RANGES = ["24h", "7d", "30d"];
|
|
2432
2534
|
var NAMED_RANGES = [
|
|
@@ -2448,46 +2550,6 @@ async function fetchServices(config) {
|
|
|
2448
2550
|
return salesRequest(config, "GET", "/services");
|
|
2449
2551
|
}
|
|
2450
2552
|
|
|
2451
|
-
// ../tracking-core/src/phone.ts
|
|
2452
|
-
var import_libphonenumber_js = require("libphonenumber-js");
|
|
2453
|
-
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
2454
|
-
function parsePhone(raw, country) {
|
|
2455
|
-
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
2456
|
-
const parsed = (0, import_libphonenumber_js.parsePhoneNumberFromString)(raw ?? "", region);
|
|
2457
|
-
if (!parsed) {
|
|
2458
|
-
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
2459
|
-
}
|
|
2460
|
-
const isValid = parsed.isValid();
|
|
2461
|
-
return {
|
|
2462
|
-
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
2463
|
-
// (e.g. too few digits) still parses but must not be transmitted.
|
|
2464
|
-
e164: isValid ? parsed.number : null,
|
|
2465
|
-
national: parsed.formatNational(),
|
|
2466
|
-
international: parsed.formatInternational(),
|
|
2467
|
-
country: parsed.country ?? region,
|
|
2468
|
-
isValid
|
|
2469
|
-
};
|
|
2470
|
-
}
|
|
2471
|
-
function toE164(raw, country) {
|
|
2472
|
-
return parsePhone(raw, country).e164;
|
|
2473
|
-
}
|
|
2474
|
-
function formatPhone(value, format = "national", country) {
|
|
2475
|
-
const parsed = parsePhone(value, country);
|
|
2476
|
-
if (typeof format === "function") return format(parsed);
|
|
2477
|
-
switch (format) {
|
|
2478
|
-
case "international":
|
|
2479
|
-
return parsed.international || value;
|
|
2480
|
-
case "e164":
|
|
2481
|
-
return parsed.e164 ?? value;
|
|
2482
|
-
case "national":
|
|
2483
|
-
default:
|
|
2484
|
-
return parsed.national || value;
|
|
2485
|
-
}
|
|
2486
|
-
}
|
|
2487
|
-
function formatPhoneAsTyped(raw, country) {
|
|
2488
|
-
return new import_libphonenumber_js.AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
2489
|
-
}
|
|
2490
|
-
|
|
2491
2553
|
// ../tracking-core/src/phone-field.ts
|
|
2492
2554
|
function phoneField(name, raw, country) {
|
|
2493
2555
|
return { name, type: "phone", value: toE164(raw, country) };
|
|
@@ -2810,7 +2872,7 @@ function GoogleAdsTracking(props) {
|
|
|
2810
2872
|
var import_react6 = require("react");
|
|
2811
2873
|
|
|
2812
2874
|
// package.json
|
|
2813
|
-
var version = "0.
|
|
2875
|
+
var version = "0.17.1";
|
|
2814
2876
|
|
|
2815
2877
|
// ../tracking-core/src/phone-react.tsx
|
|
2816
2878
|
var import_react5 = require("react");
|
|
@@ -3016,6 +3078,10 @@ function createTracking(options) {
|
|
|
3016
3078
|
if (ctaClick) {
|
|
3017
3079
|
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
3018
3080
|
}
|
|
3081
|
+
const phoneClick = triggers.manual?.phone_click;
|
|
3082
|
+
if (phoneClick) {
|
|
3083
|
+
detachers.push(attachPhoneClickCapture(detectorClient, phoneClick));
|
|
3084
|
+
}
|
|
3019
3085
|
return () => {
|
|
3020
3086
|
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
3021
3087
|
detachers[i]();
|