@aranova/tracking-react 1.4.1 → 1.6.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.
@@ -1,4 +1,4 @@
1
- import { j as BookingDayWindows, c as BookingMode, k as ConversionIntegrations } from './bookings-CqCuuyP6.mjs';
1
+ import { j as BookingDayWindows, c as BookingMode, k as ConversionIntegrations } from './bookings-n8UUzrak.mjs';
2
2
  import * as zod_v4_core from 'zod/v4/core';
3
3
  import * as z from 'zod/mini';
4
4
  import { J as JsonValue, F as FormSubmitConfig, a as FormSubmitMetadata } from './form-submit-BLb28aCk.mjs';
@@ -9,6 +9,15 @@ type BookingProvider = "autoleap";
9
9
  interface BookingOption {
10
10
  key: string;
11
11
  label: string;
12
+ /** The shop's service category, for a heading over its choices; null when it has none. */
13
+ group: string | null;
14
+ /** Optional helper text to show under the label. */
15
+ description: string | null;
16
+ }
17
+ /** One heading on the form and the choices under it; `group` null holds the ungrouped ones. */
18
+ interface BookingOptionGroup {
19
+ group: string | null;
20
+ options: BookingOption[];
12
21
  }
13
22
  /** The booking rules in camelCase, all in the shop's wall time. */
