glitchgrab 1.58.1 → 1.58.2
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 +28 -0
- package/dist/index.d.mts +21 -3
- package/dist/index.d.ts +21 -3
- package/dist/index.js +730 -569
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +729 -569
- package/dist/index.mjs.map +1 -1
- package/dist/server.d.mts +30 -3
- package/dist/server.d.ts +30 -3
- package/dist/server.js +42 -13
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +40 -13
- package/dist/server.mjs.map +1 -1
- package/dist/{types-DfVtKZcp.d.mts → types-BpTLWJ1y.d.mts} +8 -0
- package/dist/{types-DfVtKZcp.d.ts → types-BpTLWJ1y.d.ts} +8 -0
- package/package.json +1 -1
package/dist/server.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { l as ReportType, k as ReportSeverity, j as ReportResult } from './types-
|
|
1
|
+
import { l as ReportType, k as ReportSeverity, j as ReportResult } from './types-BpTLWJ1y.mjs';
|
|
2
2
|
import 'react';
|
|
3
3
|
|
|
4
4
|
/** Who to attribute the report to. A server has no signed-in user, so this is the job or service. */
|
|
@@ -382,6 +382,14 @@ interface BookingSettings {
|
|
|
382
382
|
* and it keeps what is stored. The answers come back on {@link Booking.answers}.
|
|
383
383
|
*/
|
|
384
384
|
questions: BookingQuestion[];
|
|
385
|
+
/**
|
|
386
|
+
* Questions saved as a draft and not live yet — the dialog and the WhatsApp
|
|
387
|
+
* chat still ask {@link questions}. Preview them with
|
|
388
|
+
* `useGlitchgrab().openBookingPreview()`, make them live with
|
|
389
|
+
* {@link publishBookingQuestions}. `null` = no draft; `[]` = a draft that
|
|
390
|
+
* asks nothing.
|
|
391
|
+
*/
|
|
392
|
+
draftQuestions: BookingQuestion[] | null;
|
|
385
393
|
/**
|
|
386
394
|
* Text a code to the prospect's phone before the demo is confirmed. `false`
|
|
387
395
|
* books the slot the moment the form is sent — one step fewer, but a
|
|
@@ -410,8 +418,14 @@ type BookingQuestionInput = Omit<BookingQuestion, "id" | "required"> & {
|
|
|
410
418
|
required?: boolean;
|
|
411
419
|
};
|
|
412
420
|
/** What {@link updateBookingSettings} accepts — any subset of the settings. */
|
|
413
|
-
type BookingSettingsChanges = Partial<Omit<BookingSettings, "questions">> & {
|
|
421
|
+
type BookingSettingsChanges = Partial<Omit<BookingSettings, "questions" | "draftQuestions">> & {
|
|
414
422
|
questions?: BookingQuestionInput[];
|
|
423
|
+
/**
|
|
424
|
+
* With `questions`: save them as a draft instead — the live dialog and chat
|
|
425
|
+
* are unchanged until {@link publishBookingQuestions}. Left out, `questions`
|
|
426
|
+
* go live at once (and any draft is dropped), as before.
|
|
427
|
+
*/
|
|
428
|
+
draft?: boolean;
|
|
415
429
|
};
|
|
416
430
|
/** One answer a prospect gave, with the question as it was worded when they booked. */
|
|
417
431
|
interface BookingAnswer {
|
|
@@ -459,6 +473,19 @@ declare function getBookingSettings(options?: CallsOptions): Promise<BookingSett
|
|
|
459
473
|
* comes back as one.
|
|
460
474
|
*/
|
|
461
475
|
declare function updateBookingSettings(changes: BookingSettingsChanges, options?: CallsOptions): Promise<BookingSettingsResult>;
|
|
476
|
+
/**
|
|
477
|
+
* Make the draft questions live — the booking dialog and the WhatsApp chat ask
|
|
478
|
+
* them from now on. `error` when there is no draft to publish.
|
|
479
|
+
*
|
|
480
|
+
* ```ts
|
|
481
|
+
* await updateBookingSettings({ questions, draft: true }); // live dialog unchanged
|
|
482
|
+
* // …preview with useGlitchgrab().openBookingPreview() on your admin page…
|
|
483
|
+
* await publishBookingQuestions();
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
declare function publishBookingQuestions(options?: CallsOptions): Promise<BookingSettingsResult>;
|
|
487
|
+
/** Throw the draft questions away; the live ones are untouched. */
|
|
488
|
+
declare function discardBookingQuestionsDraft(options?: CallsOptions): Promise<BookingSettingsResult>;
|
|
462
489
|
/** One booked demo. Times are ISO strings in UTC; `timezone` is what the prospect picked in. */
|
|
463
490
|
interface Booking {
|
|
464
491
|
id: string;
|
|
@@ -597,4 +624,4 @@ interface ListLeadsOptions extends CallsOptions {
|
|
|
597
624
|
*/
|
|
598
625
|
declare function listLeads(options?: ListLeadsOptions): Promise<Lead[]>;
|
|
599
626
|
|
|
600
|
-
export { type Booking, type BookingAnswer, type BookingClientNotice, type BookingMutationResult, type BookingNotifyRecipient, type BookingQuestion, type BookingQuestionInput, type BookingSettings, type BookingSettingsChanges, type BookingSettingsResult, type BookingSettingsState, type BookingWorkingHours, type Call, type CallAudio, type CallListItem, type CallMoment, type CallParticipant, type CallsOptions, type CaptureServerErrorsOptions, type DeleteCallResult, type GetCallOptions, type Guide, type GuideReadOptions, type GuideSummary, type Lead, type ListBookingsOptions, type ListCallsOptions, type ListLeadsOptions, ReportResult, ReportSeverity, ReportType, type ServerReportOptions, type ServerReporterConfig, type ServerReporterIdentity, type SignSessionOptions, cancelBooking, captureServerErrors, configureServerReporter, deleteCall, escapeJsonForScript, getBookingSettings, getCall, getGuide, listBookings, listCalls, listGuides, listLeads, reportServerError, rescheduleBooking, resetServerReporter, signSession, updateBookingSettings };
|
|
627
|
+
export { type Booking, type BookingAnswer, type BookingClientNotice, type BookingMutationResult, type BookingNotifyRecipient, type BookingQuestion, type BookingQuestionInput, type BookingSettings, type BookingSettingsChanges, type BookingSettingsResult, type BookingSettingsState, type BookingWorkingHours, type Call, type CallAudio, type CallListItem, type CallMoment, type CallParticipant, type CallsOptions, type CaptureServerErrorsOptions, type DeleteCallResult, type GetCallOptions, type Guide, type GuideReadOptions, type GuideSummary, type Lead, type ListBookingsOptions, type ListCallsOptions, type ListLeadsOptions, ReportResult, ReportSeverity, ReportType, type ServerReportOptions, type ServerReporterConfig, type ServerReporterIdentity, type SignSessionOptions, cancelBooking, captureServerErrors, configureServerReporter, deleteCall, discardBookingQuestionsDraft, escapeJsonForScript, getBookingSettings, getCall, getGuide, listBookings, listCalls, listGuides, listLeads, publishBookingQuestions, reportServerError, rescheduleBooking, resetServerReporter, signSession, updateBookingSettings };
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { l as ReportType, k as ReportSeverity, j as ReportResult } from './types-
|
|
1
|
+
import { l as ReportType, k as ReportSeverity, j as ReportResult } from './types-BpTLWJ1y.js';
|
|
2
2
|
import 'react';
|
|
3
3
|
|
|
4
4
|
/** Who to attribute the report to. A server has no signed-in user, so this is the job or service. */
|
|
@@ -382,6 +382,14 @@ interface BookingSettings {
|
|
|
382
382
|
* and it keeps what is stored. The answers come back on {@link Booking.answers}.
|
|
383
383
|
*/
|
|
384
384
|
questions: BookingQuestion[];
|
|
385
|
+
/**
|
|
386
|
+
* Questions saved as a draft and not live yet — the dialog and the WhatsApp
|
|
387
|
+
* chat still ask {@link questions}. Preview them with
|
|
388
|
+
* `useGlitchgrab().openBookingPreview()`, make them live with
|
|
389
|
+
* {@link publishBookingQuestions}. `null` = no draft; `[]` = a draft that
|
|
390
|
+
* asks nothing.
|
|
391
|
+
*/
|
|
392
|
+
draftQuestions: BookingQuestion[] | null;
|
|
385
393
|
/**
|
|
386
394
|
* Text a code to the prospect's phone before the demo is confirmed. `false`
|
|
387
395
|
* books the slot the moment the form is sent — one step fewer, but a
|
|
@@ -410,8 +418,14 @@ type BookingQuestionInput = Omit<BookingQuestion, "id" | "required"> & {
|
|
|
410
418
|
required?: boolean;
|
|
411
419
|
};
|
|
412
420
|
/** What {@link updateBookingSettings} accepts — any subset of the settings. */
|
|
413
|
-
type BookingSettingsChanges = Partial<Omit<BookingSettings, "questions">> & {
|
|
421
|
+
type BookingSettingsChanges = Partial<Omit<BookingSettings, "questions" | "draftQuestions">> & {
|
|
414
422
|
questions?: BookingQuestionInput[];
|
|
423
|
+
/**
|
|
424
|
+
* With `questions`: save them as a draft instead — the live dialog and chat
|
|
425
|
+
* are unchanged until {@link publishBookingQuestions}. Left out, `questions`
|
|
426
|
+
* go live at once (and any draft is dropped), as before.
|
|
427
|
+
*/
|
|
428
|
+
draft?: boolean;
|
|
415
429
|
};
|
|
416
430
|
/** One answer a prospect gave, with the question as it was worded when they booked. */
|
|
417
431
|
interface BookingAnswer {
|
|
@@ -459,6 +473,19 @@ declare function getBookingSettings(options?: CallsOptions): Promise<BookingSett
|
|
|
459
473
|
* comes back as one.
|
|
460
474
|
*/
|
|
461
475
|
declare function updateBookingSettings(changes: BookingSettingsChanges, options?: CallsOptions): Promise<BookingSettingsResult>;
|
|
476
|
+
/**
|
|
477
|
+
* Make the draft questions live — the booking dialog and the WhatsApp chat ask
|
|
478
|
+
* them from now on. `error` when there is no draft to publish.
|
|
479
|
+
*
|
|
480
|
+
* ```ts
|
|
481
|
+
* await updateBookingSettings({ questions, draft: true }); // live dialog unchanged
|
|
482
|
+
* // …preview with useGlitchgrab().openBookingPreview() on your admin page…
|
|
483
|
+
* await publishBookingQuestions();
|
|
484
|
+
* ```
|
|
485
|
+
*/
|
|
486
|
+
declare function publishBookingQuestions(options?: CallsOptions): Promise<BookingSettingsResult>;
|
|
487
|
+
/** Throw the draft questions away; the live ones are untouched. */
|
|
488
|
+
declare function discardBookingQuestionsDraft(options?: CallsOptions): Promise<BookingSettingsResult>;
|
|
462
489
|
/** One booked demo. Times are ISO strings in UTC; `timezone` is what the prospect picked in. */
|
|
463
490
|
interface Booking {
|
|
464
491
|
id: string;
|
|
@@ -597,4 +624,4 @@ interface ListLeadsOptions extends CallsOptions {
|
|
|
597
624
|
*/
|
|
598
625
|
declare function listLeads(options?: ListLeadsOptions): Promise<Lead[]>;
|
|
599
626
|
|
|
600
|
-
export { type Booking, type BookingAnswer, type BookingClientNotice, type BookingMutationResult, type BookingNotifyRecipient, type BookingQuestion, type BookingQuestionInput, type BookingSettings, type BookingSettingsChanges, type BookingSettingsResult, type BookingSettingsState, type BookingWorkingHours, type Call, type CallAudio, type CallListItem, type CallMoment, type CallParticipant, type CallsOptions, type CaptureServerErrorsOptions, type DeleteCallResult, type GetCallOptions, type Guide, type GuideReadOptions, type GuideSummary, type Lead, type ListBookingsOptions, type ListCallsOptions, type ListLeadsOptions, ReportResult, ReportSeverity, ReportType, type ServerReportOptions, type ServerReporterConfig, type ServerReporterIdentity, type SignSessionOptions, cancelBooking, captureServerErrors, configureServerReporter, deleteCall, escapeJsonForScript, getBookingSettings, getCall, getGuide, listBookings, listCalls, listGuides, listLeads, reportServerError, rescheduleBooking, resetServerReporter, signSession, updateBookingSettings };
|
|
627
|
+
export { type Booking, type BookingAnswer, type BookingClientNotice, type BookingMutationResult, type BookingNotifyRecipient, type BookingQuestion, type BookingQuestionInput, type BookingSettings, type BookingSettingsChanges, type BookingSettingsResult, type BookingSettingsState, type BookingWorkingHours, type Call, type CallAudio, type CallListItem, type CallMoment, type CallParticipant, type CallsOptions, type CaptureServerErrorsOptions, type DeleteCallResult, type GetCallOptions, type Guide, type GuideReadOptions, type GuideSummary, type Lead, type ListBookingsOptions, type ListCallsOptions, type ListLeadsOptions, ReportResult, ReportSeverity, ReportType, type ServerReportOptions, type ServerReporterConfig, type ServerReporterIdentity, type SignSessionOptions, cancelBooking, captureServerErrors, configureServerReporter, deleteCall, discardBookingQuestionsDraft, escapeJsonForScript, getBookingSettings, getCall, getGuide, listBookings, listCalls, listGuides, listLeads, publishBookingQuestions, reportServerError, rescheduleBooking, resetServerReporter, signSession, updateBookingSettings };
|
package/dist/server.js
CHANGED
|
@@ -24,6 +24,7 @@ __export(server_exports, {
|
|
|
24
24
|
captureServerErrors: () => captureServerErrors,
|
|
25
25
|
configureServerReporter: () => configureServerReporter,
|
|
26
26
|
deleteCall: () => deleteCall,
|
|
27
|
+
discardBookingQuestionsDraft: () => discardBookingQuestionsDraft,
|
|
27
28
|
escapeJsonForScript: () => escapeJsonForScript,
|
|
28
29
|
getBookingSettings: () => getBookingSettings,
|
|
29
30
|
getCall: () => getCall,
|
|
@@ -32,6 +33,7 @@ __export(server_exports, {
|
|
|
32
33
|
listCalls: () => listCalls,
|
|
33
34
|
listGuides: () => listGuides,
|
|
34
35
|
listLeads: () => listLeads,
|
|
36
|
+
publishBookingQuestions: () => publishBookingQuestions,
|
|
35
37
|
reportServerError: () => reportServerError,
|
|
36
38
|
rescheduleBooking: () => rescheduleBooking,
|
|
37
39
|
resetServerReporter: () => resetServerReporter,
|
|
@@ -48,6 +50,9 @@ var pageLoadedAt = Date.now();
|
|
|
48
50
|
var DEFAULT_BASE_URL = "https://glitchgrab.dev";
|
|
49
51
|
var MAX_RETRIES = 3;
|
|
50
52
|
var RETRY_BASE_MS = 500;
|
|
53
|
+
function reportAttemptTimeoutMs(bodyLength) {
|
|
54
|
+
return 1e4 + Math.ceil(bodyLength / 1e5) * 1e3;
|
|
55
|
+
}
|
|
51
56
|
async function sendReport(payload, baseUrl) {
|
|
52
57
|
var _a;
|
|
53
58
|
try {
|
|
@@ -58,13 +63,18 @@ async function sendReport(payload, baseUrl) {
|
|
|
58
63
|
Authorization: `Bearer ${payload.token}`
|
|
59
64
|
};
|
|
60
65
|
const useKeepalive = body.length < 6e4;
|
|
66
|
+
const timeoutMs = reportAttemptTimeoutMs(body.length);
|
|
61
67
|
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
|
|
68
|
+
const isLast = attempt === MAX_RETRIES - 1;
|
|
69
|
+
const controller = !isLast && typeof AbortController === "function" ? new AbortController() : null;
|
|
70
|
+
const timer = controller ? setTimeout(() => controller.abort(), timeoutMs) : null;
|
|
62
71
|
try {
|
|
63
72
|
const response = await fetch(url, {
|
|
64
73
|
method: "POST",
|
|
65
74
|
headers,
|
|
66
75
|
body,
|
|
67
|
-
...useKeepalive ? { keepalive: true } : {}
|
|
76
|
+
...useKeepalive ? { keepalive: true } : {},
|
|
77
|
+
...controller ? { signal: controller.signal } : {}
|
|
68
78
|
});
|
|
69
79
|
if (response.ok) {
|
|
70
80
|
const envelope = await response.json();
|
|
@@ -74,6 +84,8 @@ async function sendReport(payload, baseUrl) {
|
|
|
74
84
|
return null;
|
|
75
85
|
}
|
|
76
86
|
} catch (e) {
|
|
87
|
+
} finally {
|
|
88
|
+
if (timer) clearTimeout(timer);
|
|
77
89
|
}
|
|
78
90
|
if (attempt < MAX_RETRIES - 1) {
|
|
79
91
|
await new Promise(
|
|
@@ -466,8 +478,20 @@ async function deleteCall(id, options = {}) {
|
|
|
466
478
|
}
|
|
467
479
|
}
|
|
468
480
|
var WEEKDAY = /^[1-7]$/;
|
|
481
|
+
function readQuestionList(value) {
|
|
482
|
+
if (!Array.isArray(value)) return null;
|
|
483
|
+
return value.filter(isRecord).map((row) => {
|
|
484
|
+
var _a, _b;
|
|
485
|
+
return {
|
|
486
|
+
id: (_a = stringOrNull(row.id)) != null ? _a : "",
|
|
487
|
+
label: (_b = stringOrNull(row.label)) != null ? _b : "",
|
|
488
|
+
options: Array.isArray(row.options) ? row.options.filter((option) => typeof option === "string") : [],
|
|
489
|
+
required: row.required !== false
|
|
490
|
+
};
|
|
491
|
+
}).filter((row) => row.id !== "" && row.label !== "");
|
|
492
|
+
}
|
|
469
493
|
function readBookingSettingsState(value) {
|
|
470
|
-
var _a, _b, _c, _d;
|
|
494
|
+
var _a, _b, _c, _d, _e;
|
|
471
495
|
if (!isRecord(value) || !isRecord(value.settings)) return null;
|
|
472
496
|
const s = value.settings;
|
|
473
497
|
const hours = {};
|
|
@@ -501,15 +525,9 @@ function readBookingSettingsState(value) {
|
|
|
501
525
|
phone: (_b2 = stringOrNull(row.phone)) != null ? _b2 : ""
|
|
502
526
|
};
|
|
503
527
|
}).filter((row) => row.phone !== "") : [],
|
|
504
|
-
questions:
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
id: (_a2 = stringOrNull(row.id)) != null ? _a2 : "",
|
|
508
|
-
label: (_b2 = stringOrNull(row.label)) != null ? _b2 : "",
|
|
509
|
-
options: Array.isArray(row.options) ? row.options.filter((option) => typeof option === "string") : [],
|
|
510
|
-
required: row.required !== false
|
|
511
|
-
};
|
|
512
|
-
}).filter((row) => row.id !== "" && row.label !== "") : [],
|
|
528
|
+
questions: (_e = readQuestionList(s.questions)) != null ? _e : [],
|
|
529
|
+
// A server from before drafts sends no key: no draft.
|
|
530
|
+
draftQuestions: readQuestionList(s.draftQuestions),
|
|
513
531
|
// Missing means a server from before the switch, which always asked.
|
|
514
532
|
requireOtp: s.requireOtp !== false
|
|
515
533
|
},
|
|
@@ -528,13 +546,16 @@ async function getBookingSettings(options = {}) {
|
|
|
528
546
|
return { ok: false, error: "Could not read booking settings" };
|
|
529
547
|
}
|
|
530
548
|
}
|
|
531
|
-
|
|
549
|
+
function updateBookingSettings(changes, options = {}) {
|
|
550
|
+
return putBookingSettings(changes != null ? changes : {}, options);
|
|
551
|
+
}
|
|
552
|
+
async function putBookingSettings(body, options) {
|
|
532
553
|
try {
|
|
533
554
|
const key = callsKey(options);
|
|
534
555
|
if (!key) return { ok: false, error: NO_KEY_ERROR };
|
|
535
556
|
const { data, error } = await callSdkApi("/api/v1/sdk/booking-settings", key, options, {
|
|
536
557
|
method: "PUT",
|
|
537
|
-
body
|
|
558
|
+
body,
|
|
538
559
|
cache: "no-store"
|
|
539
560
|
});
|
|
540
561
|
const state = error === null ? readBookingSettingsState(data) : null;
|
|
@@ -543,6 +564,12 @@ async function updateBookingSettings(changes, options = {}) {
|
|
|
543
564
|
return { ok: false, error: "Could not save booking settings" };
|
|
544
565
|
}
|
|
545
566
|
}
|
|
567
|
+
function publishBookingQuestions(options = {}) {
|
|
568
|
+
return putBookingSettings({ publishDraft: true }, options);
|
|
569
|
+
}
|
|
570
|
+
function discardBookingQuestionsDraft(options = {}) {
|
|
571
|
+
return putBookingSettings({ discardDraft: true }, options);
|
|
572
|
+
}
|
|
546
573
|
function readBooking(value) {
|
|
547
574
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
548
575
|
if (!isRecord(value) || typeof value.id !== "string") return null;
|
|
@@ -691,6 +718,7 @@ async function listLeads(options = {}) {
|
|
|
691
718
|
captureServerErrors,
|
|
692
719
|
configureServerReporter,
|
|
693
720
|
deleteCall,
|
|
721
|
+
discardBookingQuestionsDraft,
|
|
694
722
|
escapeJsonForScript,
|
|
695
723
|
getBookingSettings,
|
|
696
724
|
getCall,
|
|
@@ -699,6 +727,7 @@ async function listLeads(options = {}) {
|
|
|
699
727
|
listCalls,
|
|
700
728
|
listGuides,
|
|
701
729
|
listLeads,
|
|
730
|
+
publishBookingQuestions,
|
|
702
731
|
reportServerError,
|
|
703
732
|
rescheduleBooking,
|
|
704
733
|
resetServerReporter,
|