@aranova/tracking-next 0.27.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blog-server.d.mts +2 -1
- package/dist/blog-server.d.ts +2 -1
- package/dist/blog-server.js +121 -98
- package/dist/blog-server.js.map +1 -1
- package/dist/blog-server.mjs +86 -63
- package/dist/blog-server.mjs.map +1 -1
- package/dist/blog.d.mts +651 -1755
- package/dist/blog.d.ts +651 -1755
- package/dist/blog.js +121 -98
- package/dist/blog.js.map +1 -1
- package/dist/blog.mjs +86 -63
- package/dist/blog.mjs.map +1 -1
- package/dist/calendar-server.d.mts +2 -2
- package/dist/calendar-server.d.ts +2 -2
- package/dist/calendar-server.js +0 -26
- package/dist/calendar-server.js.map +1 -1
- package/dist/calendar-server.mjs +0 -26
- package/dist/calendar-server.mjs.map +1 -1
- package/dist/calendar.d.mts +3 -3
- package/dist/calendar.d.ts +3 -3
- package/dist/calendar.js +227 -126
- package/dist/calendar.js.map +1 -1
- package/dist/calendar.mjs +216 -125
- package/dist/calendar.mjs.map +1 -1
- package/dist/client.d.mts +11 -4
- package/dist/client.d.ts +11 -4
- package/dist/client.js +611 -347
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +611 -347
- package/dist/client.mjs.map +1 -1
- package/dist/index.d.mts +9 -8
- package/dist/index.d.ts +9 -8
- package/dist/index.js +550 -487
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +539 -487
- package/dist/index.mjs.map +1 -1
- package/dist/ingest-typed-MBuMe9Pn.d.ts +883 -0
- package/dist/ingest-typed-UA13xTfI.d.mts +883 -0
- package/dist/middleware.js +0 -467
- package/dist/middleware.js.map +1 -1
- package/dist/middleware.mjs +0 -467
- package/dist/middleware.mjs.map +1 -1
- package/dist/{phone-utils-BVzSNBf1.d.mts → phone-utils-C0ds6cqZ.d.mts} +24 -78
- package/dist/{phone-utils-BVzSNBf1.d.ts → phone-utils-C0ds6cqZ.d.ts} +24 -78
- package/dist/phone.d.mts +2 -2
- package/dist/phone.d.ts +2 -2
- package/dist/phone.js +0 -464
- package/dist/phone.js.map +1 -1
- package/dist/phone.mjs +0 -464
- package/dist/phone.mjs.map +1 -1
- package/dist/{sales-IGC2tq4J.d.ts → sales-DQC815f3.d.ts} +90 -329
- package/dist/{sales-DQGzXSgL.d.mts → sales-w1reW_Y3.d.mts} +90 -329
- package/dist/sales.d.mts +3 -3
- package/dist/sales.d.ts +3 -3
- package/dist/sales.js +270 -127
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +259 -127
- package/dist/sales.mjs.map +1 -1
- package/dist/server.d.mts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js +0 -467
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +0 -467
- package/dist/server.mjs.map +1 -1
- package/dist/{tracking-config-runtime-D7prdTE1.d.mts → tracking-config-runtime-C6H7ofmo.d.mts} +6 -0
- package/dist/{tracking-config-runtime-D7prdTE1.d.ts → tracking-config-runtime-C6H7ofmo.d.ts} +6 -0
- package/dist/transport-CDmGOiCq.d.ts +253 -0
- package/dist/transport-I_cMSFQ6.d.mts +253 -0
- package/package.json +2 -2
- package/dist/ingest-typed-BxLFlZ7N.d.mts +0 -1371
- package/dist/ingest-typed-ByQVRMvP.d.ts +0 -1371
- package/dist/transport-C-_rFSR4.d.ts +0 -721
- package/dist/transport-yUF5Wize.d.mts +0 -721
package/dist/sales.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/sales.ts
|
|
@@ -25,6 +35,7 @@ __export(sales_exports, {
|
|
|
25
35
|
SUPPORTED_CURRENCIES: () => SUPPORTED_CURRENCIES,
|
|
26
36
|
TRACKING_RANGES: () => TRACKING_RANGES,
|
|
27
37
|
createSalesClient: () => createSalesClient,
|
|
38
|
+
currencySchema: () => currencySchema,
|
|
28
39
|
fetchServices: () => fetchServices,
|
|
29
40
|
formatDateInTz: () => formatDateInTz,
|
|
30
41
|
formatMoney: () => formatMoney,
|
|
@@ -77,7 +88,7 @@ function normalizeEmail(raw) {
|
|
|
77
88
|
return EMAIL_SHAPE.test(cleaned) ? cleaned : null;
|
|
78
89
|
}
|
|
79
90
|
function stashUserData(data, country) {
|
|
80
|
-
const
|
|
91
|
+
const email3 = normalizeEmail(data.email);
|
|
81
92
|
let phoneNumber = null;
|
|
82
93
|
if (typeof data.phone === "string" && data.phone.length > 0) {
|
|
83
94
|
try {
|
|
@@ -87,17 +98,17 @@ function stashUserData(data, country) {
|
|
|
87
98
|
}
|
|
88
99
|
}
|
|
89
100
|
stash = {
|
|
90
|
-
email:
|
|
101
|
+
email: email3 ?? stash.email,
|
|
91
102
|
phoneNumber: phoneNumber ?? stash.phoneNumber
|
|
92
103
|
};
|
|
93
104
|
}
|
|
94
105
|
function applyUserDataForConversion(explicit, country) {
|
|
95
106
|
if (typeof window === "undefined" || typeof window.gtag !== "function") return false;
|
|
96
|
-
let
|
|
107
|
+
let email3 = stash.email;
|
|
97
108
|
let phoneNumber = stash.phoneNumber;
|
|
98
109
|
if (explicit) {
|
|
99
110
|
const normalizedEmail = normalizeEmail(explicit.email);
|
|
100
|
-
if (normalizedEmail)
|
|
111
|
+
if (normalizedEmail) email3 = normalizedEmail;
|
|
101
112
|
if (typeof explicit.phone === "string" && explicit.phone.length > 0) {
|
|
102
113
|
try {
|
|
103
114
|
phoneNumber = toE164(explicit.phone, country) ?? phoneNumber;
|
|
@@ -105,10 +116,10 @@ function applyUserDataForConversion(explicit, country) {
|
|
|
105
116
|
}
|
|
106
117
|
}
|
|
107
118
|
}
|
|
108
|
-
if (
|
|
119
|
+
if (email3 === null && phoneNumber === null) return false;
|
|
109
120
|
try {
|
|
110
121
|
window.gtag("set", "user_data", {
|
|
111
|
-
...
|
|
122
|
+
...email3 !== null ? { email: email3 } : {},
|
|
112
123
|
...phoneNumber !== null ? { phone_number: phoneNumber } : {}
|
|
113
124
|
});
|
|
114
125
|
return true;
|
|
@@ -210,29 +221,6 @@ function fireConversionWithConsent(input, options) {
|
|
|
210
221
|
}
|
|
211
222
|
}
|
|
212
223
|
|
|
213
|
-
// ../tracking-core/src/events/page-view.ts
|
|
214
|
-
var import_zod = require("zod");
|
|
215
|
-
var pageViewMetadataSchema = import_zod.z.object({
|
|
216
|
-
page: import_zod.z.object({
|
|
217
|
-
title: import_zod.z.string().nullable(),
|
|
218
|
-
path: import_zod.z.string(),
|
|
219
|
-
search: import_zod.z.string(),
|
|
220
|
-
hash: import_zod.z.string()
|
|
221
|
-
}).strict(),
|
|
222
|
-
referrer: import_zod.z.string().nullable(),
|
|
223
|
-
// `.nullable().optional()` — absent (undefined) OR explicit null OR a
|
|
224
|
-
// real viewport object. Mirrors Pydantic's `_Viewport | None = None`
|
|
225
|
-
// on the backend side so the drift test stays clean.
|
|
226
|
-
viewport: import_zod.z.object({
|
|
227
|
-
w: import_zod.z.number(),
|
|
228
|
-
h: import_zod.z.number()
|
|
229
|
-
}).strict().nullable().optional()
|
|
230
|
-
}).strict();
|
|
231
|
-
var pageViewConfigSchema = import_zod.z.object({}).strict();
|
|
232
|
-
|
|
233
|
-
// ../tracking-core/src/session.ts
|
|
234
|
-
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
235
|
-
|
|
236
224
|
// ../tracking-core/src/ingest.ts
|
|
237
225
|
var API_KEY_HEADER = "X-Aranova-Api-Key";
|
|
238
226
|
var SDK_VERSION_HEADER = "X-Aranova-Sdk-Version";
|
|
@@ -277,9 +265,9 @@ async function apiRequest(config, method, path, body, extraHeaders) {
|
|
|
277
265
|
try {
|
|
278
266
|
const parsed = await response.json();
|
|
279
267
|
if (parsed && typeof parsed === "object") {
|
|
280
|
-
const
|
|
281
|
-
if (typeof
|
|
282
|
-
if (typeof
|
|
268
|
+
const record3 = parsed;
|
|
269
|
+
if (typeof record3.detail === "string") detail = record3.detail;
|
|
270
|
+
if (typeof record3.code === "string") code = record3.code;
|
|
283
271
|
}
|
|
284
272
|
} catch {
|
|
285
273
|
}
|
|
@@ -297,9 +285,9 @@ async function apiRequest(config, method, path, body, extraHeaders) {
|
|
|
297
285
|
var salesRequest = apiRequest;
|
|
298
286
|
|
|
299
287
|
// ../tracking-core/src/resources/intl/date.ts
|
|
300
|
-
function formatDateInTz(
|
|
301
|
-
const date = new Date(
|
|
302
|
-
if (Number.isNaN(date.getTime())) return
|
|
288
|
+
function formatDateInTz(iso3, timeZone, opts, locale) {
|
|
289
|
+
const date = new Date(iso3);
|
|
290
|
+
if (Number.isNaN(date.getTime())) return iso3;
|
|
303
291
|
return new Intl.DateTimeFormat(locale, {
|
|
304
292
|
year: "numeric",
|
|
305
293
|
month: "short",
|
|
@@ -363,7 +351,7 @@ function fireRecordedConversions(firing, input, recorded, sale, currency) {
|
|
|
363
351
|
}
|
|
364
352
|
function createSalesClient(config) {
|
|
365
353
|
if (config.firing) registerCapability("conversion_goals_manual");
|
|
366
|
-
async function
|
|
354
|
+
async function record3(input) {
|
|
367
355
|
const currency = input.currency ?? config.defaultCurrency;
|
|
368
356
|
if (!currency) {
|
|
369
357
|
throw new Error(
|
|
@@ -389,9 +377,9 @@ function createSalesClient(config) {
|
|
|
389
377
|
return sale;
|
|
390
378
|
}
|
|
391
379
|
return {
|
|
392
|
-
record,
|
|
380
|
+
record: record3,
|
|
393
381
|
// recordSale is the intent-revealing alias — same behavior, clearer call site.
|
|
394
|
-
recordSale:
|
|
382
|
+
recordSale: record3,
|
|
395
383
|
trackConversion(key, options) {
|
|
396
384
|
if (config.firing && "fireConversion" in config.firing) {
|
|
397
385
|
if (options?.userData && getConsentState() !== "denied") stashUserData(options.userData);
|
|
@@ -510,115 +498,269 @@ function createSalesClient(config) {
|
|
|
510
498
|
}
|
|
511
499
|
|
|
512
500
|
// ../tracking-core/src/resources/sales/schema.ts
|
|
513
|
-
var
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
var
|
|
517
|
-
var
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
501
|
+
var z2 = __toESM(require("zod/mini"));
|
|
502
|
+
|
|
503
|
+
// ../tracking-core/src/resources/sales/generated/zod.gen.ts
|
|
504
|
+
var z = __toESM(require("zod/mini"));
|
|
505
|
+
var zErrorCode = z.enum([
|
|
506
|
+
"missing_credentials",
|
|
507
|
+
"invalid_api_key",
|
|
508
|
+
"not_authenticated",
|
|
509
|
+
"wrong_key_type",
|
|
510
|
+
"origin_missing",
|
|
511
|
+
"origin_not_allowed",
|
|
512
|
+
"capability_denied",
|
|
513
|
+
"session_required",
|
|
514
|
+
"operator_only",
|
|
515
|
+
"cross_tenant",
|
|
516
|
+
"business_id_required",
|
|
517
|
+
"bad_request",
|
|
518
|
+
"not_found",
|
|
519
|
+
"conflict",
|
|
520
|
+
"incompatible_payload",
|
|
521
|
+
"repeat_confirmation_required",
|
|
522
|
+
"idempotency_conflict",
|
|
523
|
+
"validation_error",
|
|
524
|
+
"unknown_service",
|
|
525
|
+
"invalid_sale_properties",
|
|
526
|
+
"invalid_cursor",
|
|
527
|
+
"rate_limited",
|
|
528
|
+
"internal_error"
|
|
529
|
+
]);
|
|
530
|
+
var zSaleItemEntitySchema = z.object({
|
|
531
|
+
category: z.nullable(z.string()),
|
|
532
|
+
external_item_id: z.nullable(z.string()),
|
|
533
|
+
id: z.uuid(),
|
|
534
|
+
name: z.nullable(z.string()),
|
|
535
|
+
quantity: z.string().check(z.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
|
|
536
|
+
unit_cost_cents: z.nullable(z.int()),
|
|
537
|
+
unit_price_cents: z.int()
|
|
538
|
+
});
|
|
539
|
+
var zSaleItemInputSchema = z.strictObject({
|
|
540
|
+
category: z.nullish(z.string()),
|
|
541
|
+
external_item_id: z.nullish(z.string()),
|
|
542
|
+
name: z.nullish(z.string()),
|
|
543
|
+
quantity: z.string().check(z.regex(/^\d+(\.\d{1,3})?$/)),
|
|
544
|
+
unit_cost_cents: z.nullish(z.int().check(z.gte(0))),
|
|
545
|
+
unit_price_cents: z.int().check(z.gte(0))
|
|
546
|
+
});
|
|
547
|
+
var zSaleServiceEntitySchema = z.object({
|
|
548
|
+
amount_cents: z.int(),
|
|
549
|
+
id: z.uuid(),
|
|
550
|
+
mapped: z.nullable(z.boolean()),
|
|
551
|
+
service_id: z.uuid(),
|
|
552
|
+
service_key: z.string(),
|
|
553
|
+
service_label: z.string()
|
|
554
|
+
});
|
|
555
|
+
var zSaleServiceInputSchema = z.strictObject({
|
|
556
|
+
amount_cents: z.int().check(z.gte(0)),
|
|
557
|
+
service: z.string()
|
|
558
|
+
});
|
|
559
|
+
var zSmsAutomationState = z.enum([
|
|
560
|
+
"needs_check",
|
|
561
|
+
"failed",
|
|
562
|
+
"undelivered",
|
|
563
|
+
"blocked_opted_out",
|
|
564
|
+
"withheld",
|
|
565
|
+
"queued",
|
|
566
|
+
"sent",
|
|
567
|
+
"delivered",
|
|
568
|
+
"eligible",
|
|
569
|
+
"not_applicable"
|
|
570
|
+
]);
|
|
571
|
+
var zSmsWithheldReason = z.enum([
|
|
572
|
+
"automation_disabled",
|
|
573
|
+
"sms_disabled",
|
|
574
|
+
"no_phone",
|
|
575
|
+
"no_consent",
|
|
576
|
+
"no_customer_identity",
|
|
577
|
+
"missing_customer_name",
|
|
578
|
+
"placeholder_customer_name",
|
|
579
|
+
"opted_out",
|
|
580
|
+
"already_messaged",
|
|
581
|
+
"sender_not_ready",
|
|
582
|
+
"missing_review_url",
|
|
583
|
+
"no_handler",
|
|
584
|
+
"dispatch_already_recorded",
|
|
585
|
+
"text_back_disabled",
|
|
586
|
+
"number_not_active",
|
|
587
|
+
"a2p_registration_required",
|
|
588
|
+
"alert_recipient_cannot_receive_sms",
|
|
589
|
+
"line_type_unresolved"
|
|
590
|
+
]);
|
|
591
|
+
var zSaleSmsStatusSchema = z.object({
|
|
592
|
+
can_send_now: z._default(z.boolean(), false),
|
|
593
|
+
last_message_at: z.nullable(z.iso.datetime({ offset: true })),
|
|
594
|
+
reason_detail: z.nullable(z.string()),
|
|
595
|
+
state: zSmsAutomationState,
|
|
596
|
+
suppressed_by_other_sale: z._default(z.boolean(), false),
|
|
597
|
+
withheld_reason: z.nullable(zSmsWithheldReason)
|
|
598
|
+
});
|
|
599
|
+
var zSupportedCurrency = z.enum(["USD", "CAD"]);
|
|
600
|
+
var zTrackingEnvironment = z.enum(["production", "development"]);
|
|
601
|
+
var zSaleCreateSchema = z.strictObject({
|
|
602
|
+
amount_total_cents: z.nullish(z.int().check(z.gte(0))),
|
|
603
|
+
currency: zSupportedCurrency,
|
|
604
|
+
customer_email: z.nullish(z.email().check(z.maxLength(320))),
|
|
605
|
+
customer_name: z.nullish(z.string().check(z.maxLength(200))),
|
|
606
|
+
customer_phone: z.nullish(z.string().check(z.maxLength(64))),
|
|
607
|
+
description: z.nullish(z.string()),
|
|
608
|
+
environment: z._default(z.optional(zTrackingEnvironment), "production"),
|
|
609
|
+
external_id: z.nullish(z.string()),
|
|
610
|
+
items: z.optional(z.array(zSaleItemInputSchema)),
|
|
611
|
+
metadata: z.nullish(z.record(z.string(), z.unknown())),
|
|
612
|
+
occurred_at: z.iso.datetime({ offset: true }),
|
|
613
|
+
service: z.nullish(z.string()),
|
|
614
|
+
services: z.nullish(z.array(zSaleServiceInputSchema)),
|
|
615
|
+
sms_consent: z.nullish(z.boolean())
|
|
616
|
+
});
|
|
617
|
+
var zValidationError = z.object({
|
|
618
|
+
ctx: z.optional(z.record(z.string(), z.unknown())),
|
|
619
|
+
input: z.optional(z.unknown()),
|
|
620
|
+
loc: z.array(z.union([z.string(), z.int()])),
|
|
621
|
+
msg: z.string(),
|
|
622
|
+
type: z.string()
|
|
623
|
+
});
|
|
624
|
+
var zHttpValidationError = z.object({
|
|
625
|
+
detail: z.optional(z.array(zValidationError))
|
|
626
|
+
});
|
|
627
|
+
var zValidationErrorItem = z.object({
|
|
628
|
+
loc: z.array(z.union([z.string(), z.int()])),
|
|
629
|
+
msg: z.string(),
|
|
630
|
+
type: z.string()
|
|
631
|
+
});
|
|
632
|
+
var zApiErrorSchema = z.object({
|
|
633
|
+
code: zErrorCode,
|
|
634
|
+
context: z._default(z.nullish(z.record(z.string(), z.unknown())), null),
|
|
635
|
+
detail: z.string(),
|
|
636
|
+
errors: z._default(z.nullish(z.array(zValidationErrorItem)), null),
|
|
637
|
+
request_id: z._default(z.nullish(z.string()), null)
|
|
638
|
+
});
|
|
639
|
+
var zWritebackEmailSource = z.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
|
|
640
|
+
var zWritebackEnrichmentStatus = z.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
|
|
641
|
+
var zWritebackSaleUploadCounts = z.object({
|
|
642
|
+
failed: z._default(z.int(), 0),
|
|
643
|
+
pending: z._default(z.int(), 0),
|
|
644
|
+
skipped: z._default(z.int(), 0),
|
|
645
|
+
submitted: z._default(z.int(), 0),
|
|
646
|
+
total: z._default(z.int(), 0),
|
|
647
|
+
uploaded: z._default(z.int(), 0)
|
|
648
|
+
});
|
|
649
|
+
var zSaleWritebackStatusSchema = z.object({
|
|
650
|
+
blocked_reason: z.nullable(z.string()),
|
|
651
|
+
can_dispatch: z._default(z.boolean(), false),
|
|
652
|
+
email_source: z.nullable(zWritebackEmailSource),
|
|
653
|
+
enrichment_status: z.nullable(zWritebackEnrichmentStatus),
|
|
654
|
+
gclid_attached: z._default(z.boolean(), false),
|
|
655
|
+
identifiers_sent: z.nullable(z.string()),
|
|
656
|
+
mapped_service_ids: z.array(z.uuid()),
|
|
657
|
+
matched_submit_count: z.nullable(z.int()),
|
|
658
|
+
needs_force: z._default(z.boolean(), false),
|
|
659
|
+
rollup: z.enum([
|
|
660
|
+
"failed",
|
|
661
|
+
"skipped",
|
|
662
|
+
"pending",
|
|
663
|
+
"submitted",
|
|
664
|
+
"uploaded",
|
|
665
|
+
"not_uploaded",
|
|
666
|
+
"out_of_window",
|
|
667
|
+
"blocked"
|
|
668
|
+
]),
|
|
669
|
+
stale: z._default(z.boolean(), false),
|
|
670
|
+
uncovered_service_ids: z.array(z.uuid()),
|
|
671
|
+
uploads: zWritebackSaleUploadCounts
|
|
672
|
+
});
|
|
673
|
+
var zSaleEntitySchema = z.object({
|
|
674
|
+
amount_total_cents: z.int(),
|
|
675
|
+
business_id: z.uuid(),
|
|
676
|
+
business_name: z.nullable(z.string()),
|
|
677
|
+
created_at: z.iso.datetime({ offset: true }),
|
|
678
|
+
currency: z.string(),
|
|
679
|
+
customer_email: z.nullable(z.string()),
|
|
680
|
+
customer_name: z.nullable(z.string()),
|
|
681
|
+
customer_name_placeholder_confirmed: z._default(z.boolean(), false),
|
|
682
|
+
customer_name_placeholder_confirmed_at: z.nullable(z.iso.datetime({ offset: true })),
|
|
683
|
+
customer_phone: z.nullable(z.string()),
|
|
684
|
+
description: z.nullable(z.string()),
|
|
685
|
+
environment: zTrackingEnvironment,
|
|
686
|
+
external_id: z.nullable(z.string()),
|
|
687
|
+
id: z.uuid(),
|
|
688
|
+
items: z.array(zSaleItemEntitySchema),
|
|
689
|
+
metadata: z.nullable(z.record(z.string(), z.unknown())),
|
|
690
|
+
occurred_at: z.iso.datetime({ offset: true }),
|
|
691
|
+
service_id: z.nullable(z.uuid()),
|
|
692
|
+
service_key: z.nullable(z.string()),
|
|
693
|
+
service_label: z.nullable(z.string()),
|
|
694
|
+
services: z.array(zSaleServiceEntitySchema),
|
|
695
|
+
sms_automation: z.nullable(zSaleSmsStatusSchema),
|
|
696
|
+
sms_consent: z._default(z.boolean(), false),
|
|
697
|
+
sms_consent_granted_at: z.nullable(z.iso.datetime({ offset: true })),
|
|
698
|
+
updated_at: z.iso.datetime({ offset: true }),
|
|
699
|
+
writeback: z.nullable(zSaleWritebackStatusSchema)
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
// ../tracking-core/src/resources/sales/schema.ts
|
|
703
|
+
var saleItemSchema = zSaleItemInputSchema;
|
|
704
|
+
var saleServiceSchema = zSaleServiceInputSchema;
|
|
705
|
+
var currencySchema = zSupportedCurrency;
|
|
706
|
+
var SUPPORTED_CURRENCIES = currencySchema.options;
|
|
707
|
+
var centsSchema = z2.int().check(z2.gte(0));
|
|
708
|
+
var metadataSchema = z2.record(z2.string(), z2.unknown());
|
|
709
|
+
var customerNameSchema = z2.string().check(z2.maxLength(200));
|
|
710
|
+
var customerPhoneSchema = z2.string().check(z2.maxLength(64));
|
|
711
|
+
var customerEmailSchema = z2.email().check(z2.maxLength(320));
|
|
712
|
+
function addIssue(ctx, path, message) {
|
|
713
|
+
ctx.issues.push({ code: "custom", input: ctx.value, path, message });
|
|
714
|
+
}
|
|
537
715
|
function refineServiceXor(val, ctx, { requireAmount }) {
|
|
538
716
|
if (val.services != null) {
|
|
539
717
|
if (val.service != null) {
|
|
540
|
-
|
|
541
|
-
code: import_zod2.z.ZodIssueCode.custom,
|
|
542
|
-
message: "pass either `service` or `services`, not both",
|
|
543
|
-
path: ["services"]
|
|
544
|
-
});
|
|
718
|
+
addIssue(ctx, ["services"], "pass either `service` or `services`, not both");
|
|
545
719
|
}
|
|
546
720
|
if (val.services.length === 0) {
|
|
547
|
-
|
|
548
|
-
code: import_zod2.z.ZodIssueCode.custom,
|
|
549
|
-
message: "`services` must not be empty",
|
|
550
|
-
path: ["services"]
|
|
551
|
-
});
|
|
721
|
+
addIssue(ctx, ["services"], "`services` must not be empty");
|
|
552
722
|
}
|
|
553
723
|
const keys = val.services.map((s) => s.service);
|
|
554
724
|
if (new Set(keys).size !== keys.length) {
|
|
555
|
-
|
|
556
|
-
code: import_zod2.z.ZodIssueCode.custom,
|
|
557
|
-
message: "`services` must not list the same service more than once",
|
|
558
|
-
path: ["services"]
|
|
559
|
-
});
|
|
725
|
+
addIssue(ctx, ["services"], "`services` must not list the same service more than once");
|
|
560
726
|
}
|
|
561
727
|
if (val.amount_total_cents != null) {
|
|
562
728
|
const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
|
|
563
729
|
if (val.amount_total_cents !== sum) {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
730
|
+
addIssue(
|
|
731
|
+
ctx,
|
|
732
|
+
["amount_total_cents"],
|
|
733
|
+
"amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)"
|
|
734
|
+
);
|
|
569
735
|
}
|
|
570
736
|
}
|
|
571
737
|
} else if (requireAmount && val.amount_total_cents == null) {
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
738
|
+
addIssue(
|
|
739
|
+
ctx,
|
|
740
|
+
["amount_total_cents"],
|
|
741
|
+
"amount_total_cents is required unless `services` is provided"
|
|
742
|
+
);
|
|
577
743
|
}
|
|
578
744
|
}
|
|
579
|
-
var saleCreateSchema =
|
|
580
|
-
|
|
581
|
-
description:
|
|
582
|
-
service:
|
|
583
|
-
services:
|
|
584
|
-
currency: currencySchema,
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
items: import_zod2.z.array(saleItemSchema).default([]),
|
|
591
|
-
metadata: metadataSchema.nullable().optional(),
|
|
592
|
-
customer_name: customerNameSchema.nullable().optional(),
|
|
593
|
-
customer_phone: customerPhoneSchema.nullable().optional(),
|
|
594
|
-
customer_email: customerEmailSchema.nullable().optional(),
|
|
595
|
-
// CASL consent attestation: the customer agreed to receive SMS. Recorded
|
|
596
|
-
// with a timestamp server-side; every SMS send path gates on it.
|
|
597
|
-
//
|
|
598
|
-
// Tri-state: omit it (or send null) to let the server apply the business's
|
|
599
|
-
// configured default-opt-in policy, honouring a returning customer's
|
|
600
|
-
// remembered preference. Send an explicit boolean to assert consent state
|
|
601
|
-
// yourself — `false` records a deliberate opt-out.
|
|
602
|
-
sms_consent: import_zod2.z.boolean().nullable().optional()
|
|
603
|
-
}).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
|
|
604
|
-
var saleUpdateSchema = import_zod2.z.object({
|
|
605
|
-
description: import_zod2.z.string().nullable().optional(),
|
|
606
|
-
service: import_zod2.z.string().nullable().optional(),
|
|
607
|
-
services: import_zod2.z.array(saleServiceSchema).nullable().optional(),
|
|
608
|
-
currency: currencySchema.optional(),
|
|
609
|
-
amount_total_cents: centsSchema.optional(),
|
|
610
|
-
occurred_at: import_zod2.z.string().datetime().optional(),
|
|
611
|
-
items: import_zod2.z.array(saleItemSchema).optional(),
|
|
612
|
-
metadata: metadataSchema.nullable().optional(),
|
|
613
|
-
customer_name: customerNameSchema.nullable().optional(),
|
|
745
|
+
var saleCreateSchema = z2.extend(zSaleCreateSchema, { items: z2._default(z2.array(saleItemSchema), []) }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: true }));
|
|
746
|
+
var saleUpdateSchema = z2.strictObject({
|
|
747
|
+
description: z2.nullish(z2.string()),
|
|
748
|
+
service: z2.nullish(z2.string()),
|
|
749
|
+
services: z2.nullish(z2.array(saleServiceSchema)),
|
|
750
|
+
currency: z2.optional(currencySchema),
|
|
751
|
+
amount_total_cents: z2.optional(centsSchema),
|
|
752
|
+
occurred_at: z2.optional(z2.iso.datetime()),
|
|
753
|
+
items: z2.optional(z2.array(saleItemSchema)),
|
|
754
|
+
metadata: z2.nullish(metadataSchema),
|
|
755
|
+
customer_name: z2.nullish(customerNameSchema),
|
|
614
756
|
// Re-attest when changing a filler-looking name; the server clears the
|
|
615
757
|
// prior attestation whenever `customer_name` changes.
|
|
616
|
-
customer_name_placeholder_confirmed:
|
|
617
|
-
customer_phone:
|
|
618
|
-
customer_email:
|
|
758
|
+
customer_name_placeholder_confirmed: z2.optional(z2.boolean()),
|
|
759
|
+
customer_phone: z2.nullish(customerPhoneSchema),
|
|
760
|
+
customer_email: z2.nullish(customerEmailSchema),
|
|
619
761
|
// NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
|
|
620
|
-
sms_consent:
|
|
621
|
-
}).
|
|
762
|
+
sms_consent: z2.optional(z2.boolean())
|
|
763
|
+
}).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: false }));
|
|
622
764
|
var TRACKING_RANGES = ["24h", "7d", "30d"];
|
|
623
765
|
var NAMED_RANGES = [
|
|
624
766
|
"today",
|
|
@@ -645,6 +787,7 @@ async function fetchServices(config) {
|
|
|
645
787
|
SUPPORTED_CURRENCIES,
|
|
646
788
|
TRACKING_RANGES,
|
|
647
789
|
createSalesClient,
|
|
790
|
+
currencySchema,
|
|
648
791
|
fetchServices,
|
|
649
792
|
formatDateInTz,
|
|
650
793
|
formatMoney,
|