@aranova/tracking-react 1.9.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -366,11 +366,15 @@ await submit({
366
366
  form's own questions with `formSubmit.extraFields`; a name the booking already reports
367
367
  (`phone`, `email`, ...) is dropped.
368
368
  - Ask for the last name separately, and a mobile number (the shop's confirmation text goes to it).
369
- - Details after booking (when `booking.rules.vehicleDeferred`, or for extra notes):
370
- `updateBooking({ vehicle, notes })` from the same hook. It resolves `updated` / `queued` /
369
+ - Details after booking (when `booking.rules.vehicleDeferred`, for extra notes, or for the site's
370
+ own "How did you hear about us?" answer):
371
+ `updateBooking({ vehicle, notes, heardVia })` from the same hook. It resolves `updated` / `queued` /
371
372
  `notified_owner` (all saved) or `invalid`, `mismatch`, `conflict`, `not_found`, `failed`
372
373
  (only `failed` is worth a retry). To survive a reload, save `booked` (`{ bookingId, attemptKey }`)
373
- in `sessionStorage` and pass it back: `updateBooking(details, saved)`.
374
+ in `sessionStorage` and pass it back: `updateBooking(details, saved)`. `heardVia` is reporting-only
375
+ and never reaches the shop; it takes the same values as the form's `heardVia` `form_submit` field,
376
+ so asking it on the success screen instead of the form reports the same. One update per booking,
377
+ so send it with a deferred vehicle rather than in a second call.
374
378
  - Reports the `booking_integration` capability.
375
379
 
376
380
  ## On-site conversion firing
@@ -1,4 +1,4 @@
1
- import { a as FormSubmitMetadata } from './form-submit-BLb28aCk.mjs';
1
+ import { a as FormSubmitMetadata } from './form-submit-CX-CxJjQ.mjs';
2
2
 
3
3
  interface ServiceFiring {
4
4
  send_to: string;
@@ -45,6 +45,12 @@ interface ConversionConfig {
45
45
  linked_hostnames?: string[];
46
46
  /** Third-party integrations the site renders UI for; a missing provider means none. */
47
47
  integrations?: ConversionIntegrations;
48
+ /** The lead-form contract (ADR-0024); null from an API that predates it. */
49
+ lead_forms?: LeadFormsConfig | null;
50
+ }
51
+ interface LeadFormsConfig {
52
+ /** The registry version the object was published under. */
53
+ registry_version: number;
48
54
  }
49
55
  /** Bookable start hours on one weekday, shop wall time (8 = 08:00); both empty = closed. */
50
56
  interface BookingDayWindows {
@@ -284,6 +290,12 @@ interface BookingDetailsInput {
284
290
  model: string;
285
291
  } | null;
286
292
  notes?: string | null;
293
+ /**
294
+ * The site's own "How did you hear about us?" answer, verbatim — the same values the form's
295
+ * `form_submit` `heardVia` field carries, so one answer reports the same whether it is asked
296
+ * on the form or on the success screen. Ours for reporting: never sent to the shop.
297
+ */
298
+ heardVia?: string | null;
287
299
  }
288
300
  interface BookingDetailsOptions {
289
301
  /** The `attemptKey` the booking was submitted with; only that submit may add to it. */
@@ -416,8 +428,9 @@ interface SalesBookingsClient {
416
428
  /** A booking's current status by the id `submit` returned. */
417
429
  status(id: string): Promise<BookingOutcome>;
418
430
  /**
419
- * Add the vehicle or notes after booking (e.g. `rules.vehicleDeferred`). Pass the booking's
420
- * own `attemptKey`. Never rejects: they reach the shop's request, or the owner by text.
431
+ * Add the vehicle, notes or "How did you hear about us?" after booking (e.g.
432
+ * `rules.vehicleDeferred`, or an answer asked on the success screen). Pass the booking's own
433
+ * `attemptKey`. Never rejects: they reach the shop's request, or the owner by text.
421
434
  */
422
435
  updateBooking(bookingId: string, details: BookingDetailsInput, options: BookingDetailsOptions): Promise<BookingDetailsOutcome>;
423
436
  }
@@ -1,4 +1,4 @@
1
- import { a as FormSubmitMetadata } from './form-submit-BLb28aCk.js';
1
+ import { a as FormSubmitMetadata } from './form-submit-CX-CxJjQ.js';
2
2
 
3
3
  interface ServiceFiring {
4
4
  send_to: string;
@@ -45,6 +45,12 @@ interface ConversionConfig {
45
45
  linked_hostnames?: string[];
46
46
  /** Third-party integrations the site renders UI for; a missing provider means none. */
47
47
  integrations?: ConversionIntegrations;
48
+ /** The lead-form contract (ADR-0024); null from an API that predates it. */
49
+ lead_forms?: LeadFormsConfig | null;
50
+ }
51
+ interface LeadFormsConfig {
52
+ /** The registry version the object was published under. */
53
+ registry_version: number;
48
54
  }
49
55
  /** Bookable start hours on one weekday, shop wall time (8 = 08:00); both empty = closed. */
50
56
  interface BookingDayWindows {
@@ -284,6 +290,12 @@ interface BookingDetailsInput {
284
290
  model: string;
285
291
  } | null;
286
292
  notes?: string | null;
293
+ /**
294
+ * The site's own "How did you hear about us?" answer, verbatim — the same values the form's
295
+ * `form_submit` `heardVia` field carries, so one answer reports the same whether it is asked
296
+ * on the form or on the success screen. Ours for reporting: never sent to the shop.
297
+ */
298
+ heardVia?: string | null;
287
299
  }
288
300
  interface BookingDetailsOptions {
289
301
  /** The `attemptKey` the booking was submitted with; only that submit may add to it. */
@@ -416,8 +428,9 @@ interface SalesBookingsClient {
416
428
  /** A booking's current status by the id `submit` returned. */
417
429
  status(id: string): Promise<BookingOutcome>;
418
430
  /**
419
- * Add the vehicle or notes after booking (e.g. `rules.vehicleDeferred`). Pass the booking's
420
- * own `attemptKey`. Never rejects: they reach the shop's request, or the owner by text.
431
+ * Add the vehicle, notes or "How did you hear about us?" after booking (e.g.
432
+ * `rules.vehicleDeferred`, or an answer asked on the success screen). Pass the booking's own
433
+ * `attemptKey`. Never rejects: they reach the shop's request, or the owner by text.
421
434
  */
422
435
  updateBooking(bookingId: string, details: BookingDetailsInput, options: BookingDetailsOptions): Promise<BookingDetailsOutcome>;
423
436
  }
package/dist/client.d.mts CHANGED
@@ -1,10 +1,10 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, CSSProperties, InputHTMLAttributes, ChangeEvent, FocusEvent, AnchorHTMLAttributes } from 'react';
3
- import { G as GtagEnvironmentMap, M as MetaPixelEnvironmentMap, h as ConsentState, f as ConsentChoiceState, g as ConsentSource, T as TrackingParams, b as TrackingEnvironment, j as PhoneConfig, P as ParsedPhone, k as PhoneDisplayFormat } from './phone-utils-CM8eUPz8.mjs';
4
- import { T as TrackingConfigReference, C as ConversionConfig, i as BookingOutcome, g as BookingInput, a as BookingDetailsInput, c as BookingDetailsOutcome, S as SalesBookingsClient, f as BookingFormSubmit, j as BookingSimulation } from './bookings-DtcwdM_I.mjs';
5
- import { X as TriggerRegistryConfig, Z as TypedTrackingClient, a as BookingHandoffPrefill, b as BookingIntegration, B as BookableDay } from './ingest-typed-C2OvZ7dp.mjs';
3
+ import { G as GtagEnvironmentMap, M as MetaPixelEnvironmentMap, h as ConsentState, f as ConsentChoiceState, g as ConsentSource, T as TrackingParams, b as TrackingEnvironment, j as PhoneConfig, P as ParsedPhone, k as PhoneDisplayFormat } from './phone-utils-BNiSqeF7.mjs';
4
+ import { T as TrackingConfigReference, C as ConversionConfig, i as BookingOutcome, g as BookingInput, a as BookingDetailsInput, c as BookingDetailsOutcome, S as SalesBookingsClient, f as BookingFormSubmit, j as BookingSimulation } from './bookings-BnXZGgwr.mjs';
5
+ import { X as TriggerRegistryConfig, Z as TypedTrackingClient, a as BookingHandoffPrefill, b as BookingIntegration, B as BookableDay } from './ingest-typed-TI6KqVzL.mjs';
6
6
  import { CountryCode } from 'libphonenumber-js';
7
- import './form-submit-BLb28aCk.mjs';
7
+ import './form-submit-CX-CxJjQ.mjs';
8
8
  import 'zod/mini';
9
9
  import 'zod/v4/core';
10
10
 
@@ -418,8 +418,8 @@ interface BookingSubmitState {
418
418
  */
419
419
  booked: BookedAttempt | null;
420
420
  /**
421
- * Add the vehicle or notes to `booked`, or to `target` (a persisted one). Resolves `not_found`
422
- * when there is neither.
421
+ * Add the vehicle, notes or "How did you hear about us?" to `booked`, or to `target` (a
422
+ * persisted one). Resolves `not_found` when there is neither.
423
423
  */
424
424
  updateBooking(details: BookingDetailsInput, target?: BookedAttempt): Promise<BookingDetailsOutcome>;
425
425
  /** Back to `idle` with a fresh attempt key, e.g. "book another car". */
package/dist/client.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode, CSSProperties, InputHTMLAttributes, ChangeEvent, FocusEvent, AnchorHTMLAttributes } from 'react';
3
- import { G as GtagEnvironmentMap, M as MetaPixelEnvironmentMap, h as ConsentState, f as ConsentChoiceState, g as ConsentSource, T as TrackingParams, b as TrackingEnvironment, j as PhoneConfig, P as ParsedPhone, k as PhoneDisplayFormat } from './phone-utils-l8ey3Zdm.js';
4
- import { T as TrackingConfigReference, C as ConversionConfig, i as BookingOutcome, g as BookingInput, a as BookingDetailsInput, c as BookingDetailsOutcome, S as SalesBookingsClient, f as BookingFormSubmit, j as BookingSimulation } from './bookings-Bx7totlS.js';
5
- import { X as TriggerRegistryConfig, Z as TypedTrackingClient, a as BookingHandoffPrefill, b as BookingIntegration, B as BookableDay } from './ingest-typed-B-BgEZdW.js';
3
+ import { G as GtagEnvironmentMap, M as MetaPixelEnvironmentMap, h as ConsentState, f as ConsentChoiceState, g as ConsentSource, T as TrackingParams, b as TrackingEnvironment, j as PhoneConfig, P as ParsedPhone, k as PhoneDisplayFormat } from './phone-utils-D12FW8tT.js';
4
+ import { T as TrackingConfigReference, C as ConversionConfig, i as BookingOutcome, g as BookingInput, a as BookingDetailsInput, c as BookingDetailsOutcome, S as SalesBookingsClient, f as BookingFormSubmit, j as BookingSimulation } from './bookings-vM_aCNOS.js';
5
+ import { X as TriggerRegistryConfig, Z as TypedTrackingClient, a as BookingHandoffPrefill, b as BookingIntegration, B as BookableDay } from './ingest-typed-BS9agXM5.js';
6
6
  import { CountryCode } from 'libphonenumber-js';
7
- import './form-submit-BLb28aCk.js';
7
+ import './form-submit-CX-CxJjQ.js';
8
8
  import 'zod/mini';
9
9
  import 'zod/v4/core';
10
10
 
@@ -418,8 +418,8 @@ interface BookingSubmitState {
418
418
  */
419
419
  booked: BookedAttempt | null;
420
420
  /**
421
- * Add the vehicle or notes to `booked`, or to `target` (a persisted one). Resolves `not_found`
422
- * when there is neither.
421
+ * Add the vehicle, notes or "How did you hear about us?" to `booked`, or to `target` (a
422
+ * persisted one). Resolves `not_found` when there is neither.
423
423
  */
424
424
  updateBooking(details: BookingDetailsInput, target?: BookedAttempt): Promise<BookingDetailsOutcome>;
425
425
  /** Back to `idle` with a fresh attempt key, e.g. "book another car". */
package/dist/client.js CHANGED
@@ -1128,9 +1128,15 @@ function parseConversionConfig(raw) {
1128
1128
  services,
1129
1129
  goals,
1130
1130
  linked_hostnames: Array.isArray(obj.linked_hostnames) ? obj.linked_hostnames.filter((h) => typeof h === "string" && h.length > 0) : [],
1131
- integrations: parseIntegrations(obj.integrations)
1131
+ integrations: parseIntegrations(obj.integrations),
1132
+ lead_forms: parseLeadForms(obj.lead_forms)
1132
1133
  };
1133
1134
  }
1135
+ function parseLeadForms(value) {
1136
+ if (!value || typeof value !== "object") return null;
1137
+ const version2 = value.registry_version;
1138
+ return typeof version2 === "number" ? { registry_version: version2 } : null;
1139
+ }
1134
1140
  var CACHE_PREFIX = "_aranova_cfg_";
1135
1141
  function cacheKey(url) {
1136
1142
  return `${CACHE_PREFIX}${url}`;
@@ -2711,6 +2717,7 @@ var jsonValueSchema = z7.lazy(
2711
2717
  z7.record(z7.string(), jsonValueSchema)
2712
2718
  ])
2713
2719
  ).register(z7.globalRegistry, { id: "JsonSerializableValue" });
2720
+ var contractName = z7.string().check(z7.regex(/^[a-z][a-z0-9_]{0,47}(:[a-z0-9_-]{1,48})?$/));
2714
2721
  var formSubmitMetadataSchema = z7.strictObject({
2715
2722
  form: z7.strictObject({
2716
2723
  id: z7.string(),
@@ -2721,9 +2728,24 @@ var formSubmitMetadataSchema = z7.strictObject({
2721
2728
  name: z7.string(),
2722
2729
  type: z7.string(),
2723
2730
  label: z7.nullable(z7.string()),
2724
- value: jsonValueSchema
2731
+ value: jsonValueSchema,
2732
+ role: z7.optional(z7.nullable(contractName))
2725
2733
  })
2726
2734
  )
2735
+ ),
2736
+ kind: z7.optional(z7.nullable(contractName)),
2737
+ contract_version: z7.optional(z7.nullable(z7.int().check(z7.gte(1)))),
2738
+ contract_hash: z7.optional(z7.nullable(z7.string().check(z7.maxLength(64)))),
2739
+ extra: z7.optional(
2740
+ z7.nullable(
2741
+ z7.array(
2742
+ z7.strictObject({
2743
+ key: z7.string().check(z7.maxLength(64)),
2744
+ label: z7.string().check(z7.maxLength(200)),
2745
+ value: jsonValueSchema
2746
+ })
2747
+ ).check(z7.maxLength(20))
2748
+ )
2727
2749
  )
2728
2750
  }),
2729
2751
  page: z7.strictObject({
@@ -4009,7 +4031,7 @@ function GoogleAdsTracking(props) {
4009
4031
  var import_react6 = require("react");
4010
4032
 
4011
4033
  // package.json
4012
- var version = "1.9.0";
4034
+ var version = "1.11.0";
4013
4035
 
4014
4036
  // ../tracking-core/src/phone-react.tsx
4015
4037
  var import_react5 = require("react");