@aranova/tracking-next 0.27.0 → 1.0.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.
Files changed (71) hide show
  1. package/dist/blog-server.d.mts +2 -1
  2. package/dist/blog-server.d.ts +2 -1
  3. package/dist/blog-server.js +121 -98
  4. package/dist/blog-server.js.map +1 -1
  5. package/dist/blog-server.mjs +86 -63
  6. package/dist/blog-server.mjs.map +1 -1
  7. package/dist/blog.d.mts +651 -1755
  8. package/dist/blog.d.ts +651 -1755
  9. package/dist/blog.js +121 -98
  10. package/dist/blog.js.map +1 -1
  11. package/dist/blog.mjs +86 -63
  12. package/dist/blog.mjs.map +1 -1
  13. package/dist/calendar-server.d.mts +2 -2
  14. package/dist/calendar-server.d.ts +2 -2
  15. package/dist/calendar-server.js +0 -26
  16. package/dist/calendar-server.js.map +1 -1
  17. package/dist/calendar-server.mjs +0 -26
  18. package/dist/calendar-server.mjs.map +1 -1
  19. package/dist/calendar.d.mts +3 -3
  20. package/dist/calendar.d.ts +3 -3
  21. package/dist/calendar.js +227 -126
  22. package/dist/calendar.js.map +1 -1
  23. package/dist/calendar.mjs +216 -125
  24. package/dist/calendar.mjs.map +1 -1
  25. package/dist/client.d.mts +4 -3
  26. package/dist/client.d.ts +4 -3
  27. package/dist/client.js +185 -277
  28. package/dist/client.js.map +1 -1
  29. package/dist/client.mjs +157 -249
  30. package/dist/client.mjs.map +1 -1
  31. package/dist/index.d.mts +8 -7
  32. package/dist/index.d.ts +8 -7
  33. package/dist/index.js +482 -484
  34. package/dist/index.js.map +1 -1
  35. package/dist/index.mjs +471 -484
  36. package/dist/index.mjs.map +1 -1
  37. package/dist/ingest-typed-BdKmlouW.d.ts +791 -0
  38. package/dist/ingest-typed-Bo7WPmpU.d.mts +791 -0
  39. package/dist/middleware.js +0 -467
  40. package/dist/middleware.js.map +1 -1
  41. package/dist/middleware.mjs +0 -467
  42. package/dist/middleware.mjs.map +1 -1
  43. package/dist/{phone-utils-BVzSNBf1.d.mts → phone-utils-CubQif9Z.d.mts} +18 -78
  44. package/dist/{phone-utils-BVzSNBf1.d.ts → phone-utils-CubQif9Z.d.ts} +18 -78
  45. package/dist/phone.d.mts +2 -2
  46. package/dist/phone.d.ts +2 -2
  47. package/dist/phone.js +0 -464
  48. package/dist/phone.js.map +1 -1
  49. package/dist/phone.mjs +0 -464
  50. package/dist/phone.mjs.map +1 -1
  51. package/dist/{sales-DQGzXSgL.d.mts → sales-D7KstKA-.d.mts} +89 -328
  52. package/dist/{sales-IGC2tq4J.d.ts → sales-DG150g3o.d.ts} +89 -328
  53. package/dist/sales.d.mts +2 -2
  54. package/dist/sales.d.ts +2 -2
  55. package/dist/sales.js +265 -127
  56. package/dist/sales.js.map +1 -1
  57. package/dist/sales.mjs +254 -127
  58. package/dist/sales.mjs.map +1 -1
  59. package/dist/server.d.mts +2 -2
  60. package/dist/server.d.ts +2 -2
  61. package/dist/server.js +0 -467
  62. package/dist/server.js.map +1 -1
  63. package/dist/server.mjs +0 -467
  64. package/dist/server.mjs.map +1 -1
  65. package/dist/transport-CDmGOiCq.d.ts +253 -0
  66. package/dist/transport-I_cMSFQ6.d.mts +253 -0
  67. package/package.json +2 -2
  68. package/dist/ingest-typed-BxLFlZ7N.d.mts +0 -1371
  69. package/dist/ingest-typed-ByQVRMvP.d.ts +0 -1371
  70. package/dist/transport-C-_rFSR4.d.ts +0 -721
  71. package/dist/transport-yUF5Wize.d.mts +0 -721
package/dist/index.mjs CHANGED
@@ -47,7 +47,7 @@ function normalizeEmail(raw) {
47
47
  return EMAIL_SHAPE.test(cleaned) ? cleaned : null;
48
48
  }
49
49
  function stashUserData(data, country) {
50
- const email = normalizeEmail(data.email);
50
+ const email4 = normalizeEmail(data.email);
51
51
  let phoneNumber = null;
52
52
  if (typeof data.phone === "string" && data.phone.length > 0) {
53
53
  try {
@@ -57,7 +57,7 @@ function stashUserData(data, country) {
57
57
  }
58
58
  }
59
59
  stash = {
60
- email: email ?? stash.email,
60
+ email: email4 ?? stash.email,
61
61
  phoneNumber: phoneNumber ?? stash.phoneNumber
62
62
  };
63
63
  }
@@ -66,11 +66,11 @@ function clearStashedUserData() {
66
66
  }
67
67
  function applyUserDataForConversion(explicit, country) {
68
68
  if (typeof window === "undefined" || typeof window.gtag !== "function") return false;
69
- let email = stash.email;
69
+ let email4 = stash.email;
70
70
  let phoneNumber = stash.phoneNumber;
71
71
  if (explicit) {
72
72
  const normalizedEmail = normalizeEmail(explicit.email);
73
- if (normalizedEmail) email = normalizedEmail;
73
+ if (normalizedEmail) email4 = normalizedEmail;
74
74
  if (typeof explicit.phone === "string" && explicit.phone.length > 0) {
75
75
  try {
76
76
  phoneNumber = toE164(explicit.phone, country) ?? phoneNumber;
@@ -78,10 +78,10 @@ function applyUserDataForConversion(explicit, country) {
78
78
  }
79
79
  }
80
80
  }
81
- if (email === null && phoneNumber === null) return false;
81
+ if (email4 === null && phoneNumber === null) return false;
82
82
  try {
83
83
  window.gtag("set", "user_data", {
84
- ...email !== null ? { email } : {},
84
+ ...email4 !== null ? { email: email4 } : {},
85
85
  ...phoneNumber !== null ? { phone_number: phoneNumber } : {}
86
86
  });
87
87
  return true;
@@ -437,10 +437,10 @@ function readStoredRecord() {
437
437
  return null;
438
438
  }
439
439
  }
440
- function writeRecord(record) {
441
- memoryRecord = record;
440
+ function writeRecord(record5) {
441
+ memoryRecord = record5;
442
442
  try {
443
- window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record));
443
+ window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record5));
444
444
  } catch {
445
445
  }
446
446
  }
@@ -462,9 +462,9 @@ function getOrCaptureLandingParams(sessionId, url) {
462
462
  if (memoryRecord && memoryRecord.session_id === sessionId) {
463
463
  return memoryRecord.params;
464
464
  }
465
- const record = { session_id: sessionId, params: captureFromUrl(url) };
466
- writeRecord(record);
467
- return record.params;
465
+ const record5 = { session_id: sessionId, params: captureFromUrl(url) };
466
+ writeRecord(record5);
467
+ return record5.params;
468
468
  }