14
23
  interface BookingRules {
@@ -82,6 +91,11 @@ declare function bookableSlots(rules: BookingRules, { timeZone, now }: {
82
91
  * https link on the shop's booking host (a config value never becomes an arbitrary redirect).
83
92
  */
84
93
  declare function buildBookingHandoffUrl(fallbackUrl: string, prefill?: BookingHandoffPrefill): string | null;
94
+ /**
95
+ * The options as headed sections, in published order: one per category, choices in order
96
+ * under it. The API saves them grouped, so a category is never split; this keeps the first run.
97
+ */
98
+ declare function groupBookingOptions(options: readonly BookingOption[]): BookingOptionGroup[];
85
99
 
86
100
  /**
87
101
  * Metadata for a manually fired `cta_click` event.
@@ -1001,4 +1015,4 @@ interface TypedTrackingClient<TRegistry extends TriggerRegistryConfig> {
1001
1015
  getVisitorId(): string;
1002
1016
  }
1003
1017
 
1004
- export { getBookingIntegration as $, type AutomaticEventName as A, type BookableDay as B, type CtaClickConfig as C, type ScrollDepthMetadata as D, EVENT_SEMANTICS as E, type FormStartConfig as F, type SdkHeartbeatConfig as G, type SdkHeartbeatMetadata as H, type SiteLinkArrivalConfig as I, type SiteLinkArrivalMetadata as J, type SiteLinkClickConfig as K, type SiteLinkClickMetadata as L, type ManualEventName as M, type SpecificPageName as N, type SpecificPageVisitConfig as O, type PageExitConfig as P, type SpecificPageVisitMetadata as Q, type RegisteredAutomaticEvents as R, type ScrollDepthConfig as S, type TimeOnSiteConfig as T, type TimeOnSiteMetadata as U, type TrackableEvent as V, type TriggerRegistryConfig as W, type TypedTrackEventOptions as X, type TypedTrackingClient as Y, bookableSlots as Z, buildBookingHandoffUrl as _, type BookingHandoffPrefill as a, getEventSemantics as a0, shopToday as a1, type BookingIntegration as b, type BookingOption as c, type BookingProvider as d, type BookingRules as e, type CtaClickMetadata as f, type EventCategory as g, type EventClientVisibility as h, type EventConfig as i, type EventKind as j, type EventMetadata as k, type EventName as l, type EventOutcomeRole as m, type EventSemantics as n, type FormStartMetadata as o, type FormStepConfig as p, type FormStepMetadata as q, type MultiPageSessionConfig as r, type MultiPageSessionMetadata as s, type PageExitMetadata as t, type PageIdentity as u, type PageViewConfig as v, type PageViewMetadata as w, type PhoneClickConfig as x, type PhoneClickMetadata as y, type RegisteredManualEvents as z };
1018
+ export { buildBookingHandoffUrl as $, type AutomaticEventName as A, type BookableDay as B, type CtaClickConfig as C, type RegisteredManualEvents as D, EVENT_SEMANTICS as E, type FormStartConfig as F, type ScrollDepthMetadata as G, type SdkHeartbeatConfig as H, type SdkHeartbeatMetadata as I, type SiteLinkArrivalConfig as J, type SiteLinkArrivalMetadata as K, type SiteLinkClickConfig as L, type ManualEventName as M, type SiteLinkClickMetadata as N, type SpecificPageName as O, type PageExitConfig as P, type SpecificPageVisitConfig as Q, type RegisteredAutomaticEvents as R, type ScrollDepthConfig as S, type SpecificPageVisitMetadata as T, type TimeOnSiteConfig as U, type TimeOnSiteMetadata as V, type TrackableEvent as W, type TriggerRegistryConfig as X, type TypedTrackEventOptions as Y, type TypedTrackingClient as Z, bookableSlots as _, type BookingHandoffPrefill as a, getBookingIntegration as a0, getEventSemantics as a1, groupBookingOptions as a2, shopToday as a3, type BookingIntegration as b, type BookingOption as c, type BookingOptionGroup as d, type BookingProvider as e, type BookingRules as f, type CtaClickMetadata as g, type EventCategory as h, type EventClientVisibility as i, type EventConfig as j, type EventKind as k, type EventMetadata as l, type EventName as m, type EventOutcomeRole as n, type EventSemantics as o, type FormStartMetadata as p, type FormStepConfig as q, type FormStepMetadata as r, type MultiPageSessionConfig as s, type MultiPageSessionMetadata as t, type PageExitMetadata as u, type PageIdentity as v, type PageViewConfig as w, type PageViewMetadata as x, type PhoneClickConfig as y, type PhoneClickMetadata as z };
@@ -1,4 +1,4 @@
1
- import { j as BookingDayWindows, c as BookingMode, k as ConversionIntegrations } from './bookings-DIu1ho6v.js';
1
+ import { j as BookingDayWindows, c as BookingMode, k as ConversionIntegrations } from './bookings-B50X7GSG.js';
2
2
  import * as zod_v4_core from 'zod/v4/core';
3
3
  import * as z from 'zod/mini';
4
4
  import { J as JsonValue, F as FormSubmitConfig, a as FormSubmitMetadata } from './form-submit-BLb28aCk.js';
@@ -9,6 +9,15 @@ type BookingProvider = "autoleap";
9
9
  interface BookingOption {
10
10
  key: string;
11
11
  label: string;
12
+ /** The shop's service category, for a heading over its choices; null when it has none. */
13
+ group: string | null;
14
+ /** Optional helper text to show under the label. */
15
+ description: string | null;
16
+ }
17
+ /** One heading on the form and the choices under it; `group` null holds the ungrouped ones. */
18
+ interface BookingOptionGroup {
19
+ group: string | null;
20
+ options: BookingOption[];
12
21
  }
13
22
  /** The booking rules in camelCase, all in the shop's wall time. */
14
23
  interface BookingRules {
@@ -82,6 +91,11 @@ declare function bookableSlots(rules: BookingRules, { timeZone, now }: {
82
91
  * https link on the shop's booking host (a config value never becomes an arbitrary redirect).
83
92
  */
84
93
  declare function buildBookingHandoffUrl(fallbackUrl: string, prefill?: BookingHandoffPrefill): string | null;
94
+ /**
95
+ * The options as headed sections, in published order: one per category, choices in order
96
+ * under it. The API saves them grouped, so a category is never split; this keeps the first run.
97
+ */
98
+ declare function groupBookingOptions(options: readonly BookingOption[]): BookingOptionGroup[];
85
99
 
86
100
  /**
87
101
  * Metadata for a manually fired `cta_click` event.
@@ -1001,4 +1015,4 @@ interface TypedTrackingClient<TRegistry extends TriggerRegistryConfig> {
1001
1015
  getVisitorId(): string;
1002
1016
  }
1003
1017
 
1004
- export { getBookingIntegration as $, type AutomaticEventName as A, type BookableDay as B, type CtaClickConfig as C, type ScrollDepthMetadata as D, EVENT_SEMANTICS as E, type FormStartConfig as F, type SdkHeartbeatConfig as G, type SdkHeartbeatMetadata as H, type SiteLinkArrivalConfig as I, type SiteLinkArrivalMetadata as J, type SiteLinkClickConfig as K, type SiteLinkClickMetadata as L, type ManualEventName as M, type SpecificPageName as N, type SpecificPageVisitConfig as O, type PageExitConfig as P, type SpecificPageVisitMetadata as Q, type RegisteredAutomaticEvents as R, type ScrollDepthConfig as S, type TimeOnSiteConfig as T, type TimeOnSiteMetadata as U, type TrackableEvent as V, type TriggerRegistryConfig as W, type TypedTrackEventOptions as X, type TypedTrackingClient as Y, bookableSlots as Z, buildBookingHandoffUrl as _, type BookingHandoffPrefill as a, getEventSemantics as a0, shopToday as a1, type BookingIntegration as b, type BookingOption as c, type BookingProvider as d, type BookingRules as e, type CtaClickMetadata as f, type EventCategory as g, type EventClientVisibility as h, type EventConfig as i, type EventKind as j, type EventMetadata as k, type EventName as l, type EventOutcomeRole as m, type EventSemantics as n, type FormStartMetadata as o, type FormStepConfig as p, type FormStepMetadata as q, type MultiPageSessionConfig as r, type MultiPageSessionMetadata as s, type PageExitMetadata as t, type PageIdentity as u, type PageViewConfig as v, type PageViewMetadata as w, type PhoneClickConfig as x, type PhoneClickMetadata as y, type RegisteredManualEvents as z };
1018
+ export { buildBookingHandoffUrl as $, type AutomaticEventName as A, type BookableDay as B, type CtaClickConfig as C, type RegisteredManualEvents as D, EVENT_SEMANTICS as E, type FormStartConfig as F, type ScrollDepthMetadata as G, type SdkHeartbeatConfig as H, type SdkHeartbeatMetadata as I, type SiteLinkArrivalConfig as J, type SiteLinkArrivalMetadata as K, type SiteLinkClickConfig as L, type ManualEventName as M, type SiteLinkClickMetadata as N, type SpecificPageName as O, type PageExitConfig as P, type SpecificPageVisitConfig as Q, type RegisteredAutomaticEvents as R, type ScrollDepthConfig as S, type SpecificPageVisitMetadata as T, type TimeOnSiteConfig as U, type TimeOnSiteMetadata as V, type TrackableEvent as W, type TriggerRegistryConfig as X, type TypedTrackEventOptions as Y, type TypedTrackingClient as Z, bookableSlots as _, type BookingHandoffPrefill as a, getBookingIntegration as a0, getEventSemantics as a1, groupBookingOptions as a2, shopToday as a3, type BookingIntegration as b, type BookingOption as c, type BookingOptionGroup as d, type BookingProvider as e, type BookingRules as f, type CtaClickMetadata as g, type EventCategory as h, type EventClientVisibility as i, type EventConfig as j, type EventKind as k, type EventMetadata as l, type EventName as m, type EventOutcomeRole as n, type EventSemantics as o, type FormStartMetadata as p, type FormStepConfig as q, type FormStepMetadata as r, type MultiPageSessionConfig as s, type MultiPageSessionMetadata as t, type PageExitMetadata as u, type PageIdentity as v, type PageViewConfig as w, type PageViewMetadata as x, type PhoneClickConfig as y, type PhoneClickMetadata as z };
@@ -1,5 +1,5 @@
1
1
  import * as z from 'zod/mini';
2
- import { S as SalesBookingsClient, g as ConversionConfigStore, l as TrackingConfigRuntime } from './bookings-DIu1ho6v.js';
2
+ import { S as SalesBookingsClient, g as ConversionConfigStore, l as TrackingConfigRuntime } from './bookings-B50X7GSG.js';
3
3
  import { CountryCode } from 'libphonenumber-js';
4
4
 
5
5
  /** Raw identifiers a caller may hand us (normalized before use). */
@@ -1,5 +1,5 @@
1
1
  import * as z from 'zod/mini';
2
- import { S as SalesBookingsClient, g as ConversionConfigStore, l as TrackingConfigRuntime } from './bookings-CqCuuyP6.mjs';
2
+ import { S as SalesBookingsClient, g as ConversionConfigStore, l as TrackingConfigRuntime } from './bookings-n8UUzrak.mjs';
3
3
  import { CountryCode } from 'libphonenumber-js';
4
4
 
5
5
  /** Raw identifiers a caller may hand us (normalized before use). */
package/dist/sales.d.mts CHANGED
@@ -1,5 +1,5 @@
1
- export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, C as CompareTo, d as CurrencyRevenue, e as CustomerCurrencyDelta, f as CustomerCurrencyTotal, g as CustomerGetOptions, h as CustomerGetResult, i as CustomerKpis, j as CustomerKpisDeltas, k as CustomerKpisPrevious, l as CustomerListPage, m as CustomerListQuery, n as CustomerProfile, o as CustomerSegment, p as CustomerSegmentCount, q as CustomerSortField, r as CustomerSummary, s as CustomerSummaryQuery, D as DistinctCustomersByCurrency, E as EffectiveSaleProperty, G as Granularity, N as NAMED_RANGES, t as NamedRange, P as PublicServiceItem, S as SALE_SOURCES, u as SUPPORTED_CURRENCIES, v as Sale, w as SaleBuiltinRequirableField, x as SaleCursorPage, y as SaleFilters, z as SaleInput, F as SaleItem, H as SaleItemInput, I as SaleKeysetSortField, J as SaleListPage, K as SaleListQuery, L as SaleListQueryV2, M as SalePropertyOption, O as SalePropertyType, Q as SaleService, R as SaleServiceInput, T as SaleSortField, U as SaleSortOrder, V as SaleSource, W as SaleSourceFacts, X as SaleSummary, Y as SaleSummaryPrevious, Z as SaleSummaryQuery, _ as SaleSummaryQueryV2, $ as SaleSummaryV2, a0 as SaleUpdateInput, a1 as SalesBusinessClient, a2 as SalesCategoryBreakdown, a3 as SalesClient, a4 as SalesClientConfig, a5 as SalesCustomersClient, a6 as SalesServiceBreakdown, a7 as SalesTransportConfig, a8 as SalesTrendPoint, a9 as SummaryCurrencyDelta, aa as SummaryDeltas, ab as SummaryWindow, ac as SupportedCurrency, ad as TRACKING_RANGES, ae as TrackingOverviewRange, ag as createSalesClient, ah as currencySchema, ai as fetchServices, aj as formatDateInTz, ak as formatMoney, al as fromMinor, am as saleCreateSchema, an as saleItemSchema, ao as saleServiceSchema, ap as saleUpdateSchema, aq as salesRequest, as as toMinor } from './sales-CxJVthx_.mjs';
2
- export { B as BookingDropOff, a as BookingFormSubmit, b as BookingInput, c as BookingMode, d as BookingOutcome, e as BookingSimulation, f as BookingSubmitOptions, S as SalesBookingsClient, n as newBookingAttemptKey } from './bookings-CqCuuyP6.mjs';
1
+ export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, C as CompareTo, d as CurrencyRevenue, e as CustomerCurrencyDelta, f as CustomerCurrencyTotal, g as CustomerGetOptions, h as CustomerGetResult, i as CustomerKpis, j as CustomerKpisDeltas, k as CustomerKpisPrevious, l as CustomerListPage, m as CustomerListQuery, n as CustomerProfile, o as CustomerSegment, p as CustomerSegmentCount, q as CustomerSortField, r as CustomerSummary, s as CustomerSummaryQuery, D as DistinctCustomersByCurrency, E as EffectiveSaleProperty, G as Granularity, N as NAMED_RANGES, t as NamedRange, P as PublicServiceItem, S as SALE_SOURCES, u as SUPPORTED_CURRENCIES, v as Sale, w as SaleBuiltinRequirableField, x as SaleCursorPage, y as SaleFilters, z as SaleInput, F as SaleItem, H as SaleItemInput, I as SaleKeysetSortField, J as SaleListPage, K as SaleListQuery, L as SaleListQueryV2, M as SalePropertyOption, O as SalePropertyType, Q as SaleService, R as SaleServiceInput, T as SaleSortField, U as SaleSortOrder, V as SaleSource, W as SaleSourceFacts, X as SaleSummary, Y as SaleSummaryPrevious, Z as SaleSummaryQuery, _ as SaleSummaryQueryV2, $ as SaleSummaryV2, a0 as SaleUpdateInput, a1 as SalesBusinessClient, a2 as SalesCategoryBreakdown, a3 as SalesClient, a4 as SalesClientConfig, a5 as SalesCustomersClient, a6 as SalesServiceBreakdown, a7 as SalesTransportConfig, a8 as SalesTrendPoint, a9 as SummaryCurrencyDelta, aa as SummaryDeltas, ab as SummaryWindow, ac as SupportedCurrency, ad as TRACKING_RANGES, ae as TrackingOverviewRange, ag as createSalesClient, ah as currencySchema, ai as fetchServices, aj as formatDateInTz, ak as formatMoney, al as fromMinor, am as saleCreateSchema, an as saleItemSchema, ao as saleServiceSchema, ap as saleUpdateSchema, aq as salesRequest, as as toMinor } from './sales-DByfvgzT.mjs';
2
+ export { B as BookingDropOff, a as BookingFormSubmit, b as BookingInput, c as BookingMode, d as BookingOutcome, e as BookingSimulation, f as BookingSubmitOptions, F as FormSubmitField, S as SalesBookingsClient, n as newBookingAttemptKey } from './bookings-n8UUzrak.mjs';
3
3
  import 'zod/mini';
4
4
  import 'libphonenumber-js';
5
5
  import './form-submit-BLb28aCk.mjs';
package/dist/sales.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, C as CompareTo, d as CurrencyRevenue, e as CustomerCurrencyDelta, f as CustomerCurrencyTotal, g as CustomerGetOptions, h as CustomerGetResult, i as CustomerKpis, j as CustomerKpisDeltas, k as CustomerKpisPrevious, l as CustomerListPage, m as CustomerListQuery, n as CustomerProfile, o as CustomerSegment, p as CustomerSegmentCount, q as CustomerSortField, r as CustomerSummary, s as CustomerSummaryQuery, D as DistinctCustomersByCurrency, E as EffectiveSaleProperty, G as Granularity, N as NAMED_RANGES, t as NamedRange, P as PublicServiceItem, S as SALE_SOURCES, u as SUPPORTED_CURRENCIES, v as Sale, w as SaleBuiltinRequirableField, x as SaleCursorPage, y as SaleFilters, z as SaleInput, F as SaleItem, H as SaleItemInput, I as SaleKeysetSortField, J as SaleListPage, K as SaleListQuery, L as SaleListQueryV2, M as SalePropertyOption, O as SalePropertyType, Q as SaleService, R as SaleServiceInput, T as SaleSortField, U as SaleSortOrder, V as SaleSource, W as SaleSourceFacts, X as SaleSummary, Y as SaleSummaryPrevious, Z as SaleSummaryQuery, _ as SaleSummaryQueryV2, $ as SaleSummaryV2, a0 as SaleUpdateInput, a1 as SalesBusinessClient, a2 as SalesCategoryBreakdown, a3 as SalesClient, a4 as SalesClientConfig, a5 as SalesCustomersClient, a6 as SalesServiceBreakdown, a7 as SalesTransportConfig, a8 as SalesTrendPoint, a9 as SummaryCurrencyDelta, aa as SummaryDeltas, ab as SummaryWindow, ac as SupportedCurrency, ad as TRACKING_RANGES, ae as TrackingOverviewRange, ag as createSalesClient, ah as currencySchema, ai as fetchServices, aj as formatDateInTz, ak as formatMoney, al as fromMinor, am as saleCreateSchema, an as saleItemSchema, ao as saleServiceSchema, ap as saleUpdateSchema, aq as salesRequest, as as toMinor } from './sales-hlcVTJSS.js';
2
- export { B as BookingDropOff, a as BookingFormSubmit, b as BookingInput, c as BookingMode, d as BookingOutcome, e as BookingSimulation, f as BookingSubmitOptions, S as SalesBookingsClient, n as newBookingAttemptKey } from './bookings-DIu1ho6v.js';
1
+ export { A as AranovaApiError, B as BusinessConfig, a as BusinessConfigFeatures, b as BusinessConfigService, C as CompareTo, d as CurrencyRevenue, e as CustomerCurrencyDelta, f as CustomerCurrencyTotal, g as CustomerGetOptions, h as CustomerGetResult, i as CustomerKpis, j as CustomerKpisDeltas, k as CustomerKpisPrevious, l as CustomerListPage, m as CustomerListQuery, n as CustomerProfile, o as CustomerSegment, p as CustomerSegmentCount, q as CustomerSortField, r as CustomerSummary, s as CustomerSummaryQuery, D as DistinctCustomersByCurrency, E as EffectiveSaleProperty, G as Granularity, N as NAMED_RANGES, t as NamedRange, P as PublicServiceItem, S as SALE_SOURCES, u as SUPPORTED_CURRENCIES, v as Sale, w as SaleBuiltinRequirableField, x as SaleCursorPage, y as SaleFilters, z as SaleInput, F as SaleItem, H as SaleItemInput, I as SaleKeysetSortField, J as SaleListPage, K as SaleListQuery, L as SaleListQueryV2, M as SalePropertyOption, O as SalePropertyType, Q as SaleService, R as SaleServiceInput, T as SaleSortField, U as SaleSortOrder, V as SaleSource, W as SaleSourceFacts, X as SaleSummary, Y as SaleSummaryPrevious, Z as SaleSummaryQuery, _ as SaleSummaryQueryV2, $ as SaleSummaryV2, a0 as SaleUpdateInput, a1 as SalesBusinessClient, a2 as SalesCategoryBreakdown, a3 as SalesClient, a4 as SalesClientConfig, a5 as SalesCustomersClient, a6 as SalesServiceBreakdown, a7 as SalesTransportConfig, a8 as SalesTrendPoint, a9 as SummaryCurrencyDelta, aa as SummaryDeltas, ab as SummaryWindow, ac as SupportedCurrency, ad as TRACKING_RANGES, ae as TrackingOverviewRange, ag as createSalesClient, ah as currencySchema, ai as fetchServices, aj as formatDateInTz, ak as formatMoney, al as fromMinor, am as saleCreateSchema, an as saleItemSchema, ao as saleServiceSchema, ap as saleUpdateSchema, aq as salesRequest, as as toMinor } from './sales-D4QRnpdz.js';
2
+ export { B as BookingDropOff, a as BookingFormSubmit, b as BookingInput, c as BookingMode, d as BookingOutcome, e as BookingSimulation, f as BookingSubmitOptions, F as FormSubmitField, S as SalesBookingsClient, n as newBookingAttemptKey } from './bookings-B50X7GSG.js';
3
3
  import 'zod/mini';
4
4
  import 'libphonenumber-js';
5
5
  import './form-submit-BLb28aCk.js';
package/dist/sales.js CHANGED
@@ -242,7 +242,12 @@ function getBookingIntegration(integrations) {
242
242
  timezone: booking.timezone,
243
243
  configVersion: booking.config_version,
244
244
  rules,
245
- options: booking.options.map((option) => ({ key: option.key, label: option.label })),
245
+ options: booking.options.map((option) => ({
246
+ key: option.key,
247
+ label: option.label,
248
+ group: option.group,
249
+ description: option.description
250
+ })),
246
251
  mode: booking.mode ?? "live"
247
252
  };
248
253
  }
@@ -464,7 +469,7 @@ function outcomeOf(body) {
464
469
  if (body.status === "pending") return { status: "pending", id: body.id, mode };
465
470
  return { status: "failed", id: body.id, fallbackUrl: body.fallback_url, mode };
466
471
  }
467
- function formSubmitPayload(input, formId, labels) {
472
+ function formSubmitPayload(input, formSubmit, labels) {
468
473
  const vehicle = input.vehicle ? `${input.vehicle.year} ${input.vehicle.make} ${input.vehicle.model}` : "";
469
474
  const field = (name, type, label, value) => ({
470
475
  name,
@@ -472,32 +477,31 @@ function formSubmitPayload(input, formId, labels) {
472
477
  label,
473
478
  value
474
479
  });
480
+ const fields = [
481
+ field("first_name", "text", "First name", input.firstName),
482
+ field("last_name", "text", "Last name", input.lastName),
483
+ // E.164 on the wire: it keys the customer and enhanced-conversion matching.
484
+ field("phone", "tel", "Phone", toE164(input.phone) ?? input.phone),
485
+ field("email", "email", "Email", input.email ?? ""),
486
+ field(
487
+ "service",
488
+ "select",
489
+ "Service",
490
+ input.services.map((key) => labels.get(key) ?? key).join(", ")
491
+ ),
492
+ field("vehicle", "text", "Vehicle", vehicle),
493
+ field(
494
+ "start",
495
+ "text",
496
+ "Requested time",
497
+ `${input.startDate} ${String(input.startHour).padStart(2, "0")}:00`
498
+ ),
499
+ field("note", "textarea", "Notes", input.notes ?? "")
500
+ ];
501
+ const reported = new Set(fields.map((item) => item.name));
502
+ const extra = (formSubmit.extraFields ?? []).filter((item) => !reported.has(item.name));
475
503
  return {
476
- form: {
477
- id: formId,
478
- action: "/tracking/bookings",
479
- fields: [
480
- field("first_name", "text", "First name", input.firstName),
481
- field("last_name", "text", "Last name", input.lastName),
482
- // E.164 on the wire: it keys the customer and enhanced-conversion matching.
483
- field("phone", "tel", "Phone", toE164(input.phone) ?? input.phone),
484
- field("email", "email", "Email", input.email ?? ""),
485
- field(
486
- "service",
487
- "select",
488
- "Service",
489
- input.services.map((key) => labels.get(key) ?? key).join(", ")
490
- ),
491
- field("vehicle", "text", "Vehicle", vehicle),
492
- field(
493
- "start",
494
- "text",
495
- "Requested time",
496
- `${input.startDate} ${String(input.startHour).padStart(2, "0")}:00`
497
- ),
498
- field("note", "textarea", "Notes", input.notes ?? "")
499
- ]
500
- },
504
+ form: { id: formSubmit.formId, action: "/tracking/bookings", fields: [...fields, ...extra] },
501
505
  page: { path: typeof window === "undefined" ? "/" : window.location.pathname }
502
506
  };
503
507
  }
@@ -585,7 +589,7 @@ function createSalesBookingsClient(config, firing) {
585
589
  return failedBeforeSend(input);
586
590
  }
587
591
  return {
588
- async submit(input, { attemptKey, formSubmit, simulate }) {
592
+ async submit(input, { attemptKey, formSubmit, simulate, onPending }) {
589
593
  registerCapability("booking_integration");
590
594
  const runtime = runtimeOf(firing);
591
595
  warnOnSetupMismatch(runtime);
@@ -596,10 +600,7 @@ function createSalesBookingsClient(config, firing) {
596
600
  if (formSubmit && !submittedForms.has(attemptKey)) {
597
601
  submittedForms.add(attemptKey);
598
602
  const labels = new Map(booking.options.map((option) => [option.key, option.label]));
599
- formSubmit.tracking.trackEvent(
600
- "form_submit",
601
- formSubmitPayload(input, formSubmit.formId, labels)
602
- );
603
+ formSubmit.tracking.trackEvent("form_submit", formSubmitPayload(input, formSubmit, labels));
603
604
  }
604
605
  const body = {
605
606
  idempotency_key: attemptKey,
@@ -633,10 +634,9 @@ function createSalesBookingsClient(config, firing) {
633
634
  return rejected(error, input, attemptKey, runtime);
634
635
  }
635
636
  const outcome = outcomeOf(response);
636
- return withHandoff(
637
- outcome.status === "pending" ? await poll(outcome.id, outcome.mode) : outcome,
638
- input
639
- );
637
+ if (outcome.status !== "pending") return withHandoff(outcome, input);
638
+ onPending?.(outcome);
639
+ return withHandoff(await poll(outcome.id, outcome.mode), input);
640
640
  },
641
641
  async status(id) {
642
642
  return outcomeOf(