@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/README.md
CHANGED
|
@@ -169,6 +169,41 @@ export function LeadForm() {
|
|
|
169
169
|
|
|
170
170
|
`fields[].value` can be any JSON value: string, number, boolean, null, array, or object. 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.
|
|
171
171
|
|
|
172
|
+
### Phone clicks (`tel:` taps) — manual or auto-capture
|
|
173
|
+
|
|
174
|
+
Opt into **auto-capture** and every `tel:` link is tracked with no per-link code. Add
|
|
175
|
+
`autoCapture` to the `phone_click` registration — a single delegated click listener does the rest:
|
|
176
|
+
|
|
177
|
+
```tsx
|
|
178
|
+
manual: {
|
|
179
|
+
phone_click: { autoCapture: {} }, // default selector: a[href^="tel:"]
|
|
180
|
+
// or narrow it: { autoCapture: { selector: "a.call" } }
|
|
181
|
+
},
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
```tsx
|
|
185
|
+
<a href="tel:+14165550199" data-aranova-section="header">
|
|
186
|
+
(416) 555-0199
|
|
187
|
+
</a>
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The number is read from the `href` (normalized to E.164); `section` comes from an optional
|
|
191
|
+
`data-aranova-section`. **Unlike `cta_click`, a `phone_click` also fires the Google Ads
|
|
192
|
+
conversion** for a linked phone-call goal (a `CLICK_TO_CALL` action) — auto-fired the moment the
|
|
193
|
+
tap is captured, so you never call `trackConversion` (firing needs the sales client wired with the
|
|
194
|
+
same config; see below).
|
|
195
|
+
|
|
196
|
+
Prefer to instrument links yourself? Fire it from a click handler — this fires the conversion the
|
|
197
|
+
same way:
|
|
198
|
+
|
|
199
|
+
```tsx
|
|
200
|
+
tracking.trackEvent("phone_click", {
|
|
201
|
+
phone_number: "+14165550199",
|
|
202
|
+
page: { path: window.location.pathname },
|
|
203
|
+
section: "header",
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
172
207
|
### CTA clicks — manual or auto-capture
|
|
173
208
|
|
|
174
209
|
Fire `cta_click` yourself for full control over the name:
|
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
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, C as ConsentState, g as ConsentChoiceState, h as ConsentSource, G as GtagEnvironmentMap, M as MetaPixelEnvironmentMap, P as PhoneConfig, i as ParsedPhone, j as PhoneDisplayFormat } from './phone-utils-DlAQK-gU.mjs';
|
|
2
2
|
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';
|
|
3
|
-
import { C as ConversionConfig } from './sales-
|
|
4
|
-
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-
|
|
3
|
+
import { C as ConversionConfig } from './sales-C3jFBx08.mjs';
|
|
4
|
+
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';
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
import * as src from 'src';
|
|
7
7
|
import * as react from 'react';
|
|
@@ -436,9 +436,28 @@ type PhoneClickMetadata = z.infer<typeof phoneClickMetadataSchema>;
|
|
|
436
436
|
/**
|
|
437
437
|
* Registration config for `phone_click`.
|
|
438
438
|
*
|
|
439
|
-
*
|
|
439
|
+
* The event stays manually fireable; `autoCapture` additionally attaches a
|
|
440
|
+
* delegated click listener that fires it for any `tel:` link matching
|
|
441
|
+
* `selector` (default `a[href^="tel:"]`) — link your phone number, get the
|
|
442
|
+
* analytics event (and, for a linked phone-click goal, the conversion) for free.
|
|
440
443
|
*/
|
|
441
|
-
declare const phoneClickConfigSchema: z.ZodObject<{
|
|
444
|
+
declare const phoneClickConfigSchema: z.ZodObject<{
|
|
445
|
+
autoCapture: z.ZodOptional<z.ZodObject<{
|
|
446
|
+
selector: z.ZodOptional<z.ZodString>;
|
|
447
|
+
}, "strict", z.ZodTypeAny, {
|
|
448
|
+
selector?: string | undefined;
|
|
449
|
+
}, {
|
|
450
|
+
selector?: string | undefined;
|
|
451
|
+
}>>;
|
|
452
|
+
}, "strict", z.ZodTypeAny, {
|
|
453
|
+
autoCapture?: {
|
|
454
|
+
selector?: string | undefined;
|
|
455
|
+
} | undefined;
|
|
456
|
+
}, {
|
|
457
|
+
autoCapture?: {
|
|
458
|
+
selector?: string | undefined;
|
|
459
|
+
} | undefined;
|
|
460
|
+
}>;
|
|
442
461
|
type PhoneClickConfig = z.infer<typeof phoneClickConfigSchema>;
|
|
443
462
|
|
|
444
463
|
/**
|
|
@@ -994,7 +1013,23 @@ declare const EVENT_REGISTRY: {
|
|
|
994
1013
|
phone_number: string;
|
|
995
1014
|
section?: string | null | undefined;
|
|
996
1015
|
}>;
|
|
997
|
-
readonly configSchema: z.ZodObject<{
|
|
1016
|
+
readonly configSchema: z.ZodObject<{
|
|
1017
|
+
autoCapture: z.ZodOptional<z.ZodObject<{
|
|
1018
|
+
selector: z.ZodOptional<z.ZodString>;
|
|
1019
|
+
}, "strict", z.ZodTypeAny, {
|
|
1020
|
+
selector?: string | undefined;
|
|
1021
|
+
}, {
|
|
1022
|
+
selector?: string | undefined;
|
|
1023
|
+
}>>;
|
|
1024
|
+
}, "strict", z.ZodTypeAny, {
|
|
1025
|
+
autoCapture?: {
|
|
1026
|
+
selector?: string | undefined;
|
|
1027
|
+
} | undefined;
|
|
1028
|
+
}, {
|
|
1029
|
+
autoCapture?: {
|
|
1030
|
+
selector?: string | undefined;
|
|
1031
|
+
} | undefined;
|
|
1032
|
+
}>;
|
|
998
1033
|
};
|
|
999
1034
|
readonly cta_click: {
|
|
1000
1035
|
readonly kind: "manual";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
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, C as ConsentState, g as ConsentChoiceState, h as ConsentSource, G as GtagEnvironmentMap, M as MetaPixelEnvironmentMap, P as PhoneConfig, i as ParsedPhone, j as PhoneDisplayFormat } from './phone-utils-DlAQK-gU.js';
|
|
2
2
|
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';
|
|
3
|
-
import { C as ConversionConfig } from './sales-
|
|
4
|
-
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-
|
|
3
|
+
import { C as ConversionConfig } from './sales-C3jFBx08.js';
|
|
4
|
+
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';
|
|
5
5
|
import { z } from 'zod';
|
|
6
6
|
import * as src from 'src';
|
|
7
7
|
import * as react from 'react';
|
|
@@ -436,9 +436,28 @@ type PhoneClickMetadata = z.infer<typeof phoneClickMetadataSchema>;
|
|
|
436
436
|
/**
|
|
437
437
|
* Registration config for `phone_click`.
|
|
438
438
|
*
|
|
439
|
-
*
|
|
439
|
+
* The event stays manually fireable; `autoCapture` additionally attaches a
|
|
440
|
+
* delegated click listener that fires it for any `tel:` link matching
|
|
441
|
+
* `selector` (default `a[href^="tel:"]`) — link your phone number, get the
|
|
442
|
+
* analytics event (and, for a linked phone-click goal, the conversion) for free.
|
|
440
443
|
*/
|
|
441
|
-
declare const phoneClickConfigSchema: z.ZodObject<{
|
|
444
|
+
declare const phoneClickConfigSchema: z.ZodObject<{
|
|
445
|
+
autoCapture: z.ZodOptional<z.ZodObject<{
|
|
446
|
+
selector: z.ZodOptional<z.ZodString>;
|
|
447
|
+
}, "strict", z.ZodTypeAny, {
|
|
448
|
+
selector?: string | undefined;
|
|
449
|
+
}, {
|
|
450
|
+
selector?: string | undefined;
|
|
451
|
+
}>>;
|
|
452
|
+
}, "strict", z.ZodTypeAny, {
|
|
453
|
+
autoCapture?: {
|
|
454
|
+
selector?: string | undefined;
|
|
455
|
+
} | undefined;
|
|
456
|
+
}, {
|
|
457
|
+
autoCapture?: {
|
|
458
|
+
selector?: string | undefined;
|
|
459
|
+
} | undefined;
|
|
460
|
+
}>;
|
|
442
461
|
type PhoneClickConfig = z.infer<typeof phoneClickConfigSchema>;
|
|
443
462
|
|
|
444
463
|
/**
|
|
@@ -994,7 +1013,23 @@ declare const EVENT_REGISTRY: {
|
|
|
994
1013
|
phone_number: string;
|
|
995
1014
|
section?: string | null | undefined;
|
|
996
1015
|
}>;
|
|
997
|
-
readonly configSchema: z.ZodObject<{
|
|
1016
|
+
readonly configSchema: z.ZodObject<{
|
|
1017
|
+
autoCapture: z.ZodOptional<z.ZodObject<{
|
|
1018
|
+
selector: z.ZodOptional<z.ZodString>;
|
|
1019
|
+
}, "strict", z.ZodTypeAny, {
|
|
1020
|
+
selector?: string | undefined;
|
|
1021
|
+
}, {
|
|
1022
|
+
selector?: string | undefined;
|
|
1023
|
+
}>>;
|
|
1024
|
+
}, "strict", z.ZodTypeAny, {
|
|
1025
|
+
autoCapture?: {
|
|
1026
|
+
selector?: string | undefined;
|
|
1027
|
+
} | undefined;
|
|
1028
|
+
}, {
|
|
1029
|
+
autoCapture?: {
|
|
1030
|
+
selector?: string | undefined;
|
|
1031
|
+
} | undefined;
|
|
1032
|
+
}>;
|
|
998
1033
|
};
|
|
999
1034
|
readonly cta_click: {
|
|
1000
1035
|
readonly kind: "manual";
|
package/dist/index.js
CHANGED
|
@@ -784,8 +784,8 @@ function thresholdMet(goal, eventType, metadata) {
|
|
|
784
784
|
return typeof metadata.page_name === "string" && metadata.page_name === t.page_name;
|
|
785
785
|
case "page_view":
|
|
786
786
|
case "form_start":
|
|
787
|
+
case "phone_click":
|
|
787
788
|
return true;
|
|
788
|
-
// no threshold — fire whenever the detector emits
|
|
789
789
|
default:
|
|
790
790
|
return false;
|
|
791
791
|
}
|
|
@@ -1406,7 +1406,11 @@ var phoneClickMetadataSchema = import_zod8.z.object({
|
|
|
1406
1406
|
}).strict(),
|
|
1407
1407
|
section: import_zod8.z.string().nullable().optional()
|
|
1408
1408
|
}).strict();
|
|
1409
|
-
var phoneClickConfigSchema = import_zod8.z.object({
|
|
1409
|
+
var phoneClickConfigSchema = import_zod8.z.object({
|
|
1410
|
+
autoCapture: import_zod8.z.object({
|
|
1411
|
+
selector: import_zod8.z.string().optional()
|
|
1412
|
+
}).strict().optional()
|
|
1413
|
+
}).strict();
|
|
1410
1414
|
|
|
1411
1415
|
// ../tracking-core/src/events/scroll-depth.ts
|
|
1412
1416
|
var import_zod9 = require("zod");
|
|
@@ -1907,6 +1911,99 @@ function attachCtaClickCapture(client, config) {
|
|
|
1907
1911
|
};
|
|
1908
1912
|
}
|
|
1909
1913
|
|
|
1914
|
+
// ../tracking-core/src/phone.ts
|
|
1915
|
+
var import_libphonenumber_js = require("libphonenumber-js");
|
|
1916
|
+
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
1917
|
+
function parsePhone(raw, country) {
|
|
1918
|
+
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
1919
|
+
const parsed = (0, import_libphonenumber_js.parsePhoneNumberFromString)(raw ?? "", region);
|
|
1920
|
+
if (!parsed) {
|
|
1921
|
+
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
1922
|
+
}
|
|
1923
|
+
const isValid = parsed.isValid();
|
|
1924
|
+
return {
|
|
1925
|
+
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
1926
|
+
// (e.g. too few digits) still parses but must not be transmitted.
|
|
1927
|
+
e164: isValid ? parsed.number : null,
|
|
1928
|
+
national: parsed.formatNational(),
|
|
1929
|
+
international: parsed.formatInternational(),
|
|
1930
|
+
country: parsed.country ?? region,
|
|
1931
|
+
isValid
|
|
1932
|
+
};
|
|
1933
|
+
}
|
|
1934
|
+
function toE164(raw, country) {
|
|
1935
|
+
return parsePhone(raw, country).e164;
|
|
1936
|
+
}
|
|
1937
|
+
function formatPhone(value, format = "national", country) {
|
|
1938
|
+
const parsed = parsePhone(value, country);
|
|
1939
|
+
if (typeof format === "function") return format(parsed);
|
|
1940
|
+
switch (format) {
|
|
1941
|
+
case "international":
|
|
1942
|
+
return parsed.international || value;
|
|
1943
|
+
case "e164":
|
|
1944
|
+
return parsed.e164 ?? value;
|
|
1945
|
+
case "national":
|
|
1946
|
+
default:
|
|
1947
|
+
return parsed.national || value;
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
function formatPhoneAsTyped(raw, country) {
|
|
1951
|
+
return new import_libphonenumber_js.AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
1952
|
+
}
|
|
1953
|
+
|
|
1954
|
+
// ../tracking-core/src/triggers/phone-click-capture.ts
|
|
1955
|
+
var DEFAULT_TEL_SELECTOR = 'a[href^="tel:"]';
|
|
1956
|
+
function safeDecodeURIComponent(value) {
|
|
1957
|
+
try {
|
|
1958
|
+
return decodeURIComponent(value);
|
|
1959
|
+
} catch {
|
|
1960
|
+
return value;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
function resolvePhoneNumber(el) {
|
|
1964
|
+
const href = el instanceof HTMLAnchorElement ? el.href : el.getAttribute("href") ?? "";
|
|
1965
|
+
const raw = safeDecodeURIComponent(href.replace(/^tel:/i, "").split(";")[0]).trim();
|
|
1966
|
+
return toE164(raw) ?? raw;
|
|
1967
|
+
}
|
|
1968
|
+
function attachPhoneClickCapture(client, config) {
|
|
1969
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
1970
|
+
return () => {
|
|
1971
|
+
};
|
|
1972
|
+
}
|
|
1973
|
+
const autoCapture = config.autoCapture;
|
|
1974
|
+
if (!autoCapture) {
|
|
1975
|
+
return () => {
|
|
1976
|
+
};
|
|
1977
|
+
}
|
|
1978
|
+
const selector = autoCapture.selector ?? DEFAULT_TEL_SELECTOR;
|
|
1979
|
+
function onClick(event) {
|
|
1980
|
+
const target = event.target;
|
|
1981
|
+
if (!(target instanceof Element)) return;
|
|
1982
|
+
let matched = null;
|
|
1983
|
+
try {
|
|
1984
|
+
matched = target.closest(selector);
|
|
1985
|
+
} catch {
|
|
1986
|
+
return;
|
|
1987
|
+
}
|
|
1988
|
+
if (matched === null) return;
|
|
1989
|
+
const metadata = {
|
|
1990
|
+
phone_number: resolvePhoneNumber(matched),
|
|
1991
|
+
page: { path: window.location.pathname },
|
|
1992
|
+
section: matched.getAttribute("data-aranova-section")
|
|
1993
|
+
};
|
|
1994
|
+
client.trackEvent({
|
|
1995
|
+
eventType: "phone_click",
|
|
1996
|
+
metadata,
|
|
1997
|
+
pageUrl: window.location.href,
|
|
1998
|
+
occurredAt: null
|
|
1999
|
+
});
|
|
2000
|
+
}
|
|
2001
|
+
document.addEventListener("click", onClick, true);
|
|
2002
|
+
return () => {
|
|
2003
|
+
document.removeEventListener("click", onClick, true);
|
|
2004
|
+
};
|
|
2005
|
+
}
|
|
2006
|
+
|
|
1910
2007
|
// ../tracking-core/src/resources/sales/errors.ts
|
|
1911
2008
|
var AranovaApiError = class extends Error {
|
|
1912
2009
|
constructor(message, options) {
|
|
@@ -2194,7 +2291,10 @@ var saleCreateSchema = import_zod12.z.object({
|
|
|
2194
2291
|
metadata: metadataSchema.nullable().optional(),
|
|
2195
2292
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2196
2293
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2197
|
-
customer_email: customerEmailSchema.nullable().optional()
|
|
2294
|
+
customer_email: customerEmailSchema.nullable().optional(),
|
|
2295
|
+
// CASL consent attestation: the customer agreed to receive SMS. Recorded
|
|
2296
|
+
// with a timestamp server-side; every SMS send path gates on it.
|
|
2297
|
+
sms_consent: import_zod12.z.boolean().default(false)
|
|
2198
2298
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
2199
2299
|
var saleUpdateSchema = import_zod12.z.object({
|
|
2200
2300
|
description: import_zod12.z.string().nullable().optional(),
|
|
@@ -2207,7 +2307,9 @@ var saleUpdateSchema = import_zod12.z.object({
|
|
|
2207
2307
|
metadata: metadataSchema.nullable().optional(),
|
|
2208
2308
|
customer_name: customerNameSchema.nullable().optional(),
|
|
2209
2309
|
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
2210
|
-
customer_email: customerEmailSchema.nullable().optional()
|
|
2310
|
+
customer_email: customerEmailSchema.nullable().optional(),
|
|
2311
|
+
// NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
|
|
2312
|
+
sms_consent: import_zod12.z.boolean().optional()
|
|
2211
2313
|
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: false }));
|
|
2212
2314
|
var TRACKING_RANGES = ["24h", "7d", "30d"];
|
|
2213
2315
|
var NAMED_RANGES = [
|
|
@@ -2229,46 +2331,6 @@ async function fetchServices(config) {
|
|
|
2229
2331
|
return salesRequest(config, "GET", "/services");
|
|
2230
2332
|
}
|
|
2231
2333
|
|
|
2232
|
-
// ../tracking-core/src/phone.ts
|
|
2233
|
-
var import_libphonenumber_js = require("libphonenumber-js");
|
|
2234
|
-
var DEFAULT_PHONE_COUNTRY = "CA";
|
|
2235
|
-
function parsePhone(raw, country) {
|
|
2236
|
-
const region = country ?? DEFAULT_PHONE_COUNTRY;
|
|
2237
|
-
const parsed = (0, import_libphonenumber_js.parsePhoneNumberFromString)(raw ?? "", region);
|
|
2238
|
-
if (!parsed) {
|
|
2239
|
-
return { e164: null, national: "", international: "", country: region, isValid: false };
|
|
2240
|
-
}
|
|
2241
|
-
const isValid = parsed.isValid();
|
|
2242
|
-
return {
|
|
2243
|
-
// E.164 is only surfaced for a *valid* number — a possible-but-invalid input
|
|
2244
|
-
// (e.g. too few digits) still parses but must not be transmitted.
|
|
2245
|
-
e164: isValid ? parsed.number : null,
|
|
2246
|
-
national: parsed.formatNational(),
|
|
2247
|
-
international: parsed.formatInternational(),
|
|
2248
|
-
country: parsed.country ?? region,
|
|
2249
|
-
isValid
|
|
2250
|
-
};
|
|
2251
|
-
}
|
|
2252
|
-
function toE164(raw, country) {
|
|
2253
|
-
return parsePhone(raw, country).e164;
|
|
2254
|
-
}
|
|
2255
|
-
function formatPhone(value, format = "national", country) {
|
|
2256
|
-
const parsed = parsePhone(value, country);
|
|
2257
|
-
if (typeof format === "function") return format(parsed);
|
|
2258
|
-
switch (format) {
|
|
2259
|
-
case "international":
|
|
2260
|
-
return parsed.international || value;
|
|
2261
|
-
case "e164":
|
|
2262
|
-
return parsed.e164 ?? value;
|
|
2263
|
-
case "national":
|
|
2264
|
-
default:
|
|
2265
|
-
return parsed.national || value;
|
|
2266
|
-
}
|
|
2267
|
-
}
|
|
2268
|
-
function formatPhoneAsTyped(raw, country) {
|
|
2269
|
-
return new import_libphonenumber_js.AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
|
|
2270
|
-
}
|
|
2271
|
-
|
|
2272
2334
|
// ../tracking-core/src/phone-field.ts
|
|
2273
2335
|
function phoneField(name, raw, country) {
|
|
2274
2336
|
return { name, type: "phone", value: toE164(raw, country) };
|
|
@@ -2605,7 +2667,7 @@ function GoogleAdsTracking(props) {
|
|
|
2605
2667
|
var import_navigation = require("next/navigation");
|
|
2606
2668
|
|
|
2607
2669
|
// package.json
|
|
2608
|
-
var version = "0.
|
|
2670
|
+
var version = "0.17.1";
|
|
2609
2671
|
|
|
2610
2672
|
// src/factory.tsx
|
|
2611
2673
|
var import_react4 = require("react");
|
|
@@ -2906,6 +2968,10 @@ function createTracking(options) {
|
|
|
2906
2968
|
if (ctaClick) {
|
|
2907
2969
|
detachers.push(attachCtaClickCapture(detectorClient, ctaClick));
|
|
2908
2970
|
}
|
|
2971
|
+
const phoneClick = triggers.manual?.phone_click;
|
|
2972
|
+
if (phoneClick) {
|
|
2973
|
+
detachers.push(attachPhoneClickCapture(detectorClient, phoneClick));
|
|
2974
|
+
}
|
|
2909
2975
|
return () => {
|
|
2910
2976
|
for (let i = detachers.length - 1; i >= 0; i--) {
|
|
2911
2977
|
detachers[i]();
|