@aranova/tracking-next 1.1.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -1
- package/dist/calendar-server.d.mts +1 -1
- package/dist/calendar-server.d.ts +1 -1
- package/dist/calendar.d.mts +18 -4
- package/dist/calendar.d.ts +18 -4
- package/dist/calendar.js +218 -18
- package/dist/calendar.js.map +1 -1
- package/dist/calendar.mjs +217 -18
- package/dist/calendar.mjs.map +1 -1
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +1 -1
- package/dist/client.mjs.map +1 -1
- package/dist/index.d.mts +5 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +171 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +170 -19
- package/dist/index.mjs.map +1 -1
- package/dist/sales.js +15 -0
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +15 -0
- package/dist/sales.mjs.map +1 -1
- package/dist/{transport-CDmGOiCq.d.ts → transport-ChCL6vPv.d.ts} +122 -50
- package/dist/{transport-I_cMSFQ6.d.mts → transport-DvAEZ1xf.d.mts} +122 -50
- package/package.json +1 -1
package/dist/calendar.mjs
CHANGED
|
@@ -1,3 +1,132 @@
|
|
|
1
|
+
// ../tracking-core/src/tracking.ts
|
|
2
|
+
var TRACKING_PARAM_KEYS = [
|
|
3
|
+
"gclid",
|
|
4
|
+
// Google's iOS/Safari replacement click IDs — issued when privacy features
|
|
5
|
+
// withhold gclid (wbraid: web-to-web, gbraid: app-to-web). First-class
|
|
6
|
+
// citizens: captured, persisted, and attributed exactly like gclid.
|
|
7
|
+
"wbraid",
|
|
8
|
+
"gbraid",
|
|
9
|
+
// Yelp Ads click id (40 hex chars), appended to ad-click URLs.
|
|
10
|
+
"ylpcid",
|
|
11
|
+
"fbclid",
|
|
12
|
+
"utm_source",
|
|
13
|
+
"utm_medium",
|
|
14
|
+
"utm_campaign",
|
|
15
|
+
"utm_term",
|
|
16
|
+
"utm_content"
|
|
17
|
+
];
|
|
18
|
+
function createEmptyTrackingParams() {
|
|
19
|
+
return {
|
|
20
|
+
gclid: null,
|
|
21
|
+
wbraid: null,
|
|
22
|
+
gbraid: null,
|
|
23
|
+
ylpcid: null,
|
|
24
|
+
fbclid: null,
|
|
25
|
+
utm_source: null,
|
|
26
|
+
utm_medium: null,
|
|
27
|
+
utm_campaign: null,
|
|
28
|
+
utm_term: null,
|
|
29
|
+
utm_content: null
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function normalizeTrackingCookieValue(value) {
|
|
33
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
34
|
+
}
|
|
35
|
+
function getTrackingParamsFromCookieReader(readCookie) {
|
|
36
|
+
return TRACKING_PARAM_KEYS.reduce((params, key) => {
|
|
37
|
+
params[key] = normalizeTrackingCookieValue(readCookie(key));
|
|
38
|
+
return params;
|
|
39
|
+
}, createEmptyTrackingParams());
|
|
40
|
+
}
|
|
41
|
+
var FALLBACK_STORAGE_PREFIX = "_aranova_track_";
|
|
42
|
+
function fallbackKey(name) {
|
|
43
|
+
return `${FALLBACK_STORAGE_PREFIX}${name}`;
|
|
44
|
+
}
|
|
45
|
+
function readCookieValue(name) {
|
|
46
|
+
if (typeof document !== "undefined") {
|
|
47
|
+
const cookies = document.cookie ? document.cookie.split("; ") : [];
|
|
48
|
+
const match = cookies.find((cookie) => cookie.startsWith(`${name}=`));
|
|
49
|
+
if (match) {
|
|
50
|
+
const [, rawValue = ""] = match.split("=");
|
|
51
|
+
return normalizeTrackingCookieValue(decodeURIComponent(rawValue));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (typeof window !== "undefined") {
|
|
55
|
+
try {
|
|
56
|
+
const stored = window.localStorage.getItem(fallbackKey(name));
|
|
57
|
+
if (stored) return normalizeTrackingCookieValue(decodeURIComponent(stored));
|
|
58
|
+
} catch {
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
function getCookieValueFromDocument(key) {
|
|
64
|
+
return readCookieValue(key);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ../tracking-core/src/session.ts
|
|
68
|
+
var VISITOR_STORAGE_KEY = "aranova_tracking_visitor";
|
|
69
|
+
var SESSION_STORAGE_KEY = "aranova_tracking_session";
|
|
70
|
+
var SESSION_IDLE_MS = 30 * 60 * 1e3;
|
|
71
|
+
function readLocalStorage(key) {
|
|
72
|
+
try {
|
|
73
|
+
return window.localStorage.getItem(key);
|
|
74
|
+
} catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function peekVisitorId() {
|
|
79
|
+
if (typeof window === "undefined") return null;
|
|
80
|
+
const existing = readLocalStorage(VISITOR_STORAGE_KEY);
|
|
81
|
+
return existing && existing.length > 0 ? existing : null;
|
|
82
|
+
}
|
|
83
|
+
function peekSessionId(now = Date.now()) {
|
|
84
|
+
if (typeof window === "undefined") return null;
|
|
85
|
+
const raw = readLocalStorage(SESSION_STORAGE_KEY);
|
|
86
|
+
if (!raw) return null;
|
|
87
|
+
try {
|
|
88
|
+
const parsed = JSON.parse(raw);
|
|
89
|
+
if (typeof parsed.id !== "string" || typeof parsed.last_event_at !== "number") return null;
|
|
90
|
+
return now - parsed.last_event_at <= SESSION_IDLE_MS ? parsed.id : null;
|
|
91
|
+
} catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// ../tracking-core/src/resources/calendar/attribution.ts
|
|
97
|
+
var LIMITS = {
|
|
98
|
+
session_id: 64,
|
|
99
|
+
visitor_id: 64,
|
|
100
|
+
gclid: 256,
|
|
101
|
+
fbclid: 256,
|
|
102
|
+
utm_source: 128,
|
|
103
|
+
utm_medium: 128,
|
|
104
|
+
utm_campaign: 128,
|
|
105
|
+
utm_term: 128,
|
|
106
|
+
utm_content: 128
|
|
107
|
+
};
|
|
108
|
+
function getBookingAttribution() {
|
|
109
|
+
if (typeof window === "undefined") return {};
|
|
110
|
+
const params = getTrackingParamsFromCookieReader(getCookieValueFromDocument);
|
|
111
|
+
const values = {
|
|
112
|
+
session_id: peekSessionId(),
|
|
113
|
+
visitor_id: peekVisitorId(),
|
|
114
|
+
gclid: params.gclid,
|
|
115
|
+
fbclid: params.fbclid,
|
|
116
|
+
utm_source: params.utm_source,
|
|
117
|
+
utm_medium: params.utm_medium,
|
|
118
|
+
utm_campaign: params.utm_campaign,
|
|
119
|
+
utm_term: params.utm_term,
|
|
120
|
+
utm_content: params.utm_content
|
|
121
|
+
};
|
|
122
|
+
const attribution = {};
|
|
123
|
+
for (const key of Object.keys(LIMITS)) {
|
|
124
|
+
const value = values[key];
|
|
125
|
+
if (value) attribution[key] = value.slice(0, LIMITS[key]);
|
|
126
|
+
}
|
|
127
|
+
return attribution;
|
|
128
|
+
}
|
|
129
|
+
|
|
1
130
|
// ../tracking-core/src/capabilities.ts
|
|
2
131
|
var registered = /* @__PURE__ */ new Set();
|
|
3
132
|
function registerCapability(capability) {
|
|
@@ -211,22 +340,27 @@ var zBookingRescheduleSchema = z.strictObject({
|
|
|
211
340
|
time_zone: z.string().check(z.minLength(1), z.maxLength(64), z.regex(/^[A-Za-z0-9_+\-\/]+$/))
|
|
212
341
|
});
|
|
213
342
|
var zBookingResponse = z.strictObject({
|
|
343
|
+
all_day: z.boolean(),
|
|
214
344
|
appointment_type: z.nullable(z.string()),
|
|
215
345
|
calendar_key: z.string(),
|
|
346
|
+
created_at: z.iso.datetime({ offset: true }),
|
|
216
347
|
customer: zBookingCustomerOutput,
|
|
217
348
|
end_at: z.iso.datetime({ offset: true }),
|
|
349
|
+
google_event_id: z.nullable(z.string()),
|
|
218
350
|
google_html_link: z.nullable(z.string()),
|
|
219
|
-
google_sync_state: z.
|
|
351
|
+
google_sync_state: z.enum(["queued", "synced", "uncertain", "failed", "drifted"]),
|
|
352
|
+
ical_uid: z.nullable(z.string()),
|
|
220
353
|
id: z.string(),
|
|
221
354
|
manage_token: z.nullable(z.string()),
|
|
222
355
|
meet_url: z.nullable(z.string()),
|
|
356
|
+
organizer_email: z.nullable(z.string()),
|
|
223
357
|
start_at: z.iso.datetime({ offset: true }),
|
|
224
|
-
status: z.
|
|
358
|
+
status: z.enum(["pending", "confirmed", "cancelled", "no_show"]),
|
|
225
359
|
time_zone: z.string(),
|
|
226
360
|
title: z.string()
|
|
227
361
|
});
|
|
228
362
|
var zBookingSource = z.enum(["website", "phone", "walk_in", "import", "operator"]);
|
|
229
|
-
var
|
|
363
|
+
var zBookingMetadataInput = z.strictObject({
|
|
230
364
|
custom: z.nullish(
|
|
231
365
|
z.record(z.string(), z.nullable(z.union([z.string(), z.int(), z.number(), z.boolean()])))
|
|
232
366
|
),
|
|
@@ -246,6 +380,42 @@ var zBookingMetadata = z.strictObject({
|
|
|
246
380
|
utm_term: z.nullish(z.string().check(z.maxLength(128))),
|
|
247
381
|
visitor_id: z.nullish(z.string().check(z.maxLength(64)))
|
|
248
382
|
});
|
|
383
|
+
var zBusySource = z.enum(["google", "booking"]);
|
|
384
|
+
var zBusyInterval = z.strictObject({
|
|
385
|
+
end_at: z.iso.datetime({ offset: true }),
|
|
386
|
+
source: zBusySource,
|
|
387
|
+
start_at: z.iso.datetime({ offset: true })
|
|
388
|
+
});
|
|
389
|
+
var zBusyWindow = z.strictObject({
|
|
390
|
+
since: z.iso.datetime({ offset: true }),
|
|
391
|
+
until: z.iso.datetime({ offset: true })
|
|
392
|
+
});
|
|
393
|
+
var zBusyResponse = z.strictObject({
|
|
394
|
+
busy: z.array(zBusyInterval),
|
|
395
|
+
calendar_key: z.string(),
|
|
396
|
+
generated_at: z.iso.datetime({ offset: true }),
|
|
397
|
+
time_zone: z.string(),
|
|
398
|
+
window: zBusyWindow
|
|
399
|
+
});
|
|
400
|
+
var zCalendarSummary = z.strictObject({
|
|
401
|
+
allow_overlaps: z.boolean(),
|
|
402
|
+
calendar_key: z.string(),
|
|
403
|
+
connected_at: z.nullable(z.iso.datetime({ offset: true })),
|
|
404
|
+
google_account_email: z.nullable(z.string()),
|
|
405
|
+
granted_scopes: z.nullable(z.array(z.string())),
|
|
406
|
+
is_sandbox: z.boolean(),
|
|
407
|
+
label: z.string(),
|
|
408
|
+
sandbox_key: z.nullable(z.string()),
|
|
409
|
+
status: z.enum([
|
|
410
|
+
"pending_invite",
|
|
411
|
+
"awaiting_calendar_selection",
|
|
412
|
+
"connected",
|
|
413
|
+
"needs_reconnect",
|
|
414
|
+
"revoked",
|
|
415
|
+
"disabled"
|
|
416
|
+
]),
|
|
417
|
+
time_zone: z.string()
|
|
418
|
+
});
|
|
249
419
|
var zCustomLocation = z.strictObject({
|
|
250
420
|
kind: z.literal("custom"),
|
|
251
421
|
text: z.string().check(z.maxLength(1024))
|
|
@@ -265,9 +435,23 @@ var zErrorCode = z.enum([
|
|
|
265
435
|
"bad_request",
|
|
266
436
|
"not_found",
|
|
267
437
|
"conflict",
|
|
438
|
+
"gone",
|
|
268
439
|
"incompatible_payload",
|
|
269
440
|
"repeat_confirmation_required",
|
|
270
441
|
"idempotency_conflict",
|
|
442
|
+
"slot_unavailable",
|
|
443
|
+
"calendar_not_connected",
|
|
444
|
+
"calendar_disconnected",
|
|
445
|
+
"booking_not_found",
|
|
446
|
+
"booking_not_cancellable",
|
|
447
|
+
"booking_not_reschedulable",
|
|
448
|
+
"manage_token_invalid",
|
|
449
|
+
"google_error",
|
|
450
|
+
"calendar_not_owned",
|
|
451
|
+
"calendar_is_sandbox",
|
|
452
|
+
"sandbox_exists",
|
|
453
|
+
"sandbox_key_too_long",
|
|
454
|
+
"sandbox_not_found",
|
|
271
455
|
"validation_error",
|
|
272
456
|
"unknown_service",
|
|
273
457
|
"invalid_sale_properties",
|
|
@@ -302,15 +486,16 @@ var zBookingCreateSchema = z.strictObject({
|
|
|
302
486
|
buffer_before_minutes: z._default(z.optional(z.int().check(z.gte(0), z.lte(1440))), 0),
|
|
303
487
|
calendar_key: z.string().check(z.minLength(1), z.maxLength(64)),
|
|
304
488
|
customer: zBookingCustomerInput,
|
|
489
|
+
date: z.nullish(z.iso.date()),
|
|
305
490
|
description: z.nullish(z.string().check(z.maxLength(8e3))),
|
|
306
491
|
duration_minutes: z.nullish(z.int().check(z.gt(0), z.lte(1440))),
|
|
307
492
|
end_at: z.nullish(z.iso.datetime({ offset: true })),
|
|
308
493
|
idempotency_key: z.nullish(z.string().check(z.maxLength(128))),
|
|
309
494
|
location: z.nullish(z.union([zMeetLocation, zPhysicalLocation, zPhoneLocation, zCustomLocation])),
|
|
310
|
-
metadata: z.nullish(
|
|
495
|
+
metadata: z.nullish(zBookingMetadataInput),
|
|
311
496
|
reminders: z.nullish(zBookingReminders),
|
|
312
497
|
send_invites: z._default(z.optional(z.boolean()), true),
|
|
313
|
-
start_at: z.iso.datetime({ offset: true }),
|
|
498
|
+
start_at: z.nullish(z.iso.datetime({ offset: true })),
|
|
314
499
|
time_zone: z.string().check(z.minLength(1), z.maxLength(64), z.regex(/^[A-Za-z0-9_+\-\/]+$/)),
|
|
315
500
|
title: z.nullish(z.string().check(z.maxLength(300)))
|
|
316
501
|
});
|
|
@@ -344,22 +529,17 @@ var MAX_REMINDER_OVERRIDES = 5;
|
|
|
344
529
|
var MAX_REMINDER_MINUTES = 40320;
|
|
345
530
|
var MAX_BOOKING_MINUTES = 1440;
|
|
346
531
|
var BOOKING_SOURCES = ["website", "phone", "walk_in", "import", "operator"];
|
|
347
|
-
var BOOKING_STATUSES =
|
|
348
|
-
var GOOGLE_SYNC_STATES =
|
|
349
|
-
var CALENDAR_SYNC_STATUSES =
|
|
350
|
-
"pending_invite",
|
|
351
|
-
"awaiting_calendar_selection",
|
|
352
|
-
"connected",
|
|
353
|
-
"needs_reconnect",
|
|
354
|
-
"revoked",
|
|
355
|
-
"disabled"
|
|
356
|
-
];
|
|
532
|
+
var BOOKING_STATUSES = zBookingResponse.shape.status.options;
|
|
533
|
+
var GOOGLE_SYNC_STATES = zBookingResponse.shape.google_sync_state.options;
|
|
534
|
+
var CALENDAR_SYNC_STATUSES = zCalendarSummary.shape.status.options;
|
|
357
535
|
var CALENDAR_ERROR_CODES = [
|
|
358
536
|
"slot_unavailable",
|
|
359
537
|
"calendar_not_connected",
|
|
360
538
|
"calendar_disconnected",
|
|
361
539
|
"booking_not_found",
|
|
362
|
-
"
|
|
540
|
+
"booking_not_cancellable",
|
|
541
|
+
"booking_not_reschedulable",
|
|
542
|
+
"manage_token_invalid",
|
|
363
543
|
"rate_limited",
|
|
364
544
|
"google_error"
|
|
365
545
|
];
|
|
@@ -380,7 +560,7 @@ var ianaTz = z2.string().check(
|
|
|
380
560
|
var bookingAttendeeSchema = zBookingAttendee;
|
|
381
561
|
var bookingReminderSchema = zBookingReminder;
|
|
382
562
|
var bookingCustomerSchema = zBookingCustomerInput;
|
|
383
|
-
var bookingMetadataSchema = z2.extend(
|
|
563
|
+
var bookingMetadataSchema = z2.extend(zBookingMetadataInput, {
|
|
384
564
|
custom: z2.nullish(
|
|
385
565
|
z2.record(z2.string(), z2.union([z2.string(), z2.int(), z2.number(), z2.boolean(), z2.null()]))
|
|
386
566
|
)
|
|
@@ -409,6 +589,24 @@ function refineEndXor(value, ctx) {
|
|
|
409
589
|
addIssue(ctx, ["end_at"], "end_at must be after start_at");
|
|
410
590
|
}
|
|
411
591
|
}
|
|
592
|
+
function refineStartXor(value, ctx) {
|
|
593
|
+
const hasStart = value.start_at !== void 0 && value.start_at !== null;
|
|
594
|
+
const hasDate = value.date !== void 0 && value.date !== null;
|
|
595
|
+
if (hasStart === hasDate) {
|
|
596
|
+
addIssue(ctx, ["start_at"], "provide exactly one of start_at or date");
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
if (hasStart) {
|
|
600
|
+
refineEndXor(value, ctx);
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
if (value.end_at != null || value.duration_minutes != null) {
|
|
604
|
+
addIssue(ctx, ["date"], "an all-day booking (date) takes no end_at or duration_minutes");
|
|
605
|
+
}
|
|
606
|
+
if (value.buffer_before_minutes || value.buffer_after_minutes) {
|
|
607
|
+
addIssue(ctx, ["date"], "an all-day booking (date) takes no buffers");
|
|
608
|
+
}
|
|
609
|
+
}
|
|
412
610
|
var bookingRemindersSchema = z2.extend(zBookingReminders, {
|
|
413
611
|
overrides: z2._default(
|
|
414
612
|
z2.array(bookingReminderSchema).check(z2.maxLength(MAX_REMINDER_OVERRIDES)),
|
|
@@ -427,7 +625,7 @@ var bookingCreateSchema = z2.extend(zBookingCreateSchema, {
|
|
|
427
625
|
// our compositions into its own output.
|
|
428
626
|
reminders: z2.nullish(bookingRemindersSchema),
|
|
429
627
|
metadata: z2.nullish(bookingMetadataSchema)
|
|
430
|
-
}).check((ctx) =>
|
|
628
|
+
}).check((ctx) => refineStartXor(ctx.value, ctx));
|
|
431
629
|
var bookingRescheduleSchema = z2.extend(zBookingRescheduleSchema, { time_zone: ianaTz }).check((ctx) => refineEndXor(ctx.value, ctx));
|
|
432
630
|
var bookingCancelSchema = zBookingCancelSchema;
|
|
433
631
|
|
|
@@ -544,6 +742,7 @@ export {
|
|
|
544
742
|
endOfDayInTz,
|
|
545
743
|
formatDateInTz,
|
|
546
744
|
formatSlotRange,
|
|
745
|
+
getBookingAttribution,
|
|
547
746
|
groupSlotsByDay,
|
|
548
747
|
instantFromWallClock,
|
|
549
748
|
isCalendarError,
|