@aranova/tracking-react 0.18.1 → 0.19.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/dist/index.d.mts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, CSSProperties, InputHTMLAttributes, ChangeEvent, FocusEvent } from 'react';
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-CVCzW04Z.mjs';
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-CVCzW04Z.mjs';
5
- import { T as TrackingConfigReference, C as ConversionConfig } from './sales-QqKh6_iy.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, U as SaleSummaryQuery, V as SaleSummaryQueryV2, W as SaleSummaryV2, X as SaleUpdateInput, Y as SalesBusinessClient, Z as SalesCategoryBreakdown, _ as SalesClient, $ as SalesClientConfig, a0 as SalesCustomersClient, a1 as SalesServiceBreakdown, a2 as SalesTransportConfig, a3 as SalesTrendPoint, a4 as SummaryCurrencyDelta, a5 as SummaryDeltas, a6 as SummaryWindow, a7 as SupportedCurrency, a8 as TRACKING_RANGES, a9 as TrackingOverviewRange, aa as createSalesClient, ab as fetchServices, ac as formatDateInTz, ad as formatMoney, ae as fromMinor, af as getTrackingConfigRuntime, ag as resolveConversionConfig, ah as saleCreateSchema, ai as saleItemSchema, aj as saleServiceSchema, ak as saleUpdateSchema, al as salesRequest, am as toMinor } from './sales-QqKh6_iy.mjs';
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-B2vHJkNz.mjs';
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-B2vHJkNz.mjs';
5
+ import { T as TrackingConfigReference, C as ConversionConfig } from './sales--WzOzyiO.mjs';
6
+ export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, c as CompareTo, d as ConversionConfigStore, e as ConversionUserData, f as CurrencyRevenue, g as CustomerCurrencyDelta, h as CustomerCurrencyTotal, i as CustomerGetOptions, j as CustomerGetResult, k as CustomerKpis, l as CustomerKpisDeltas, m as CustomerKpisPrevious, n as CustomerListPage, o as CustomerListQuery, p as CustomerProfile, q as CustomerSegment, r as CustomerSegmentCount, s as CustomerSortField, t as CustomerSummary, u as CustomerSummaryQuery, D as DistinctCustomersByCurrency, G as Granularity, N as NAMED_RANGES, v as NamedRange, P as PublicServiceItem, S as SUPPORTED_CURRENCIES, w as Sale, x as SaleCursorPage, y as SaleFilters, z as SaleInput, E as SaleItem, F as SaleItemInput, H as SaleKeysetSortField, I as SaleListPage, J as SaleListQuery, K as SaleListQueryV2, L as SaleService, M as SaleServiceInput, O as SaleSortField, Q as SaleSortOrder, R as SaleSummary, U as SaleSummaryPrevious, V as SaleSummaryQuery, W as SaleSummaryQueryV2, X as SaleSummaryV2, Y as SaleUpdateInput, Z as SalesBusinessClient, _ as SalesCategoryBreakdown, $ as SalesClient, a0 as SalesClientConfig, a1 as SalesCustomersClient, a2 as SalesServiceBreakdown, a3 as SalesTransportConfig, a4 as SalesTrendPoint, a5 as SummaryCurrencyDelta, a6 as SummaryDeltas, a7 as SummaryWindow, a8 as SupportedCurrency, a9 as TRACKING_RANGES, aa as TrackingOverviewRange, ab as clearStashedUserData, ac as createSalesClient, ad as fetchServices, ae as formatDateInTz, af as formatMoney, ag as fromMinor, ah as getTrackingConfigRuntime, ai as resolveConversionConfig, aj as saleCreateSchema, ak as saleItemSchema, al as saleServiceSchema, am as saleUpdateSchema, an as salesRequest, ao as stashUserData, ap as toMinor } from './sales--WzOzyiO.mjs';
7
7
  import * as src from 'src';
8
8
  import { z } from 'zod';
9
9
  import { CountryCode } from 'libphonenumber-js';
