@aranova/tracking-react 0.13.0 → 0.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -0
- package/dist/index.d.mts +26 -14
- package/dist/index.d.ts +26 -14
- package/dist/index.js +442 -68
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +441 -68
- package/dist/index.mjs.map +1 -1
- package/dist/phone.js +73 -0
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +73 -0
- package/dist/phone.mjs.map +1 -1
- package/dist/sales-7w7-Ud60.d.mts +895 -0
- package/dist/sales-7w7-Ud60.d.ts +895 -0
- package/dist/sales.d.mts +2 -784
- package/dist/sales.d.ts +2 -784
- package/dist/sales.js +172 -45
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +172 -45
- package/dist/sales.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,895 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
interface ServiceFiring {
|
|
4
|
+
send_to: string;
|
|
5
|
+
/** Action's configured default value (cents); the SDK fires it only when a sale has no amount. */
|
|
6
|
+
value_cents?: number | null;
|
|
7
|
+
currency?: string | null;
|
|
8
|
+
}
|
|
9
|
+
/** Serializable on-page trigger (owned by tracking-core/src/events/trigger-spec.ts). The shape
|
|
10
|
+
* varies by `event_type`; only the parameter for that type is set. */
|
|
11
|
+
interface ConfigTriggerSpec {
|
|
12
|
+
event_type: string;
|
|
13
|
+
threshold_percent?: number;
|
|
14
|
+
threshold_seconds?: number;
|
|
15
|
+
page_threshold?: number;
|
|
16
|
+
page_name?: string;
|
|
17
|
+
}
|
|
18
|
+
/** One unified conversion goal: a revenue `sale` or an on-page `event`. */
|
|
19
|
+
interface ConversionGoal {
|
|
20
|
+
key: string;
|
|
21
|
+
label?: string;
|
|
22
|
+
kind: "sale" | "event";
|
|
23
|
+
/** Structured fire-when for event-goals; null for sales. */
|
|
24
|
+
trigger: ConfigTriggerSpec | null;
|
|
25
|
+
firing: ServiceFiring | null;
|
|
26
|
+
}
|
|
27
|
+
interface ConversionConfig {
|
|
28
|
+
schema_version: number;
|
|
29
|
+
config_version: number;
|
|
30
|
+
business_id?: string;
|
|
31
|
+
customer_id?: string | null;
|
|
32
|
+
environment?: string;
|
|
33
|
+
gtag_ids: Record<string, string>;
|
|
34
|
+
meta_pixel_ids: Record<string, string>;
|
|
35
|
+
/** LEGACY: sale-goals only (for pre-unified-goal readers). */
|
|
36
|
+
services: Array<{
|
|
37
|
+
key: string;
|
|
38
|
+
label?: string;
|
|
39
|
+
firing: ServiceFiring | null;
|
|
40
|
+
}>;
|
|
41
|
+
/** Unified goal list (sales + on-page events). Superset of `services`. */
|
|
42
|
+
goals: ConversionGoal[];
|
|
43
|
+
}
|
|
44
|
+
interface ConversionConfigStore {
|
|
45
|
+
/** Firing config for a goal/service key, or null when it doesn't fire on-site. */
|
|
46
|
+
getFiring(key: string): ServiceFiring | null;
|
|
47
|
+
/** The full goal for a key, or null when unknown. */
|
|
48
|
+
getGoal(key: string): ConversionGoal | null;
|
|
49
|
+
/** Every adopted goal (sales + events). */
|
|
50
|
+
listGoals(): ConversionGoal[];
|
|
51
|
+
/** The currently adopted config (baked / cached fallback until the fetch lands). */
|
|
52
|
+
current(): ConversionConfig | null;
|
|
53
|
+
/** True once a config is adopted (seeded synchronously from cache/baked, or fetched). */
|
|
54
|
+
isReady(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Run `listener` when a config first becomes available — immediately if already
|
|
57
|
+
* ready, otherwise on the first adopt. Lets auto-fire replay automatic events that
|
|
58
|
+
* occurred before the async CDN fetch resolved. Returns an unsubscribe fn.
|
|
59
|
+
*/
|
|
60
|
+
onResolve(listener: () => void): () => void;
|
|
61
|
+
/** Force a background revalidate against the CDN object. */
|
|
62
|
+
revalidate(): Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
interface ResolveConversionConfigOptions {
|
|
65
|
+
/** Full URL of the per-business CDN object. */
|
|
66
|
+
cdnUrl: string;
|
|
67
|
+
/** Offline-correct fallback (e.g. the CLI-baked snapshot). */
|
|
68
|
+
baked?: ConversionConfig | null;
|
|
69
|
+
/** Injectable for tests / non-global-fetch runtimes. */
|
|
70
|
+
fetchImpl?: typeof fetch;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolve the config with stale-while-revalidate: seed synchronously from the
|
|
74
|
+
* sessionStorage cache (or the baked fallback), then conditionally re-fetch the CDN object
|
|
75
|
+
* with `If-None-Match`. A fetched object is adopted only if its `config_version` is strictly
|
|
76
|
+
* greater than what's cached, so a reordered edge copy can't downgrade fresher state.
|
|
77
|
+
* Non-blocking and browser-only; a failed fetch leaves the seed in place.
|
|
78
|
+
*/
|
|
79
|
+
declare function resolveConversionConfig(options: ResolveConversionConfigOptions): ConversionConfigStore;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Sales / Conversions wire schemas — the client-side source of truth.
|
|
83
|
+
*
|
|
84
|
+
* `saleCreateSchema` is mirrored by `SaleCreateSchema` in
|
|
85
|
+
* `apps/api/src/schemas/tracking_sales.py` and enforced by the backend drift
|
|
86
|
+
* test (the `resources` section of `events.schema.json`). Keep them in lockstep.
|
|
87
|
+
*
|
|
88
|
+
* Money is **integer minor units (cents)**; `quantity` is a decimal string;
|
|
89
|
+
* `currency` is the required `SupportedCurrency` enum.
|
|
90
|
+
*/
|
|
91
|
+
declare const SUPPORTED_CURRENCIES: readonly ["USD", "CAD"];
|
|
92
|
+
type SupportedCurrency = (typeof SUPPORTED_CURRENCIES)[number];
|
|
93
|
+
declare const TRACKING_ENVIRONMENTS: readonly ["production", "development"];
|
|
94
|
+
declare const saleItemSchema: z.ZodObject<{
|
|
95
|
+
external_item_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
96
|
+
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
97
|
+
category: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
98
|
+
quantity: z.ZodString;
|
|
99
|
+
unit_price_cents: z.ZodNumber;
|
|
100
|
+
unit_cost_cents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
101
|
+
}, "strict", z.ZodTypeAny, {
|
|
102
|
+
quantity: string;
|
|
103
|
+
unit_price_cents: number;
|
|
104
|
+
name?: string | null | undefined;
|
|
105
|
+
external_item_id?: string | null | undefined;
|
|
106
|
+
category?: string | null | undefined;
|
|
107
|
+
unit_cost_cents?: number | null | undefined;
|
|
108
|
+
}, {
|
|
109
|
+
quantity: string;
|
|
110
|
+
unit_price_cents: number;
|
|
111
|
+
name?: string | null | undefined;
|
|
112
|
+
external_item_id?: string | null | undefined;
|
|
113
|
+
category?: string | null | undefined;
|
|
114
|
+
unit_cost_cents?: number | null | undefined;
|
|
115
|
+
}>;
|
|
116
|
+
declare const saleServiceSchema: z.ZodObject<{
|
|
117
|
+
service: z.ZodString;
|
|
118
|
+
amount_cents: z.ZodNumber;
|
|
119
|
+
}, "strict", z.ZodTypeAny, {
|
|
120
|
+
service: string;
|
|
121
|
+
amount_cents: number;
|
|
122
|
+
}, {
|
|
123
|
+
service: string;
|
|
124
|
+
amount_cents: number;
|
|
125
|
+
}>;
|
|
126
|
+
declare const saleCreateSchema: z.ZodEffects<z.ZodObject<{
|
|
127
|
+
external_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
128
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
129
|
+
service: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
130
|
+
services: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
131
|
+
service: z.ZodString;
|
|
132
|
+
amount_cents: z.ZodNumber;
|
|
133
|
+
}, "strict", z.ZodTypeAny, {
|
|
134
|
+
service: string;
|
|
135
|
+
amount_cents: number;
|
|
136
|
+
}, {
|
|
137
|
+
service: string;
|
|
138
|
+
amount_cents: number;
|
|
139
|
+
}>, "many">>>;
|
|
140
|
+
currency: z.ZodEnum<["USD", "CAD"]>;
|
|
141
|
+
amount_total_cents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
142
|
+
occurred_at: z.ZodString;
|
|
143
|
+
environment: z.ZodDefault<z.ZodEnum<["production", "development"]>>;
|
|
144
|
+
items: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
145
|
+
external_item_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
146
|
+
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
147
|
+
category: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
148
|
+
quantity: z.ZodString;
|
|
149
|
+
unit_price_cents: z.ZodNumber;
|
|
150
|
+
unit_cost_cents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
151
|
+
}, "strict", z.ZodTypeAny, {
|
|
152
|
+
quantity: string;
|
|
153
|
+
unit_price_cents: number;
|
|
154
|
+
name?: string | null | undefined;
|
|
155
|
+
external_item_id?: string | null | undefined;
|
|
156
|
+
category?: string | null | undefined;
|
|
157
|
+
unit_cost_cents?: number | null | undefined;
|
|
158
|
+
}, {
|
|
159
|
+
quantity: string;
|
|
160
|
+
unit_price_cents: number;
|
|
161
|
+
name?: string | null | undefined;
|
|
162
|
+
external_item_id?: string | null | undefined;
|
|
163
|
+
category?: string | null | undefined;
|
|
164
|
+
unit_cost_cents?: number | null | undefined;
|
|
165
|
+
}>, "many">>;
|
|
166
|
+
metadata: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
167
|
+
customer_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
168
|
+
customer_phone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
169
|
+
customer_email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
170
|
+
}, "strict", z.ZodTypeAny, {
|
|
171
|
+
currency: "USD" | "CAD";
|
|
172
|
+
environment: "production" | "development";
|
|
173
|
+
occurred_at: string;
|
|
174
|
+
items: {
|
|
175
|
+
quantity: string;
|
|
176
|
+
unit_price_cents: number;
|
|
177
|
+
name?: string | null | undefined;
|
|
178
|
+
external_item_id?: string | null | undefined;
|
|
179
|
+
category?: string | null | undefined;
|
|
180
|
+
unit_cost_cents?: number | null | undefined;
|
|
181
|
+
}[];
|
|
182
|
+
metadata?: Record<string, unknown> | null | undefined;
|
|
183
|
+
services?: {
|
|
184
|
+
service: string;
|
|
185
|
+
amount_cents: number;
|
|
186
|
+
}[] | null | undefined;
|
|
187
|
+
service?: string | null | undefined;
|
|
188
|
+
amount_total_cents?: number | null | undefined;
|
|
189
|
+
external_id?: string | null | undefined;
|
|
190
|
+
description?: string | null | undefined;
|
|
191
|
+
customer_name?: string | null | undefined;
|
|
192
|
+
customer_phone?: string | null | undefined;
|
|
193
|
+
customer_email?: string | null | undefined;
|
|
194
|
+
}, {
|
|
195
|
+
currency: "USD" | "CAD";
|
|
196
|
+
occurred_at: string;
|
|
197
|
+
metadata?: Record<string, unknown> | null | undefined;
|
|
198
|
+
services?: {
|
|
199
|
+
service: string;
|
|
200
|
+
amount_cents: number;
|
|
201
|
+
}[] | null | undefined;
|
|
202
|
+
environment?: "production" | "development" | undefined;
|
|
203
|
+
service?: string | null | undefined;
|
|
204
|
+
amount_total_cents?: number | null | undefined;
|
|
205
|
+
external_id?: string | null | undefined;
|
|
206
|
+
description?: string | null | undefined;
|
|
207
|
+
items?: {
|
|
208
|
+
quantity: string;
|
|
209
|
+
unit_price_cents: number;
|
|
210
|
+
name?: string | null | undefined;
|
|
211
|
+
external_item_id?: string | null | undefined;
|
|
212
|
+
category?: string | null | undefined;
|
|
213
|
+
unit_cost_cents?: number | null | undefined;
|
|
214
|
+
}[] | undefined;
|
|
215
|
+
customer_name?: string | null | undefined;
|
|
216
|
+
customer_phone?: string | null | undefined;
|
|
217
|
+
customer_email?: string | null | undefined;
|
|
218
|
+
}>, {
|
|
219
|
+
currency: "USD" | "CAD";
|
|
220
|
+
environment: "production" | "development";
|
|
221
|
+
occurred_at: string;
|
|
222
|
+
items: {
|
|
223
|
+
quantity: string;
|
|
224
|
+
unit_price_cents: number;
|
|
225
|
+
name?: string | null | undefined;
|
|
226
|
+
external_item_id?: string | null | undefined;
|
|
227
|
+
category?: string | null | undefined;
|
|
228
|
+
unit_cost_cents?: number | null | undefined;
|
|
229
|
+
}[];
|
|
230
|
+
metadata?: Record<string, unknown> | null | undefined;
|
|
231
|
+
services?: {
|
|
232
|
+
service: string;
|
|
233
|
+
amount_cents: number;
|
|
234
|
+
}[] | null | undefined;
|
|
235
|
+
service?: string | null | undefined;
|
|
236
|
+
amount_total_cents?: number | null | undefined;
|
|
237
|
+
external_id?: string | null | undefined;
|
|
238
|
+
description?: string | null | undefined;
|
|
239
|
+
customer_name?: string | null | undefined;
|
|
240
|
+
customer_phone?: string | null | undefined;
|
|
241
|
+
customer_email?: string | null | undefined;
|
|
242
|
+
}, {
|
|
243
|
+
currency: "USD" | "CAD";
|
|
244
|
+
occurred_at: string;
|
|
245
|
+
metadata?: Record<string, unknown> | null | undefined;
|
|
246
|
+
services?: {
|
|
247
|
+
service: string;
|
|
248
|
+
amount_cents: number;
|
|
249
|
+
}[] | null | undefined;
|
|
250
|
+
environment?: "production" | "development" | undefined;
|
|
251
|
+
service?: string | null | undefined;
|
|
252
|
+
amount_total_cents?: number | null | undefined;
|
|
253
|
+
external_id?: string | null | undefined;
|
|
254
|
+
description?: string | null | undefined;
|
|
255
|
+
items?: {
|
|
256
|
+
quantity: string;
|
|
257
|
+
unit_price_cents: number;
|
|
258
|
+
name?: string | null | undefined;
|
|
259
|
+
external_item_id?: string | null | undefined;
|
|
260
|
+
category?: string | null | undefined;
|
|
261
|
+
unit_cost_cents?: number | null | undefined;
|
|
262
|
+
}[] | undefined;
|
|
263
|
+
customer_name?: string | null | undefined;
|
|
264
|
+
customer_phone?: string | null | undefined;
|
|
265
|
+
customer_email?: string | null | undefined;
|
|
266
|
+
}>;
|
|
267
|
+
declare const saleUpdateSchema: z.ZodEffects<z.ZodObject<{
|
|
268
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
269
|
+
service: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
270
|
+
services: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
271
|
+
service: z.ZodString;
|
|
272
|
+
amount_cents: z.ZodNumber;
|
|
273
|
+
}, "strict", z.ZodTypeAny, {
|
|
274
|
+
service: string;
|
|
275
|
+
amount_cents: number;
|
|
276
|
+
}, {
|
|
277
|
+
service: string;
|
|
278
|
+
amount_cents: number;
|
|
279
|
+
}>, "many">>>;
|
|
280
|
+
currency: z.ZodOptional<z.ZodEnum<["USD", "CAD"]>>;
|
|
281
|
+
amount_total_cents: z.ZodOptional<z.ZodNumber>;
|
|
282
|
+
occurred_at: z.ZodOptional<z.ZodString>;
|
|
283
|
+
items: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
284
|
+
external_item_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
285
|
+
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
286
|
+
category: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
287
|
+
quantity: z.ZodString;
|
|
288
|
+
unit_price_cents: z.ZodNumber;
|
|
289
|
+
unit_cost_cents: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
290
|
+
}, "strict", z.ZodTypeAny, {
|
|
291
|
+
quantity: string;
|
|
292
|
+
unit_price_cents: number;
|
|
293
|
+
name?: string | null | undefined;
|
|
294
|
+
external_item_id?: string | null | undefined;
|
|
295
|
+
category?: string | null | undefined;
|
|
296
|
+
unit_cost_cents?: number | null | undefined;
|
|
297
|
+
}, {
|
|
298
|
+
quantity: string;
|
|
299
|
+
unit_price_cents: number;
|
|
300
|
+
name?: string | null | undefined;
|
|
301
|
+
external_item_id?: string | null | undefined;
|
|
302
|
+
category?: string | null | undefined;
|
|
303
|
+
unit_cost_cents?: number | null | undefined;
|
|
304
|
+
}>, "many">>;
|
|
305
|
+
metadata: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
306
|
+
customer_name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
307
|
+
customer_phone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
308
|
+
customer_email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
309
|
+
}, "strict", z.ZodTypeAny, {
|
|
310
|
+
currency?: "USD" | "CAD" | undefined;
|
|
311
|
+
metadata?: Record<string, unknown> | null | undefined;
|
|
312
|
+
services?: {
|
|
313
|
+
service: string;
|
|
314
|
+
amount_cents: number;
|
|
315
|
+
}[] | null | undefined;
|
|
316
|
+
service?: string | null | undefined;
|
|
317
|
+
amount_total_cents?: number | undefined;
|
|
318
|
+
description?: string | null | undefined;
|
|
319
|
+
occurred_at?: string | undefined;
|
|
320
|
+
items?: {
|
|
321
|
+
quantity: string;
|
|
322
|
+
unit_price_cents: number;
|
|
323
|
+
name?: string | null | undefined;
|
|
324
|
+
external_item_id?: string | null | undefined;
|
|
325
|
+
category?: string | null | undefined;
|
|
326
|
+
unit_cost_cents?: number | null | undefined;
|
|
327
|
+
}[] | undefined;
|
|
328
|
+
customer_name?: string | null | undefined;
|
|
329
|
+
customer_phone?: string | null | undefined;
|
|
330
|
+
customer_email?: string | null | undefined;
|
|
331
|
+
}, {
|
|
332
|
+
currency?: "USD" | "CAD" | undefined;
|
|
333
|
+
metadata?: Record<string, unknown> | null | undefined;
|
|
334
|
+
services?: {
|
|
335
|
+
service: string;
|
|
336
|
+
amount_cents: number;
|
|
337
|
+
}[] | null | undefined;
|
|
338
|
+
service?: string | null | undefined;
|
|
339
|
+
amount_total_cents?: number | undefined;
|
|
340
|
+
description?: string | null | undefined;
|
|
341
|
+
occurred_at?: string | undefined;
|
|
342
|
+
items?: {
|
|
343
|
+
quantity: string;
|
|
344
|
+
unit_price_cents: number;
|
|
345
|
+
name?: string | null | undefined;
|
|
346
|
+
external_item_id?: string | null | undefined;
|
|
347
|
+
category?: string | null | undefined;
|
|
348
|
+
unit_cost_cents?: number | null | undefined;
|
|
349
|
+
}[] | undefined;
|
|
350
|
+
customer_name?: string | null | undefined;
|
|
351
|
+
customer_phone?: string | null | undefined;
|
|
352
|
+
customer_email?: string | null | undefined;
|
|
353
|
+
}>, {
|
|
354
|
+
currency?: "USD" | "CAD" | undefined;
|
|
355
|
+
metadata?: Record<string, unknown> | null | undefined;
|
|
356
|
+
services?: {
|
|
357
|
+
service: string;
|
|
358
|
+
amount_cents: number;
|
|
359
|
+
}[] | null | undefined;
|
|
360
|
+
service?: string | null | undefined;
|
|
361
|
+
amount_total_cents?: number | undefined;
|
|
362
|
+
description?: string | null | undefined;
|
|
363
|
+
occurred_at?: string | undefined;
|
|
364
|
+
items?: {
|
|
365
|
+
quantity: string;
|
|
366
|
+
unit_price_cents: number;
|
|
367
|
+
name?: string | null | undefined;
|
|
368
|
+
external_item_id?: string | null | undefined;
|
|
369
|
+
category?: string | null | undefined;
|
|
370
|
+
unit_cost_cents?: number | null | undefined;
|
|
371
|
+
}[] | undefined;
|
|
372
|
+
customer_name?: string | null | undefined;
|
|
373
|
+
customer_phone?: string | null | undefined;
|
|
374
|
+
customer_email?: string | null | undefined;
|
|
375
|
+
}, {
|
|
376
|
+
currency?: "USD" | "CAD" | undefined;
|
|
377
|
+
metadata?: Record<string, unknown> | null | undefined;
|
|
378
|
+
services?: {
|
|
379
|
+
service: string;
|
|
380
|
+
amount_cents: number;
|
|
381
|
+
}[] | null | undefined;
|
|
382
|
+
service?: string | null | undefined;
|
|
383
|
+
amount_total_cents?: number | undefined;
|
|
384
|
+
description?: string | null | undefined;
|
|
385
|
+
occurred_at?: string | undefined;
|
|
386
|
+
items?: {
|
|
387
|
+
quantity: string;
|
|
388
|
+
unit_price_cents: number;
|
|
389
|
+
name?: string | null | undefined;
|
|
390
|
+
external_item_id?: string | null | undefined;
|
|
391
|
+
category?: string | null | undefined;
|
|
392
|
+
unit_cost_cents?: number | null | undefined;
|
|
393
|
+
}[] | undefined;
|
|
394
|
+
customer_name?: string | null | undefined;
|
|
395
|
+
customer_phone?: string | null | undefined;
|
|
396
|
+
customer_email?: string | null | undefined;
|
|
397
|
+
}>;
|
|
398
|
+
type SaleItemInput = z.input<typeof saleItemSchema>;
|
|
399
|
+
type SaleServiceInput = z.input<typeof saleServiceSchema>;
|
|
400
|
+
type SaleInput = z.input<typeof saleCreateSchema>;
|
|
401
|
+
type SaleUpdateInput = z.input<typeof saleUpdateSchema>;
|
|
402
|
+
interface SaleItem {
|
|
403
|
+
id: string;
|
|
404
|
+
external_item_id: string | null;
|
|
405
|
+
name: string | null;
|
|
406
|
+
category: string | null;
|
|
407
|
+
quantity: string;
|
|
408
|
+
unit_price_cents: number;
|
|
409
|
+
unit_cost_cents: number | null;
|
|
410
|
+
}
|
|
411
|
+
interface SaleService {
|
|
412
|
+
id: string;
|
|
413
|
+
service_id: string;
|
|
414
|
+
service_key: string;
|
|
415
|
+
service_label: string;
|
|
416
|
+
amount_cents: number;
|
|
417
|
+
}
|
|
418
|
+
interface Sale {
|
|
419
|
+
id: string;
|
|
420
|
+
business_id: string;
|
|
421
|
+
business_name?: string | null;
|
|
422
|
+
external_id: string | null;
|
|
423
|
+
currency: SupportedCurrency;
|
|
424
|
+
amount_total_cents: number;
|
|
425
|
+
description: string | null;
|
|
426
|
+
service_id: string | null;
|
|
427
|
+
service_key?: string | null;
|
|
428
|
+
service_label?: string | null;
|
|
429
|
+
services: SaleService[];
|
|
430
|
+
occurred_at: string;
|
|
431
|
+
environment: (typeof TRACKING_ENVIRONMENTS)[number];
|
|
432
|
+
metadata: Record<string, unknown> | null;
|
|
433
|
+
customer_name: string | null;
|
|
434
|
+
customer_phone: string | null;
|
|
435
|
+
customer_email: string | null;
|
|
436
|
+
created_at: string;
|
|
437
|
+
updated_at: string;
|
|
438
|
+
items: SaleItem[];
|
|
439
|
+
}
|
|
440
|
+
interface SaleListPage {
|
|
441
|
+
items: Sale[];
|
|
442
|
+
total: number;
|
|
443
|
+
}
|
|
444
|
+
interface SaleCursorPage {
|
|
445
|
+
items: Sale[];
|
|
446
|
+
next_cursor: string | null;
|
|
447
|
+
/** Populated only when `want_total` was requested (a single indexed COUNT). */
|
|
448
|
+
total_count?: number;
|
|
449
|
+
has_more?: boolean;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Sortable columns on the secret-key (keyset) and admin (offset) list endpoints.
|
|
453
|
+
* `business_name` only applies to the cross-business admin list — it sorts the
|
|
454
|
+
* joined `businesses.name` column.
|
|
455
|
+
*/
|
|
456
|
+
type SaleSortField = "occurred_at" | "created_at" | "amount_total_cents" | "customer_name" | "business_name";
|
|
457
|
+
type SaleSortOrder = "asc" | "desc";
|
|
458
|
+
/**
|
|
459
|
+
* Comprehensive filter shape mirrored from the backend's `SaleQueryFilters`.
|
|
460
|
+
*
|
|
461
|
+
* `search` runs case-insensitively across `customer_name`, `customer_phone`,
|
|
462
|
+
* `customer_email`, `description`, and `external_id` — the human-facing
|
|
463
|
+
* columns. `service_id` is the resolved per-business service UUID (different
|
|
464
|
+
* from the create-time `service` *key*).
|
|
465
|
+
*/
|
|
466
|
+
interface SaleFilters {
|
|
467
|
+
business_id?: string;
|
|
468
|
+
external_id?: string;
|
|
469
|
+
service_id?: string;
|
|
470
|
+
/** E.164 phone — the canonical customer key; filters sales for one customer. */
|
|
471
|
+
customer_phone?: string;
|
|
472
|
+
currency?: SupportedCurrency;
|
|
473
|
+
environment?: (typeof TRACKING_ENVIRONMENTS)[number];
|
|
474
|
+
since?: string;
|
|
475
|
+
until?: string;
|
|
476
|
+
min_amount_cents?: number;
|
|
477
|
+
max_amount_cents?: number;
|
|
478
|
+
search?: string;
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Full query input for `SalesClient.list()` — filters + pagination.
|
|
482
|
+
*
|
|
483
|
+
* Pagination is **keyset (cursor)**: `next_cursor` returned by one page is
|
|
484
|
+
* passed back as `cursor` on the next. `null` / undefined cursor = first page.
|
|
485
|
+
*
|
|
486
|
+
* Ordering on this endpoint is fixed at **`occurred_at DESC, id DESC`** — the
|
|
487
|
+
* cursor encodes a position in that index, so a different sort would
|
|
488
|
+
* invalidate cursors mid-pagination. For ad-hoc sorted reads use the
|
|
489
|
+
* dashboard admin endpoint, which is offset-paginated.
|
|
490
|
+
*/
|
|
491
|
+
interface SaleListQuery extends SaleFilters {
|
|
492
|
+
limit?: number;
|
|
493
|
+
cursor?: string | null;
|
|
494
|
+
}
|
|
495
|
+
/** Keyset-safe sort columns (NOT-NULL, indexed). */
|
|
496
|
+
type SaleKeysetSortField = "occurred_at" | "created_at" | "amount_total_cents";
|
|
497
|
+
/** v2 list query — adds server sort + opt-in total. */
|
|
498
|
+
interface SaleListQueryV2 extends SaleListQuery {
|
|
499
|
+
sort?: SaleKeysetSortField;
|
|
500
|
+
order?: SaleSortOrder;
|
|
501
|
+
/** Opt-in: a single indexed COUNT over the filtered set. */
|
|
502
|
+
want_total?: boolean;
|
|
503
|
+
}
|
|
504
|
+
declare const TRACKING_RANGES: readonly ["24h", "7d", "30d"];
|
|
505
|
+
type TrackingOverviewRange = (typeof TRACKING_RANGES)[number];
|
|
506
|
+
/** Query input for `SalesClient.summary()` — filters + range + options. */
|
|
507
|
+
interface SaleSummaryQuery extends SaleFilters {
|
|
508
|
+
range: TrackingOverviewRange;
|
|
509
|
+
/** Include the per-category line-item breakdown (extra join; default false). */
|
|
510
|
+
include_categories?: boolean;
|
|
511
|
+
/** Surface soft-deleted services individually (flagged "(deleted)") instead of
|
|
512
|
+
* rolling them into a single "Deleted services" bucket. Default false. */
|
|
513
|
+
include_deleted_services?: boolean;
|
|
514
|
+
/** Cap on the by-service / by-category rows (1–50, default 10). */
|
|
515
|
+
top_n?: number;
|
|
516
|
+
}
|
|
517
|
+
interface CurrencyRevenue {
|
|
518
|
+
currency: SupportedCurrency;
|
|
519
|
+
sale_count: number;
|
|
520
|
+
revenue_cents: number;
|
|
521
|
+
average_order_value_cents: number;
|
|
522
|
+
}
|
|
523
|
+
interface SalesServiceBreakdown {
|
|
524
|
+
service_id: string | null;
|
|
525
|
+
service_key: string | null;
|
|
526
|
+
/** "Unassigned" when the sale has no service. */
|
|
527
|
+
service_label: string | null;
|
|
528
|
+
currency: SupportedCurrency;
|
|
529
|
+
sale_count: number;
|
|
530
|
+
revenue_cents: number;
|
|
531
|
+
}
|
|
532
|
+
interface SalesCategoryBreakdown {
|
|
533
|
+
category: string | null;
|
|
534
|
+
currency: SupportedCurrency;
|
|
535
|
+
/** sum(unit_price_cents * quantity) — advisory, not authoritative. */
|
|
536
|
+
revenue_cents: number;
|
|
537
|
+
/** Decimal string. */
|
|
538
|
+
quantity: string;
|
|
539
|
+
}
|
|
540
|
+
interface SalesTrendPoint {
|
|
541
|
+
bucket_start: string;
|
|
542
|
+
currency: SupportedCurrency;
|
|
543
|
+
sale_count: number;
|
|
544
|
+
revenue_cents: number;
|
|
545
|
+
}
|
|
546
|
+
interface SaleSummary {
|
|
547
|
+
range: TrackingOverviewRange;
|
|
548
|
+
business_id: string | null;
|
|
549
|
+
metrics: {
|
|
550
|
+
sale_count: number;
|
|
551
|
+
distinct_customers: number;
|
|
552
|
+
by_currency: CurrencyRevenue[];
|
|
553
|
+
};
|
|
554
|
+
by_service: SalesServiceBreakdown[];
|
|
555
|
+
by_currency: CurrencyRevenue[];
|
|
556
|
+
by_category: SalesCategoryBreakdown[];
|
|
557
|
+
series: SalesTrendPoint[];
|
|
558
|
+
}
|
|
559
|
+
declare const NAMED_RANGES: readonly ["today", "yesterday", "wtd", "mtd", "qtd", "ytd", "24h", "7d", "30d", "90d", "custom"];
|
|
560
|
+
/** Superset of `TrackingOverviewRange` (`24h`/`7d`/`30d` stay valid). */
|
|
561
|
+
type NamedRange = (typeof NAMED_RANGES)[number];
|
|
562
|
+
type Granularity = "hour" | "day" | "week" | "month" | "auto";
|
|
563
|
+
type CompareTo = "previous_period" | "previous_year" | "none";
|
|
564
|
+
interface DistinctCustomersByCurrency {
|
|
565
|
+
currency: SupportedCurrency;
|
|
566
|
+
distinct_customers: number;
|
|
567
|
+
}
|
|
568
|
+
interface SummaryWindow {
|
|
569
|
+
since: string;
|
|
570
|
+
until: string;
|
|
571
|
+
}
|
|
572
|
+
interface SummaryCurrencyDelta {
|
|
573
|
+
currency: SupportedCurrency;
|
|
574
|
+
revenue_cents_delta: number;
|
|
575
|
+
/** Ratio (0.12 = +12%); null when previous revenue was 0. */
|
|
576
|
+
revenue_pct_delta: number | null;
|
|
577
|
+
sale_count_delta: number;
|
|
578
|
+
}
|
|
579
|
+
interface SummaryDeltas {
|
|
580
|
+
by_currency: SummaryCurrencyDelta[];
|
|
581
|
+
sale_count_delta: number;
|
|
582
|
+
distinct_customers_delta: number;
|
|
583
|
+
}
|
|
584
|
+
interface SaleSummaryPrevious {
|
|
585
|
+
window: SummaryWindow;
|
|
586
|
+
metrics: SaleSummaryV2["metrics"];
|
|
587
|
+
by_currency: CurrencyRevenue[];
|
|
588
|
+
series: SalesTrendPoint[];
|
|
589
|
+
}
|
|
590
|
+
/** Query input for `SalesClient.summary()` v2 — widened range + tz/compare options. */
|
|
591
|
+
interface SaleSummaryQueryV2 extends SaleFilters {
|
|
592
|
+
range?: NamedRange;
|
|
593
|
+
/** Required when `range === 'custom'`. */
|
|
594
|
+
since?: string;
|
|
595
|
+
until?: string;
|
|
596
|
+
/** IANA tz, e.g. `America/Toronto`. Default = business tz. */
|
|
597
|
+
timezone?: string;
|
|
598
|
+
granularity?: Granularity;
|
|
599
|
+
compare_to?: CompareTo;
|
|
600
|
+
include_categories?: boolean;
|
|
601
|
+
include_deleted_services?: boolean;
|
|
602
|
+
top_n?: number;
|
|
603
|
+
}
|
|
604
|
+
/** Superset of `SaleSummary` (assignable to it). */
|
|
605
|
+
interface SaleSummaryV2 extends Omit<SaleSummary, "range" | "metrics"> {
|
|
606
|
+
range: NamedRange;
|
|
607
|
+
metrics: SaleSummary["metrics"] & {
|
|
608
|
+
distinct_customers_by_currency: DistinctCustomersByCurrency[];
|
|
609
|
+
};
|
|
610
|
+
timezone: string | null;
|
|
611
|
+
window: SummaryWindow | null;
|
|
612
|
+
granularity: string | null;
|
|
613
|
+
previous: SaleSummaryPrevious | null;
|
|
614
|
+
deltas: SummaryDeltas | null;
|
|
615
|
+
}
|
|
616
|
+
type CustomerSegment = "new" | "returning" | "repeat" | "lapsed";
|
|
617
|
+
type CustomerSortField = "total_spent" | "last_purchase" | "purchases" | "first_purchase";
|
|
618
|
+
interface CustomerCurrencyTotal {
|
|
619
|
+
currency: SupportedCurrency;
|
|
620
|
+
revenue_cents: number;
|
|
621
|
+
sale_count: number;
|
|
622
|
+
average_order_value_cents: number;
|
|
623
|
+
}
|
|
624
|
+
interface CustomerSummary {
|
|
625
|
+
/** The E.164 phone — the canonical customer id. */
|
|
626
|
+
customer_id: string;
|
|
627
|
+
display_name: string | null;
|
|
628
|
+
email: string | null;
|
|
629
|
+
phone: string;
|
|
630
|
+
first_purchase_at: string;
|
|
631
|
+
last_purchase_at: string;
|
|
632
|
+
purchase_count: number;
|
|
633
|
+
segment: CustomerSegment;
|
|
634
|
+
totals: CustomerCurrencyTotal[];
|
|
635
|
+
}
|
|
636
|
+
type CustomerProfile = CustomerSummary;
|
|
637
|
+
interface CustomerListQuery extends Omit<SaleFilters, "external_id"> {
|
|
638
|
+
segment?: CustomerSegment;
|
|
639
|
+
sort?: CustomerSortField;
|
|
640
|
+
order?: SaleSortOrder;
|
|
641
|
+
cursor?: string | null;
|
|
642
|
+
limit?: number;
|
|
643
|
+
want_total?: boolean;
|
|
644
|
+
}
|
|
645
|
+
interface CustomerListPage {
|
|
646
|
+
items: CustomerSummary[];
|
|
647
|
+
next_cursor: string | null;
|
|
648
|
+
total_count: number | null;
|
|
649
|
+
}
|
|
650
|
+
interface CustomerGetOptions {
|
|
651
|
+
include_sales?: boolean;
|
|
652
|
+
limit?: number;
|
|
653
|
+
cursor?: string | null;
|
|
654
|
+
}
|
|
655
|
+
interface CustomerGetResult {
|
|
656
|
+
customer: CustomerProfile;
|
|
657
|
+
/** Present only when `include_sales: true` (and a business-scoped key). */
|
|
658
|
+
sales?: SaleCursorPage | null;
|
|
659
|
+
}
|
|
660
|
+
interface CustomerSummaryQuery extends SaleFilters {
|
|
661
|
+
range?: NamedRange;
|
|
662
|
+
since?: string;
|
|
663
|
+
until?: string;
|
|
664
|
+
timezone?: string;
|
|
665
|
+
compare_to?: CompareTo;
|
|
666
|
+
}
|
|
667
|
+
interface CustomerSegmentCount {
|
|
668
|
+
segment: CustomerSegment;
|
|
669
|
+
count: number;
|
|
670
|
+
}
|
|
671
|
+
interface CustomerCurrencyDelta {
|
|
672
|
+
currency: SupportedCurrency;
|
|
673
|
+
revenue_cents_delta: number;
|
|
674
|
+
/** Ratio (0.12 = +12%); null when previous revenue was 0. */
|
|
675
|
+
revenue_pct_delta: number | null;
|
|
676
|
+
}
|
|
677
|
+
interface CustomerKpisDeltas {
|
|
678
|
+
total_customers_delta: number;
|
|
679
|
+
new_customers_delta: number;
|
|
680
|
+
returning_customers_delta: number;
|
|
681
|
+
repeat_rate_delta: number;
|
|
682
|
+
ltv_by_currency: CustomerCurrencyDelta[];
|
|
683
|
+
}
|
|
684
|
+
interface CustomerKpisPrevious {
|
|
685
|
+
window_since: string;
|
|
686
|
+
window_until: string;
|
|
687
|
+
total_customers: number;
|
|
688
|
+
new_customers: number;
|
|
689
|
+
returning_customers: number;
|
|
690
|
+
repeat_rate: number;
|
|
691
|
+
ltv_by_currency: CustomerCurrencyTotal[];
|
|
692
|
+
}
|
|
693
|
+
interface CustomerKpis {
|
|
694
|
+
range: NamedRange;
|
|
695
|
+
timezone: string;
|
|
696
|
+
window_since: string;
|
|
697
|
+
window_until: string;
|
|
698
|
+
total_customers: number;
|
|
699
|
+
new_customers: number;
|
|
700
|
+
returning_customers: number;
|
|
701
|
+
repeat_rate: number;
|
|
702
|
+
by_segment: CustomerSegmentCount[];
|
|
703
|
+
ltv_by_currency: CustomerCurrencyTotal[];
|
|
704
|
+
/** Present only when `compare_to` is set. */
|
|
705
|
+
previous?: CustomerKpisPrevious | null;
|
|
706
|
+
deltas?: CustomerKpisDeltas | null;
|
|
707
|
+
}
|
|
708
|
+
interface BusinessConfigService {
|
|
709
|
+
key: string;
|
|
710
|
+
label: string;
|
|
711
|
+
archived: boolean;
|
|
712
|
+
}
|
|
713
|
+
interface BusinessConfigFeatures {
|
|
714
|
+
customers: boolean;
|
|
715
|
+
comparisons: boolean;
|
|
716
|
+
retention: boolean;
|
|
717
|
+
}
|
|
718
|
+
interface BusinessConfig {
|
|
719
|
+
business_id: string;
|
|
720
|
+
display_name: string;
|
|
721
|
+
timezone: string;
|
|
722
|
+
primary_currency: SupportedCurrency;
|
|
723
|
+
currencies: SupportedCurrency[];
|
|
724
|
+
default_phone_country: string | null;
|
|
725
|
+
services: BusinessConfigService[];
|
|
726
|
+
features: BusinessConfigFeatures;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
/** Shared config for every sales HTTP helper. */
|
|
730
|
+
interface SalesTransportConfig {
|
|
731
|
+
/** Public (`aranv_pk_…`) or secret (`aranv_sk_…`) API key. */
|
|
732
|
+
apiKey: string;
|
|
733
|
+
/**
|
|
734
|
+
* Base tracking endpoint, e.g. `https://aranovainternal-production.up.railway.app/tracking`.
|
|
735
|
+
* The `/sales` path is appended by the helpers.
|
|
736
|
+
*/
|
|
737
|
+
endpoint: string;
|
|
738
|
+
/** Optional SDK identity headers (mirrors the event ingest client). */
|
|
739
|
+
sdkVersion?: string;
|
|
740
|
+
packageName?: string;
|
|
741
|
+
surface?: string;
|
|
742
|
+
environment?: string;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Single awaited request used by every sales helper. Unlike the event queue,
|
|
746
|
+
* this surfaces failures: any non-2xx rejects with an {@link AranovaApiError}.
|
|
747
|
+
* Returns `undefined` for 204 No Content.
|
|
748
|
+
*/
|
|
749
|
+
declare function salesRequest<T>(config: SalesTransportConfig, method: string, path: string, body?: unknown): Promise<T>;
|
|
750
|
+
|
|
751
|
+
/** Config for {@link createSalesClient}. */
|
|
752
|
+
interface SalesClientConfig extends SalesTransportConfig {
|
|
753
|
+
/** Applied when an individual `record()` call omits `currency`. */
|
|
754
|
+
defaultCurrency?: SupportedCurrency;
|
|
755
|
+
/**
|
|
756
|
+
* GAP28: when present, `record()` ALSO fires a real-time on-site conversion
|
|
757
|
+
* (`gtag('event','conversion')`) for any recorded service that has a `firing` send_to in
|
|
758
|
+
* the resolved config. Consent-gated + de-duped; no-ops server-side. Wire it from
|
|
759
|
+
* `resolveConversionConfig(...)`.
|
|
760
|
+
*/
|
|
761
|
+
firing?: Pick<ConversionConfigStore, "getFiring">;
|
|
762
|
+
}
|
|
763
|
+
/** Phone-keyed customer rollups (sk-only; a public key gets a `403`). */
|
|
764
|
+
interface SalesCustomersClient {
|
|
765
|
+
list(query?: CustomerListQuery): Promise<CustomerListPage>;
|
|
766
|
+
/** `id` is the customer's E.164 phone. */
|
|
767
|
+
get(id: string, options?: CustomerGetOptions): Promise<CustomerGetResult>;
|
|
768
|
+
summary(query?: CustomerSummaryQuery): Promise<CustomerKpis>;
|
|
769
|
+
}
|
|
770
|
+
/** Business config (low-sensitivity — accepts a public or secret key). */
|
|
771
|
+
interface SalesBusinessClient {
|
|
772
|
+
config(): Promise<BusinessConfig>;
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* One isomorphic sales client — what a key may *do* is enforced by the backend,
|
|
776
|
+
* not by hiding methods. A **public** key (`aranv_pk_…`) may `record` (the
|
|
777
|
+
* backend rejects reads/CRUD from it with a `403`); a **secret** key
|
|
778
|
+
* (`aranv_sk_…`), used **server-side only**, gets full read/list/update/delete.
|
|
779
|
+
* Never ship a secret key in a browser bundle.
|
|
780
|
+
*
|
|
781
|
+
* Generic over the service-key union `TService`: bind the type emitted by
|
|
782
|
+
* `@aranova/tracking-cli gen` for compile-time-checked `service` values.
|
|
783
|
+
*/
|
|
784
|
+
interface SalesClient<TService extends string = string> {
|
|
785
|
+
record(input: Omit<SaleInput, "currency" | "occurred_at" | "service" | "services"> & {
|
|
786
|
+
service?: TService | null;
|
|
787
|
+
services?: Array<{
|
|
788
|
+
service: TService;
|
|
789
|
+
amount_cents: number;
|
|
790
|
+
}>;
|
|
791
|
+
currency?: SupportedCurrency;
|
|
792
|
+
occurred_at?: string;
|
|
793
|
+
}): Promise<Sale>;
|
|
794
|
+
/**
|
|
795
|
+
* Record a revenue sale — the intent-revealing alias of {@link record} in the unified-goal
|
|
796
|
+
* API. POSTs `/sales` and ALSO fires the on-site conversion when the sale-goal is
|
|
797
|
+
* WEBPAGE-mapped. Use this for anything with real revenue; use {@link trackConversion} for a
|
|
798
|
+
* non-revenue on-page event.
|
|
799
|
+
*/
|
|
800
|
+
recordSale(input: Omit<SaleInput, "currency" | "occurred_at" | "service" | "services"> & {
|
|
801
|
+
service?: TService | null;
|
|
802
|
+
services?: Array<{
|
|
803
|
+
service: TService;
|
|
804
|
+
amount_cents: number;
|
|
805
|
+
}>;
|
|
806
|
+
currency?: SupportedCurrency;
|
|
807
|
+
occurred_at?: string;
|
|
808
|
+
}): Promise<Sale>;
|
|
809
|
+
/**
|
|
810
|
+
* Fire ONLY the on-site conversion for an event-goal `key` — for MANUAL event-goals
|
|
811
|
+
* (`form_submit`, `phone_click`, `cta_click`) the consumer triggers explicitly. No `/sales`
|
|
812
|
+
* write. No-ops when the goal isn't WEBPAGE-mapped (no resolved `send_to`) or the config
|
|
813
|
+
* isn't wired. Consent-gated + de-duped. (Automatic event-goals fire themselves — no call.)
|
|
814
|
+
*/
|
|
815
|
+
trackConversion(key: string, options?: {
|
|
816
|
+
transactionId?: string | null;
|
|
817
|
+
value?: number | null;
|
|
818
|
+
currency?: SupportedCurrency;
|
|
819
|
+
}): void;
|
|
820
|
+
/** Keyset list with optional server sort + opt-in `total_count`. */
|
|
821
|
+
list(query?: SaleListQueryV2): Promise<SaleCursorPage>;
|
|
822
|
+
/**
|
|
823
|
+
* Currency-grouped aggregations for the key's business. Additive v2 options:
|
|
824
|
+
* calendar/custom ranges, IANA `timezone`, `granularity`, and `compare_to`.
|
|
825
|
+
* Legacy `24h/7d/30d` keep their exact prior numbers. Secret key only.
|
|
826
|
+
*/
|
|
827
|
+
summary(query: SaleSummaryQueryV2): Promise<SaleSummaryV2>;
|
|
828
|
+
get(id: string): Promise<Sale>;
|
|
829
|
+
update(id: string, patch: Omit<SaleUpdateInput, "service" | "services"> & {
|
|
830
|
+
service?: TService | null;
|
|
831
|
+
services?: Array<{
|
|
832
|
+
service: TService;
|
|
833
|
+
amount_cents: number;
|
|
834
|
+
}>;
|
|
835
|
+
}): Promise<Sale>;
|
|
836
|
+
delete(id: string): Promise<void>;
|
|
837
|
+
/** Phone-keyed customer rollups (sk-only). */
|
|
838
|
+
customers: SalesCustomersClient;
|
|
839
|
+
/** Business config (pk or sk). */
|
|
840
|
+
business: SalesBusinessClient;
|
|
841
|
+
}
|
|
842
|
+
declare function createSalesClient<TService extends string = string>(config: SalesClientConfig): SalesClient<TService>;
|
|
843
|
+
|
|
844
|
+
/**
|
|
845
|
+
* Error thrown by the sales client (`createSalesClient`) on a
|
|
846
|
+
* non-2xx response. Unlike the fire-and-forget event queue (which swallows
|
|
847
|
+
* failures), a sale is a transaction the caller must be able to react to.
|
|
848
|
+
*/
|
|
849
|
+
declare class AranovaApiError extends Error {
|
|
850
|
+
readonly status: number;
|
|
851
|
+
readonly code: string | undefined;
|
|
852
|
+
readonly requestId: string | undefined;
|
|
853
|
+
constructor(message: string, options: {
|
|
854
|
+
status: number;
|
|
855
|
+
code?: string;
|
|
856
|
+
requestId?: string;
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* Convert a major amount (dollars `250.5`) to integer minor units (`25050`).
|
|
862
|
+
*
|
|
863
|
+
* Convenience only — the wire is always integer cents. Uses float multiply +
|
|
864
|
+
* `Math.round`, so values that aren't exactly representable in binary float
|
|
865
|
+
* (e.g. `1.005`) can round to the neighbouring cent. If you already hold an
|
|
866
|
+
* exact cents integer, pass it straight through and skip this helper.
|
|
867
|
+
*/
|
|
868
|
+
declare function toMinor(amount: number, currency: SupportedCurrency): number;
|
|
869
|
+
/** Convert integer minor units (`25050`) to a major amount (`250.5`). */
|
|
870
|
+
declare function fromMinor(cents: number, currency: SupportedCurrency): number;
|
|
871
|
+
/**
|
|
872
|
+
* Format integer minor units as a localized currency string (e.g. `"$250.50"`).
|
|
873
|
+
* Uses the built-in `Intl.NumberFormat` — no extra dependency.
|
|
874
|
+
*/
|
|
875
|
+
declare function formatMoney(cents: number, currency: SupportedCurrency, locale?: string): string;
|
|
876
|
+
/**
|
|
877
|
+
* Format an ISO timestamp in a specific IANA time zone (e.g. `America/Toronto`),
|
|
878
|
+
* so dashboards stop hand-rolling `Intl`. Defaults to a short date-time; pass
|
|
879
|
+
* `opts` to override fields. The `timeZone` is always forced to the argument.
|
|
880
|
+
*/
|
|
881
|
+
declare function formatDateInTz(iso: string, timeZone: string, opts?: Intl.DateTimeFormatOptions, locale?: string): string;
|
|
882
|
+
|
|
883
|
+
/** A business's active service, as returned by `GET /tracking/services`. */
|
|
884
|
+
interface PublicServiceItem {
|
|
885
|
+
key: string;
|
|
886
|
+
label: string;
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Fetch the caller's business's active service taxonomy. Accepts a public or
|
|
890
|
+
* secret key (the taxonomy is low-sensitivity category names). Powers the
|
|
891
|
+
* `@aranova/tracking-cli gen` codegen.
|
|
892
|
+
*/
|
|
893
|
+
declare function fetchServices(config: SalesTransportConfig): Promise<PublicServiceItem[]>;
|
|
894
|
+
|
|
895
|
+
export { type SalesCustomersClient as $, AranovaApiError 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 SaleSummaryQuery as T, type SaleSummaryQueryV2 as U, type SaleSummaryV2 as V, type SaleUpdateInput as W, type SalesBusinessClient as X, type SalesCategoryBreakdown as Y, type SalesClient as Z, type SalesClientConfig as _, type BusinessConfigFeatures as a, type SalesServiceBreakdown as a0, type SalesTransportConfig as a1, type SalesTrendPoint as a2, type SummaryCurrencyDelta as a3, type SummaryDeltas as a4, type SummaryWindow as a5, type SupportedCurrency as a6, TRACKING_RANGES as a7, type TrackingOverviewRange as a8, createSalesClient as a9, fetchServices as aa, formatDateInTz as ab, formatMoney as ac, fromMinor as ad, resolveConversionConfig as ae, saleCreateSchema as af, saleItemSchema as ag, saleServiceSchema as ah, saleUpdateSchema as ai, salesRequest as aj, toMinor as ak, type BusinessConfigService as b, type CompareTo as c, type ConversionConfigStore as d, type CurrencyRevenue as e, type CustomerCurrencyDelta as f, type CustomerCurrencyTotal as g, type CustomerGetOptions as h, type CustomerGetResult as i, type CustomerKpis as j, type CustomerKpisDeltas as k, type CustomerKpisPrevious as l, type CustomerListPage as m, type CustomerListQuery as n, type CustomerProfile as o, type CustomerSegment as p, type CustomerSegmentCount as q, type CustomerSortField as r, type CustomerSummary as s, type CustomerSummaryQuery as t, type NamedRange as u, type Sale as v, type SaleCursorPage as w, type SaleFilters as x, type SaleInput as y, type SaleItem as z };
|