@aranova/tracking-react 1.3.0 → 1.4.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 +7 -0
- package/dist/{bookings-VsQdopTt.d.mts → bookings-CqCuuyP6.d.mts} +26 -5
- package/dist/{bookings-CqdjLMkv.d.ts → bookings-DIu1ho6v.d.ts} +26 -5
- package/dist/client.d.mts +4 -2
- package/dist/client.d.ts +4 -2
- package/dist/client.js +12 -6
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +12 -6
- package/dist/client.mjs.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +58 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +58 -16
- package/dist/index.mjs.map +1 -1
- package/dist/{ingest-typed-DGqzbteM.d.ts → ingest-typed-D2S3Kb8m.d.ts} +6 -1
- package/dist/{ingest-typed-BCUv93ax.d.mts → ingest-typed-D7UZr0EM.d.mts} +6 -1
- package/dist/{sales-DSL6vMuY.d.mts → sales-CxJVthx_.d.mts} +1 -1
- package/dist/{sales-_F3nnI2r.d.ts → sales-hlcVTJSS.d.ts} +1 -1
- package/dist/sales.d.mts +2 -2
- package/dist/sales.d.ts +2 -2
- package/dist/sales.js +101 -50
- package/dist/sales.js.map +1 -1
- package/dist/sales.mjs +101 -50
- package/dist/sales.mjs.map +1 -1
- package/package.json +1 -1
package/dist/sales.mjs
CHANGED
|
@@ -189,7 +189,8 @@ function getBookingIntegration(integrations) {
|
|
|
189
189
|
timezone: booking.timezone,
|
|
190
190
|
configVersion: booking.config_version,
|
|
191
191
|
rules,
|
|
192
|
-
options: booking.options.map((option) => ({ key: option.key, label: option.label }))
|
|
192
|
+
options: booking.options.map((option) => ({ key: option.key, label: option.label })),
|
|
193
|
+
mode: booking.mode ?? "live"
|
|
193
194
|
};
|
|
194
195
|
}
|
|
195
196
|
function camelRules(rules) {
|
|
@@ -282,6 +283,55 @@ var AranovaApiError = class extends Error {
|
|
|
282
283
|
}
|
|
283
284
|
};
|
|
284
285
|
|
|
286
|
+
// ../tracking-core/src/resources/intl/date.ts
|
|
287
|
+
function formatDateInTz(iso3, timeZone, opts, locale) {
|
|
288
|
+
const date = new Date(iso3);
|
|
289
|
+
if (Number.isNaN(date.getTime())) return iso3;
|
|
290
|
+
return new Intl.DateTimeFormat(locale, {
|
|
291
|
+
year: "numeric",
|
|
292
|
+
month: "short",
|
|
293
|
+
day: "2-digit",
|
|
294
|
+
hour: "2-digit",
|
|
295
|
+
minute: "2-digit",
|
|
296
|
+
...opts,
|
|
297
|
+
timeZone
|
|
298
|
+
}).format(date);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// ../tracking-core/src/resources/sales/money.ts
|
|
302
|
+
var MINOR_UNIT_EXPONENT = {
|
|
303
|
+
USD: 2,
|
|
304
|
+
CAD: 2
|
|
305
|
+
};
|
|
306
|
+
function exponentFor(currency) {
|
|
307
|
+
return MINOR_UNIT_EXPONENT[currency] ?? 2;
|
|
308
|
+
}
|
|
309
|
+
function toMinor(amount, currency) {
|
|
310
|
+
return Math.round(amount * 10 ** exponentFor(currency));
|
|
311
|
+
}
|
|
312
|
+
function fromMinor(cents, currency) {
|
|
313
|
+
return cents / 10 ** exponentFor(currency);
|
|
314
|
+
}
|
|
315
|
+
function formatMoney(cents, currency, locale) {
|
|
316
|
+
return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
|
|
317
|
+
fromMinor(cents, currency)
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// ../tracking-core/src/resources/tracking-config-runtime.ts
|
|
322
|
+
var DEFAULT_CDN_BASE_URL = "https://demos.aranova.io";
|
|
323
|
+
function trackingConfigKey(ref) {
|
|
324
|
+
if (ref.siteId) return `tracking-config/v1/sites/${ref.siteId}-${ref.environment}.json`;
|
|
325
|
+
return `tracking-config/v1/${ref.businessId}-${ref.environment}.json`;
|
|
326
|
+
}
|
|
327
|
+
function resolveTrackingConfigUrl(ref) {
|
|
328
|
+
if (ref.cdnUrl) return ref.cdnUrl;
|
|
329
|
+
const configured = ref.cdnBaseUrl?.trim();
|
|
330
|
+
const base = (configured || DEFAULT_CDN_BASE_URL).replace(/\/+$/, "");
|
|
331
|
+
return `${base}/${trackingConfigKey(ref)}`;
|
|
332
|
+
}
|
|
333
|
+
var RETRY_MAX_MS = 5 * 6e4;
|
|
334
|
+
|
|
285
335
|
// ../tracking-core/src/ingest.ts
|
|
286
336
|
var API_KEY_HEADER = "X-Aranova-Api-Key";
|
|
287
337
|
var SDK_VERSION_HEADER = "X-Aranova-Sdk-Version";
|
|
@@ -340,6 +390,7 @@ async function apiRequest(config, method, path, body, extraHeaders) {
|
|
|
340
390
|
var salesRequest = apiRequest;
|
|
341
391
|
|
|
342
392
|
// ../tracking-core/src/resources/sales/bookings.ts
|
|
393
|
+
var BOOKING_SIMULATE_HEADER = "X-Aranova-Simulate";
|
|
343
394
|
var BOOKING_ERROR_CODES = {
|
|
344
395
|
unavailable: "booking_unavailable",
|
|
345
396
|
stale: "booking_config_stale",
|
|
@@ -354,10 +405,11 @@ function sleep(ms) {
|
|
|
354
405
|
});
|
|
355
406
|
}
|
|
356
407
|
function outcomeOf(body) {
|
|
408
|
+
const mode = body.mode ?? "live";
|
|
357
409
|
if (body.status === "created")
|
|
358
|
-
return { status: "created", id: body.id, requestCode: body.request_code };
|
|
359
|
-
if (body.status === "pending") return { status: "pending", id: body.id };
|
|
360
|
-
return { status: "failed", id: body.id, fallbackUrl: body.fallback_url };
|
|
410
|
+
return { status: "created", id: body.id, requestCode: body.request_code, mode };
|
|
411
|
+
if (body.status === "pending") return { status: "pending", id: body.id, mode };
|
|
412
|
+
return { status: "failed", id: body.id, fallbackUrl: body.fallback_url, mode };
|
|
361
413
|
}
|
|
362
414
|
function formSubmitPayload(input, formId, labels) {
|
|
363
415
|
const vehicle = input.vehicle ? `${input.vehicle.year} ${input.vehicle.make} ${input.vehicle.model}` : "";
|
|
@@ -399,9 +451,29 @@ function formSubmitPayload(input, formId, labels) {
|
|
|
399
451
|
function runtimeOf(firing) {
|
|
400
452
|
return firing && "integrations" in firing ? firing : null;
|
|
401
453
|
}
|
|
454
|
+
function isLocalUrl(url) {
|
|
455
|
+
try {
|
|
456
|
+
return ["localhost", "127.0.0.1", "[::1]"].includes(new URL(url).hostname);
|
|
457
|
+
} catch {
|
|
458
|
+
return false;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
function bookingSetupMismatch(endpoint, runtime) {
|
|
462
|
+
if (!runtime || !isLocalUrl(endpoint)) return null;
|
|
463
|
+
const configUrl = resolveTrackingConfigUrl(runtime.ref);
|
|
464
|
+
if (isLocalUrl(configUrl)) return null;
|
|
465
|
+
return `[aranova] Bookings go to the local API (${endpoint}) but the runtime config comes from ${configUrl}. Set NEXT_PUBLIC_ARANOVA_CDN_BASE_URL to the local bucket (http://localhost:9100/aranova-demos) so both come from one backend.`;
|
|
466
|
+
}
|
|
402
467
|
function createSalesBookingsClient(config, firing) {
|
|
403
468
|
const submittedForms = /* @__PURE__ */ new Set();
|
|
404
469
|
const staleAttempts = /* @__PURE__ */ new Set();
|
|
470
|
+
let isSetupChecked = false;
|
|
471
|
+
function warnOnSetupMismatch(runtime) {
|
|
472
|
+
if (isSetupChecked) return;
|
|
473
|
+
isSetupChecked = true;
|
|
474
|
+
const warning = bookingSetupMismatch(config.endpoint, runtime);
|
|
475
|
+
if (warning) console.warn(warning);
|
|
476
|
+
}
|
|
405
477
|
function handoff(input) {
|
|
406
478
|
const booking = getBookingIntegration(runtimeOf(firing)?.integrations());
|
|
407
479
|
if (!booking) return null;
|
|
@@ -412,14 +484,18 @@ function createSalesBookingsClient(config, firing) {
|
|
|
412
484
|
email: input.email
|
|
413
485
|
});
|
|
414
486
|
}
|
|
487
|
+
function failedBeforeSend(input) {
|
|
488
|
+
const mode = getBookingIntegration(runtimeOf(firing)?.integrations())?.mode ?? "live";
|
|
489
|
+
return { status: "failed", id: null, fallbackUrl: handoff(input), mode };
|
|
490
|
+
}
|
|
415
491
|
function withHandoff(outcome, input) {
|
|
416
492
|
if (outcome.status === "failed" && !outcome.fallbackUrl) {
|
|
417
493
|
return { ...outcome, fallbackUrl: handoff(input) };
|
|
418
494
|
}
|
|
419
495
|
return outcome;
|
|
420
496
|
}
|
|
421
|
-
async function poll(id) {
|
|
422
|
-
let outcome = { status: "pending", id };
|
|
497
|
+
async function poll(id, mode) {
|
|
498
|
+
let outcome = { status: "pending", id, mode };
|
|
423
499
|
for (const delay of POLL_DELAYS_MS) {
|
|
424
500
|
await sleep(delay);
|
|
425
501
|
try {
|
|
@@ -434,12 +510,10 @@ function createSalesBookingsClient(config, firing) {
|
|
|
434
510
|
}
|
|
435
511
|
async function rejected(error, input, attemptKey, runtime) {
|
|
436
512
|
if (!(error instanceof AranovaApiError)) {
|
|
437
|
-
return
|
|
513
|
+
return failedBeforeSend(input);
|
|
438
514
|
}
|
|
439
515
|
if (error.code === BOOKING_ERROR_CODES.stale) {
|
|
440
|
-
if (staleAttempts.has(attemptKey))
|
|
441
|
-
return { status: "failed", id: null, fallbackUrl: handoff(input) };
|
|
442
|
-
}
|
|
516
|
+
if (staleAttempts.has(attemptKey)) return failedBeforeSend(input);
|
|
443
517
|
staleAttempts.add(attemptKey);
|
|
444
518
|
await runtime?.revalidate();
|
|
445
519
|
return { status: "stale", message: error.message };
|
|
@@ -455,15 +529,16 @@ function createSalesBookingsClient(config, firing) {
|
|
|
455
529
|
if (error.code === "validation_error") {
|
|
456
530
|
return { status: "invalid", message: INVALID_DETAILS, reasons: [] };
|
|
457
531
|
}
|
|
458
|
-
return
|
|
532
|
+
return failedBeforeSend(input);
|
|
459
533
|
}
|
|
460
534
|
return {
|
|
461
|
-
async submit(input, { attemptKey, formSubmit }) {
|
|
535
|
+
async submit(input, { attemptKey, formSubmit, simulate }) {
|
|
462
536
|
registerCapability("booking_integration");
|
|
463
537
|
const runtime = runtimeOf(firing);
|
|
538
|
+
warnOnSetupMismatch(runtime);
|
|
464
539
|
const booking = getBookingIntegration(runtime?.integrations());
|
|
465
540
|
if (!booking?.acceptsBookings || booking.configVersion === null) {
|
|
466
|
-
return
|
|
541
|
+
return failedBeforeSend(input);
|
|
467
542
|
}
|
|
468
543
|
if (formSubmit && !submittedForms.has(attemptKey)) {
|
|
469
544
|
submittedForms.add(attemptKey);
|
|
@@ -493,12 +568,22 @@ function createSalesBookingsClient(config, firing) {
|
|
|
493
568
|
};
|
|
494
569
|
let response;
|
|
495
570
|
try {
|
|
496
|
-
|
|
571
|
+
const headers = simulate ? { [BOOKING_SIMULATE_HEADER]: simulate } : void 0;
|
|
572
|
+
response = await salesRequest(
|
|
573
|
+
config,
|
|
574
|
+
"POST",
|
|
575
|
+
"/bookings",
|
|
576
|
+
body,
|
|
577
|
+
headers
|
|
578
|
+
);
|
|
497
579
|
} catch (error) {
|
|
498
580
|
return rejected(error, input, attemptKey, runtime);
|
|
499
581
|
}
|
|
500
582
|
const outcome = outcomeOf(response);
|
|
501
|
-
return withHandoff(
|
|
583
|
+
return withHandoff(
|
|
584
|
+
outcome.status === "pending" ? await poll(outcome.id, outcome.mode) : outcome,
|
|
585
|
+
input
|
|
586
|
+
);
|
|
502
587
|
},
|
|
503
588
|
async status(id) {
|
|
504
589
|
return outcomeOf(
|
|
@@ -512,41 +597,6 @@ function createSalesBookingsClient(config, firing) {
|
|
|
512
597
|
};
|
|
513
598
|
}
|
|
514
599
|
|
|
515
|
-
// ../tracking-core/src/resources/intl/date.ts
|
|
516
|
-
function formatDateInTz(iso3, timeZone, opts, locale) {
|
|
517
|
-
const date = new Date(iso3);
|
|
518
|
-
if (Number.isNaN(date.getTime())) return iso3;
|
|
519
|
-
return new Intl.DateTimeFormat(locale, {
|
|
520
|
-
year: "numeric",
|
|
521
|
-
month: "short",
|
|
522
|
-
day: "2-digit",
|
|
523
|
-
hour: "2-digit",
|
|
524
|
-
minute: "2-digit",
|
|
525
|
-
...opts,
|
|
526
|
-
timeZone
|
|
527
|
-
}).format(date);
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
// ../tracking-core/src/resources/sales/money.ts
|
|
531
|
-
var MINOR_UNIT_EXPONENT = {
|
|
532
|
-
USD: 2,
|
|
533
|
-
CAD: 2
|
|
534
|
-
};
|
|
535
|
-
function exponentFor(currency) {
|
|
536
|
-
return MINOR_UNIT_EXPONENT[currency] ?? 2;
|
|
537
|
-
}
|
|
538
|
-
function toMinor(amount, currency) {
|
|
539
|
-
return Math.round(amount * 10 ** exponentFor(currency));
|
|
540
|
-
}
|
|
541
|
-
function fromMinor(cents, currency) {
|
|
542
|
-
return cents / 10 ** exponentFor(currency);
|
|
543
|
-
}
|
|
544
|
-
function formatMoney(cents, currency, locale) {
|
|
545
|
-
return new Intl.NumberFormat(locale, { style: "currency", currency }).format(
|
|
546
|
-
fromMinor(cents, currency)
|
|
547
|
-
);
|
|
548
|
-
}
|
|
549
|
-
|
|
550
600
|
// ../tracking-core/src/resources/sales/client.ts
|
|
551
601
|
function fireRecordedConversions(firing, input, recorded, sale, currency) {
|
|
552
602
|
if (!firing) return;
|
|
@@ -762,6 +812,7 @@ var zErrorCode = z.enum([
|
|
|
762
812
|
"booking_not_found",
|
|
763
813
|
"booking_not_cancellable",
|
|
764
814
|
"booking_not_reschedulable",
|
|
815
|
+
"booking_not_synced",
|
|
765
816
|
"manage_token_invalid",
|
|
766
817
|
"google_error",
|
|
767
818
|
"booking_unavailable",
|