@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.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/index.ts
@@ -62,6 +72,7 @@ __export(src_exports, {
62
72
  createTrackingClientContext: () => createTrackingClientContext,
63
73
  createTrackingEventCreatePayload: () => createTrackingEventCreatePayload,
64
74
  createTrackingSessionUpsertPayload: () => createTrackingSessionUpsertPayload,
75
+ currencySchema: () => currencySchema,
65
76
  durationMinutes: () => durationMinutes,
66
77
  endOfDayInTz: () => endOfDayInTz,
67
78
  fetchServices: () => fetchServices,
@@ -162,7 +173,7 @@ function normalizeEmail(raw) {
162
173
  return EMAIL_SHAPE.test(cleaned) ? cleaned : null;
163
174
  }
164
175
  function stashUserData(data, country) {
165
- const email = normalizeEmail(data.email);
176
+ const email4 = normalizeEmail(data.email);
166
177
  let phoneNumber = null;
167
178
  if (typeof data.phone === "string" && data.phone.length > 0) {
168
179
  try {
@@ -172,7 +183,7 @@ function stashUserData(data, country) {
172
183
  }
173
184
  }
174
185
  stash = {
175
- email: email ?? stash.email,
186
+ email: email4 ?? stash.email,
176
187
  phoneNumber: phoneNumber ?? stash.phoneNumber
177
188
  };
178
189
  }
@@ -181,11 +192,11 @@ function clearStashedUserData() {
181
192
  }
182
193
  function applyUserDataForConversion(explicit, country) {
183
194
  if (typeof window === "undefined" || typeof window.gtag !== "function") return false;
184
- let email = stash.email;
195
+ let email4 = stash.email;
185
196
  let phoneNumber = stash.phoneNumber;
186
197
  if (explicit) {
187
198
  const normalizedEmail = normalizeEmail(explicit.email);
188
- if (normalizedEmail) email = normalizedEmail;
199
+ if (normalizedEmail) email4 = normalizedEmail;
189
200
  if (typeof explicit.phone === "string" && explicit.phone.length > 0) {
190
201
  try {
191
202
  phoneNumber = toE164(explicit.phone, country) ?? phoneNumber;
@@ -193,10 +204,10 @@ function applyUserDataForConversion(explicit, country) {
193
204
  }
194
205
  }
195
206
  }
196
- if (email === null && phoneNumber === null) return false;
207
+ if (email4 === null && phoneNumber === null) return false;
197
208
  try {
198
209
  window.gtag("set", "user_data", {
199
- ...email !== null ? { email } : {},
210
+ ...email4 !== null ? { email: email4 } : {},
200
211
  ...phoneNumber !== null ? { phone_number: phoneNumber } : {}
201
212
  });
202
213
  return true;
@@ -552,10 +563,10 @@ function readStoredRecord() {
552
563
  return null;
553
564
  }
554
565
  }
555
- function writeRecord(record) {
556
- memoryRecord = record;
566
+ function writeRecord(record5) {
567
+ memoryRecord = record5;
557
568
  try {
558
- window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record));
569
+ window.localStorage.setItem(LANDING_STORAGE_KEY, JSON.stringify(record5));
559
570
  } catch {
560
571
  }
561
572
  }
@@ -577,9 +588,9 @@ function getOrCaptureLandingParams(sessionId, url) {
577
588
  if (memoryRecord && memoryRecord.session_id === sessionId) {
578
589
  return memoryRecord.params;
579
590
  }
580
- const record = { session_id: sessionId, params: captureFromUrl(url) };
581
- writeRecord(record);
582
- return record.params;
591
+ const record5 = { session_id: sessionId, params: captureFromUrl(url) };
592
+ writeRecord(record5);
593
+ return record5.params;
583
594
  }
584
595
  function buildLandingPayloadFields(sessionId, override) {
585
596
  const params = override ?? (typeof window === "undefined" ? null : getOrCaptureLandingParams(sessionId));
@@ -956,9 +967,9 @@ function automaticThresholdMet(goal, eventType, metadata) {
956
967
  }
957
968
 
958
969
  // ../tracking-core/src/resources/intl/date.ts
959
- function formatDateInTz(iso, timeZone, opts, locale) {
960
- const date = new Date(iso);
961
- if (Number.isNaN(date.getTime())) return iso;
970
+ function formatDateInTz(iso4, timeZone, opts, locale) {
971
+ const date = new Date(iso4);
972
+ if (Number.isNaN(date.getTime())) return iso4;
962
973
  return new Intl.DateTimeFormat(locale, {
963
974
  year: "numeric",
964
975
  month: "short",
@@ -1370,29 +1381,6 @@ function getTrackingConfigRuntime(ref, fetchImpl) {
1370
1381
  return runtime;
1371
1382
  }
1372
1383
 
1373
- // ../tracking-core/src/session.ts
1374
- var SESSION_IDLE_MS = 30 * 60 * 1e3;
1375
-
1376
- // ../tracking-core/src/events/page-view.ts
1377
- var import_zod = require("zod");
1378
- var pageViewMetadataSchema = import_zod.z.object({
1379
- page: import_zod.z.object({
1380
- title: import_zod.z.string().nullable(),
1381
- path: import_zod.z.string(),
1382
- search: import_zod.z.string(),
1383
- hash: import_zod.z.string()
1384
- }).strict(),
1385
- referrer: import_zod.z.string().nullable(),
1386
- // `.nullable().optional()` — absent (undefined) OR explicit null OR a
1387
- // real viewport object. Mirrors Pydantic's `_Viewport | None = None`
1388
- // on the backend side so the drift test stays clean.
1389
- viewport: import_zod.z.object({
1390
- w: import_zod.z.number(),
1391
- h: import_zod.z.number()
1392
- }).strict().nullable().optional()
1393
- }).strict();
1394
- var pageViewConfigSchema = import_zod.z.object({}).strict();
1395
-
1396
1384
  // ../tracking-core/src/ingest.ts
1397
1385
  var API_KEY_HEADER = "X-Aranova-Api-Key";
1398
1386
  var SDK_VERSION_HEADER = "X-Aranova-Sdk-Version";
@@ -1400,187 +1388,6 @@ var SDK_PACKAGE_HEADER = "X-Aranova-Sdk-Package";
1400
1388
  var SDK_SURFACE_HEADER = "X-Aranova-Sdk-Surface";
1401
1389
  var SDK_ENVIRONMENT_HEADER = "X-Aranova-Sdk-Environment";
1402
1390
 
1403
- // ../tracking-core/src/events/cta-click.ts
1404
- var import_zod2 = require("zod");
1405
- var ctaClickMetadataSchema = import_zod2.z.object({
1406
- cta_name: import_zod2.z.string(),
1407
- page: import_zod2.z.object({
1408
- path: import_zod2.z.string()
1409
- }).strict(),
1410
- section: import_zod2.z.string().nullable().optional(),
1411
- destination_url: import_zod2.z.string().nullable().optional(),
1412
- // Set by auto-capture (and available to manual callers): the link target
1413
- // and a short element descriptor (tag#id) for tying clicks to specific UI.
1414
- href: import_zod2.z.string().nullable().optional(),
1415
- element: import_zod2.z.string().nullable().optional()
1416
- }).strict();
1417
- var ctaClickConfigSchema = import_zod2.z.object({
1418
- autoCapture: import_zod2.z.object({
1419
- selector: import_zod2.z.string().optional()
1420
- }).strict().optional()
1421
- }).strict();
1422
-
1423
- // ../tracking-core/src/events/sdk-heartbeat.ts
1424
- var import_zod3 = require("zod");
1425
- var sdkHeartbeatTriggersSchema = import_zod3.z.object({
1426
- automatic: import_zod3.z.array(import_zod3.z.string()),
1427
- manual: import_zod3.z.array(import_zod3.z.string())
1428
- }).strict();
1429
- var sdkHeartbeatMetadataSchema = import_zod3.z.object({
1430
- sdk_version: import_zod3.z.string(),
1431
- package_name: import_zod3.z.string().nullable(),
1432
- surface: import_zod3.z.enum(["next", "react", "script"]),
1433
- triggers: sdkHeartbeatTriggersSchema,
1434
- trigger_config: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.record(import_zod3.z.string(), import_zod3.z.unknown())).nullable().optional(),
1435
- configured_gtag_ids: import_zod3.z.record(import_zod3.z.string(), import_zod3.z.string()).nullable().optional(),
1436
- // Site whose config object the SDK resolves; null on a legacy business ref.
1437
- config_site_id: import_zod3.z.string().uuid().nullable().optional()
1438
- }).strict();
1439
- var sdkHeartbeatConfigSchema = import_zod3.z.object({}).strict();
1440
-
1441
- // ../tracking-core/src/events/form-start.ts
1442
- var import_zod4 = require("zod");
1443
- var formStartMetadataSchema = import_zod4.z.object({
1444
- form: import_zod4.z.object({
1445
- id: import_zod4.z.string(),
1446
- action: import_zod4.z.string().nullable()
1447
- }).strict(),
1448
- page: import_zod4.z.object({
1449
- path: import_zod4.z.string()
1450
- }).strict()
1451
- }).strict();
1452
- var formStartConfigSchema = import_zod4.z.object({
1453
- selector: import_zod4.z.string().optional()
1454
- }).strict();
1455
-
1456
- // ../tracking-core/src/events/form-submit.ts
1457
- var import_zod5 = require("zod");
1458
- var jsonValueSchema = import_zod5.z.lazy(
1459
- () => import_zod5.z.union([
1460
- import_zod5.z.string(),
1461
- import_zod5.z.number().finite(),
1462
- import_zod5.z.boolean(),
1463
- import_zod5.z.null(),
1464
- import_zod5.z.array(jsonValueSchema),
1465
- import_zod5.z.record(jsonValueSchema)
1466
- ])
1467
- );
1468
- var formSubmitMetadataSchema = import_zod5.z.object({
1469
- form: import_zod5.z.object({
1470
- id: import_zod5.z.string(),
1471
- action: import_zod5.z.string().nullable(),
1472
- fields: import_zod5.z.array(
1473
- import_zod5.z.object({
1474
- name: import_zod5.z.string(),
1475
- type: import_zod5.z.string(),
1476
- label: import_zod5.z.string().nullable(),
1477
- value: jsonValueSchema
1478
- }).strict()
1479
- ).optional()
1480
- }).strict(),
1481
- page: import_zod5.z.object({
1482
- path: import_zod5.z.string()
1483
- }).strict()
1484
- }).strict();
1485
- var formSubmitConfigSchema = import_zod5.z.object({}).strict();
1486
-
1487
- // ../tracking-core/src/events/multi-page-session.ts
1488
- var import_zod6 = require("zod");
1489
- var multiPageSessionMetadataSchema = import_zod6.z.object({
1490
- page_count: import_zod6.z.number().int().min(2),
1491
- page: import_zod6.z.object({
1492
- path: import_zod6.z.string()
1493
- }).strict()
1494
- }).strict();
1495
- var multiPageSessionConfigSchema = import_zod6.z.object({
1496
- pageThreshold: import_zod6.z.number().int().min(2)
1497
- }).strict();
1498
-
1499
- // ../tracking-core/src/events/page-exit.ts
1500
- var import_zod7 = require("zod");
1501
- var pageExitMetadataSchema = import_zod7.z.object({
1502
- dwell_ms: import_zod7.z.number().int().min(0),
1503
- // null = left without any scroll signal; floor is 0 so a valid 0% is never
1504
- // rejected (a single bad field 422s the whole keepalive beacon batch).
1505
- max_scroll_percent: import_zod7.z.number().int().min(0).max(100).nullable(),
1506
- // The gating baseline: the fraction of the page visible at load with
1507
- // zero scrolling — or, for pages that grew after the post-paint snapshot
1508
- // (skeleton/streaming renders), the first-scroll position that
1509
- // established it. null = page had no scrollable range, or the segment
1510
- // ended before the snapshot. `.optional()` is load-bearing: SDK builds
1511
- // predating this field keep POSTing page_exit without the key —
1512
- // requiring it would 422 whole keepalive beacon batches.
1513
- scroll_baseline_percent: import_zod7.z.number().int().min(0).max(100).nullable().optional(),
1514
- page: import_zod7.z.object({
1515
- path: import_zod7.z.string()
1516
- }).strict()
1517
- }).strict();
1518
- var pageExitConfigSchema = import_zod7.z.object({}).strict();
1519
-
1520
- // ../tracking-core/src/events/phone-click.ts
1521
- var import_zod8 = require("zod");
1522
- var phoneClickMetadataSchema = import_zod8.z.object({
1523
- phone_number: import_zod8.z.string(),
1524
- page: import_zod8.z.object({
1525
- path: import_zod8.z.string()
1526
- }).strict(),
1527
- section: import_zod8.z.string().nullable().optional()
1528
- }).strict();
1529
- var phoneClickConfigSchema = import_zod8.z.object({
1530
- autoCapture: import_zod8.z.object({
1531
- selector: import_zod8.z.string().optional()
1532
- }).strict().optional()
1533
- }).strict();
1534
-
1535
- // ../tracking-core/src/events/scroll-depth.ts
1536
- var import_zod9 = require("zod");
1537
- var scrollDepthMetadataSchema = import_zod9.z.object({
1538
- depth_percent: import_zod9.z.number().int().min(1).max(100),
1539
- page: import_zod9.z.object({
1540
- path: import_zod9.z.string()
1541
- }).strict()
1542
- }).strict();
1543
- var scrollDepthConfigSchema = import_zod9.z.object({
1544
- thresholds: import_zod9.z.array(import_zod9.z.number().int().min(1).max(100)).min(1)
1545
- }).strict();
1546
-
1547
- // ../tracking-core/src/events/specific-page-visit.ts
1548
- var import_zod10 = require("zod");
1549
- var PAGE_IDENTITY_MAX_LENGTH = 64;
1550
- var PAGE_IDENTITY_PATTERN = /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/;
1551
- var pageIdentitySchema = import_zod10.z.string().max(PAGE_IDENTITY_MAX_LENGTH).regex(PAGE_IDENTITY_PATTERN, {
1552
- message: "page identity must be lowercase snake_case, start with a letter, and contain at most 64 characters"
1553
- });
1554
- var specificPageNameSchema = pageIdentitySchema;
1555
- var specificPageVisitMetadataSchema = import_zod10.z.object({
1556
- page_name: specificPageNameSchema,
1557
- page: import_zod10.z.object({
1558
- path: import_zod10.z.string()
1559
- }).strict()
1560
- }).strict();
1561
- var specificPageVisitConfigSchema = import_zod10.z.object({
1562
- pages: import_zod10.z.array(
1563
- import_zod10.z.object({
1564
- name: specificPageNameSchema,
1565
- pathPattern: import_zod10.z.custom((value) => value instanceof RegExp, {
1566
- message: "pathPattern must be a RegExp"
1567
- })
1568
- }).strict()
1569
- ).min(1)
1570
- }).strict();
1571
-
1572
- // ../tracking-core/src/events/time-on-site.ts
1573
- var import_zod11 = require("zod");
1574
- var timeOnSiteMetadataSchema = import_zod11.z.object({
1575
- duration_ms: import_zod11.z.number().int().nonnegative(),
1576
- page: import_zod11.z.object({
1577
- path: import_zod11.z.string()
1578
- }).strict()
1579
- }).strict();
1580
- var timeOnSiteConfigSchema = import_zod11.z.object({
1581
- thresholdSeconds: import_zod11.z.number().int().positive()
1582
- }).strict();
1583
-
1584
1391
  // ../tracking-core/src/events/semantics.ts
1585
1392
  var EVENT_SEMANTICS = {
1586
1393
  page_view: {
@@ -1654,82 +1461,6 @@ function getEventSemantics(eventName) {
1654
1461
  return eventName in EVENT_SEMANTICS ? EVENT_SEMANTICS[eventName] : null;
1655
1462
  }
1656
1463
 
1657
- // ../tracking-core/src/events/registry.ts
1658
- var EVENT_REGISTRY = {
1659
- // --- automatic triggers ---
1660
- page_view: {
1661
- kind: "automatic",
1662
- semantics: EVENT_SEMANTICS.page_view,
1663
- metadataSchema: pageViewMetadataSchema,
1664
- configSchema: pageViewConfigSchema
1665
- },
1666
- time_on_site: {
1667
- kind: "automatic",
1668
- semantics: EVENT_SEMANTICS.time_on_site,
1669
- metadataSchema: timeOnSiteMetadataSchema,
1670
- configSchema: timeOnSiteConfigSchema
1671
- },
1672
- specific_page_visit: {
1673
- kind: "automatic",
1674
- semantics: EVENT_SEMANTICS.specific_page_visit,
1675
- metadataSchema: specificPageVisitMetadataSchema,
1676
- configSchema: specificPageVisitConfigSchema
1677
- },
1678
- scroll_depth: {
1679
- kind: "automatic",
1680
- semantics: EVENT_SEMANTICS.scroll_depth,
1681
- metadataSchema: scrollDepthMetadataSchema,
1682
- configSchema: scrollDepthConfigSchema
1683
- },
1684
- multi_page_session: {
1685
- kind: "automatic",
1686
- semantics: EVENT_SEMANTICS.multi_page_session,
1687
- metadataSchema: multiPageSessionMetadataSchema,
1688
- configSchema: multiPageSessionConfigSchema
1689
- },
1690
- form_start: {
1691
- kind: "automatic",
1692
- semantics: EVENT_SEMANTICS.form_start,
1693
- metadataSchema: formStartMetadataSchema,
1694
- configSchema: formStartConfigSchema
1695
- },
1696
- // --- SDK-internal automatic (not consumer-configurable) ---
1697
- sdk_heartbeat: {
1698
- kind: "automatic",
1699
- semantics: EVENT_SEMANTICS.sdk_heartbeat,
1700
- metadataSchema: sdkHeartbeatMetadataSchema,
1701
- configSchema: sdkHeartbeatConfigSchema
1702
- },
1703
- page_exit: {
1704
- kind: "automatic",
1705
- semantics: EVENT_SEMANTICS.page_exit,
1706
- metadataSchema: pageExitMetadataSchema,
1707
- configSchema: pageExitConfigSchema
1708
- },
1709
- // --- manual triggers ---
1710
- form_submit: {
1711
- kind: "manual",
1712
- semantics: EVENT_SEMANTICS.form_submit,
1713
- metadataSchema: formSubmitMetadataSchema,
1714
- configSchema: formSubmitConfigSchema
1715
- },
1716
- phone_click: {
1717
- kind: "manual",
1718
- semantics: EVENT_SEMANTICS.phone_click,
1719
- metadataSchema: phoneClickMetadataSchema,
1720
- configSchema: phoneClickConfigSchema
1721
- },
1722
- cta_click: {
1723
- kind: "manual",
1724
- semantics: EVENT_SEMANTICS.cta_click,
1725
- metadataSchema: ctaClickMetadataSchema,
1726
- configSchema: ctaClickConfigSchema
1727
- }
1728
- };
1729
- var ALL_AUTOMATIC_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "automatic").map(([name]) => name);
1730
- var ALL_MANUAL_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.kind === "manual").map(([name]) => name);
1731
- var ALL_LEAD_EVENT_NAMES = Object.entries(EVENT_REGISTRY).filter(([, def]) => def.semantics.outcomeRole === "lead").map(([name]) => name);
1732
-
1733
1464
  // ../tracking-core/src/resources/http/errors.ts
1734
1465
  var AranovaApiError = class extends Error {
1735
1466
  constructor(message, options) {
@@ -1767,9 +1498,9 @@ async function apiRequest(config, method, path, body, extraHeaders) {
1767
1498
  try {
1768
1499
  const parsed = await response.json();
1769
1500
  if (parsed && typeof parsed === "object") {
1770
- const record = parsed;
1771
- if (typeof record.detail === "string") detail = record.detail;
1772
- if (typeof record.code === "string") code = record.code;
1501
+ const record5 = parsed;
1502
+ if (typeof record5.detail === "string") detail = record5.detail;
1503
+ if (typeof record5.code === "string") code = record5.code;
1773
1504
  }
1774
1505
  } catch {
1775
1506
  }
@@ -1818,7 +1549,7 @@ function fireRecordedConversions(firing, input, recorded, sale, currency) {
1818
1549
  }
1819
1550
  function createSalesClient(config) {
1820
1551
  if (config.firing) registerCapability("conversion_goals_manual");
1821
- async function record(input) {
1552
+ async function record5(input) {
1822
1553
  const currency = input.currency ?? config.defaultCurrency;
1823
1554
  if (!currency) {
1824
1555
  throw new Error(
@@ -1844,9 +1575,9 @@ function createSalesClient(config) {
1844
1575
  return sale;
1845
1576
  }
1846
1577
  return {
1847
- record,
1578
+ record: record5,
1848
1579
  // recordSale is the intent-revealing alias — same behavior, clearer call site.
1849
- recordSale: record,
1580
+ recordSale: record5,
1850
1581
  trackConversion(key, options) {
1851
1582
  if (config.firing && "fireConversion" in config.firing) {
1852
1583
  if (options?.userData && getConsentState() !== "denied") stashUserData(options.userData);
@@ -1965,115 +1696,264 @@ function createSalesClient(config) {
1965
1696
  }
1966
1697
 
1967
1698
  // ../tracking-core/src/resources/sales/schema.ts
1968
- var import_zod12 = require("zod");
1969
- var SUPPORTED_CURRENCIES = ["USD", "CAD"];
1970
- var TRACKING_ENVIRONMENTS = ["production", "development"];
1971
- var currencySchema = import_zod12.z.enum(SUPPORTED_CURRENCIES);
1972
- var centsSchema = import_zod12.z.number().int().nonnegative();
1973
- var quantitySchema = import_zod12.z.string().regex(/^\d+(\.\d{1,3})?$/);
1974
- var metadataSchema = import_zod12.z.record(import_zod12.z.unknown());
1975
- var saleItemSchema = import_zod12.z.object({
1976
- external_item_id: import_zod12.z.string().nullable().optional(),
1977
- name: import_zod12.z.string().nullable().optional(),
1978
- category: import_zod12.z.string().nullable().optional(),
1979
- quantity: quantitySchema,
1980
- unit_price_cents: centsSchema,
1981
- // Non-negativity validated on the wire — same contract as the other cents
1982
- // fields — and backstopped by the DB CHECK.
1983
- unit_cost_cents: centsSchema.nullable().optional()
1984
- }).strict();
1985
- var saleServiceSchema = import_zod12.z.object({
1986
- service: import_zod12.z.string(),
1987
- amount_cents: centsSchema
1988
- }).strict();
1989
- var customerNameSchema = import_zod12.z.string().max(200);
1990
- var customerPhoneSchema = import_zod12.z.string().max(64);
1991
- var customerEmailSchema = import_zod12.z.string().max(320).email();
1699
+ var z2 = __toESM(require("zod/mini"));
1700
+
1701
+ // ../tracking-core/src/resources/sales/generated/zod.gen.ts
1702
+ var z = __toESM(require("zod/mini"));
1703
+ var zErrorCode = z.enum([
1704
+ "missing_credentials",
1705
+ "invalid_api_key",
1706
+ "not_authenticated",
1707
+ "wrong_key_type",
1708
+ "origin_missing",
1709
+ "origin_not_allowed",
1710
+ "capability_denied",
1711
+ "session_required",
1712
+ "operator_only",
1713
+ "cross_tenant",
1714
+ "business_id_required",
1715
+ "bad_request",
1716
+ "not_found",
1717
+ "conflict",
1718
+ "incompatible_payload",
1719
+ "repeat_confirmation_required",
1720
+ "idempotency_conflict",
1721
+ "validation_error",
1722
+ "unknown_service",
1723
+ "invalid_sale_properties",
1724
+ "invalid_cursor",
1725
+ "rate_limited",
1726
+ "internal_error"
1727
+ ]);
1728
+ var zSaleItemEntitySchema = z.object({
1729
+ category: z.nullable(z.string()),
1730
+ external_item_id: z.nullable(z.string()),
1731
+ id: z.uuid(),
1732
+ name: z.nullable(z.string()),
1733
+ quantity: z.string().check(z.regex(/^(?!^[-+.]*$)[+-]?0*\d*\.?\d*$/)),
1734
+ unit_cost_cents: z.nullable(z.int()),
1735
+ unit_price_cents: z.int()
1736
+ });
1737
+ var zSaleItemInputSchema = z.strictObject({
1738
+ category: z.nullish(z.string()),
1739
+ external_item_id: z.nullish(z.string()),
1740
+ name: z.nullish(z.string()),
1741
+ quantity: z.string().check(z.regex(/^\d+(\.\d{1,3})?$/)),
1742
+ unit_cost_cents: z.nullish(z.int().check(z.gte(0))),
1743
+ unit_price_cents: z.int().check(z.gte(0))
1744
+ });
1745
+ var zSaleServiceEntitySchema = z.object({
1746
+ amount_cents: z.int(),
1747
+ id: z.uuid(),
1748
+ mapped: z.nullable(z.boolean()),
1749
+ service_id: z.uuid(),
1750
+ service_key: z.string(),
1751
+ service_label: z.string()
1752
+ });
1753
+ var zSaleServiceInputSchema = z.strictObject({
1754
+ amount_cents: z.int().check(z.gte(0)),
1755
+ service: z.string()
1756
+ });
1757
+ var zSmsAutomationState = z.enum([
1758
+ "needs_check",
1759
+ "failed",
1760
+ "undelivered",
1761
+ "blocked_opted_out",
1762
+ "withheld",
1763
+ "queued",
1764
+ "sent",
1765
+ "delivered",
1766
+ "eligible",
1767
+ "not_applicable"
1768
+ ]);
1769
+ var zSmsWithheldReason = z.enum([
1770
+ "automation_disabled",
1771
+ "sms_disabled",
1772
+ "no_phone",
1773
+ "no_consent",
1774
+ "no_customer_identity",
1775
+ "missing_customer_name",
1776
+ "placeholder_customer_name",
1777
+ "opted_out",
1778
+ "already_messaged",
1779
+ "sender_not_ready",
1780
+ "missing_review_url",
1781
+ "no_handler",
1782
+ "dispatch_already_recorded"
1783
+ ]);
1784
+ var zSaleSmsStatusSchema = z.object({
1785
+ can_send_now: z._default(z.boolean(), false),
1786
+ last_message_at: z.nullable(z.iso.datetime({ offset: true })),
1787
+ reason_detail: z.nullable(z.string()),
1788
+ state: zSmsAutomationState,
1789
+ suppressed_by_other_sale: z._default(z.boolean(), false),
1790
+ withheld_reason: z.nullable(zSmsWithheldReason)
1791
+ });
1792
+ var zSupportedCurrency = z.enum(["USD", "CAD"]);
1793
+ var zTrackingEnvironment = z.enum(["production", "development"]);
1794
+ var zSaleCreateSchema = z.strictObject({
1795
+ amount_total_cents: z.nullish(z.int().check(z.gte(0))),
1796
+ currency: zSupportedCurrency,
1797
+ customer_email: z.nullish(z.email().check(z.maxLength(320))),
1798
+ customer_name: z.nullish(z.string().check(z.maxLength(200))),
1799
+ customer_phone: z.nullish(z.string().check(z.maxLength(64))),
1800
+ description: z.nullish(z.string()),
1801
+ environment: z._default(z.optional(zTrackingEnvironment), "production"),
1802
+ external_id: z.nullish(z.string()),
1803
+ items: z.optional(z.array(zSaleItemInputSchema)),
1804
+ metadata: z.nullish(z.record(z.string(), z.unknown())),
1805
+ occurred_at: z.iso.datetime({ offset: true }),
1806
+ service: z.nullish(z.string()),
1807
+ services: z.nullish(z.array(zSaleServiceInputSchema)),
1808
+ sms_consent: z.nullish(z.boolean())
1809
+ });
1810
+ var zValidationError = z.object({
1811
+ ctx: z.optional(z.record(z.string(), z.unknown())),
1812
+ input: z.optional(z.unknown()),
1813
+ loc: z.array(z.union([z.string(), z.int()])),
1814
+ msg: z.string(),
1815
+ type: z.string()
1816
+ });
1817
+ var zHttpValidationError = z.object({
1818
+ detail: z.optional(z.array(zValidationError))
1819
+ });
1820
+ var zValidationErrorItem = z.object({
1821
+ loc: z.array(z.union([z.string(), z.int()])),
1822
+ msg: z.string(),
1823
+ type: z.string()
1824
+ });
1825
+ var zApiErrorSchema = z.object({
1826
+ code: zErrorCode,
1827
+ context: z._default(z.nullish(z.record(z.string(), z.unknown())), null),
1828
+ detail: z.string(),
1829
+ errors: z._default(z.nullish(z.array(zValidationErrorItem)), null),
1830
+ request_id: z._default(z.nullish(z.string()), null)
1831
+ });
1832
+ var zWritebackEmailSource = z.enum(["NONE", "SALE", "CUSTOMER", "HARVESTED"]);
1833
+ var zWritebackEnrichmentStatus = z.enum(["NONE", "MATCHED", "AMBIGUOUS"]);
1834
+ var zWritebackSaleUploadCounts = z.object({
1835
+ failed: z._default(z.int(), 0),
1836
+ pending: z._default(z.int(), 0),
1837
+ skipped: z._default(z.int(), 0),
1838
+ submitted: z._default(z.int(), 0),
1839
+ total: z._default(z.int(), 0),
1840
+ uploaded: z._default(z.int(), 0)
1841
+ });
1842
+ var zSaleWritebackStatusSchema = z.object({
1843
+ blocked_reason: z.nullable(z.string()),
1844
+ can_dispatch: z._default(z.boolean(), false),
1845
+ email_source: z.nullable(zWritebackEmailSource),
1846
+ enrichment_status: z.nullable(zWritebackEnrichmentStatus),
1847
+ gclid_attached: z._default(z.boolean(), false),
1848
+ identifiers_sent: z.nullable(z.string()),
1849
+ mapped_service_ids: z.array(z.uuid()),
1850
+ matched_submit_count: z.nullable(z.int()),
1851
+ needs_force: z._default(z.boolean(), false),
1852
+ rollup: z.enum([
1853
+ "failed",
1854
+ "skipped",
1855
+ "pending",
1856
+ "submitted",
1857
+ "uploaded",
1858
+ "not_uploaded",
1859
+ "out_of_window",
1860
+ "blocked"
1861
+ ]),
1862
+ stale: z._default(z.boolean(), false),
1863
+ uncovered_service_ids: z.array(z.uuid()),
1864
+ uploads: zWritebackSaleUploadCounts
1865
+ });
1866
+ var zSaleEntitySchema = z.object({
1867
+ amount_total_cents: z.int(),
1868
+ business_id: z.uuid(),
1869
+ business_name: z.nullable(z.string()),
1870
+ created_at: z.iso.datetime({ offset: true }),
1871
+ currency: z.string(),
1872
+ customer_email: z.nullable(z.string()),
1873
+ customer_name: z.nullable(z.string()),
1874
+ customer_name_placeholder_confirmed: z._default(z.boolean(), false),
1875
+ customer_name_placeholder_confirmed_at: z.nullable(z.iso.datetime({ offset: true })),
1876
+ customer_phone: z.nullable(z.string()),
1877
+ description: z.nullable(z.string()),
1878
+ environment: zTrackingEnvironment,
1879
+ external_id: z.nullable(z.string()),
1880
+ id: z.uuid(),
1881
+ items: z.array(zSaleItemEntitySchema),
1882
+ metadata: z.nullable(z.record(z.string(), z.unknown())),
1883
+ occurred_at: z.iso.datetime({ offset: true }),
1884
+ service_id: z.nullable(z.uuid()),
1885
+ service_key: z.nullable(z.string()),
1886
+ service_label: z.nullable(z.string()),
1887
+ services: z.array(zSaleServiceEntitySchema),
1888
+ sms_automation: z.nullable(zSaleSmsStatusSchema),
1889
+ sms_consent: z._default(z.boolean(), false),
1890
+ sms_consent_granted_at: z.nullable(z.iso.datetime({ offset: true })),
1891
+ updated_at: z.iso.datetime({ offset: true }),
1892
+ writeback: z.nullable(zSaleWritebackStatusSchema)
1893
+ });
1894
+
1895
+ // ../tracking-core/src/resources/sales/schema.ts
1896
+ var saleItemSchema = zSaleItemInputSchema;
1897
+ var saleServiceSchema = zSaleServiceInputSchema;
1898
+ var currencySchema = zSupportedCurrency;
1899
+ var SUPPORTED_CURRENCIES = currencySchema.options;
1900
+ var centsSchema = z2.int().check(z2.gte(0));
1901
+ var metadataSchema = z2.record(z2.string(), z2.unknown());
1902
+ var customerNameSchema = z2.string().check(z2.maxLength(200));
1903
+ var customerPhoneSchema = z2.string().check(z2.maxLength(64));
1904
+ var customerEmailSchema = z2.email().check(z2.maxLength(320));
1905
+ function addIssue(ctx, path, message) {
1906
+ ctx.issues.push({ code: "custom", input: ctx.value, path, message });
1907
+ }
1992
1908
  function refineServiceXor(val, ctx, { requireAmount }) {
1993
1909
  if (val.services != null) {
1994
1910
  if (val.service != null) {
1995
- ctx.addIssue({
1996
- code: import_zod12.z.ZodIssueCode.custom,
1997
- message: "pass either `service` or `services`, not both",
1998
- path: ["services"]
1999
- });
1911
+ addIssue(ctx, ["services"], "pass either `service` or `services`, not both");
2000
1912
  }
2001
1913
  if (val.services.length === 0) {
2002
- ctx.addIssue({
2003
- code: import_zod12.z.ZodIssueCode.custom,
2004
- message: "`services` must not be empty",
2005
- path: ["services"]
2006
- });
1914
+ addIssue(ctx, ["services"], "`services` must not be empty");
2007
1915
  }
2008
1916
  const keys = val.services.map((s) => s.service);
2009
1917
  if (new Set(keys).size !== keys.length) {
2010
- ctx.addIssue({
2011
- code: import_zod12.z.ZodIssueCode.custom,
2012
- message: "`services` must not list the same service more than once",
2013
- path: ["services"]
2014
- });
1918
+ addIssue(ctx, ["services"], "`services` must not list the same service more than once");
2015
1919
  }
2016
1920
  if (val.amount_total_cents != null) {
2017
1921
  const sum = val.services.reduce((acc, s) => acc + s.amount_cents, 0);
2018
1922
  if (val.amount_total_cents !== sum) {
2019
- ctx.addIssue({
2020
- code: import_zod12.z.ZodIssueCode.custom,
2021
- message: "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)",
2022
- path: ["amount_total_cents"]
2023
- });
1923
+ addIssue(
1924
+ ctx,
1925
+ ["amount_total_cents"],
1926
+ "amount_total_cents must equal the sum of the services amounts (omit it to derive it automatically)"
1927
+ );
2024
1928
  }
2025
1929
  }
2026
1930
  } else if (requireAmount && val.amount_total_cents == null) {
2027
- ctx.addIssue({
2028
- code: import_zod12.z.ZodIssueCode.custom,
2029
- message: "amount_total_cents is required unless `services` is provided",
2030
- path: ["amount_total_cents"]
2031
- });
1931
+ addIssue(
1932
+ ctx,
1933
+ ["amount_total_cents"],
1934
+ "amount_total_cents is required unless `services` is provided"
1935
+ );
2032
1936
  }
2033
1937
  }
2034
- var saleCreateSchema = import_zod12.z.object({
2035
- external_id: import_zod12.z.string().nullable().optional(),
2036
- description: import_zod12.z.string().nullable().optional(),
2037
- service: import_zod12.z.string().nullable().optional(),
2038
- services: import_zod12.z.array(saleServiceSchema).nullable().optional(),
2039
- currency: currencySchema,
2040
- // Optional only because the plural `services` form derives it from the sum
2041
- // (see refineServiceXor); the singular/serviceless path still requires it.
2042
- amount_total_cents: centsSchema.nullable().optional(),
2043
- occurred_at: import_zod12.z.string().datetime(),
2044
- environment: import_zod12.z.enum(TRACKING_ENVIRONMENTS).default("production"),
2045
- items: import_zod12.z.array(saleItemSchema).default([]),
2046
- metadata: metadataSchema.nullable().optional(),
2047
- customer_name: customerNameSchema.nullable().optional(),
2048
- customer_phone: customerPhoneSchema.nullable().optional(),
2049
- customer_email: customerEmailSchema.nullable().optional(),
2050
- // CASL consent attestation: the customer agreed to receive SMS. Recorded
2051
- // with a timestamp server-side; every SMS send path gates on it.
2052
- //
2053
- // Tri-state: omit it (or send null) to let the server apply the business's
2054
- // configured default-opt-in policy, honouring a returning customer's
2055
- // remembered preference. Send an explicit boolean to assert consent state
2056
- // yourself — `false` records a deliberate opt-out.
2057
- sms_consent: import_zod12.z.boolean().nullable().optional()
2058
- }).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: true }));
2059
- var saleUpdateSchema = import_zod12.z.object({
2060
- description: import_zod12.z.string().nullable().optional(),
2061
- service: import_zod12.z.string().nullable().optional(),
2062
- services: import_zod12.z.array(saleServiceSchema).nullable().optional(),
2063
- currency: currencySchema.optional(),
2064
- amount_total_cents: centsSchema.optional(),
2065
- occurred_at: import_zod12.z.string().datetime().optional(),
2066
- items: import_zod12.z.array(saleItemSchema).optional(),
2067
- metadata: metadataSchema.nullable().optional(),
2068
- customer_name: customerNameSchema.nullable().optional(),
1938
+ var saleCreateSchema = z2.extend(zSaleCreateSchema, { items: z2._default(z2.array(saleItemSchema), []) }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: true }));
1939
+ var saleUpdateSchema = z2.strictObject({
1940
+ description: z2.nullish(z2.string()),
1941
+ service: z2.nullish(z2.string()),
1942
+ services: z2.nullish(z2.array(saleServiceSchema)),
1943
+ currency: z2.optional(currencySchema),
1944
+ amount_total_cents: z2.optional(centsSchema),
1945
+ occurred_at: z2.optional(z2.iso.datetime()),
1946
+ items: z2.optional(z2.array(saleItemSchema)),
1947
+ metadata: z2.nullish(metadataSchema),
1948
+ customer_name: z2.nullish(customerNameSchema),
2069
1949
  // Re-attest when changing a filler-looking name; the server clears the
2070
1950
  // prior attestation whenever `customer_name` changes.
2071
- customer_name_placeholder_confirmed: import_zod12.z.boolean().optional(),
2072
- customer_phone: customerPhoneSchema.nullable().optional(),
2073
- customer_email: customerEmailSchema.nullable().optional(),
1951
+ customer_name_placeholder_confirmed: z2.optional(z2.boolean()),
1952
+ customer_phone: z2.nullish(customerPhoneSchema),
1953
+ customer_email: z2.nullish(customerEmailSchema),
2074
1954
  // NOT NULL server-side: omit to leave unchanged (explicit null is rejected).
2075
- sms_consent: import_zod12.z.boolean().optional()
2076
- }).strict().superRefine((val, ctx) => refineServiceXor(val, ctx, { requireAmount: false }));
1955
+ sms_consent: z2.optional(z2.boolean())
1956
+ }).check((ctx) => refineServiceXor(ctx.value, ctx, { requireAmount: false }));
2077
1957
  var TRACKING_RANGES = ["24h", "7d", "30d"];
2078
1958
  var NAMED_RANGES = [
2079
1959
  "today",
@@ -2144,8 +2024,8 @@ function instantFromWallClock(timeZone, year, month, day, hour = 0, minute = 0)
2144
2024
  const corrected = naive - offsetMinutesAt(firstGuess, timeZone) * 6e4;
2145
2025
  return new Date(corrected);
2146
2026
  }
2147
- function localDateKey(iso, timeZone) {
2148
- const p = partsInTz(new Date(iso), timeZone);
2027
+ function localDateKey(iso4, timeZone) {
2028
+ const p = partsInTz(new Date(iso4), timeZone);
2149
2029
  const pad = (n) => String(n).padStart(2, "0");
2150
2030
  return `${p.year}-${pad(p.month)}-${pad(p.day)}`;
2151
2031
  }
@@ -2200,7 +2080,167 @@ function isCalendarError(error, code) {
2200
2080
  }
2201
2081
 
2202
2082
  // ../tracking-core/src/resources/calendar/schema.ts
2203
- var import_zod13 = require("zod");
2083
+ var z4 = __toESM(require("zod/mini"));
2084
+
2085
+ // ../tracking-core/src/resources/calendar/generated/zod.gen.ts
2086
+ var z3 = __toESM(require("zod/mini"));
2087
+ var zBookingAttendee = z3.strictObject({
2088
+ display_name: z3.nullish(z3.string().check(z3.maxLength(200))),
2089
+ email: z3.email().check(z3.maxLength(320)),
2090
+ optional: z3._default(z3.optional(z3.boolean()), false)
2091
+ });
2092
+ var zBookingCancelSchema = z3.strictObject({
2093
+ notify_attendees: z3._default(z3.optional(z3.boolean()), true),
2094
+ reason: z3.nullish(z3.string().check(z3.maxLength(500)))
2095
+ });
2096
+ var zBookingCustomerInput = z3.strictObject({
2097
+ email: z3.email().check(z3.maxLength(320)),
2098
+ name: z3.nullish(z3.string().check(z3.maxLength(200))),
2099
+ phone: z3.nullish(z3.string().check(z3.maxLength(64))),
2100
+ sms_consent: z3._default(z3.optional(z3.boolean()), false)
2101
+ });
2102
+ var zBookingCustomerOutput = z3.strictObject({
2103
+ email: z3.email().check(z3.maxLength(320)),
2104
+ name: z3.nullable(z3.string().check(z3.maxLength(200))),
2105
+ phone: z3.nullable(z3.string().check(z3.maxLength(64))),
2106
+ sms_consent: z3._default(z3.boolean(), false)
2107
+ });
2108
+ var zBookingRescheduleSchema = z3.strictObject({
2109
+ duration_minutes: z3.nullish(z3.int().check(z3.gt(0), z3.lte(1440))),
2110
+ end_at: z3.nullish(z3.iso.datetime({ offset: true })),
2111
+ notify_attendees: z3._default(z3.optional(z3.boolean()), true),
2112
+ reason: z3.nullish(z3.string().check(z3.maxLength(500))),
2113
+ start_at: z3.iso.datetime({ offset: true }),
2114
+ time_zone: z3.string().check(z3.minLength(1), z3.maxLength(64), z3.regex(/^[A-Za-z0-9_+\-\/]+$/))
2115
+ });
2116
+ var zBookingResponse = z3.strictObject({
2117
+ appointment_type: z3.nullable(z3.string()),
2118
+ calendar_key: z3.string(),
2119
+ customer: zBookingCustomerOutput,
2120
+ end_at: z3.iso.datetime({ offset: true }),
2121
+ google_html_link: z3.nullable(z3.string()),
2122
+ google_sync_state: z3.string(),
2123
+ id: z3.string(),
2124
+ manage_token: z3.nullable(z3.string()),
2125
+ meet_url: z3.nullable(z3.string()),
2126
+ start_at: z3.iso.datetime({ offset: true }),
2127
+ status: z3.string(),
2128
+ time_zone: z3.string(),
2129
+ title: z3.string()
2130
+ });
2131
+ var zBookingSource = z3.enum(["website", "phone", "walk_in", "import", "operator"]);
2132
+ var zBookingMetadata = z3.strictObject({
2133
+ custom: z3.nullish(
2134
+ z3.record(z3.string(), z3.nullable(z3.union([z3.string(), z3.int(), z3.number(), z3.boolean()])))
2135
+ ),
2136
+ fbclid: z3.nullish(z3.string().check(z3.maxLength(256))),
2137
+ gclid: z3.nullish(z3.string().check(z3.maxLength(256))),
2138
+ landing_page: z3.nullish(z3.string().check(z3.maxLength(2048))),
2139
+ notes: z3.nullish(z3.string().check(z3.maxLength(2e3))),
2140
+ referrer: z3.nullish(z3.string().check(z3.maxLength(2048))),
2141
+ schema_version: z3._default(z3.optional(z3.int()), 1),
2142
+ service: z3.nullish(z3.string().check(z3.maxLength(64))),
2143
+ session_id: z3.nullish(z3.string().check(z3.maxLength(64))),
2144
+ source: z3.nullish(zBookingSource),
2145
+ utm_campaign: z3.nullish(z3.string().check(z3.maxLength(128))),
2146
+ utm_content: z3.nullish(z3.string().check(z3.maxLength(128))),
2147
+ utm_medium: z3.nullish(z3.string().check(z3.maxLength(128))),
2148
+ utm_source: z3.nullish(z3.string().check(z3.maxLength(128))),
2149
+ utm_term: z3.nullish(z3.string().check(z3.maxLength(128))),
2150
+ visitor_id: z3.nullish(z3.string().check(z3.maxLength(64)))
2151
+ });
2152
+ var zCustomLocation = z3.strictObject({
2153
+ kind: z3.literal("custom"),
2154
+ text: z3.string().check(z3.maxLength(1024))
2155
+ });
2156
+ var zErrorCode2 = z3.enum([
2157
+ "missing_credentials",
2158
+ "invalid_api_key",
2159
+ "not_authenticated",
2160
+ "wrong_key_type",
2161
+ "origin_missing",
2162
+ "origin_not_allowed",
2163
+ "capability_denied",
2164
+ "session_required",
2165
+ "operator_only",
2166
+ "cross_tenant",
2167
+ "business_id_required",
2168
+ "bad_request",
2169
+ "not_found",
2170
+ "conflict",
2171
+ "incompatible_payload",
2172
+ "repeat_confirmation_required",
2173
+ "idempotency_conflict",
2174
+ "validation_error",
2175
+ "unknown_service",
2176
+ "invalid_sale_properties",
2177
+ "invalid_cursor",
2178
+ "rate_limited",
2179
+ "internal_error"
2180
+ ]);
2181
+ var zMeetLocation = z3.strictObject({
2182
+ kind: z3.literal("google_meet")
2183
+ });
2184
+ var zPhoneLocation = z3.strictObject({
2185
+ kind: z3.literal("phone"),
2186
+ phone: z3.string().check(z3.maxLength(64))
2187
+ });
2188
+ var zPhysicalLocation = z3.strictObject({
2189
+ address: z3.string().check(z3.maxLength(1024)),
2190
+ kind: z3.literal("physical")
2191
+ });
2192
+ var zReminderMethod = z3.enum(["email", "popup"]);
2193
+ var zBookingReminder = z3.strictObject({
2194
+ method: zReminderMethod,
2195
+ minutes_before: z3.int().check(z3.gte(0), z3.lte(40320))
2196
+ });
2197
+ var zBookingReminders = z3.strictObject({
2198
+ overrides: z3.optional(z3.array(zBookingReminder).check(z3.maxLength(5))),
2199
+ use_calendar_defaults: z3._default(z3.optional(z3.boolean()), true)
2200
+ });
2201
+ var zBookingCreateSchema = z3.strictObject({
2202
+ appointment_type: z3.nullish(z3.string().check(z3.maxLength(64))),
2203
+ attendees: z3.optional(z3.array(zBookingAttendee).check(z3.maxLength(20))),
2204
+ buffer_after_minutes: z3._default(z3.optional(z3.int().check(z3.gte(0), z3.lte(1440))), 0),
2205
+ buffer_before_minutes: z3._default(z3.optional(z3.int().check(z3.gte(0), z3.lte(1440))), 0),
2206
+ calendar_key: z3.string().check(z3.minLength(1), z3.maxLength(64)),
2207
+ customer: zBookingCustomerInput,
2208
+ description: z3.nullish(z3.string().check(z3.maxLength(8e3))),
2209
+ duration_minutes: z3.nullish(z3.int().check(z3.gt(0), z3.lte(1440))),
2210
+ end_at: z3.nullish(z3.iso.datetime({ offset: true })),
2211
+ idempotency_key: z3.nullish(z3.string().check(z3.maxLength(128))),
2212
+ location: z3.nullish(z3.union([zMeetLocation, zPhysicalLocation, zPhoneLocation, zCustomLocation])),
2213
+ metadata: z3.nullish(zBookingMetadata),
2214
+ reminders: z3.nullish(zBookingReminders),
2215
+ send_invites: z3._default(z3.optional(z3.boolean()), true),
2216
+ start_at: z3.iso.datetime({ offset: true }),
2217
+ time_zone: z3.string().check(z3.minLength(1), z3.maxLength(64), z3.regex(/^[A-Za-z0-9_+\-\/]+$/)),
2218
+ title: z3.nullish(z3.string().check(z3.maxLength(300)))
2219
+ });
2220
+ var zValidationError2 = z3.object({
2221
+ ctx: z3.optional(z3.record(z3.string(), z3.unknown())),
2222
+ input: z3.optional(z3.unknown()),
2223
+ loc: z3.array(z3.union([z3.string(), z3.int()])),
2224
+ msg: z3.string(),
2225
+ type: z3.string()
2226
+ });
2227
+ var zHttpValidationError2 = z3.object({
2228
+ detail: z3.optional(z3.array(zValidationError2))
2229
+ });
2230
+ var zValidationErrorItem2 = z3.object({
2231
+ loc: z3.array(z3.union([z3.string(), z3.int()])),
2232
+ msg: z3.string(),
2233
+ type: z3.string()
2234
+ });
2235
+ var zApiErrorSchema2 = z3.object({
2236
+ code: zErrorCode2,
2237
+ context: z3._default(z3.nullish(z3.record(z3.string(), z3.unknown())), null),
2238
+ detail: z3.string(),
2239
+ errors: z3._default(z3.nullish(z3.array(zValidationErrorItem2)), null),
2240
+ request_id: z3._default(z3.nullish(z3.string()), null)
2241
+ });
2242
+
2243
+ // ../tracking-core/src/resources/calendar/schema.ts
2204
2244
  var CALENDAR_METADATA_SCHEMA_VERSION = 1;
2205
2245
  var MAX_ATTENDEES = 20;
2206
2246
  var MAX_REMINDER_OVERRIDES = 5;
@@ -2226,7 +2266,6 @@ var CALENDAR_ERROR_CODES = [
2226
2266
  "rate_limited",
2227
2267
  "google_error"
2228
2268
  ];
2229
- var isoInstant = import_zod13.z.string().datetime({ offset: true });
2230
2269
  function isKnownTimeZone(timeZone) {
2231
2270
  try {
2232
2271
  new Intl.DateTimeFormat(void 0, { timeZone });
@@ -2235,107 +2274,65 @@ function isKnownTimeZone(timeZone) {
2235
2274
  return false;
2236
2275
  }
2237
2276
  }
2238
- var ianaTz = import_zod13.z.string().min(1).max(64).regex(/^[A-Za-z0-9_+\-/]+$/).refine(isKnownTimeZone, { message: "unknown IANA time zone" });
2239
- var bookingAttendeeSchema = import_zod13.z.object({
2240
- email: import_zod13.z.string().max(320).email(),
2241
- display_name: import_zod13.z.string().max(200).nullable().optional(),
2242
- optional: import_zod13.z.boolean().default(false)
2243
- }).strict();
2244
- var bookingReminderSchema = import_zod13.z.object({
2245
- method: import_zod13.z.enum(["email", "popup"]),
2246
- minutes_before: import_zod13.z.number().int().min(0).max(MAX_REMINDER_MINUTES)
2247
- }).strict();
2248
- var bookingRemindersSchema = import_zod13.z.object({
2249
- use_calendar_defaults: import_zod13.z.boolean().default(true),
2250
- overrides: import_zod13.z.array(bookingReminderSchema).max(MAX_REMINDER_OVERRIDES).default([])
2251
- }).strict();
2252
- var bookingLocationSchema = import_zod13.z.union([
2253
- import_zod13.z.object({ kind: import_zod13.z.literal("google_meet") }).strict(),
2254
- import_zod13.z.object({ kind: import_zod13.z.literal("physical"), address: import_zod13.z.string().max(1024) }).strict(),
2255
- import_zod13.z.object({ kind: import_zod13.z.literal("phone"), phone: import_zod13.z.string().max(64) }).strict(),
2256
- import_zod13.z.object({ kind: import_zod13.z.literal("custom"), text: import_zod13.z.string().max(1024) }).strict()
2277
+ var ianaTz = z4.string().check(
2278
+ z4.minLength(1),
2279
+ z4.maxLength(64),
2280
+ z4.regex(/^[A-Za-z0-9_+\-/]+$/),
2281
+ z4.refine(isKnownTimeZone, { error: "unknown IANA time zone" })
2282
+ );
2283
+ var bookingAttendeeSchema = zBookingAttendee;
2284
+ var bookingReminderSchema = zBookingReminder;
2285
+ var bookingCustomerSchema = zBookingCustomerInput;
2286
+ var bookingMetadataSchema = z4.extend(zBookingMetadata, {
2287
+ custom: z4.nullish(
2288
+ z4.record(z4.string(), z4.union([z4.string(), z4.int(), z4.number(), z4.boolean(), z4.null()]))
2289
+ )
2290
+ });
2291
+ var bookingLocationSchema = z4.union([
2292
+ zMeetLocation,
2293
+ zPhysicalLocation,
2294
+ zPhoneLocation,
2295
+ zCustomLocation
2257
2296
  ]);
2258
- var bookingLocationNullableSchema = import_zod13.z.union([...bookingLocationSchema.options, import_zod13.z.null()]);
2259
- var bookingCustomerSchema = import_zod13.z.object({
2260
- // Required: Google needs an address to send the invite that confirms the
2261
- // booking, and that invite is the whole confirmation mechanism.
2262
- email: import_zod13.z.string().max(320).email(),
2263
- name: import_zod13.z.string().max(200).nullable().optional(),
2264
- phone: import_zod13.z.string().max(64).nullable().optional(),
2265
- sms_consent: import_zod13.z.boolean().default(false)
2266
- }).strict();
2267
- var jsonScalar = import_zod13.z.union([import_zod13.z.string(), import_zod13.z.number(), import_zod13.z.boolean(), import_zod13.z.null()]);
2268
- var bookingMetadataSchema = import_zod13.z.object({
2269
- schema_version: import_zod13.z.number().int().default(CALENDAR_METADATA_SCHEMA_VERSION),
2270
- source: import_zod13.z.enum(BOOKING_SOURCES).nullable().optional(),
2271
- service: import_zod13.z.string().max(64).nullable().optional(),
2272
- visitor_id: import_zod13.z.string().max(64).nullable().optional(),
2273
- session_id: import_zod13.z.string().max(64).nullable().optional(),
2274
- gclid: import_zod13.z.string().max(256).nullable().optional(),
2275
- fbclid: import_zod13.z.string().max(256).nullable().optional(),
2276
- utm_source: import_zod13.z.string().max(128).nullable().optional(),
2277
- utm_medium: import_zod13.z.string().max(128).nullable().optional(),
2278
- utm_campaign: import_zod13.z.string().max(128).nullable().optional(),
2279
- utm_term: import_zod13.z.string().max(128).nullable().optional(),
2280
- utm_content: import_zod13.z.string().max(128).nullable().optional(),
2281
- landing_page: import_zod13.z.string().max(2048).nullable().optional(),
2282
- referrer: import_zod13.z.string().max(2048).nullable().optional(),
2283
- notes: import_zod13.z.string().max(2e3).nullable().optional(),
2284
- custom: import_zod13.z.record(jsonScalar).nullable().optional()
2285
- }).strict();
2297
+ var bookingLocationNullableSchema = z4.union([
2298
+ ...bookingLocationSchema.def.options,
2299
+ z4.null()
2300
+ ]);
2301
+ function addIssue2(ctx, path, message) {
2302
+ ctx.issues.push({ code: "custom", input: ctx.value, path, message });
2303
+ }
2286
2304
  function refineEndXor(value, ctx) {
2287
2305
  const hasEnd = value.end_at !== void 0 && value.end_at !== null;
2288
2306
  const hasDuration = value.duration_minutes !== void 0 && value.duration_minutes !== null;
2289
2307
  if (hasEnd === hasDuration) {
2290
- ctx.addIssue({
2291
- code: import_zod13.z.ZodIssueCode.custom,
2292
- message: "provide exactly one of end_at or duration_minutes",
2293
- path: ["end_at"]
2294
- });
2308
+ addIssue2(ctx, ["end_at"], "provide exactly one of end_at or duration_minutes");
2295
2309
  return;
2296
2310
  }
2297
2311
  if (hasEnd && new Date(value.end_at) <= new Date(value.start_at)) {
2298
- ctx.addIssue({
2299
- code: import_zod13.z.ZodIssueCode.custom,
2300
- message: "end_at must be after start_at",
2301
- path: ["end_at"]
2302
- });
2312
+ addIssue2(ctx, ["end_at"], "end_at must be after start_at");
2303
2313
  }
2304
2314
  }
2305
- var bookingCreateSchema = import_zod13.z.object({
2306
- calendar_key: import_zod13.z.string().min(1).max(64),
2307
- // Free-form: appointment types are the client site's own vocabulary, not
2308
- // configuration the dashboard holds.
2309
- appointment_type: import_zod13.z.string().max(64).nullable().optional(),
2310
- start_at: isoInstant,
2311
- end_at: isoInstant.nullable().optional(),
2312
- duration_minutes: import_zod13.z.number().int().positive().max(MAX_BOOKING_MINUTES).nullable().optional(),
2313
- /** The booker's zone — distinct from the business's and the calendar's. */
2314
- time_zone: ianaTz,
2315
- title: import_zod13.z.string().max(300).nullable().optional(),
2316
- description: import_zod13.z.string().max(8e3).nullable().optional(),
2317
- location: bookingLocationNullableSchema.optional(),
2318
- customer: bookingCustomerSchema,
2319
- attendees: import_zod13.z.array(bookingAttendeeSchema).max(MAX_ATTENDEES).default([]),
2320
- send_invites: import_zod13.z.boolean().default(true),
2321
- reminders: bookingRemindersSchema.nullable().optional(),
2322
- metadata: bookingMetadataSchema.nullable().optional(),
2323
- idempotency_key: import_zod13.z.string().max(128).nullable().optional(),
2324
- buffer_before_minutes: import_zod13.z.number().int().min(0).max(MAX_BOOKING_MINUTES).default(0),
2325
- buffer_after_minutes: import_zod13.z.number().int().min(0).max(MAX_BOOKING_MINUTES).default(0)
2326
- }).strict().superRefine(refineEndXor);
2327
- var bookingRescheduleSchema = import_zod13.z.object({
2328
- start_at: isoInstant,
2329
- end_at: isoInstant.nullable().optional(),
2330
- duration_minutes: import_zod13.z.number().int().positive().max(MAX_BOOKING_MINUTES).nullable().optional(),
2315
+ var bookingRemindersSchema = z4.extend(zBookingReminders, {
2316
+ overrides: z4._default(
2317
+ z4.array(bookingReminderSchema).check(z4.maxLength(MAX_REMINDER_OVERRIDES)),
2318
+ []
2319
+ )
2320
+ });
2321
+ var bookingCreateSchema = z4.extend(zBookingCreateSchema, {
2331
2322
  time_zone: ianaTz,
2332
- notify_attendees: import_zod13.z.boolean().default(true),
2333
- reason: import_zod13.z.string().max(500).nullable().optional()
2334
- }).strict().superRefine(refineEndXor);
2335
- var bookingCancelSchema = import_zod13.z.object({
2336
- reason: import_zod13.z.string().max(500).nullable().optional(),
2337
- notify_attendees: import_zod13.z.boolean().default(true)
2338
- }).strict();
2323
+ // The generated field is `z.union([...variants]).nullish()`, which nests one
2324
+ // `anyOf` inside another; Pydantic's `BookingLocation | None` flattens to a
2325
+ // single list and the drift snapshot compares structure. Override with the
2326
+ // flattened union.
2327
+ location: z4.optional(bookingLocationNullableSchema),
2328
+ attendees: z4._default(z4.array(bookingAttendeeSchema).check(z4.maxLength(MAX_ATTENDEES)), []),
2329
+ // These reference the un-composed generated schemas; generation can't nest
2330
+ // our compositions into its own output.
2331
+ reminders: z4.nullish(bookingRemindersSchema),
2332
+ metadata: z4.nullish(bookingMetadataSchema)
2333
+ }).check((ctx) => refineEndXor(ctx.value, ctx));
2334
+ var bookingRescheduleSchema = z4.extend(zBookingRescheduleSchema, { time_zone: ianaTz }).check((ctx) => refineEndXor(ctx.value, ctx));
2335
+ var bookingCancelSchema = zBookingCancelSchema;
2339
2336
 
2340
2337
  // ../tracking-core/src/resources/calendar/slots.ts
2341
2338
  function parseHhMm(value) {
@@ -2563,6 +2560,7 @@ var import_client2 = require("@aranova/tracking-next/client");
2563
2560
  createTrackingClientContext,
2564
2561
  createTrackingEventCreatePayload,
2565
2562
  createTrackingSessionUpsertPayload,
2563
+ currencySchema,
2566
2564
  durationMinutes,
2567
2565
  endOfDayInTz,
2568
2566
  fetchServices,