469
469
  function buildLandingPayloadFields(sessionId, override) {
470
470
  const params = override ?? (typeof window === "undefined" ? null : getOrCaptureLandingParams(sessionId));
@@ -841,9 +841,9 @@ function automaticThresholdMet(goal, eventType, metadata) {
841
841
  }
842
842
 
843
843
  // ../tracking-core/src/resources/intl/date.ts
844
- function formatDateInTz(iso, timeZone, opts, locale) {
845
- const date = new Date(iso);
846
- if (Number.isNaN(date.getTime())) return iso;
844
+ function formatDateInTz(iso4, timeZone, opts, locale) {
845
+ const date = new Date(iso4);
846
+ if (Number.isNaN(date.getTime())) return iso4;
847
847
  return new Intl.DateTimeFormat(locale, {
848
848
  year: "numeric",
849
849
  month: "short",
@@ -1255,29 +1255,6 @@ function getTrackingConfigRuntime(ref, fetchImpl) {
1255
1255
  return runtime;
1256
1256
  }
1257
1257
 
1258
- // ../tracking-core/src/session.ts
1259
- var SESSION_IDLE_MS = 30 * 60 * 1e3;
1260
-
1261
- // ../tracking-core/src/events/page-view.ts
1262
- import { z } from "zod";
1263
- var pageViewMetadataSchema = z.object({
1264
- page: z.object({
1265
- title: z.string().nullable(),
1266
- path: z.string(),
1267
- search: z.string(),
1268
- hash: z.string()
1269
- }).strict(),
1270
- referrer: z.string().nullable(),
1271
- // `.nullable().optional()` — absent (undefined) OR explicit null OR a
1272
- // real viewport object. Mirrors Pydantic's `_Viewport | None = None`
1273
- // on the backend side so the drift test stays clean.
1274
- viewport: z.object({
1275
- w: z.number(),
1276
- h: z.number()
1277
- }).strict().nullable().optional()
1278
- }).strict();
1279
- var pageViewConfigSchema = z.object({}).strict();
1280
-
1281
1258
  // ../tracking-core/src/ingest.ts
1282
1259
  var API_KEY_HEADER = "X-Aranova-Api-Key";
1283
1260
  var SDK_VERSION_HEADER = "X-Aranova-Sdk-Version";
@@ -1285,187 +1262,6 @@ var SDK_PACKAGE_HEADER = "X-Aranova-Sdk-Package";
1285
1262
  var SDK_SURFACE_HEADER = "X-Aranova-Sdk-Surface";
1286
1263
  var SDK_ENVIRONMENT_HEADER = "X-Aranova-Sdk-Environment";
1287
1264
 
1288
- // ../tracking-core/src/events/cta-click.ts
1289
- import { z as z2 } from "zod";
1290
- var ctaClickMetadataSchema = z2.object({
1291
- cta_name: z2.string(),
1292
- page: z2.object({
1293
- path: z2.string()
1294
- }).strict(),
1295
- section: z2.string().nullable().optional(),
1296
- destination_url: z2.string().nullable().optional(),
1297
- // Set by auto-capture (and available to manual callers): the link target
1298
- // and a short element descriptor (tag#id) for tying clicks to specific UI.
1299
- href: z2.string().nullable().optional(),
1300
- element: z2.string().nullable().optional()
1301
- }).strict();
1302
- var ctaClickConfigSchema = z2.object({
1303
- autoCapture: z2.object({
1304
- selector: z2.string().optional()
1305
- }).strict().optional()
1306
- }).strict();
1307
-
1308
- // ../tracking-core/src/events/sdk-heartbeat.ts
1309
- import { z as z3 } from "zod";
1310
- var sdkHeartbeatTriggersSchema = z3.object({
1311
- automatic: z3.array(z3.string()),
1312
- manual: z3.array(z3.string())
1313
- }).strict();
1314
- var sdkHeartbeatMetadataSchema = z3.object({
1315
- sdk_version: z3.string(),
1316
- package_name: z3.string().nullable(),
1317
- surface: z3.enum(["next", "react", "script"]),
1318
- triggers: sdkHeartbeatTriggersSchema,
1319
- trigger_config: z3.record(z3.string(), z3.record(z3.string(), z3.unknown())).nullable().optional(),
1320
- configured_gtag_ids: z3.record(z3.string(), z3.string()).nullable().optional(),
1321
- // Site whose config object the SDK resolves; null on a legacy business ref.
1322
- config_site_id: z3.string().uuid().nullable().optional()
1323
- }).strict();
1324
- var sdkHeartbeatConfigSchema = z3.object({}).strict();
1325
-
1326
- // ../tracking-core/src/events/form-start.ts
1327
- import { z as z4 } from "zod";
1328
- var formStartMetadataSchema = z4.object({
1329
- form: z4.object({
1330
- id: z4.string(),
1331
- action: z4.string().nullable()
1332
- }).strict(),
1333
- page: z4.object({
1334
- path: z4.string()
1335
- }).strict()
1336
- }).strict();
1337
- var formStartConfigSchema = z4.object({
1338
- selector: z4.string().optional()
1339
- }).strict();
1340
-
1341
- // ../tracking-core/src/events/form-submit.ts
1342
- import { z as z5 } from "zod";
1343
- var jsonValueSchema = z5.lazy(
1344
- () => z5.union([
1345
- z5.string(),
1346
- z5.number().finite(),
1347
- z5.boolean(),
1348
- z5.null(),
1349
- z5.array(jsonValueSchema),
1350
- z5.record(jsonValueSchema)
1351
- ])
1352
- );
1353
- var formSubmitMetadataSchema = z5.object({
1354
- form: z5.object({
1355
- id: z5.string(),
1356
- action: z5.string().nullable(),
1357
- fields: z5.array(
1358
- z5.object({
1359
- name: z5.string(),
1360
- type: z5.string(),
1361
- label: z5.string().nullable(),
1362
- value: jsonValueSchema
1363
- }).strict()
1364
- ).optional()
1365
- }).strict(),
1366
- page: z5.object({
1367
- path: z5.string()
1368
- }).strict()
1369
- }).strict();
1370
- var formSubmitConfigSchema = z5.object({}).strict();
1371
-
1372
- // ../tracking-core/src/events/multi-page-session.ts
1373
- import { z as z6 } from "zod";
1374
- var multiPageSessionMetadataSchema = z6.object({
1375
- page_count: z6.number().int().min(2),
1376
- page: z6.object({
1377
- path: z6.string()
1378
- }).strict()
1379
- }).strict();
1380
- var multiPageSessionConfigSchema = z6.object({
1381
- pageThreshold: z6.number().int().min(2)
1382
- }).strict();
1383
-
1384
- // ../tracking-core/src/events/page-exit.ts
1385
- import { z as z7 } from "zod";
1386
- var pageExitMetadataSchema = z7.object({
1387
- dwell_ms: z7.number().int().min(0),
1388
- // null = left without any scroll signal; floor is 0 so a valid 0% is never
1389
- // rejected (a single bad field 422s the whole keepalive beacon batch).
1390
- max_scroll_percent: z7.number().int().min(0).max(100).nullable(),
1391
- // The gating baseline: the fraction of the page visible at load with
1392
- // zero scrolling — or, for pages that grew after the post-paint snapshot
1393
- // (skeleton/streaming renders), the first-scroll position that
1394
- // established it. null = page had no scrollable range, or the segment
1395
- // ended before the snapshot. `.optional()` is load-bearing: SDK builds
1396
- // predating this field keep POSTing page_exit without the key —
1397
- // requiring it would 422 whole keepalive beacon batches.
1398
- scroll_baseline_percent: z7.number().int().min(0).max(100).nullable().optional(),
1399
- page: z7.object({
1400
- path: z7.string()
1401
- }).strict()
1402
- }).strict();
1403
- var pageExitConfigSchema = z7.object({}).strict();
1404
-
1405
- // ../tracking-core/src/events/phone-click.ts
1406
- import { z as z8 } from "zod";
1407
- var phoneClickMetadataSchema = z8.object({
1408
- phone_number: z8.string(),
1409
- page: z8.object({
1410
- path: z8.string()
1411
- }).strict(),
1412
- section: z8.string().nullable().optional()
1413
- }).strict();
1414
- var phoneClickConfigSchema = z8.object({
1415
- autoCapture: z8.object({
1416
- selector: z8.string().optional()
1417
- }).strict().optional()
1418
- }).strict();
1419
-
1420
- // ../tracking-core/src/events/scroll-depth.ts
1421
- import { z as z9 } from "zod";
1422
- var scrollDepthMetadataSchema = z9.object({
1423
- depth_percent: z9.number().int().min(1).max(100),
1424
- page: z9.object({
1425
- path: z9.string()
1426
- }).strict()
1427
- }).strict();
1428
- var scrollDepthConfigSchema = z9.object({
1429
- thresholds: z9.array(z9.number().int().min(1).max(100)).min(1)
1430
- }).strict();
1431
-
1432
- // ../tracking-core/src/events/specific-page-visit.ts
1433
- import { z as z10 } from "zod";
1434
- var PAGE_IDENTITY_MAX_LENGTH = 64;
1435
- var PAGE_IDENTITY_PATTERN = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/;
1436
- var pageIdentitySchema = z10.string().max(PAGE_IDENTITY_MAX_LENGTH).regex(PAGE_IDENTITY_PATTERN, {
1437
- message: "page identity must be lowercase snake_case, start with a letter, and contain at most 64 characters"
1438
- });
1439
- var specificPageNameSchema = pageIdentitySchema;
1440
- var specificPageVisitMetadataSchema = z10.object({
1441
- page_name: specificPageNameSchema,
1442
- page: z10.object({
1443
- path: z10.string()
1444
- }).strict()
1445
- }).strict();
1446
- var specificPageVisitConfigSchema = z10.object({
1447
- pages: z10.array(
1448
- z10.object({
1449
- name: specificPageNameSchema,
1450
- pathPattern: z10.custom((value) => value instanceof RegExp, {
1451
- message: "pathPattern must be a RegExp"
1452
- })
1453
- }).strict()
1454
- ).min(1)
1455
- }).strict();
1456
-
1457
- // ../tracking-core/src/events/time-on-site.ts
1458
- import { z as z11 } from "zod";
1459
- var timeOnSiteMetadataSchema = z11.object({
1460
- duration_ms: z11.number().int().nonnegative(),
1461
- page: z11.object({
1462
- path: z11.string()
1463
- }).strict()
1464
- }).strict();
1465
- var timeOnSiteConfigSchema = z11.object({
1466
- thresholdSeconds: z11.number().int().positive()
1467
- }).strict();
1468
-
1469
1265
  // ../tracking-core/src/events/semantics.ts
1470
1266
  var EVENT_SEMANTICS = {
1471
1267
  page_view: {
@@ -1539,82 +1335,6 @@ function getEventSemantics(eventName) {
1539
1335
  return eventName in EVENT_SEMANTICS ? EVENT_SEMANTICS[eventName] : null;
1540
1336
  }
1541
1337
 
1542
- // ../tracking-core/src/events/registry.ts
1543
- var EVENT_REGISTRY = {
1544
- // --- automatic triggers ---
1545
- page_view: {
1546
- kind: "automatic",
1547
- semantics: EVENT_SEMANTICS.page_view,
1548
- metadataSchema: pageViewMetadataSchema,
1549
- configSchema: pageViewConfigSchema
1550
- },
1551
- time_on_site: {
1552
- kind: "automatic",
1553
- semantics: EVENT_SEMANTICS.time_on_site,
1554
- metadataSchema: timeOnSiteMetadataSchema,
1555
- configSchema: timeOnSiteConfigSchema
1556
- },
1557
- specific_page_visit: {
1558
- kind: "automatic",
1559
- semantics: EVENT_SEMANTICS.specific_page_visit,
1560
- metadataSchema: specificPageVisitMetadataSchema,
1561
- configSchema: specificPageVisitConfigSchema
1562
- },
1563
- scroll_depth: {
1564
- kind: "automatic",
1565
- semantics: EVENT_SEMANTICS.scroll_depth,
1566
- metadataSchema: scrollDepthMetadataSchema,
1567
- configSchema: scrollDepthConfigSchema
1568
- },
1569
- multi_page_session: {
1570
- kind: "automatic",
1571
- semantics: EVENT_SEMANTICS.multi_page_session,
1572
- metadataSchema: multiPageSessionMetadataSchema,
1573
- configSchema: multiPageSessionConfigSchema
1574
- },
1575
- form_start: {
1576
- kind: "automatic",
1577
- semantics: EVENT_SEMANTICS.form_start,
1578
- metadataSchema: formStartMetadataSchema,
1579
- configSchema: formStartConfigSchema
1580
- },
1581
- // --- SDK-internal automatic (not consumer-configurable) ---
1582
- sdk_heartbeat: {
1583
- kind: "automatic",
1584
- semantics: EVENT_SEMANTICS.sdk_heartbeat,
1585
- metadataSchema: sdkHeartbeatMetadataSchema,
1586
- configSchema: sdkHeartbeatConfigSchema
1587
- },
1588
- page_exit: {
1589
- kind: "automatic",
1590
- semantics: EVENT_SEMANTICS.page_exit,
1591
- metadataSchema: pageExitMetadataSchema,
1592
- configSchema: pageExitConfigSchema
1593
- },
1594
- // --- manual triggers ---
1595
- form_submit: {
1596
- kind: "manual",
1597
- semantics: EVENT_SEMANTICS.form_submit,
1598
- metadataSchema: formSubmitMetadataSchema,
1599
- configSchema: formSubmitConfigSchema
1600
- },
1601
- phone_click: {
1602
- kind: "manual",
1603
- semantics: EVENT_SEMANTICS.phone_click,
1604
- metadataSchema: phoneClickMetadataSchema,
1605
- configSchema: phoneClickConfigSchema
1606
- },
1607
- cta_click: {
1608
- kind: "manual",
1609
- semantics: EVENT_SEMANTICS.cta_click,
1610
- metadataSchema: ctaClickMetadataSchema,
1611
- configSchema: ctaClickConfigSchema
1612
- }
1613
- };
1614
- var ALL_AUTOMATIC_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "automatic").map(([name]) => name);
1615
- var ALL_MANUAL_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "manual").map(([name]) => name);
1616
- var ALL_LEAD_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.semantics.outcomeRole === "lead").map(([name]) => name);
1617
-
1618
1338
  // ../tracking-core/src/resources/http/errors.ts
1619
1339
  var AranovaApiError = class extends Error {
1620
1340
  constructor(message, options) {
@@ -1652,9 +1372,9 @@ async function apiRequest(config, method, path, body, extraHeaders) {
1652
1372
  try {
1653
1373
  const parsed = await response.json();
1654
1374
  if (parsed && typeof parsed === "object") {
1655
- const record = parsed;
1656
- if (typeof record.detail === "string") detail = record.detail;
1657
- if (typeof record.code === "string") code = record.code;
1375
+ const record5 = parsed;
1376
+ if (typeof record5.detail === "string") detail = record5.detail;
1377
+ if (typeof record5.code === "string") code = record5.code;
1658
1378
  }
1659
1379
  } catch {
1660
1380
  }
@@ -1703,7 +1423,7 @@ function fireRecordedConversions(firing, input, recorded, sale, currency) {
1703
1423
  }
1704
1424
  function createSalesClient(config) {
1705
1425
  if (config.firing) registerCapability("conversion_goals_manual");
1706
- async function record(input) {
1426
+ async function record5(input) {
1707
1427
  const currency = input.currency ?? config.defaultCurrency;
1708
1428
  if (!currency) {
1709
1429
  throw new Error(
@@ -1729,9 +1449,9 @@ function createSalesClient(config) {
1729
1449
  return sale;
1730
1450
  }
1731
1451
  return {
1732
- record,
1452
+ record: record5,
1733
1453
  // recordSale is the intent-revealing alias — same behavior, clearer call site.
1734
- recordSale: record,
1454
+ recordSale: record5,
1735
1455
  trackConversion(key, options) {
1736
1456
  if (config.firing && "fireConversion" in config.firing) {
1737
1457
  if (options?.userData && getConsentState() !== "denied") stashUserData(options.userData);
@@ -1850,115 +1570,264 @@ function createSalesClient(config) {
1850
1570
  }
1851
1571
 
1852
1572
  // ../tracking-core/src/resources/sales/schema.ts
1853
- import { z as z12 } from "zod";
1854
- var SUPPORTED_CURRENCIES = ["USD", "CAD"];
1855
- var TRACKING_ENVIRONMENTS = ["production", "development"];
1856
- var currencySchema = z12.enum(SUPPORTED_CURRENCIES);
1857
- var centsSchema = z12.number().int().nonnegative();
1858
- var quantitySchema = z12.string().regex(/^\d+(\.\d{1,3})?$/);
1859
- var metadataSchema = z12.record(z12.unknown());
1860
- var saleItemSchema = z12.object({
1861
- external_item_id: z12.string().nullable().optional(),
1862
- name: z12.string().nullable().optional(),
1863
- category: z12.string().nullable().optional(),
1864
- quantity: quantitySchema,
1865
- unit_price_cents: centsSchema,
1866
- // Non-negativity validated on the wire — same contract as the other cents
1867
- // fields — and backstopped by the DB CHECK.
1868
- unit_cost_cents: centsSchema.nullable().optional()
1869
- }).strict();
1870
- var saleServiceSchema = z12.object({
1871
- service: z12.string(),
1872
- amount_cents: centsSchema
1873
- }).strict();
1874
- var customerNameSchema = z12.string().max(200);
1875
- var customerPhoneSchema = z12.string().max(64);
1876
- var customerEmailSchema = z12.string().max(320).email();
1573
+ import * as z2 from "zod/mini";
1574
+
1575
+ // ../tracking-core/src/resources/sales/generated/zod.gen.ts
1576
+ import * as z from "zod/mini";
1577
+ var zErrorCode = z.enum([
1578
+ "missing_credentials",
1579
+ "invalid_api_key",
1580
+ "not_authenticated",
1581
+ "wrong_key_type",
1582
+ "origin_missing",
1583
+ "origin_not_allowed",
1584
+ "capability_denied",
1585
+ "session_required",
1586
+ "operator_only",
1587
+ "cross_tenant",
1588
+ "business_id_required",
1589
+ "bad_request",
1590
+ "not_found",
1591
+ "conflict",
1592
+ "incompatible_payload",
1593
+ "repeat_confirmation_required",
1594
+ "idempotency_conflict",
1595
+ "validation_error",
1596
+ "unknown_service",
1597
+ "invalid_sale_properties",
1598
+ "invalid_cursor",
1599
+ "rate_limited",
1600
+ "internal_error"
1601
+ ]);
1602
+ var zSaleItemEntitySchema = z.object({
1603
+ category: z.nullable(z.string()),
1604
+ external_item_id: z.nullable(z.string()),
1605
+ id: z.uuid(),
1606
+ name: z.nullable(z.string()),
1607
+ quantity: z.string().check(z.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
1608
+ unit_cost_cents: z.nullable(z.int()),
1609
+ unit_price_cents: z.int()
1610
+ });
1611
+ var zSaleItemInputSchema = z.strictObject({
1612
+ category: z.nullish(z.string()),
1613
+ external_item_id: z.nullish(z.string()),
1614
+ name: z.nullish(z.string()),
1615
+ quantity: z.string().check(z.regex(/^\d+(\.\d{1,3})?$/)),
1616
+ unit_cost_cents: z.nullish(z.int().check(z.gte(0))),
1617
+ unit_price_cents: z.int().check(z.gte(0))
1618
+ });
1619
+ var zSaleServiceEntitySchema = z.object({
1620
+ amount_cents: z.int(),
1621
+ id: z.uuid(),
1622
+ mapped: z.nullable(z.boolean()),
1623
+ service_id: z.uuid(),
1624
+ service_key: z.string(),
1625
+ service_label: z.string()
1626
+ });
1627
+ var zSaleServiceInputSchema = z.strictObject({
1628
+ amount_cents: z.int().check(z.gte(0)),
1629
+ service: z.string()
1630
+ });
1631
+ var zSmsAutomationState = z.enum([
1632
+ "needs_check",
1633
+ "failed",
1634
+ "undelivered",
1635
+ "blocked_opted_out",
1636
+ "withheld",
1637
+ "queued",
1638
+ "sent",
1639
+ "delivered",
1640
+ "eligible",
1641
+ "not_applicable"
1642
+ ]);
1643
+ var zSmsWithheldReason = z.enum([
1644
+ "automation_disabled",
1645
+ "sms_disabled",
1646
+ "no_phone",
1647
+ "no_consent",
1648
+ "no_customer_identity",
1649
+ "missing_customer_name",
1650
+ "placeholder_customer_name",
1651
+ "opted_out",
1652
+ "already_messaged",
1653
+ "sender_not_ready",
1654
+ "missing_review_url",
1655
+ "no_handler",
1656
+ "dispatch_already_recorded"
1657
+ ]);
1658
+ var zSaleSmsStatusSchema = z.object({
1659
+ can_send_now: z._default(z.boolean(), false),
1660
+ last_message_at: z.nullable(z.iso.datetime({ offset: true })),
1661
+ reason_detail: z.nullable(z.string()),
1662
+ state: zSmsAutomationState,
1663
+ suppressed_by_other_sale: z._default(z.boolean(), false),
1664
+ withheld_reason: z.nullable(zSmsWithheldReason)
1665
+ });
1666
+ var zSupportedCurrency = z.enum(["USD", "CAD"]);
1667
+ var zTrackingEnvironment = z.enum(["production", "development"]);
1668
+ var zSaleCreateSchema = z.strictObject({
1669
+ amount_total_cents: z.nullish(z.int().check(z.gte(0))),
1670
+ currency: zSupportedCurrency,
1671
+ customer_email: z.nullish(z.email().check(z.maxLength(320))),
1672
+ customer_name: z.nullish(z.string().check(z.maxLength(200))),
1673
+ customer_phone: z.nullish(z.string().check(z.maxLength(64))),
1674
+ description: z.nullish(z.string()),
1675
+ environment: z._default(z.optional(zTrackingEnvironment), "production"),
1676
+ external_id: z.nullish(z.string()),
1677
+ items: z.optional(z.array(zSaleItemInputSchema)),
1678
+ metadata: z.nullish(z.record(z.string(), z.unknown())),
1679
+ occurred_at: z.iso.datetime({ offset: true }),
1680
+ service: z.nullish(z.string()),
1681
+ services: z.nullish(z.array(zSaleServiceInputSchema)),
1682
+ sms_consent: z.nullish(z.boolean())
1683
+ });
1684
+ var zValidationError = z.object({
1685
+ ctx: z.optional(z.record(z.string(), z.unknown())),
1686
+ input: z.optional(z.unknown()),
1687
+ loc: z.array(z.union([z.string(), z.int()])),
1688
+ msg: z.string(),
1689
+ type: z.string()
1690
+ });
1691
+ var zHttpValidationError = z.object({
1692
+ detail: z.optional(z.array(zValidationError))
1693
+ });
1694
+ var zValidationErrorItem = z.object({
1695
+ loc: z.array(z.union([z.string(), z.int()])),
1696
+ msg: z.string(),
1697
+ type: z.string()
1698
+ });
1699
+ var zApiErrorSchema = z.object({
1700
+ code: zErrorCode,
1701
+ context: z._default(z.nullish(z.record(z.string(), z.unknown())), null),
1702
+ detail: z.string(),
1703
+ errors: z._default(z.nullish(z.array(zValidationErrorItem)), null),
1704
+ request_id: z._default(z.nullish(z.string()), null)
1705
+ });
1706
+ var zWritebackEmailSource = z.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
1707
+ var zWritebackEnrichmentStatus = z.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
1708
+ var zWritebackSaleUploadCounts = z.object({
1709
+ failed: z._default(z.int(), 0),
1710
+ pending: z._default(z.int(), 0),
1711
+ skipped: z._default(z.int(), 0),
1712
+ submitted: z._default(z.int(), 0),
1713
+ total: z._default(z.int(), 0),
1714
+ uploaded: z._default(z.int(), 0)
1715
+ });
1716
+ var zSaleWritebackStatusSchema = z.object({
1717
+ blocked_reason: z.nullable(z.string()),
1718
+ can_dispatch: z._default(z.boolean(), false),
1719
+ email_source: z.nullable(zWritebackEmailSource),
1720
+ enrichment_status: z.nullable(zWritebackEnrichmentStatus),
1721
+ gclid_attached: z._default(z.boolean(), false),
1722
+ identifiers_sent: z.nullable(z.string()),
1723
+ mapped_service_ids: z.array(z.uuid()),
1724
+ matched_submit_count: z.nullable(z.int()),
1725
+ needs_force: z._default(z.boolean(), false),
1726
+ rollup: z.enum([
1727
+ "failed",
1728
+ "skipped",
1729
+ "pending",
1730
+ "submitted",
1731
+ "uploaded",
1732
+ "not_uploaded",
1733
+ "out_of_window",
1734
+ "blocked"
1735
+ ]),
1736
+ stale: z._default(z.boolean(), false),
1737
+ uncovered_service_ids: z.array(z.uuid()),
1738
+ uploads: zWritebackSaleUploadCounts
1739
+ });
1740
+ var zSaleEntitySchema = z.object({
1741
+ amount_total_cents: z.int(),
1742
+ business_id: z.uuid(),
1743
+ business_name: z.nullable(z.string()),
1744
+ created_at: z.iso.datetime({ offset: true }),
1745
+ currency: z.string(),
1746
+ customer_email: z.nullable(z.string()),
1747
+ customer_name: z.nullable(z.string()),
1748
+ customer_name_placeholder_confirmed: z._default(z.boolean(), false),
1749
+ customer_name_placeholder_confirmed_at: z.nullable(z.iso.datetime({ offset: true })),
1750
+ customer_phone: z.nullable(z.string()),
1751
+ description: z.nullable(z.string()),
1752
+ environment: zTrackingEnvironment,
1753
+ external_id: z.nullable(z.string()),
1754
+ id: z.uuid(),
1755
+ items: z.array(zSaleItemEntitySchema),
1756
+ metadata: z.nullable(z.record(z.string(), z.unknown())),
1757
+ occurred_at: z.iso.datetime({ offset: true }),
1758
+ service_id: z.nullable(z.uuid()),
1759
+ service_key: z.nullable(z.string()),
1760
+ service_label: z.nullable(z.string()),
1761
+ services: z.array(zSaleServiceEntitySchema),
1762
+ sms_automation: z.nullable(zSaleSmsStatusSchema),
1763
+ sms_consent: z._default(z.boolean(), false),
1764
+ sms_consent_granted_at: z.nullable(z.iso.datetime({ offset: true })),
1765
+ updated_at: z.iso.datetime({ offset: true }),
1766
+ writeback: z.nullable(zSaleWritebackStatusSchema)
1767
+ });
1768
+
1769
+ // ../tracking-core/src/resources/sales/schema.ts
1770
+ var saleItemSchema = zSaleItemInputSchema;
1771
+ var saleServiceSchema = zSaleServiceInputSchema;
1772
+ var currencySchema = zSupportedCurrency;
1773
+ var SUPPORTED_CURRENCIES = currencySchema.options;
1774
+ var centsSchema = z2.int().check(z2.gte(0));
1775
+ var metadataSchema = z2.record(z2.string(), z2.unknown());
1776
+ var customerNameSchema = z2.string().check(z2.maxLength(200));
1777
+ var customerPhoneSchema = z2.string().check(z2.maxLength(64));
1778
+ var customerEmailSchema = z2.email().check(z2.maxLength(320));
1779
+ function addIssue(ctx, path, message) {
1780
+ ctx.issues.push({ code: "custom", input: ctx.value, path, message });
1781
+ }
1877
1782
  function refineServiceXor(val, ctx, { requireAmount }) {
1878
1783
  if (val.services != null) {
1879
1784
  if (val.service != null) {
1880
- ctx.addIssue({
1881
- code: z12.ZodIssueCode.custom,
1882
- message: "pass either `service` or `services`, not both",
1883
- path: ["services"]
1884
- });
1785
+ addIssue(ctx, ["services"], "pass either `service` or `services`, not both");
1885
1786
  }
1886
1787
  if (val.services.length === 0) {
1887
- ctx.addIssue({
1888
- code: z12.ZodIssueCode.custom,
1889
- message: "`services` must not be empty",
1890
- path: ["services"]
1891
- });
1788
+ addIssue(ctx, ["services"], "`services` must not be empty");
1892
1789
  }
1893
1790
  const keys = val.services.map((s) => s.service);
1894
1791
  if (new Set(keys).size !== keys.length) {
1895
- ctx.addIssue({
1896
- code: z12.ZodIssueCode.custom,
1897
- message: "`services` must not list the same service more than once",
1898
- path: ["services"]
1899
- });
1792
+ addIssue(ctx, ["services"], "`services` must not list the same service more than once");
1900
1793
  }
1901
1794
  if (val.amount_total_cents != null) {
1902
1795
  const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
1903
1796
  if (val.amount_total_cents !== sum) {
1904
- ctx.addIssue({
1905
- code: z12.ZodIssueCode.custom,
1906
- message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
1907
- path: ["amount_total_cents"]
1908
- });
1797
+ addIssue(
1798
+ ctx,
1799
+ ["amount_total_cents"],
1800
+ "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)"
1801
+ );
1909
1802
  }
1910
1803
  }
1911
1804
  } else if (requireAmount && val.amount_total_cents == null) {
1912
- ctx.addIssue({
1913
- code: z12.ZodIssueCode.custom,
1914
- message: "amount_total_cents is required unless `services` is provided",
1915
- path: ["amount_total_cents"]
1916
- });
1805
+ addIssue(
1806
+ ctx,
1807
+ ["amount_total_cents"],
1808
+ "amount_total_cents is required unless `services` is provided"
1809
+ );
1917
1810
  }
1918
1811
  }
1919
- var saleCreateSchema = z12.object({
1920
- external_id: z12.string().nullable().optional(),
1921
- description: z12.string().nullable().optional(),
1922
- service: z12.string().nullable().optional(),
1923
- services: z12.array(saleServiceSchema).nullable().optional(),
1924
- currency: currencySchema,
1925
- // Optional only because the plural `services` form derives it from the sum
1926
- // (see refineServiceXor); the singular/serviceless path still requires it.
1927
- amount_total_cents: centsSchema.nullable().optional(),
1928
- occurred_at: z12.string().datetime(),
1929
- environment: z12.enum(TRACKING_ENVIRONMENTS).default("production"),
1930
- items: z12.array(saleItemSchema).default([]),
1931
- metadata: metadataSchema.nullable().optional(),
1932
- customer_name: customerNameSchema.nullable().optional(),
1933
- customer_phone: customerPhoneSchema.nullable().optional(),
1934
- customer_email: customerEmailSchema.nullable().optional(),
1935
- // CASL consent attestation: the customer agreed to receive SMS. Recorded
1936
- // with a timestamp server-side; every SMS send path gates on it.
1937
- //
1938
- // Tri-state: omit it (or send null) to let the server apply the business's
1939
- // configured default-opt-in policy, honouring a returning customer's
1940
- // remembered preference. Send an explicit boolean to assert consent state
1941
- // yourself — `false` records a deliberate opt-out.
1942
- sms_consent: z12.boolean().nullable().optional()
1943
- }).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
1944
- var saleUpdateSchema = z12.object({
1945
- description: z12.string().nullable().optional(),
1946
- service: z12.string().nullable().optional(),
1947
- services: z12.array(saleServiceSchema).nullable().optional(),
1948
- currency: currencySchema.optional(),
1949
- amount_total_cents: centsSchema.optional(),
1950
- occurred_at: z12.string().datetime().optional(),
1951
- items: z12.array(saleItemSchema).optional(),
1952
- metadata: metadataSchema.nullable().optional(),
1953
- customer_name: customerNameSchema.nullable().optional(),
1812
+ var saleCreateSchema = z2.extend(zSaleCreateSchema, { items: z2._default(z2.array(saleItemSchema), []) }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: true }));
1813
+ var saleUpdateSchema = z2.strictObject({
1814
+ description: z2.nullish(z2.string()),
1815
+ service: z2.nullish(z2.string()),
1816
+ services: z2.nullish(z2.array(saleServiceSchema)),
1817
+ currency: z2.optional(currencySchema),
1818
+ amount_total_cents: z2.optional(centsSchema),
1819
+ occurred_at: z2.optional(z2.iso.datetime()),
1820
+ items: z2.optional(z2.array(saleItemSchema)),
1821
+ metadata: z2.nullish(metadataSchema),
1822
+ customer_name: z2.nullish(customerNameSchema),
1954
1823
  // Re-attest when changing a filler-looking name; the server clears the
1955
1824
  // prior attestation whenever `customer_name` changes.
1956
- customer_name_placeholder_confirmed: z12.boolean().optional(),
1957
- customer_phone: customerPhoneSchema.nullable().optional(),
1958
- customer_email: customerEmailSchema.nullable().optional(),
1825
+ customer_name_placeholder_confirmed: z2.optional(z2.boolean()),
1826
+ customer_phone: z2.nullish(customerPhoneSchema),
1827
+ customer_email: z2.nullish(customerEmailSchema),
1959
1828
  // NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
1960
- sms_consent: z12.boolean().optional()
1961
- }).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: false }));
1829
+ sms_consent: z2.optional(z2.boolean())
1830
+ }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: false }));
1962
1831
  var TRACKING_RANGES = ["24h", "7d", "30d"];
1963
1832
  var NAMED_RANGES = [
1964
1833
  "today",
@@ -2039,8 +1908,8 @@ function instantFromWallClock(timeZone, year, month, day, hour = 0, minute = 0)
2039
1908
  const corrected = naive - offsetMinutesAt(firstGuess, timeZone) * 6e4;
2040
1909
  return new Date(corrected);
2041
1910
  }
2042
- function localDateKey(iso, timeZone) {
2043
- const p = partsInTz(new Date(iso), timeZone);
1911
+ function localDateKey(iso4, timeZone) {
1912
+ const p = partsInTz(new Date(iso4), timeZone);
2044
1913
  const pad = (n) => String(n).padStart(2, "0");
2045
1914
  return `${p.year}-${pad(p.month)}-${pad(p.day)}`;
2046
1915
  }
@@ -2095,7 +1964,167 @@ function isCalendarError(error, code) {
2095
1964
  }
2096
1965
 
2097
1966
  // ../tracking-core/src/resources/calendar/schema.ts
2098
- import { z as z13 } from "zod";
1967
+ import * as z4 from "zod/mini";
1968
+
1969
+ // ../tracking-core/src/resources/calendar/generated/zod.gen.ts
1970
+ import * as z3 from "zod/mini";
1971
+ var zBookingAttendee = z3.strictObject({
1972
+ display_name: z3.nullish(z3.string().check(z3.maxLength(200))),
1973
+ email: z3.email().check(z3.maxLength(320)),
1974
+ optional: z3._default(z3.optional(z3.boolean()), false)
1975
+ });
1976
+ var zBookingCancelSchema = z3.strictObject({
1977
+ notify_attendees: z3._default(z3.optional(z3.boolean()), true),
1978
+ reason: z3.nullish(z3.string().check(z3.maxLength(500)))
1979
+ });
1980
+ var zBookingCustomerInput = z3.strictObject({
1981
+ email: z3.email().check(z3.maxLength(320)),
1982
+ name: z3.nullish(z3.string().check(z3.maxLength(200))),
1983
+ phone: z3.nullish(z3.string().check(z3.maxLength(64))),
1984
+ sms_consent: z3._default(z3.optional(z3.boolean()), false)
1985
+ });
1986
+ var zBookingCustomerOutput = z3.strictObject({
1987
+ email: z3.email().check(z3.maxLength(320)),
1988
+ name: z3.nullable(z3.string().check(z3.maxLength(200))),
1989
+ phone: z3.nullable(z3.string().check(z3.maxLength(64))),
1990
+ sms_consent: z3._default(z3.boolean(), false)
1991
+ });
1992
+ var zBookingRescheduleSchema = z3.strictObject({
1993
+ duration_minutes: z3.nullish(z3.int().check(z3.gt(0), z3.lte(1440))),
1994
+ end_at: z3.nullish(z3.iso.datetime({ offset: true })),
1995
+ notify_attendees: z3._default(z3.optional(z3.boolean()), true),
1996
+ reason: z3.nullish(z3.string().check(z3.maxLength(500))),
1997
+ start_at: z3.iso.datetime({ offset: true }),
1998
+ time_zone: z3.string().check(z3.minLength(1), z3.maxLength(64), z3.regex(/^[A-Za-z0-9_+\-\/]+$/))
1999
+ });
2000
+ var zBookingResponse = z3.strictObject({
2001
+ appointment_type: z3.nullable(z3.string()),
2002
+ calendar_key: z3.string(),
2003
+ customer: zBookingCustomerOutput,
2004
+ end_at: z3.iso.datetime({ offset: true }),
2005
+ google_html_link: z3.nullable(z3.string()),
2006
+ google_sync_state: z3.string(),
2007
+ id: z3.string(),
2008
+ manage_token: z3.nullable(z3.string()),
2009
+ meet_url: z3.nullable(z3.string()),
2010
+ start_at: z3.iso.datetime({ offset: true }),
2011
+ status: z3.string(),
2012
+ time_zone: z3.string(),
2013
+ title: z3.string()
2014
+ });
2015
+ var zBookingSource = z3.enum(["website", "phone", "walk_in", "import", "operator"]);
2016
+ var zBookingMetadata = z3.strictObject({
2017
+ custom: z3.nullish(
2018
+ z3.record(z3.string(), z3.nullable(z3.union([z3.string(), z3.int(), z3.number(), z3.boolean()])))
2019
+ ),
2020
+ fbclid: z3.nullish(z3.string().check(z3.maxLength(256))),
2021
+ gclid: z3.nullish(z3.string().check(z3.maxLength(256))),
2022
+ landing_page: z3.nullish(z3.string().check(z3.maxLength(2048))),
2023
+ notes: z3.nullish(z3.string().check(z3.maxLength(2e3))),
2024
+ referrer: z3.nullish(z3.string().check(z3.maxLength(2048))),
2025
+ schema_version: z3._default(z3.optional(z3.int()), 1),
2026
+ service: z3.nullish(z3.string().check(z3.maxLength(64))),
2027
+ session_id: z3.nullish(z3.string().check(z3.maxLength(64))),
2028
+ source: z3.nullish(zBookingSource),
2029
+ utm_campaign: z3.nullish(z3.string().check(z3.maxLength(128))),
2030
+ utm_content: z3.nullish(z3.string().check(z3.maxLength(128))),
2031
+ utm_medium: z3.nullish(z3.string().check(z3.maxLength(128))),
2032
+ utm_source: z3.nullish(z3.string().check(z3.maxLength(128))),
2033
+ utm_term: z3.nullish(z3.string().check(z3.maxLength(128))),
2034
+ visitor_id: z3.nullish(z3.string().check(z3.maxLength(64)))
2035
+ });
2036
+ var zCustomLocation = z3.strictObject({
2037
+ kind: z3.literal("custom"),
2038
+ text: z3.string().check(z3.maxLength(1024))
2039
+ });
2040
+ var zErrorCode2 = z3.enum([
2041
+ "missing_credentials",
2042
+ "invalid_api_key",
2043
+ "not_authenticated",
2044
+ "wrong_key_type",
2045
+ "origin_missing",
2046
+ "origin_not_allowed",
2047
+ "capability_denied",
2048
+ "session_required",
2049
+ "operator_only",
2050
+ "cross_tenant",
2051
+ "business_id_required",
2052
+ "bad_request",
2053
+ "not_found",
2054
+ "conflict",
2055
+ "incompatible_payload",
2056
+ "repeat_confirmation_required",
2057
+ "idempotency_conflict",
2058
+ "validation_error",
2059
+ "unknown_service",
2060
+ "invalid_sale_properties",
2061
+ "invalid_cursor",
2062
+ "rate_limited",
2063
+ "internal_error"
2064
+ ]);
2065
+ var zMeetLocation = z3.strictObject({
2066
+ kind: z3.literal("google_meet")
2067
+ });
2068
+ var zPhoneLocation = z3.strictObject({
2069
+ kind: z3.literal("phone"),
2070
+ phone: z3.string().check(z3.maxLength(64))
2071
+ });
2072
+ var zPhysicalLocation = z3.strictObject({
2073
+ address: z3.string().check(z3.maxLength(1024)),
2074
+ kind: z3.literal("physical")
2075
+ });
2076
+ var zReminderMethod = z3.enum(["email", "popup"]);
2077
+ var zBookingReminder = z3.strictObject({
2078
+ method: zReminderMethod,
2079
+ minutes_before: z3.int().check(z3.gte(0), z3.lte(40320))
2080
+ });
2081
+ var zBookingReminders = z3.strictObject({
2082
+ overrides: z3.optional(z3.array(zBookingReminder).check(z3.maxLength(5))),
2083
+ use_calendar_defaults: z3._default(z3.optional(z3.boolean()), true)
2084
+ });
2085
+ var zBookingCreateSchema = z3.strictObject({
2086
+ appointment_type: z3.nullish(z3.string().check(z3.maxLength(64))),
2087
+ attendees: z3.optional(z3.array(zBookingAttendee).check(z3.maxLength(20))),
2088
+ buffer_after_minutes: z3._default(z3.optional(z3.int().check(z3.gte(0), z3.lte(1440))), 0),
2089
+ buffer_before_minutes: z3._default(z3.optional(z3.int().check(z3.gte(0), z3.lte(1440))), 0),
2090
+ calendar_key: z3.string().check(z3.minLength(1), z3.maxLength(64)),
2091
+ customer: zBookingCustomerInput,
2092
+ description: z3.nullish(z3.string().check(z3.maxLength(8e3))),
2093
+ duration_minutes: z3.nullish(z3.int().check(z3.gt(0), z3.lte(1440))),
2094
+ end_at: z3.nullish(z3.iso.datetime({ offset: true })),
2095
+ idempotency_key: z3.nullish(z3.string().check(z3.maxLength(128))),
2096
+ location: z3.nullish(z3.union([zMeetLocation, zPhysicalLocation, zPhoneLocation, zCustomLocation])),
2097
+ metadata: z3.nullish(zBookingMetadata),
2098
+ reminders: z3.nullish(zBookingReminders),
2099
+ send_invites: z3._default(z3.optional(z3.boolean()), true),
2100
+ start_at: z3.iso.datetime({ offset: true }),
2101
+ time_zone: z3.string().check(z3.minLength(1), z3.maxLength(64), z3.regex(/^[A-Za-z0-9_+\-\/]+$/)),
2102
+ title: z3.nullish(z3.string().check(z3.maxLength(300)))
2103
+ });
2104
+ var zValidationError2 = z3.object({
2105
+ ctx: z3.optional(z3.record(z3.string(), z3.unknown())),
2106
+ input: z3.optional(z3.unknown()),
2107
+ loc: z3.array(z3.union([z3.string(), z3.int()])),
2108
+ msg: z3.string(),
2109
+ type: z3.string()
2110
+ });
2111
+ var zHttpValidationError2 = z3.object({
2112
+ detail: z3.optional(z3.array(zValidationError2))
2113
+ });
2114
+ var zValidationErrorItem2 = z3.object({
2115
+ loc: z3.array(z3.union([z3.string(), z3.int()])),
2116
+ msg: z3.string(),
2117
+ type: z3.string()
2118
+ });
2119
+ var zApiErrorSchema2 = z3.object({
2120
+ code: zErrorCode2,
2121
+ context: z3._default(z3.nullish(z3.record(z3.string(), z3.unknown())), null),
2122
+ detail: z3.string(),
2123
+ errors: z3._default(z3.nullish(z3.array(zValidationErrorItem2)), null),
2124
+ request_id: z3._default(z3.nullish(z3.string()), null)
2125
+ });
2126
+
2127
+ // ../tracking-core/src/resources/calendar/schema.ts
2099
2128
  var CALENDAR_METADATA_SCHEMA_VERSION = 1;
2100
2129
  var MAX_ATTENDEES = 20;
2101
2130
  var MAX_REMINDER_OVERRIDES = 5;
@@ -2121,7 +2150,6 @@ var CALENDAR_ERROR_CODES = [
2121
2150
  "rate_limited",
2122
2151
  "google_error"
2123
2152
  ];
2124
- var isoInstant = z13.string().datetime({ offset: true });
2125
2153
  function isKnownTimeZone(timeZone) {
2126
2154
  try {
2127
2155
  new Intl.DateTimeFormat(void 0, { timeZone });
@@ -2130,107 +2158,65 @@ function isKnownTimeZone(timeZone) {
2130
2158
  return false;
2131
2159
  }
2132
2160
  }
2133
- var ianaTz = z13.string().min(1).max(64).regex(/^[A-Za-z0-9_+\-/]+$/).refine(isKnownTimeZone, { message: "unknown IANA time zone" });
2134
- var bookingAttendeeSchema = z13.object({
2135
- email: z13.string().max(320).email(),
2136
- display_name: z13.string().max(200).nullable().optional(),
2137
- optional: z13.boolean().default(false)
2138
- }).strict();
2139
- var bookingReminderSchema = z13.object({
2140
- method: z13.enum(["email", "popup"]),
2141
- minutes_before: z13.number().int().min(0).max(MAX_REMINDER_MINUTES)
2142
- }).strict();
2143
- var bookingRemindersSchema = z13.object({
2144
- use_calendar_defaults: z13.boolean().default(true),
2145
- overrides: z13.array(bookingReminderSchema).max(MAX_REMINDER_OVERRIDES).default([])
2146
- }).strict();
2147
- var bookingLocationSchema = z13.union([
2148
- z13.object({ kind: z13.literal("google_meet") }).strict(),
2149
- z13.object({ kind: z13.literal("physical"), address: z13.string().max(1024) }).strict(),
2150
- z13.object({ kind: z13.literal("phone"), phone: z13.string().max(64) }).strict(),
2151
- z13.object({ kind: z13.literal("custom"), text: z13.string().max(1024) }).strict()
2161
+ var ianaTz = z4.string().check(
2162
+ z4.minLength(1),
2163
+ z4.maxLength(64),
2164
+ z4.regex(/^[A-Za-z0-9_+\-/]+$/),
2165
+ z4.refine(isKnownTimeZone, { error: "unknown IANA time zone" })
2166
+ );
2167
+ var bookingAttendeeSchema = zBookingAttendee;
2168
+ var bookingReminderSchema = zBookingReminder;
2169
+ var bookingCustomerSchema = zBookingCustomerInput;
2170
+ var bookingMetadataSchema = z4.extend(zBookingMetadata, {
2171
+ custom: z4.nullish(
2172
+ z4.record(z4.string(), z4.union([z4.string(), z4.int(), z4.number(), z4.boolean(), z4.null()]))
2173
+ )
2174
+ });
2175
+ var bookingLocationSchema = z4.union([
2176
+ zMeetLocation,
2177
+ zPhysicalLocation,
2178
+ zPhoneLocation,
2179
+ zCustomLocation
2152
2180
  ]);
2153
- var bookingLocationNullableSchema = z13.union([...bookingLocationSchema.options, z13.null()]);
2154
- var bookingCustomerSchema = z13.object({
2155
- // Required: Google needs an address to send the invite that confirms the
2156
- // booking, and that invite is the whole confirmation mechanism.
2157
- email: z13.string().max(320).email(),
2158
- name: z13.string().max(200).nullable().optional(),
2159
- phone: z13.string().max(64).nullable().optional(),
2160
- sms_consent: z13.boolean().default(false)
2161
- }).strict();
2162
- var jsonScalar = z13.union([z13.string(), z13.number(), z13.boolean(), z13.null()]);
2163
- var bookingMetadataSchema = z13.object({
2164
- schema_version: z13.number().int().default(CALENDAR_METADATA_SCHEMA_VERSION),
2165
- source: z13.enum(BOOKING_SOURCES).nullable().optional(),
2166
- service: z13.string().max(64).nullable().optional(),
2167
- visitor_id: z13.string().max(64).nullable().optional(),
2168
- session_id: z13.string().max(64).nullable().optional(),
2169
- gclid: z13.string().max(256).nullable().optional(),
2170
- fbclid: z13.string().max(256).nullable().optional(),
2171
- utm_source: z13.string().max(128).nullable().optional(),
2172
- utm_medium: z13.string().max(128).nullable().optional(),
2173
- utm_campaign: z13.string().max(128).nullable().optional(),
2174
- utm_term: z13.string().max(128).nullable().optional(),
2175
- utm_content: z13.string().max(128).nullable().optional(),
2176
- landing_page: z13.string().max(2048).nullable().optional(),
2177
- referrer: z13.string().max(2048).nullable().optional(),
2178
- notes: z13.string().max(2e3).nullable().optional(),
2179
- custom: z13.record(jsonScalar).nullable().optional()
2180
- }).strict();
2181
+ var bookingLocationNullableSchema = z4.union([
2182
+ ...bookingLocationSchema.def.options,
2183
+ z4.null()
2184
+ ]);
2185
+ function addIssue2(ctx, path, message) {
2186
+ ctx.issues.push({ code: "custom", input: ctx.value, path, message });
2187
+ }
2181
2188
  function refineEndXor(value, ctx) {
2182
2189
  const hasEnd = value.end_at !== void 0 && value.end_at !== null;
2183
2190
  const hasDuration = value.duration_minutes !== void 0 && value.duration_minutes !== null;
2184
2191
  if (hasEnd === hasDuration) {
2185
- ctx.addIssue({
2186
- code: z13.ZodIssueCode.custom,
2187
- message: "provide exactly one of end_at or duration_minutes",
2188
- path: ["end_at"]
2189
- });
2192
+ addIssue2(ctx, ["end_at"], "provide exactly one of end_at or duration_minutes");
2190
2193
  return;
2191
2194
  }
2192
2195
  if (hasEnd && new Date(value.end_at) <= new Date(value.start_at)) {
2193
- ctx.addIssue({
2194
- code: z13.ZodIssueCode.custom,
2195
- message: "end_at must be after start_at",
2196
- path: ["end_at"]
2197
- });
2196
+ addIssue2(ctx, ["end_at"], "end_at must be after start_at");
2198
2197
  }
2199
2198
  }
2200
- var bookingCreateSchema = z13.object({
2201
- calendar_key: z13.string().min(1).max(64),
2202
- // Free-form: appointment types are the client site's own vocabulary, not
2203
- // configuration the dashboard holds.
2204
- appointment_type: z13.string().max(64).nullable().optional(),
2205
- start_at: isoInstant,
2206
- end_at: isoInstant.nullable().optional(),
2207
- duration_minutes: z13.number().int().positive().max(MAX_BOOKING_MINUTES).nullable().optional(),
2208
- /** The booker's zone — distinct from the business's and the calendar's. */
2209
- time_zone: ianaTz,
2210
- title: z13.string().max(300).nullable().optional(),
2211
- description: z13.string().max(8e3).nullable().optional(),
2212
- location: bookingLocationNullableSchema.optional(),
2213
- customer: bookingCustomerSchema,
2214
- attendees: z13.array(bookingAttendeeSchema).max(MAX_ATTENDEES).default([]),
2215
- send_invites: z13.boolean().default(true),
2216
- reminders: bookingRemindersSchema.nullable().optional(),
2217
- metadata: bookingMetadataSchema.nullable().optional(),
2218
- idempotency_key: z13.string().max(128).nullable().optional(),
2219
- buffer_before_minutes: z13.number().int().min(0).max(MAX_BOOKING_MINUTES).default(0),
2220
- buffer_after_minutes: z13.number().int().min(0).max(MAX_BOOKING_MINUTES).default(0)
2221
- }).strict().superRefine(refineEndXor);
2222
- var bookingRescheduleSchema = z13.object({
2223
- start_at: isoInstant,
2224
- end_at: isoInstant.nullable().optional(),
2225
- duration_minutes: z13.number().int().positive().max(MAX_BOOKING_MINUTES).nullable().optional(),
2199
+ var bookingRemindersSchema = z4.extend(zBookingReminders, {
2200
+ overrides: z4._default(
2201
+ z4.array(bookingReminderSchema).check(z4.maxLength(MAX_REMINDER_OVERRIDES)),
2202
+ []
2203
+ )
2204
+ });
2205
+ var bookingCreateSchema = z4.extend(zBookingCreateSchema, {
2226
2206
  time_zone: ianaTz,
2227
- notify_attendees: z13.boolean().default(true),
2228
- reason: z13.string().max(500).nullable().optional()
2229
- }).strict().superRefine(refineEndXor);
2230
- var bookingCancelSchema = z13.object({
2231
- reason: z13.string().max(500).nullable().optional(),
2232
- notify_attendees: z13.boolean().default(true)
2233
- }).strict();
2207
+ // The generated field is `z.union([...variants]).nullish()`, which nests one
2208
+ // `anyOf` inside another; Pydantic's `BookingLocation | None` flattens to a
2209
+ // single list and the drift snapshot compares structure. Override with the
2210
+ // flattened union.
2211
+ location: z4.optional(bookingLocationNullableSchema),
2212
+ attendees: z4._default(z4.array(bookingAttendeeSchema).check(z4.maxLength(MAX_ATTENDEES)), []),
2213
+ // These reference the un-composed generated schemas; generation can't nest
2214
+ // our compositions into its own output.
2215
+ reminders: z4.nullish(bookingRemindersSchema),
2216
+ metadata: z4.nullish(bookingMetadataSchema)
2217
+ }).check((ctx) => refineEndXor(ctx.value, ctx));
2218
+ var bookingRescheduleSchema = z4.extend(zBookingRescheduleSchema, { time_zone: ianaTz }).check((ctx) => refineEndXor(ctx.value, ctx));
2219
+ var bookingCancelSchema = zBookingCancelSchema;
2234
2220
 
2235
2221
  // ../tracking-core/src/resources/calendar/slots.ts
2236
2222
  function parseHhMm(value) {
@@ -2461,6 +2447,7 @@ export {
2461
2447
  createTrackingClientContext,
2462
2448
  createTrackingEventCreatePayload,
2463
2449
  createTrackingSessionUpsertPayload,
2450
+ currencySchema,
2464
2451
  durationMinutes,
2465
2452
  endOfDayInTz,
2466
2453
  fetchServices,