@@ -60,7 +60,7 @@ declare function ConsentBanner({ message, title, acceptLabel, declineLabel, poli
60
60
  /**
61
61
  * Attribution query/cookie keys captured by the SDK.
62
62
  */
63
- declare const TRACKING_PARAM_KEYS: readonly ["gclid", "fbclid", "utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];
63
+ declare const TRACKING_PARAM_KEYS: readonly ["gclid", "wbraid", "gbraid", "fbclid", "utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];
64
64
  type TrackingParamKey = (typeof TRACKING_PARAM_KEYS)[number];
65
65
  /**
66
66
  * Capture tracking params from a URL, persist them to first-party cookies, and
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, CSSProperties, InputHTMLAttributes, ChangeEvent, FocusEvent } from 'react';
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-CVCzW04Z.js';
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-CVCzW04Z.js';
5
- import { T as TrackingConfigReference, C as ConversionConfig } from './sales-QqKh6_iy.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, U as SaleSummaryQuery, V as SaleSummaryQueryV2, W as SaleSummaryV2, X as SaleUpdateInput, Y as SalesBusinessClient, Z as SalesCategoryBreakdown, _ as SalesClient, $ as SalesClientConfig, a0 as SalesCustomersClient, a1 as SalesServiceBreakdown, a2 as SalesTransportConfig, a3 as SalesTrendPoint, a4 as SummaryCurrencyDelta, a5 as SummaryDeltas, a6 as SummaryWindow, a7 as SupportedCurrency, a8 as TRACKING_RANGES, a9 as TrackingOverviewRange, aa as createSalesClient, ab as fetchServices, ac as formatDateInTz, ad as formatMoney, ae as fromMinor, af as getTrackingConfigRuntime, ag as resolveConversionConfig, ah as saleCreateSchema, ai as saleItemSchema, aj as saleServiceSchema, ak as saleUpdateSchema, al as salesRequest, am as toMinor } from './sales-QqKh6_iy.js';
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-B2vHJkNz.js';
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-B2vHJkNz.js';
5
+ import { T as TrackingConfigReference, C as ConversionConfig } from './sales--WzOzyiO.js';
6
+ export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, c as CompareTo, d as ConversionConfigStore, e as ConversionUserData, f as CurrencyRevenue, g as CustomerCurrencyDelta, h as CustomerCurrencyTotal, i as CustomerGetOptions, j as CustomerGetResult, k as CustomerKpis, l as CustomerKpisDeltas, m as CustomerKpisPrevious, n as CustomerListPage, o as CustomerListQuery, p as CustomerProfile, q as CustomerSegment, r as CustomerSegmentCount, s as CustomerSortField, t as CustomerSummary, u as CustomerSummaryQuery, D as DistinctCustomersByCurrency, G as Granularity, N as NAMED_RANGES, v as NamedRange, P as PublicServiceItem, S as SUPPORTED_CURRENCIES, w as Sale, x as SaleCursorPage, y as SaleFilters, z as SaleInput, E as SaleItem, F as SaleItemInput, H as SaleKeysetSortField, I as SaleListPage, J as SaleListQuery, K as SaleListQueryV2, L as SaleService, M as SaleServiceInput, O as SaleSortField, Q as SaleSortOrder, R as SaleSummary, U as SaleSummaryPrevious, V as SaleSummaryQuery, W as SaleSummaryQueryV2, X as SaleSummaryV2, Y as SaleUpdateInput, Z as SalesBusinessClient, _ as SalesCategoryBreakdown, $ as SalesClient, a0 as SalesClientConfig, a1 as SalesCustomersClient, a2 as SalesServiceBreakdown, a3 as SalesTransportConfig, a4 as SalesTrendPoint, a5 as SummaryCurrencyDelta, a6 as SummaryDeltas, a7 as SummaryWindow, a8 as SupportedCurrency, a9 as TRACKING_RANGES, aa as TrackingOverviewRange, ab as clearStashedUserData, ac as createSalesClient, ad as fetchServices, ae as formatDateInTz, af as formatMoney, ag as fromMinor, ah as getTrackingConfigRuntime, ai as resolveConversionConfig, aj as saleCreateSchema, ak as saleItemSchema, al as saleServiceSchema, am as saleUpdateSchema, an as salesRequest, ao as stashUserData, ap as toMinor } from './sales--WzOzyiO.js';
7
7
  import * as src from 'src';
8
8
  import { z } from 'zod';
9
9
  import { CountryCode } from 'libphonenumber-js';
@@ -60,7 +60,7 @@ declare function ConsentBanner({ message, title, acceptLabel, declineLabel, poli
60
60
  /**
61
61
  * Attribution query/cookie keys captured by the SDK.
62
62
  */
63
- declare const TRACKING_PARAM_KEYS: readonly ["gclid", "fbclid", "utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];
63
+ declare const TRACKING_PARAM_KEYS: readonly ["gclid", "wbraid", "gbraid", "fbclid", "utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"];
64
64
  type TrackingParamKey = (typeof TRACKING_PARAM_KEYS)[number];
65
65
  /**
66
66
  * Capture tracking params from a URL, persist them to first-party cookies, and
package/dist/index.js CHANGED
@@ -33,6 +33,7 @@ __export(src_exports, {
33
33
  TRACKING_PARAM_KEYS: () => TRACKING_PARAM_KEYS,
34
34
  TRACKING_RANGES: () => TRACKING_RANGES,
35
35
  captureTrackingParamsFromLocation: () => captureTrackingParamsFromLocation,
36
+ clearStashedUserData: () => clearStashedUserData,
36
37
  createSalesClient: () => createSalesClient,
37
38
  createTracking: () => createTracking,
38
39
  createTrackingClientContext: () => createTrackingClientContext,
@@ -61,6 +62,7 @@ __export(src_exports, {
61
62
  saleUpdateSchema: () => saleUpdateSchema,
62
63
  salesRequest: () => salesRequest,
63
64
  setConsentState: () => setConsentState,
65
+ stashUserData: () => stashUserData,
64
66
  toE164: () => toE164,
65
67
  toMinor: () => toMinor,
66
68
  useConsent: () => useConsent,
@@ -79,6 +81,140 @@ var import_react2 = require("react");
79
81
  // src/hooks.ts
80
82
  var import_react = require("react");
81
83
 
84
+ // ../tracking-core/src/phone.ts
85
+ var import_libphonenumber_js = require("libphonenumber-js");
86
+ var DEFAULT_PHONE_COUNTRY = "CA";
87
+ function parsePhone(raw, country) {
88
+ const region = country ?? DEFAULT_PHONE_COUNTRY;
89
+ const parsed = (0, import_libphonenumber_js.parsePhoneNumberFromString)(raw ?? "", region);
90
+ if (!parsed) {
91
+ return { e164: null, national: "", international: "", country: region, isValid: false };
92
+ }
93
+ const isValid = parsed.isValid();
94
+ return {
95
+ // E.164 is only surfaced for a *valid* number — a possible-but-invalid input
96
+ // (e.g. too few digits) still parses but must not be transmitted.
97
+ e164: isValid ? parsed.number : null,
98
+ national: parsed.formatNational(),
99
+ international: parsed.formatInternational(),
100
+ country: parsed.country ?? region,
101
+ isValid
102
+ };
103
+ }
104
+ function toE164(raw, country) {
105
+ return parsePhone(raw, country).e164;
106
+ }
107
+ function formatPhone(value, format = "national", country) {
108
+ const parsed = parsePhone(value, country);
109
+ if (typeof format === "function") return format(parsed);
110
+ switch (format) {
111
+ case "international":
112
+ return parsed.international || value;
113
+ case "e164":
114
+ return parsed.e164 ?? value;
115
+ case "national":
116
+ default:
117
+ return parsed.national || value;
118
+ }
119
+ }
120
+ function formatPhoneAsTyped(raw, country) {
121
+ return new import_libphonenumber_js.AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
122
+ }
123
+
124
+ // ../tracking-core/src/user-data.ts
125
+ var EMAIL_SHAPE = /^[^@\s]+@[^@\s]+\.[^@\s]+$/;
126
+ var EMAIL_NAME_HINT = /e[-_]?mail/i;
127
+ var PHONE_NAME_HINT = /(^|[^a-z])(phone|tel|mobile|cell)/i;
128
+ var stash = { email: null, phoneNumber: null };
129
+ function normalizeEmail(raw) {
130
+ if (typeof raw !== "string") return null;
131
+ const cleaned = raw.trim().toLowerCase();
132
+ return EMAIL_SHAPE.test(cleaned) ? cleaned : null;
133
+ }
134
+ function fieldText(field, key) {
135
+ const value = field[key];
136
+ return typeof value === "string" ? value : "";
137
+ }
138
+ function extractUserDataFromFormFields(fields, country) {
139
+ const result = { email: null, phoneNumber: null };
140
+ if (!Array.isArray(fields)) return result;
141
+ const passes = [
142
+ (field, _hint, type) => fieldText(field, "type").toLowerCase() === type,
143
+ (field, hint) => hint.test(fieldText(field, "name")) || hint.test(fieldText(field, "label"))
144
+ ];
145
+ for (const matches of passes) {
146
+ for (const raw of fields) {
147
+ if (raw === null || typeof raw !== "object") continue;
148
+ const field = raw;
149
+ if (typeof field.value !== "string" || field.value.length === 0) continue;
150
+ if (result.email === null && matches(field, EMAIL_NAME_HINT, "email")) {
151
+ result.email = normalizeEmail(field.value);
152
+ }
153
+ if (result.phoneNumber === null && matches(field, PHONE_NAME_HINT, "tel")) {
154
+ try {
155
+ result.phoneNumber = toE164(field.value, country);
156
+ } catch {
157
+ }
158
+ }
159
+ }
160
+ if (result.email !== null && result.phoneNumber !== null) break;
161
+ }
162
+ return result;
163
+ }
164
+ function stashUserData(data, country) {
165
+ const email = normalizeEmail(data.email);
166
+ let phoneNumber = null;
167
+ if (typeof data.phone === "string" && data.phone.length > 0) {
168
+ try {
169
+ phoneNumber = toE164(data.phone, country);
170
+ } catch {
171
+ phoneNumber = null;
172
+ }
173
+ }
174
+ stash = {
175
+ email: email ?? stash.email,
176
+ phoneNumber: phoneNumber ?? stash.phoneNumber
177
+ };
178
+ }
179
+ function stashUserDataFromFormFields(fields, country) {
180
+ try {
181
+ const extracted = extractUserDataFromFormFields(fields, country);
182
+ stash = {
183
+ email: extracted.email ?? stash.email,
184
+ phoneNumber: extracted.phoneNumber ?? stash.phoneNumber
185
+ };
186
+ } catch {
187
+ }
188
+ }
189
+ function clearStashedUserData() {
190
+ stash = { email: null, phoneNumber: null };
191
+ }
192
+ function applyUserDataForConversion(explicit, country) {
193
+ if (typeof window === "undefined" || typeof window.gtag !== "function") return false;
194
+ let email = stash.email;
195
+ let phoneNumber = stash.phoneNumber;
196
+ if (explicit) {
197
+ const normalizedEmail = normalizeEmail(explicit.email);
198
+ if (normalizedEmail) email = normalizedEmail;
199
+ if (typeof explicit.phone === "string" && explicit.phone.length > 0) {
200
+ try {
201
+ phoneNumber = toE164(explicit.phone, country) ?? phoneNumber;
202
+ } catch {
203
+ }
204
+ }
205
+ }
206
+ if (email === null && phoneNumber === null) return false;
207
+ try {
208
+ window.gtag("set", "user_data", {
209
+ ...email !== null ? { email } : {},
210
+ ...phoneNumber !== null ? { phone_number: phoneNumber } : {}
211
+ });
212
+ return true;
213
+ } catch {
214
+ return false;
215
+ }
216
+ }
217
+
82
218
  // ../tracking-core/src/consent.ts
83
219
  var CONSENT_STATE_KEY = "consent_state";
84
220
  var CONSENT_TIMESTAMP_KEY = "consent_timestamp";
@@ -164,6 +300,13 @@ function setConsentState(state, options) {
164
300
  } catch {
165
301
  }
166
302
  pushConsentToPlatforms(state);
303
+ if (state === "denied") {
304
+ clearStashedUserData();
305
+ try {
306
+ if (typeof window.gtag === "function") window.gtag("set", "user_data", null);
307
+ } catch {
308
+ }
309
+ }
167
310
  notifyConsentChanged({ state, source: "explicit", updatedAt, expiresAt });
168
311
  }
169
312
  function optIn() {
@@ -188,6 +331,11 @@ function resetConsent() {
188
331
  var TRACKING_COOKIE_MAX_AGE_SECONDS = 7776e3;
189
332
  var TRACKING_PARAM_KEYS = [
190
333
  "gclid",
334
+ // Google's iOS/Safari replacement click IDs — issued when privacy features
335
+ // withhold gclid (wbraid: web-to-web, gbraid: app-to-web). First-class
336
+ // citizens: captured, persisted, and attributed exactly like gclid.
337
+ "wbraid",
338
+ "gbraid",
191
339
  "fbclid",
192
340
  "utm_source",
193
341
  "utm_medium",
@@ -198,6 +346,8 @@ var TRACKING_PARAM_KEYS = [
198
346
  function createEmptyTrackingParams() {
199
347
  return {
200
348
  gclid: null,
349
+ wbraid: null,
350
+ gbraid: null,
201
351
  fbclid: null,
202
352
  utm_source: null,
203
353
  utm_medium: null,
@@ -529,6 +679,8 @@ function buildLandingPayloadFields(sessionId, override) {
529
679
  if (params === null) return {};
530
680
  return {
531
681
  landing_gclid: params.gclid ?? null,
682
+ landing_wbraid: params.wbraid ?? null,
683
+ landing_gbraid: params.gbraid ?? null,
532
684
  landing_fbclid: params.fbclid ?? null,
533
685
  landing_utm_source: params.utm_source ?? null,
534
686
  landing_utm_medium: params.utm_medium ?? null,
@@ -556,6 +708,8 @@ function createTrackingSessionUpsertPayload(trackingParams, input, context) {
556
708
  session_id: input.sessionId,
557
709
  visitor_id: input.visitorId ?? null,
558
710
  gclid: trackingParams.gclid,
711
+ wbraid: trackingParams.wbraid,
712
+ gbraid: trackingParams.gbraid,
559
713
  fbclid: trackingParams.fbclid,
560
714
  fbc: getFbcCookie(),
561
715
  fbp: getFbpCookie(),
@@ -577,6 +731,8 @@ function createTrackingEventCreatePayload(trackingParams, input, context) {
577
731
  session_id: input.sessionId,
578
732
  event_type: input.eventType,
579
733
  gclid: trackingParams.gclid,
734
+ wbraid: trackingParams.wbraid,
735
+ gbraid: trackingParams.gbraid,
580
736
  fbclid: trackingParams.fbclid,
581
737
  fbc: getFbcCookie(),
582
738
  fbp: getFbpCookie(),
@@ -606,14 +762,12 @@ function markFired(input) {
606
762
  } catch {
607
763
  }
608
764
  }
609
- function fireOnce(input) {
765
+ function fireConversionWithConsent(input, options) {
766
+ if (getConsentState() === "denied") return;
610
767
  if (alreadyFired(input)) return;
768
+ applyUserDataForConversion(options?.userData);
611
769
  if (fireGtagConversion(input)) markFired(input);
612
770
  }
613
- function fireConversionWithConsent(input) {
614
- if (getConsentState() === "denied") return;
615
- fireOnce(input);
616
- }
617
771
 
618
772
  // ../tracking-core/src/resources/conversion-config.ts
619
773
  function isStringMap(value) {
@@ -1058,6 +1212,7 @@ var TrackingConfigRuntime = class {
1058
1212
  if (!firing || getConsentState() === "denied") continue;
1059
1213
  const currency = item.currency ?? firing.currency ?? null;
1060
1214
  const value = item.value ?? (firing.value_cents != null && currency ? fromMinor(firing.value_cents, currency) : null);
1215
+ applyUserDataForConversion();
1061
1216
  fireGtagConversion({
1062
1217
  sendTo: firing.send_to,
1063
1218
  value,
@@ -1589,6 +1744,8 @@ function createTrackingClient(config) {
1589
1744
  session_id: sessionId,
1590
1745
  visitor_id: visitorId,
1591
1746
  gclid: params.gclid,
1747
+ wbraid: params.wbraid,
1748
+ gbraid: params.gbraid,
1592
1749
  fbclid: params.fbclid,
1593
1750
  fbc: getFbcCookie(),
1594
1751
  fbp: getFbpCookie(),
@@ -1635,6 +1792,13 @@ function createTrackingClient(config) {
1635
1792
  function trackEvent(input) {
1636
1793
  if (destroyed) return;
1637
1794
  if (!input || typeof input.eventType !== "string" || input.eventType.length === 0) return;
1795
+ if (input.eventType === "form_submit" && getConsentState() !== "denied") {
1796
+ try {
1797
+ const fields = input.metadata?.form?.fields;
1798
+ if (fields) stashUserDataFromFormFields(fields, config.phone?.defaultCountry);
1799
+ } catch {
1800
+ }
1801
+ }
1638
1802
  const occurredAt = input.occurredAt instanceof Date ? input.occurredAt.toISOString() : typeof input.occurredAt === "string" ? input.occurredAt : (/* @__PURE__ */ new Date()).toISOString();
1639
1803
  queue.push({
1640
1804
  event_type: input.eventType,
@@ -2598,46 +2762,6 @@ function attachCtaClickCapture(client, config) {
2598
2762
  };
2599
2763
  }
2600
2764
 
2601
- // ../tracking-core/src/phone.ts
2602
- var import_libphonenumber_js = require("libphonenumber-js");
2603
- var DEFAULT_PHONE_COUNTRY = "CA";
2604
- function parsePhone(raw, country) {
2605
- const region = country ?? DEFAULT_PHONE_COUNTRY;
2606
- const parsed = (0, import_libphonenumber_js.parsePhoneNumberFromString)(raw ?? "", region);
2607
- if (!parsed) {
2608
- return { e164: null, national: "", international: "", country: region, isValid: false };
2609
- }
2610
- const isValid = parsed.isValid();
2611
- return {
2612
- // E.164 is only surfaced for a *valid* number — a possible-but-invalid input
2613
- // (e.g. too few digits) still parses but must not be transmitted.
2614
- e164: isValid ? parsed.number : null,
2615
- national: parsed.formatNational(),
2616
- international: parsed.formatInternational(),
2617
- country: parsed.country ?? region,
2618
- isValid
2619
- };
2620
- }
2621
- function toE164(raw, country) {
2622
- return parsePhone(raw, country).e164;
2623
- }
2624
- function formatPhone(value, format = "national", country) {
2625
- const parsed = parsePhone(value, country);
2626
- if (typeof format === "function") return format(parsed);
2627
- switch (format) {
2628
- case "international":
2629
- return parsed.international || value;
2630
- case "e164":
2631
- return parsed.e164 ?? value;
2632
- case "national":
2633
- default:
2634
- return parsed.national || value;
2635
- }
2636
- }
2637
- function formatPhoneAsTyped(raw, country) {
2638
- return new import_libphonenumber_js.AsYouType(country ?? DEFAULT_PHONE_COUNTRY).input(raw ?? "");
2639
- }
2640
-
2641
2765
  // ../tracking-core/src/triggers/phone-click-capture.ts
2642
2766
  var DEFAULT_TEL_SELECTOR = 'a[href^="tel:"]';
2643
2767
  function safeDecodeURIComponent(value) {
@@ -2747,6 +2871,8 @@ async function salesRequest(config, method, path, body) {
2747
2871
  // ../tracking-core/src/resources/sales/client.ts
2748
2872
  function fireRecordedConversions(firing, input, recorded, sale, currency) {
2749
2873
  if (!firing) return;
2874
+ const userData = input.customer_email || input.customer_phone ? { email: input.customer_email ?? null, phone: input.customer_phone ?? null } : null;
2875
+ if (userData && getConsentState() !== "denied") stashUserData(userData);
2750
2876
  const txnBase = input.external_id ?? sale.id;
2751
2877
  for (const item of recorded) {
2752
2878
  if (!item.service) continue;
@@ -2761,12 +2887,15 @@ function fireRecordedConversions(firing, input, recorded, sale, currency) {
2761
2887
  const config = firing.getFiring(item.service);
2762
2888
  if (!config) continue;
2763
2889
  const cents = item.amount_cents ?? config.value_cents ?? null;
2764
- fireConversionWithConsent({
2765
- sendTo: config.send_to,
2766
- value: cents != null ? fromMinor(cents, currency) : null,
2767
- currency: config.currency ?? currency,
2768
- transactionId: `${txnBase}:${item.service}`
2769
- });
2890
+ fireConversionWithConsent(
2891
+ {
2892
+ sendTo: config.send_to,
2893
+ value: cents != null ? fromMinor(cents, currency) : null,
2894
+ currency: config.currency ?? currency,
2895
+ transactionId: `${txnBase}:${item.service}`
2896
+ },
2897
+ { userData }
2898
+ );
2770
2899
  }
2771
2900
  }
2772
2901
  function createSalesClient(config) {
@@ -2801,6 +2930,7 @@ function createSalesClient(config) {
2801
2930
  recordSale: record,
2802
2931
  trackConversion(key, options) {
2803
2932
  if (config.firing && "fireConversion" in config.firing) {
2933
+ if (options?.userData && getConsentState() !== "denied") stashUserData(options.userData);
2804
2934
  config.firing.fireConversion(key, {
2805
2935
  value: options?.value ?? void 0,
2806
2936
  currency: options?.currency ?? config.defaultCurrency ?? void 0,
@@ -2813,12 +2943,15 @@ function createSalesClient(config) {
2813
2943
  const currency = firing.currency ?? options?.currency ?? config.defaultCurrency ?? null;
2814
2944
  const cents = firing.value_cents ?? null;
2815
2945
  const value = options?.value ?? (cents != null && currency ? fromMinor(cents, currency) : null);
2816
- fireConversionWithConsent({
2817
- sendTo: firing.send_to,
2818
- value,
2819
- currency,
2820
- transactionId: options?.transactionId ?? null
2821
- });
2946
+ fireConversionWithConsent(
2947
+ {
2948
+ sendTo: firing.send_to,
2949
+ value,
2950
+ currency,
2951
+ transactionId: options?.transactionId ?? null
2952
+ },
2953
+ { userData: options?.userData }
2954
+ );
2822
2955
  },
2823
2956
  async list(query) {
2824
2957
  const { cursor, limit, sort, order, want_total, ...filters } = query ?? {};
@@ -3363,7 +3496,7 @@ function GoogleAdsTracking(props) {
3363
3496
  var import_react6 = require("react");
3364
3497
 
3365
3498
  // package.json
3366
- var version = "0.18.1";
3499
+ var version = "0.19.0";
3367
3500
 
3368
3501
  // ../tracking-core/src/phone-react.tsx
3369
3502
  var import_react5 = require("react");
@@ -3627,6 +3760,7 @@ function createTracking(options) {
3627
3760
  TRACKING_PARAM_KEYS,
3628
3761
  TRACKING_RANGES,
3629
3762
  captureTrackingParamsFromLocation,
3763
+ clearStashedUserData,
3630
3764
  createSalesClient,
3631
3765
  createTracking,
3632
3766
  createTrackingClientContext,
@@ -3655,6 +3789,7 @@ function createTracking(options) {
3655
3789
  saleUpdateSchema,
3656
3790
  salesRequest,
3657
3791
  setConsentState,
3792
+ stashUserData,
3658
3793
  toE164,
3659
3794
  toMinor,
3660
3795
  useConsent,