@aranova/tracking-next 0.24.1 → 0.26.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,5 @@
1
1
  import { z } from 'zod';
2
+ import { a as ConversionConfigStore, c as TrackingConfigRuntime } from './tracking-config-runtime-BnUlS_Ae.js';
2
3
  import { CountryCode } from 'libphonenumber-js';
3
4
  import { A as ApiTransportConfig, a as apiRequest } from './request-Doq36Rt0.js';
4
5
  import './date-BHetnL7s.js';
@@ -13,195 +14,6 @@ declare function stashUserData(data: ConversionUserData, country?: CountryCode):
13
14
  /** Drop everything (consent denial, tests). */
14
15
  declare function clearStashedUserData(): void;
15
16
 
16
- interface ServiceFiring {
17
- send_to: string;
18
- /** Action's configured default value (cents); the SDK fires it only when a sale has no amount. */
19
- value_cents?: number | null;
20
- currency?: string | null;
21
- }
22
- /** Serializable on-page trigger (owned by tracking-core/src/events/trigger-spec.ts). The shape
23
- * varies by `event_type`; only the parameter for that type is set. */
24
- interface ConfigTriggerSpec {
25
- event_type: string;
26
- threshold_percent?: number;
27
- threshold_seconds?: number;
28
- page_threshold?: number;
29
- page_name?: string;
30
- }
31
- /** One unified conversion goal: a revenue `sale` or an on-page `event`. */
32
- interface ConversionGoal {
33
- key: string;
34
- label?: string;
35
- kind: "sale" | "event";
36
- /** Structured fire-when for event-goals; null for sales. */
37
- trigger: ConfigTriggerSpec | null;
38
- firing: ServiceFiring | null;
39
- }
40
- interface ConversionConfig {
41
- schema_version: number;
42
- config_version: number;
43
- business_id?: string;
44
- customer_id?: string | null;
45
- environment?: string;
46
- google_tracking_state: "active" | "disabled";
47
- gtag_ids: Record<string, string>;
48
- meta_pixel_ids: Record<string, string>;
49
- /** LEGACY: sale-goals only (for pre-unified-goal readers). */
50
- services: Array<{
51
- key: string;
52
- label?: string;
53
- firing: ServiceFiring | null;
54
- }>;
55
- /** Unified goal list (sales + on-page events). Superset of `services`. */
56
- goals: ConversionGoal[];
57
- }
58
- interface ConversionConfigStore {
59
- /** Firing config for a goal/service key, or null when it doesn't fire on-site. */
60
- getFiring(key: string): ServiceFiring | null;
61
- /** The full goal for a key, or null when unknown. */
62
- getGoal(key: string): ConversionGoal | null;
63
- /** Every adopted goal (sales + events). */
64
- listGoals(): ConversionGoal[];
65
- /** The currently adopted config (baked / cached fallback until the fetch lands). */
66
- current(): ConversionConfig | null;
67
- /** True once a config is adopted (seeded synchronously from cache/baked, or fetched). */
68
- isReady(): boolean;
69
- /**
70
- * Run `listener` when a config first becomes available — immediately if already
71
- * ready, otherwise on the first adopt. Lets auto-fire replay automatic events that
72
- * occurred before the async CDN fetch resolved. Returns an unsubscribe fn.
73
- */
74
- onResolve(listener: () => void): () => void;
75
- /** Force a background revalidate against the CDN object. */
76
- revalidate(): Promise<void>;
77
- }
78
- interface ResolveConversionConfigOptions {
79
- /** Full URL of the per-business CDN object. */
80
- cdnUrl: string;
81
- /** Offline-correct fallback (e.g. the CLI-baked snapshot). */
82
- baked?: ConversionConfig | null;
83
- /** Injectable for tests / non-global-fetch runtimes. */
84
- fetchImpl?: typeof fetch;
85
- }
86
- /**
87
- * Resolve the config with stale-while-revalidate: seed synchronously from the
88
- * sessionStorage cache (or the baked fallback), then conditionally re-fetch the CDN object
89
- * with `If-None-Match`. A fetched object is adopted only if its `config_version` is strictly
90
- * greater than what's cached, so a reordered edge copy can't downgrade fresher state.
91
- * Non-blocking and browser-only; a failed fetch leaves the seed in place.
92
- */
93
- declare function resolveConversionConfig(options: ResolveConversionConfigOptions): ConversionConfigStore;
94
-
95
- /**
96
- * Where a business's published tracking config lives.
97
- *
98
- * `businessId` + `environment` are the stable identity; the ORIGIN it is fetched
99
- * from is deployment-specific (production CDN vs. a local object store), which is
100
- * why `cdnBaseUrl` exists. Codegen bakes only the identity, so one committed
101
- * generated file works in every environment and only an env var changes.
102
- *
103
- * `cdnUrl` remains supported and WINS when present — every client repo generated
104
- * before `cdnBaseUrl` passes one, and those must keep working untouched.
105
- */
106
- interface TrackingConfigReference {
107
- /**
108
- * Fully-resolved object URL. Optional: omit it and pass `cdnBaseUrl` (or rely
109
- * on the production default) to have it composed from the identity below.
110
- */
111
- cdnUrl?: string;
112
- /**
113
- * Origin (optionally with a path prefix) the config object is served from, e.g.
114
- * `https://demos.aranova.io` in production or
115
- * `http://localhost:9100/aranova-demos` against a local MinIO. Ignored when
116
- * `cdnUrl` is set; blank or omitted falls back to {@link DEFAULT_CDN_BASE_URL}.
117
- * `tracking-cli gen` wires this to an env var so retargeting is config, not code.
118
- */
119
- cdnBaseUrl?: string;
120
- businessId: string;
121
- environment: "production" | "test";
122
- }
123
- /**
124
- * The URL a reference resolves to. An explicit `cdnUrl` wins (back-compat);
125
- * otherwise compose from `cdnBaseUrl` (or the production default).
126
- *
127
- * A blank/whitespace `cdnBaseUrl` is treated as UNSET rather than composed: the
128
- * generated module reads it from an env var, and a var that is present-but-empty
129
- * (a stray `NEXT_PUBLIC_ARANOVA_CDN_BASE_URL=` line) would otherwise produce
130
- * `/tracking-config/...` — a same-origin request to the client's own site.
131
- */
132
- declare function resolveTrackingConfigUrl(ref: TrackingConfigReference): string;
133
- type RuntimeState = "unconfirmed" | "active" | "tombstone";
134
- interface QueuedConversion {
135
- key: string;
136
- value?: number | null;
137
- currency?: string | null;
138
- transactionId?: string | null;
139
- }
140
- type TrackingConfigConversionOptions = Omit<QueuedConversion, "key">;
141
- interface QueuedPageView {
142
- href: string;
143
- title: string | null;
144
- referrer: string | null;
145
- }
146
- declare class TrackingConfigRuntime {
147
- readonly ref: TrackingConfigReference;
148
- private readonly fetchImpl;
149
- /** Resolved config URL — see the constructor for why it is computed once. */
150
- private readonly url;
151
- private current;
152
- private etag;
153
- private stateValue;
154
- private confirmedAt;
155
- private authorityGeneration;
156
- private inFlight;
157
- private flushInFlight;
158
- private flushRequested;
159
- private retryTimer;
160
- private started;
161
- /** Consecutive failed authority attempts — drives the revalidate backoff. */
162
- private authorityFailures;
163
- /** Epoch ms before which `ensureAuthority` must not issue another request. */
164
- private nextAuthorityAttemptAt;
165
- private readonly conversionQueue;
166
- private readonly automaticQueue;
167
- private readonly pageQueue;
168
- private readonly listeners;
169
- constructor(ref: TrackingConfigReference, fetchImpl?: typeof fetch);
170
- /** The URL this runtime actually fetches (composed or explicit). */
171
- configUrl(): string;
172
- /**
173
- * Explicitly start authority resolution and Google-tag bootstrap.
174
- *
175
- * Idempotent so framework effects can call it after hydration without
176
- * depending on constructor timing.
177
- */
178
- start(): void;
179
- state(): RuntimeState;
180
- config(): ConversionConfig | null;
181
- __unsafeExpireAuthorityForTests(): void;
182
- /** Queue depths — asserted by tests to pin the bound. */
183
- __queueDepthsForTests(): {
184
- conversions: number;
185
- automatic: number;
186
- pages: number;
187
- };
188
- subscribe(listener: () => void): () => void;
189
- ensureAuthority(): Promise<boolean>;
190
- revalidate(): Promise<void>;
191
- private revalidateAuthority;
192
- queuePageView(snapshot?: QueuedPageView | null): void;
193
- fireConversion(key: string, options?: TrackingConfigConversionOptions): void;
194
- queueAutomaticEvent(eventType: string, metadata: Record<string, unknown>, transactionPath: string, transactionScope: string): void;
195
- listGoals(): ConversionGoal[];
196
- private revalidateNow;
197
- private expireAuthority;
198
- private confirm;
199
- private flush;
200
- private scheduleRetry;
201
- private flushNow;
202
- }
203
- declare function getTrackingConfigRuntime(ref: TrackingConfigReference, fetchImpl?: typeof fetch): TrackingConfigRuntime;
204
-
205
17
  /**
206
18
  * Sales / Conversions wire schemas — the client-side source of truth.
207
19
  *
@@ -584,6 +396,12 @@ interface Sale {
584
396
  updated_at: string;
585
397
  items: SaleItem[];
586
398
  }
399
+ /**
400
+ * The offset page shape returned by the internal admin list, which this client
401
+ * never calls (`list()` is keyset and returns {@link SaleCursorPage}).
402
+ *
403
+ * @deprecated Unused by this client — no verb returns or accepts it. Kept for one release; removed in the next major.
404
+ */
587
405
  interface SaleListPage {
588
406
  items: Sale[];
589
407
  total: number;
@@ -596,9 +414,10 @@ interface SaleCursorPage {
596
414
  has_more?: boolean;
597
415
  }
598
416
  /**
599
- * Sortable columns on the secret-key (keyset) and admin (offset) list endpoints.
600
- * `business_name` only applies to the cross-business admin list — it sorts the
601
- * joined `businesses.name` column.
417
+ * Sortable columns on the internal admin (offset) list. `list()` is typed to
418
+ * {@link SaleKeysetSortField}, which omits `customer_name` and `business_name`.
419
+ *
420
+ * @deprecated Unused by this client — no verb returns or accepts it. Kept for one release; removed in the next major.
602
421
  */
603
422
  type SaleSortField = "occurred_at" | "created_at" | "amount_total_cents" | "customer_name" | "business_name";
604
423
  type SaleSortOrder = "asc" | "desc";
@@ -630,10 +449,13 @@ interface SaleFilters {
630
449
  * Pagination is **keyset (cursor)**: `next_cursor` returned by one page is
631
450
  * passed back as `cursor` on the next. `null` / undefined cursor = first page.
632
451
  *
633
- * Ordering on this endpoint is fixed at **`occurred_at DESC, id DESC`** — the
634
- * cursor encodes a position in that index, so a different sort would
635
- * invalidate cursors mid-pagination. For ad-hoc sorted reads use the
636
- * dashboard admin endpoint, which is offset-paginated.
452
+ * Ordering is selectable via `sort`/`order` on {@link SaleListQueryV2}. A cursor
453
+ * encodes a position under the sort it was minted with, so replaying it under a
454
+ * different sort is rejected (422) — page with the sort you started with.
455
+ */
456
+ /**
457
+ * @deprecated Superseded by {@link SaleListQueryV2}, which is what `list()` accepts.
458
+ * Its ordering note was also stale — `sort`/`order` are supported. Removed in the next major.
637
459
  */
638
460
  interface SaleListQuery extends SaleFilters {
639
461
  limit?: number;
@@ -651,6 +473,10 @@ interface SaleListQueryV2 extends SaleListQuery {
651
473
  declare const TRACKING_RANGES: readonly ["24h", "7d", "30d"];
652
474
  type TrackingOverviewRange = (typeof TRACKING_RANGES)[number];
653
475
  /** Query input for `SalesClient.summary()` — filters + range + options. */
476
+ /**
477
+ * @deprecated The v1 summary query. `summary()` accepts {@link SaleSummaryQueryV2};
478
+ * the v1 endpoint no longer exists. Removed in the next major.
479
+ */
654
480
  interface SaleSummaryQuery extends SaleFilters {
655
481
  range: TrackingOverviewRange;
656
482
  /** Include the per-category line-item breakdown (extra join; default false). */
@@ -690,6 +516,10 @@ interface SalesTrendPoint {
690
516
  sale_count: number;
691
517
  revenue_cents: number;
692
518
  }
519
+ /**
520
+ * @deprecated The v1 summary response. `summary()` returns {@link SaleSummaryV2};
521
+ * the v1 endpoint no longer exists. Removed in the next major.
522
+ */
693
523
  interface SaleSummary {
694
524
  range: TrackingOverviewRange;
695
525
  business_id: string | null;
@@ -862,6 +692,23 @@ interface BusinessConfigFeatures {
862
692
  comparisons: boolean;
863
693
  retention: boolean;
864
694
  }
695
+ /** A built-in customer field a business can require on every sale. */
696
+ type SaleBuiltinRequirableField = "customer_name" | "customer_phone" | "customer_email" | "description";
697
+ /** v1 value types. `enum` is single-select over the property's `options`. */
698
+ type SalePropertyType = "string" | "number" | "boolean" | "enum" | "date";
699
+ interface SalePropertyOption {
700
+ key: string;
701
+ label: string;
702
+ }
703
+ /** One custom sale property as the sale form sees it: overrides applied, options
704
+ * already filtered to the business's enabled subset. */
705
+ interface EffectiveSaleProperty {
706
+ key: string;
707
+ label: string;
708
+ type: SalePropertyType;
709
+ required: boolean;
710
+ options?: SalePropertyOption[] | null;
711
+ }
865
712
  interface BusinessConfig {
866
713
  business_id: string;
867
714
  display_name: string;
@@ -871,6 +718,11 @@ interface BusinessConfig {
871
718
  default_phone_country: string | null;
872
719
  services: BusinessConfigService[];
873
720
  features: BusinessConfigFeatures;
721
+ builtin_required: SaleBuiltinRequirableField[];
722
+ properties: EffectiveSaleProperty[];
723
+ /** Whether the form should pre-tick the SMS consent box. A form default only —
724
+ * the per-sale `sms_consent` attestation is what every send path gates on. */
725
+ sms_consent_default_opt_in: boolean;
874
726
  }
875
727
 
876
728
  type SalesTransportConfig = ApiTransportConfig;
@@ -921,10 +773,10 @@ interface SalesClient<TService extends string = string, TConversion extends stri
921
773
  occurred_at?: string;
922
774
  }): Promise<Sale>;
923
775
  /**
924
- * Record a revenue sale — the intent-revealing alias of {@link record} in the unified-goal
925
- * API. POSTs `/sales` and ALSO fires the on-site conversion when the sale-goal is
926
- * WEBPAGE-mapped. Use this for anything with real revenue; use {@link trackConversion} for a
927
- * non-revenue on-page event.
776
+ * Record a revenue sale — the intent-revealing alias of {@link record}. Identical
777
+ * behavior (same function reference): POSTs `/sales` and fires the on-site conversion
778
+ * when the sale-goal is WEBPAGE-mapped. Use either for real revenue; use
779
+ * {@link trackConversion} for a non-revenue on-page event.
928
780
  */
929
781
  recordSale(input: Omit<SaleInput, "currency" | "occurred_at" | "service" | "services"> & {
930
782
  service?: TService | null;
@@ -1005,4 +857,4 @@ interface PublicServiceItem {
1005
857
  */
1006
858
  declare function fetchServices(config: SalesTransportConfig): Promise<PublicServiceItem[]>;
1007
859
 
1008
- export { type SalesClientConfig as $, type SaleItem as A, type BusinessConfig as B, type ConversionConfig as C, type DistinctCustomersByCurrency as D, type SaleItemInput as E, type SaleKeysetSortField as F, type Granularity as G, type SaleListPage as H, type SaleListQuery as I, type SaleListQueryV2 as J, type SaleService as K, type SaleServiceInput as L, type SaleSortField as M, NAMED_RANGES as N, type SaleSortOrder as O, type PublicServiceItem as P, type SaleSummary as Q, type SaleSummaryPrevious as R, SUPPORTED_CURRENCIES as S, type TrackingConfigReference as T, type SaleSummaryQuery as U, type SaleSummaryQueryV2 as V, type SaleSummaryV2 as W, type SaleUpdateInput as X, type SalesBusinessClient as Y, type SalesCategoryBreakdown as Z, type SalesClient as _, type BusinessConfigFeatures as a, type SalesCustomersClient as a0, type SalesServiceBreakdown as a1, type SalesTransportConfig as a2, type SalesTrendPoint as a3, type SummaryCurrencyDelta as a4, type SummaryDeltas as a5, type SummaryWindow as a6, type SupportedCurrency as a7, TRACKING_RANGES as a8, type TrackingOverviewRange as a9, clearStashedUserData as aa, createSalesClient as ab, fetchServices as ac, formatMoney as ad, fromMinor as ae, getTrackingConfigRuntime as af, resolveConversionConfig as ag, resolveTrackingConfigUrl as ah, saleCreateSchema as ai, saleItemSchema as aj, saleServiceSchema as ak, saleUpdateSchema as al, salesRequest as am, stashUserData as an, toMinor as ao, type BusinessConfigService as b, type CompareTo as c, type ConversionConfigStore as d, type ConversionUserData as e, type CurrencyRevenue as f, type CustomerCurrencyDelta as g, type CustomerCurrencyTotal as h, type CustomerGetOptions as i, type CustomerGetResult as j, type CustomerKpis as k, type CustomerKpisDeltas as l, type CustomerKpisPrevious as m, type CustomerListPage as n, type CustomerListQuery as o, type CustomerProfile as p, type CustomerSegment as q, type CustomerSegmentCount as r, type CustomerSortField as s, type CustomerSummary as t, type CustomerSummaryQuery as u, type NamedRange as v, type Sale as w, type SaleCursorPage as x, type SaleFilters as y, type SaleInput as z };
860
+ export { type SalesClient as $, type SaleItemInput as A, type BusinessConfig as B, type CompareTo as C, type DistinctCustomersByCurrency as D, type EffectiveSaleProperty as E, type SaleKeysetSortField as F, type Granularity as G, type SaleListPage as H, type SaleListQuery as I, type SaleListQueryV2 as J, type SalePropertyOption as K, type SalePropertyType as L, type SaleService as M, NAMED_RANGES as N, type SaleServiceInput as O, type PublicServiceItem as P, type SaleSortField as Q, type SaleSortOrder as R, SUPPORTED_CURRENCIES as S, type SaleSummary as T, type SaleSummaryPrevious as U, type SaleSummaryQuery as V, type SaleSummaryQueryV2 as W, type SaleSummaryV2 as X, type SaleUpdateInput as Y, type SalesBusinessClient as Z, type SalesCategoryBreakdown as _, type BusinessConfigFeatures as a, type SalesClientConfig as a0, type SalesCustomersClient as a1, type SalesServiceBreakdown as a2, type SalesTransportConfig as a3, type SalesTrendPoint as a4, type SummaryCurrencyDelta as a5, type SummaryDeltas as a6, type SummaryWindow as a7, type SupportedCurrency as a8, TRACKING_RANGES as a9, type TrackingOverviewRange as aa, clearStashedUserData as ab, createSalesClient as ac, fetchServices as ad, formatMoney as ae, fromMinor as af, saleCreateSchema as ag, saleItemSchema as ah, saleServiceSchema as ai, saleUpdateSchema as aj, salesRequest as ak, stashUserData as al, toMinor as am, type BusinessConfigService as b, type ConversionUserData as c, type CurrencyRevenue as d, type CustomerCurrencyDelta as e, type CustomerCurrencyTotal as f, type CustomerGetOptions as g, type CustomerGetResult as h, type CustomerKpis as i, type CustomerKpisDeltas as j, type CustomerKpisPrevious as k, type CustomerListPage as l, type CustomerListQuery as m, type CustomerProfile as n, type CustomerSegment as o, type CustomerSegmentCount as p, type CustomerSortField as q, type CustomerSummary as r, type CustomerSummaryQuery as s, type NamedRange as t, type Sale as u, type SaleBuiltinRequirableField as v, type SaleCursorPage as w, type SaleFilters as x, type SaleInput as y, type SaleItem as z };
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { a as ConversionConfigStore, c as TrackingConfigRuntime } from './tracking-config-runtime-BnUlS_Ae.mjs';
2
3
  import { CountryCode } from 'libphonenumber-js';
3
4
  import { A as ApiTransportConfig, a as apiRequest } from './request-Doq36Rt0.mjs';
4
5
  import './date-BHetnL7s.mjs';
@@ -13,195 +14,6 @@ declare function stashUserData(data: ConversionUserData, country?: CountryCode):
13
14
  /** Drop everything (consent denial, tests). */
14
15
  declare function clearStashedUserData(): void;
15
16
 
16
- interface ServiceFiring {
17
- send_to: string;
18
- /** Action's configured default value (cents); the SDK fires it only when a sale has no amount. */
19
- value_cents?: number | null;
20
- currency?: string | null;
21
- }
22
- /** Serializable on-page trigger (owned by tracking-core/src/events/trigger-spec.ts). The shape
23
- * varies by `event_type`; only the parameter for that type is set. */
24
- interface ConfigTriggerSpec {
25
- event_type: string;
26
- threshold_percent?: number;
27
- threshold_seconds?: number;
28
- page_threshold?: number;
29
- page_name?: string;
30
- }
31
- /** One unified conversion goal: a revenue `sale` or an on-page `event`. */
32
- interface ConversionGoal {
33
- key: string;
34
- label?: string;
35
- kind: "sale" | "event";
36
- /** Structured fire-when for event-goals; null for sales. */
37
- trigger: ConfigTriggerSpec | null;
38
- firing: ServiceFiring | null;
39
- }
40
- interface ConversionConfig {
41
- schema_version: number;
42
- config_version: number;
43
- business_id?: string;
44
- customer_id?: string | null;
45
- environment?: string;
46
- google_tracking_state: "active" | "disabled";
47
- gtag_ids: Record<string, string>;
48
- meta_pixel_ids: Record<string, string>;
49
- /** LEGACY: sale-goals only (for pre-unified-goal readers). */
50
- services: Array<{
51
- key: string;
52
- label?: string;
53
- firing: ServiceFiring | null;
54
- }>;
55
- /** Unified goal list (sales + on-page events). Superset of `services`. */
56
- goals: ConversionGoal[];
57
- }
58
- interface ConversionConfigStore {
59
- /** Firing config for a goal/service key, or null when it doesn't fire on-site. */
60
- getFiring(key: string): ServiceFiring | null;
61
- /** The full goal for a key, or null when unknown. */
62
- getGoal(key: string): ConversionGoal | null;
63
- /** Every adopted goal (sales + events). */
64
- listGoals(): ConversionGoal[];
65
- /** The currently adopted config (baked / cached fallback until the fetch lands). */
66
- current(): ConversionConfig | null;
67
- /** True once a config is adopted (seeded synchronously from cache/baked, or fetched). */
68
- isReady(): boolean;
69
- /**
70
- * Run `listener` when a config first becomes available — immediately if already
71
- * ready, otherwise on the first adopt. Lets auto-fire replay automatic events that
72
- * occurred before the async CDN fetch resolved. Returns an unsubscribe fn.
73
- */
74
- onResolve(listener: () => void): () => void;
75
- /** Force a background revalidate against the CDN object. */
76
- revalidate(): Promise<void>;
77
- }
78
- interface ResolveConversionConfigOptions {
79
- /** Full URL of the per-business CDN object. */
80
- cdnUrl: string;
81
- /** Offline-correct fallback (e.g. the CLI-baked snapshot). */
82
- baked?: ConversionConfig | null;
83
- /** Injectable for tests / non-global-fetch runtimes. */
84
- fetchImpl?: typeof fetch;
85
- }
86
- /**
87
- * Resolve the config with stale-while-revalidate: seed synchronously from the
88
- * sessionStorage cache (or the baked fallback), then conditionally re-fetch the CDN object
89
- * with `If-None-Match`. A fetched object is adopted only if its `config_version` is strictly
90
- * greater than what's cached, so a reordered edge copy can't downgrade fresher state.
91
- * Non-blocking and browser-only; a failed fetch leaves the seed in place.
92
- */
93
- declare function resolveConversionConfig(options: ResolveConversionConfigOptions): ConversionConfigStore;
94
-
95
- /**
96
- * Where a business's published tracking config lives.
97
- *
98
- * `businessId` + `environment` are the stable identity; the ORIGIN it is fetched
99
- * from is deployment-specific (production CDN vs. a local object store), which is
100
- * why `cdnBaseUrl` exists. Codegen bakes only the identity, so one committed
101
- * generated file works in every environment and only an env var changes.
102
- *
103
- * `cdnUrl` remains supported and WINS when present — every client repo generated
104
- * before `cdnBaseUrl` passes one, and those must keep working untouched.
105
- */
106
- interface TrackingConfigReference {
107
- /**
108
- * Fully-resolved object URL. Optional: omit it and pass `cdnBaseUrl` (or rely
109
- * on the production default) to have it composed from the identity below.
110
- */
111
- cdnUrl?: string;
112
- /**
113
- * Origin (optionally with a path prefix) the config object is served from, e.g.
114
- * `https://demos.aranova.io` in production or
115
- * `http://localhost:9100/aranova-demos` against a local MinIO. Ignored when
116
- * `cdnUrl` is set; blank or omitted falls back to {@link DEFAULT_CDN_BASE_URL}.
117
- * `tracking-cli gen` wires this to an env var so retargeting is config, not code.
118
- */
119
- cdnBaseUrl?: string;
120
- businessId: string;
121
- environment: "production" | "test";
122
- }
123
- /**
124
- * The URL a reference resolves to. An explicit `cdnUrl` wins (back-compat);
125
- * otherwise compose from `cdnBaseUrl` (or the production default).
126
- *
127
- * A blank/whitespace `cdnBaseUrl` is treated as UNSET rather than composed: the
128
- * generated module reads it from an env var, and a var that is present-but-empty
129
- * (a stray `NEXT_PUBLIC_ARANOVA_CDN_BASE_URL=` line) would otherwise produce
130
- * `/tracking-config/...` — a same-origin request to the client's own site.
131
- */
132
- declare function resolveTrackingConfigUrl(ref: TrackingConfigReference): string;
133
- type RuntimeState = "unconfirmed" | "active" | "tombstone";
134
- interface QueuedConversion {
135
- key: string;
136
- value?: number | null;
137
- currency?: string | null;
138
- transactionId?: string | null;
139
- }
140
- type TrackingConfigConversionOptions = Omit<QueuedConversion, "key">;
141
- interface QueuedPageView {
142
- href: string;
143
- title: string | null;
144
- referrer: string | null;
145
- }
146
- declare class TrackingConfigRuntime {
147
- readonly ref: TrackingConfigReference;
148
- private readonly fetchImpl;
149
- /** Resolved config URL — see the constructor for why it is computed once. */
150
- private readonly url;
151
- private current;
152
- private etag;
153
- private stateValue;
154
- private confirmedAt;
155
- private authorityGeneration;
156
- private inFlight;
157
- private flushInFlight;
158
- private flushRequested;
159
- private retryTimer;
160
- private started;
161
- /** Consecutive failed authority attempts — drives the revalidate backoff. */
162
- private authorityFailures;
163
- /** Epoch ms before which `ensureAuthority` must not issue another request. */
164
- private nextAuthorityAttemptAt;
165
- private readonly conversionQueue;
166
- private readonly automaticQueue;
167
- private readonly pageQueue;
168
- private readonly listeners;
169
- constructor(ref: TrackingConfigReference, fetchImpl?: typeof fetch);
170
- /** The URL this runtime actually fetches (composed or explicit). */
171
- configUrl(): string;
172
- /**
173
- * Explicitly start authority resolution and Google-tag bootstrap.
174
- *
175
- * Idempotent so framework effects can call it after hydration without
176
- * depending on constructor timing.
177
- */
178
- start(): void;
179
- state(): RuntimeState;
180
- config(): ConversionConfig | null;
181
- __unsafeExpireAuthorityForTests(): void;
182
- /** Queue depths — asserted by tests to pin the bound. */
183
- __queueDepthsForTests(): {
184
- conversions: number;
185
- automatic: number;
186
- pages: number;
187
- };
188
- subscribe(listener: () => void): () => void;
189
- ensureAuthority(): Promise<boolean>;
190
- revalidate(): Promise<void>;
191
- private revalidateAuthority;
192
- queuePageView(snapshot?: QueuedPageView | null): void;
193
- fireConversion(key: string, options?: TrackingConfigConversionOptions): void;
194
- queueAutomaticEvent(eventType: string, metadata: Record<string, unknown>, transactionPath: string, transactionScope: string): void;
195
- listGoals(): ConversionGoal[];
196
- private revalidateNow;
197
- private expireAuthority;
198
- private confirm;
199
- private flush;
200
- private scheduleRetry;
201
- private flushNow;
202
- }
203
- declare function getTrackingConfigRuntime(ref: TrackingConfigReference, fetchImpl?: typeof fetch): TrackingConfigRuntime;
204
-
205
17
  /**
206
18
  * Sales / Conversions wire schemas — the client-side source of truth.
207
19
  *
@@ -584,6 +396,12 @@ interface Sale {
584
396
  updated_at: string;
585
397
  items: SaleItem[];
586
398
  }
399
+ /**
400
+ * The offset page shape returned by the internal admin list, which this client
401
+ * never calls (`list()` is keyset and returns {@link SaleCursorPage}).
402
+ *
403
+ * @deprecated Unused by this client — no verb returns or accepts it. Kept for one release; removed in the next major.
404
+ */
587
405
  interface SaleListPage {
588
406
  items: Sale[];
589
407
  total: number;
@@ -596,9 +414,10 @@ interface SaleCursorPage {
596
414
  has_more?: boolean;
597
415
  }
598
416
  /**
599
- * Sortable columns on the secret-key (keyset) and admin (offset) list endpoints.
600
- * `business_name` only applies to the cross-business admin list — it sorts the
601
- * joined `businesses.name` column.
417
+ * Sortable columns on the internal admin (offset) list. `list()` is typed to
418
+ * {@link SaleKeysetSortField}, which omits `customer_name` and `business_name`.
419
+ *
420
+ * @deprecated Unused by this client — no verb returns or accepts it. Kept for one release; removed in the next major.
602
421
  */
603
422
  type SaleSortField = "occurred_at" | "created_at" | "amount_total_cents" | "customer_name" | "business_name";
604
423
  type SaleSortOrder = "asc" | "desc";
@@ -630,10 +449,13 @@ interface SaleFilters {
630
449
  * Pagination is **keyset (cursor)**: `next_cursor` returned by one page is
631
450
  * passed back as `cursor` on the next. `null` / undefined cursor = first page.
632
451
  *
633
- * Ordering on this endpoint is fixed at **`occurred_at DESC, id DESC`** — the
634
- * cursor encodes a position in that index, so a different sort would
635
- * invalidate cursors mid-pagination. For ad-hoc sorted reads use the
636
- * dashboard admin endpoint, which is offset-paginated.
452
+ * Ordering is selectable via `sort`/`order` on {@link SaleListQueryV2}. A cursor
453
+ * encodes a position under the sort it was minted with, so replaying it under a
454
+ * different sort is rejected (422) — page with the sort you started with.
455
+ */
456
+ /**
457
+ * @deprecated Superseded by {@link SaleListQueryV2}, which is what `list()` accepts.
458
+ * Its ordering note was also stale — `sort`/`order` are supported. Removed in the next major.
637
459
  */
638
460
  interface SaleListQuery extends SaleFilters {
639
461
  limit?: number;
@@ -651,6 +473,10 @@ interface SaleListQueryV2 extends SaleListQuery {
651
473
  declare const TRACKING_RANGES: readonly ["24h", "7d", "30d"];
652
474
  type TrackingOverviewRange = (typeof TRACKING_RANGES)[number];
653
475
  /** Query input for `SalesClient.summary()` — filters + range + options. */
476
+ /**
477
+ * @deprecated The v1 summary query. `summary()` accepts {@link SaleSummaryQueryV2};
478
+ * the v1 endpoint no longer exists. Removed in the next major.
479
+ */
654
480
  interface SaleSummaryQuery extends SaleFilters {
655
481
  range: TrackingOverviewRange;
656
482
  /** Include the per-category line-item breakdown (extra join; default false). */
@@ -690,6 +516,10 @@ interface SalesTrendPoint {
690
516
  sale_count: number;
691
517
  revenue_cents: number;
692
518
  }
519
+ /**
520
+ * @deprecated The v1 summary response. `summary()` returns {@link SaleSummaryV2};
521
+ * the v1 endpoint no longer exists. Removed in the next major.
522
+ */
693
523
  interface SaleSummary {
694
524
  range: TrackingOverviewRange;
695
525
  business_id: string | null;
@@ -862,6 +692,23 @@ interface BusinessConfigFeatures {
862
692
  comparisons: boolean;
863
693
  retention: boolean;
864
694
  }
695
+ /** A built-in customer field a business can require on every sale. */
696
+ type SaleBuiltinRequirableField = "customer_name" | "customer_phone" | "customer_email" | "description";
697
+ /** v1 value types. `enum` is single-select over the property's `options`. */
698
+ type SalePropertyType = "string" | "number" | "boolean" | "enum" | "date";
699
+ interface SalePropertyOption {
700
+ key: string;
701
+ label: string;
702
+ }
703
+ /** One custom sale property as the sale form sees it: overrides applied, options
704
+ * already filtered to the business's enabled subset. */
705
+ interface EffectiveSaleProperty {
706
+ key: string;
707
+ label: string;
708
+ type: SalePropertyType;
709
+ required: boolean;
710
+ options?: SalePropertyOption[] | null;
711
+ }
865
712
  interface BusinessConfig {
866
713
  business_id: string;
867
714
  display_name: string;
@@ -871,6 +718,11 @@ interface BusinessConfig {
871
718
  default_phone_country: string | null;
872
719
  services: BusinessConfigService[];
873
720
  features: BusinessConfigFeatures;
721
+ builtin_required: SaleBuiltinRequirableField[];
722
+ properties: EffectiveSaleProperty[];
723
+ /** Whether the form should pre-tick the SMS consent box. A form default only —
724
+ * the per-sale `sms_consent` attestation is what every send path gates on. */
725
+ sms_consent_default_opt_in: boolean;
874
726
  }
875
727
 
876
728
  type SalesTransportConfig = ApiTransportConfig;
@@ -921,10 +773,10 @@ interface SalesClient<TService extends string = string, TConversion extends stri
921
773
  occurred_at?: string;
922
774
  }): Promise<Sale>;
923
775
  /**
924
- * Record a revenue sale — the intent-revealing alias of {@link record} in the unified-goal
925
- * API. POSTs `/sales` and ALSO fires the on-site conversion when the sale-goal is
926
- * WEBPAGE-mapped. Use this for anything with real revenue; use {@link trackConversion} for a
927
- * non-revenue on-page event.
776
+ * Record a revenue sale — the intent-revealing alias of {@link record}. Identical
777
+ * behavior (same function reference): POSTs `/sales` and fires the on-site conversion
778
+ * when the sale-goal is WEBPAGE-mapped. Use either for real revenue; use
779
+ * {@link trackConversion} for a non-revenue on-page event.
928
780
  */
929
781
  recordSale(input: Omit<SaleInput, "currency" | "occurred_at" | "service" | "services"> & {
930
782
  service?: TService | null;
@@ -1005,4 +857,4 @@ interface PublicServiceItem {
1005
857
  */
1006
858
  declare function fetchServices(config: SalesTransportConfig): Promise<PublicServiceItem[]>;
1007
859
 
1008
- export { type SalesClientConfig as $, type SaleItem as A, type BusinessConfig as B, type ConversionConfig as C, type DistinctCustomersByCurrency as D, type SaleItemInput as E, type SaleKeysetSortField as F, type Granularity as G, type SaleListPage as H, type SaleListQuery as I, type SaleListQueryV2 as J, type SaleService as K, type SaleServiceInput as L, type SaleSortField as M, NAMED_RANGES as N, type SaleSortOrder as O, type PublicServiceItem as P, type SaleSummary as Q, type SaleSummaryPrevious as R, SUPPORTED_CURRENCIES as S, type TrackingConfigReference as T, type SaleSummaryQuery as U, type SaleSummaryQueryV2 as V, type SaleSummaryV2 as W, type SaleUpdateInput as X, type SalesBusinessClient as Y, type SalesCategoryBreakdown as Z, type SalesClient as _, type BusinessConfigFeatures as a, type SalesCustomersClient as a0, type SalesServiceBreakdown as a1, type SalesTransportConfig as a2, type SalesTrendPoint as a3, type SummaryCurrencyDelta as a4, type SummaryDeltas as a5, type SummaryWindow as a6, type SupportedCurrency as a7, TRACKING_RANGES as a8, type TrackingOverviewRange as a9, clearStashedUserData as aa, createSalesClient as ab, fetchServices as ac, formatMoney as ad, fromMinor as ae, getTrackingConfigRuntime as af, resolveConversionConfig as ag, resolveTrackingConfigUrl as ah, saleCreateSchema as ai, saleItemSchema as aj, saleServiceSchema as ak, saleUpdateSchema as al, salesRequest as am, stashUserData as an, toMinor as ao, type BusinessConfigService as b, type CompareTo as c, type ConversionConfigStore as d, type ConversionUserData as e, type CurrencyRevenue as f, type CustomerCurrencyDelta as g, type CustomerCurrencyTotal as h, type CustomerGetOptions as i, type CustomerGetResult as j, type CustomerKpis as k, type CustomerKpisDeltas as l, type CustomerKpisPrevious as m, type CustomerListPage as n, type CustomerListQuery as o, type CustomerProfile as p, type CustomerSegment as q, type CustomerSegmentCount as r, type CustomerSortField as s, type CustomerSummary as t, type CustomerSummaryQuery as u, type NamedRange as v, type Sale as w, type SaleCursorPage as x, type SaleFilters as y, type SaleInput as z };
860
+ export { type SalesClient as $, type SaleItemInput as A, type BusinessConfig as B, type CompareTo as C, type DistinctCustomersByCurrency as D, type EffectiveSaleProperty as E, type SaleKeysetSortField as F, type Granularity as G, type SaleListPage as H, type SaleListQuery as I, type SaleListQueryV2 as J, type SalePropertyOption as K, type SalePropertyType as L, type SaleService as M, NAMED_RANGES as N, type SaleServiceInput as O, type PublicServiceItem as P, type SaleSortField as Q, type SaleSortOrder as R, SUPPORTED_CURRENCIES as S, type SaleSummary as T, type SaleSummaryPrevious as U, type SaleSummaryQuery as V, type SaleSummaryQueryV2 as W, type SaleSummaryV2 as X, type SaleUpdateInput as Y, type SalesBusinessClient as Z, type SalesCategoryBreakdown as _, type BusinessConfigFeatures as a, type SalesClientConfig as a0, type SalesCustomersClient as a1, type SalesServiceBreakdown as a2, type SalesTransportConfig as a3, type SalesTrendPoint as a4, type SummaryCurrencyDelta as a5, type SummaryDeltas as a6, type SummaryWindow as a7, type SupportedCurrency as a8, TRACKING_RANGES as a9, type TrackingOverviewRange as aa, clearStashedUserData as ab, createSalesClient as ac, fetchServices as ad, formatMoney as ae, fromMinor as af, saleCreateSchema as ag, saleItemSchema as ah, saleServiceSchema as ai, saleUpdateSchema as aj, salesRequest as ak, stashUserData as al, toMinor as am, type BusinessConfigService as b, type ConversionUserData as c, type CurrencyRevenue as d, type CustomerCurrencyDelta as e, type CustomerCurrencyTotal as f, type CustomerGetOptions as g, type CustomerGetResult as h, type CustomerKpis as i, type CustomerKpisDeltas as j, type CustomerKpisPrevious as k, type CustomerListPage as l, type CustomerListQuery as m, type CustomerProfile as n, type CustomerSegment as o, type CustomerSegmentCount as p, type CustomerSortField as q, type CustomerSummary as r, type CustomerSummaryQuery as s, type NamedRange as t, type Sale as u, type SaleBuiltinRequirableField as v, type SaleCursorPage as w, type SaleFilters as x, type SaleInput as y, type SaleItem as z };