glitchgrab 1.53.0 → 1.55.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.
- package/README.md +24 -0
- package/dist/server.d.mts +95 -1
- package/dist/server.d.ts +95 -1
- package/dist/server.js +112 -1
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +109 -1
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -754,6 +754,29 @@ if (!result.success) {
|
|
|
754
754
|
}
|
|
755
755
|
```
|
|
756
756
|
|
|
757
|
+
### Attach the logs that led up to it
|
|
758
|
+
|
|
759
|
+
A stack says where a job broke; the lines it printed before that usually say
|
|
760
|
+
why. Pass them as `logs` — an array of lines or one string:
|
|
761
|
+
|
|
762
|
+
```ts
|
|
763
|
+
const lines: string[] = [];
|
|
764
|
+
const log = (line: string) => { lines.push(line); console.log(line); };
|
|
765
|
+
|
|
766
|
+
try {
|
|
767
|
+
log(`[filing] starting return ${returnId}`);
|
|
768
|
+
await submitReturn(returnId);
|
|
769
|
+
} catch (error) {
|
|
770
|
+
await reportServerError(error, { context: "worker/filing", logs: lines });
|
|
771
|
+
throw error;
|
|
772
|
+
}
|
|
773
|
+
```
|
|
774
|
+
|
|
775
|
+
They arrive on the issue as a `.log` file named after `context`: the start is
|
|
776
|
+
previewed in the issue body, the whole file is kept for download. Only the last
|
|
777
|
+
200,000 characters are sent. Logs are not part of the grouping key — the same
|
|
778
|
+
error with different logs still lands on one issue.
|
|
779
|
+
|
|
757
780
|
### Set the token once
|
|
758
781
|
|
|
759
782
|
```ts
|
|
@@ -795,6 +818,7 @@ reportServerError(error: unknown, options?: {
|
|
|
795
818
|
// anything else is rejected 400 by the API
|
|
796
819
|
pageUrl?: string; // a real request URL, when there is one
|
|
797
820
|
metadata?: Record<string, string>;
|
|
821
|
+
logs?: string | string[]; // attached as <context>.log — last 200,000 chars
|
|
798
822
|
reporter?: { id?: string; name?: string; email?: string; phone?: string };
|
|
799
823
|
enableInDevelopment?: boolean;
|
|
800
824
|
})
|
package/dist/server.d.mts
CHANGED
|
@@ -48,6 +48,15 @@ interface ServerReportOptions extends ServerReporterConfig {
|
|
|
48
48
|
* the synthetic URL built from `context`.
|
|
49
49
|
*/
|
|
50
50
|
pageUrl?: string;
|
|
51
|
+
/**
|
|
52
|
+
* What the job printed before it failed — lines or one string.
|
|
53
|
+
*
|
|
54
|
+
* Attached to the issue as a `.log` file: the first part is previewed in the
|
|
55
|
+
* issue body, the whole file is kept for download. A stack says where it
|
|
56
|
+
* broke; the log lines before it are usually what says why. Only the last
|
|
57
|
+
* {@link MAX_LOG_CHARS} characters are sent.
|
|
58
|
+
*/
|
|
59
|
+
logs?: string | string[];
|
|
51
60
|
}
|
|
52
61
|
/**
|
|
53
62
|
* Set the token and the defaults once, at module load, instead of passing them
|
|
@@ -359,6 +368,19 @@ interface BookingSettings {
|
|
|
359
368
|
noticeMinutes: number;
|
|
360
369
|
/** Code in the "Book on WhatsApp" link. Lower case, letters, digits and `-`; unique across projects. */
|
|
361
370
|
whatsappCode: string | null;
|
|
371
|
+
/**
|
|
372
|
+
* Who else is WhatsApped when a demo is booked, besides the project owner —
|
|
373
|
+
* sales, the founders, whoever needs the lead as it lands. At most 5; a
|
|
374
|
+
* ten-digit Indian mobile is stored with its 91. Send the whole list to
|
|
375
|
+
* change it; leave the field out and it keeps what is stored.
|
|
376
|
+
*/
|
|
377
|
+
notifyRecipients: BookingNotifyRecipient[];
|
|
378
|
+
}
|
|
379
|
+
/** One extra person alerted when a demo is booked. */
|
|
380
|
+
interface BookingNotifyRecipient {
|
|
381
|
+
name: string;
|
|
382
|
+
/** Digits only, country code included. */
|
|
383
|
+
phone: string;
|
|
362
384
|
}
|
|
363
385
|
interface BookingSettingsState {
|
|
364
386
|
settings: BookingSettings;
|
|
@@ -393,6 +415,78 @@ declare function getBookingSettings(options?: CallsOptions): Promise<BookingSett
|
|
|
393
415
|
* comes back as one.
|
|
394
416
|
*/
|
|
395
417
|
declare function updateBookingSettings(changes: Partial<BookingSettings>, options?: CallsOptions): Promise<BookingSettingsResult>;
|
|
418
|
+
/** One booked demo. Times are ISO strings in UTC; `timezone` is what the prospect picked in. */
|
|
419
|
+
interface Booking {
|
|
420
|
+
id: string;
|
|
421
|
+
/** Who booked. */
|
|
422
|
+
name: string;
|
|
423
|
+
email: string;
|
|
424
|
+
/** Digits only, country code included. */
|
|
425
|
+
phone: string;
|
|
426
|
+
startsAt: string;
|
|
427
|
+
endsAt: string;
|
|
428
|
+
/** IANA zone the prospect booked in, e.g. `"Asia/Kolkata"`. */
|
|
429
|
+
timezone: string | null;
|
|
430
|
+
/** What they typed when booking, if anything. */
|
|
431
|
+
note: string | null;
|
|
432
|
+
/** `CONFIRMED` or `CANCELLED`. Unverified holds are never returned. */
|
|
433
|
+
status: string;
|
|
434
|
+
/** The Google Meet room. Null until the booking is confirmed. */
|
|
435
|
+
meetUrl: string | null;
|
|
436
|
+
createdAt: string;
|
|
437
|
+
}
|
|
438
|
+
interface ListBookingsOptions extends CallsOptions {
|
|
439
|
+
/** `"upcoming"` (default) or `"past"`. */
|
|
440
|
+
scope?: "upcoming" | "past";
|
|
441
|
+
/** Up to 100. Defaults to 50. */
|
|
442
|
+
limit?: number;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Whether the prospect was told. A move re-sends the approved confirmation
|
|
446
|
+
* template, so `"sent"` is real. A cancellation can only go as free text, which
|
|
447
|
+
* WhatsApp delivers only inside its 24-hour window and reports nothing about —
|
|
448
|
+
* `"attempted"` means exactly that, and your panel should say so rather than
|
|
449
|
+
* telling an admin the client knows.
|
|
450
|
+
*/
|
|
451
|
+
type BookingClientNotice = "sent" | "attempted" | "none";
|
|
452
|
+
type BookingMutationResult = {
|
|
453
|
+
ok: true;
|
|
454
|
+
booking: Booking | null;
|
|
455
|
+
clientNotice: BookingClientNotice;
|
|
456
|
+
} | {
|
|
457
|
+
ok: false;
|
|
458
|
+
error: string;
|
|
459
|
+
code: string | null;
|
|
460
|
+
};
|
|
461
|
+
/**
|
|
462
|
+
* The project's booked demos, soonest first. Never throws — an empty list on
|
|
463
|
+
* any failure, so a panel renders "no demos" instead of a stack trace.
|
|
464
|
+
*
|
|
465
|
+
* ```ts
|
|
466
|
+
* const demos = await listBookings(); // GLITCHGRAB_CALLS_KEY=ggc_…
|
|
467
|
+
* ```
|
|
468
|
+
*/
|
|
469
|
+
declare function listBookings(options?: ListBookingsOptions): Promise<Booking[]>;
|
|
470
|
+
/**
|
|
471
|
+
* Move a demo to a new start time. The Google event is patched, never
|
|
472
|
+
* recreated, so the Meet link in every message already sent stays alive, and
|
|
473
|
+
* the prospect is re-sent the confirmation with the new time.
|
|
474
|
+
*
|
|
475
|
+
* `{ ok: false, code: "SLOT_TAKEN" }` when another booking holds that slot,
|
|
476
|
+
* `"PAST"` for a time that has gone, `"CALENDAR"` when Google refused — in the
|
|
477
|
+
* last case nothing was changed and the demo still stands at its old time.
|
|
478
|
+
*/
|
|
479
|
+
declare function rescheduleBooking(id: string, startsAt: Date | string, options?: CallsOptions): Promise<BookingMutationResult>;
|
|
480
|
+
/**
|
|
481
|
+
* Call a demo off: the Google event is deleted, the recorder is stood down, and
|
|
482
|
+
* the prospect is messaged if WhatsApp will carry it (see
|
|
483
|
+
* {@link BookingClientNotice}).
|
|
484
|
+
*
|
|
485
|
+
* `reason` is included in that message. Nothing is marked cancelled unless the
|
|
486
|
+
* calendar agreed first, so `{ ok: false, code: "CALENDAR" }` means the demo is
|
|
487
|
+
* still on.
|
|
488
|
+
*/
|
|
489
|
+
declare function cancelBooking(id: string, reason?: string, options?: CallsOptions): Promise<BookingMutationResult>;
|
|
396
490
|
/**
|
|
397
491
|
* `JSON.stringify` that is safe inside `<script type="application/ld+json">`.
|
|
398
492
|
*
|
|
@@ -413,4 +507,4 @@ declare function updateBookingSettings(changes: Partial<BookingSettings>, option
|
|
|
413
507
|
*/
|
|
414
508
|
declare function escapeJsonForScript(value: unknown): string;
|
|
415
509
|
|
|
416
|
-
export { type BookingSettings, 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 ListCallsOptions, ReportResult, ReportSeverity, ReportType, type ServerReportOptions, type ServerReporterConfig, type ServerReporterIdentity, type SignSessionOptions, captureServerErrors, configureServerReporter, deleteCall, escapeJsonForScript, getBookingSettings, getCall, getGuide, listCalls, listGuides, reportServerError, resetServerReporter, signSession, updateBookingSettings };
|
|
510
|
+
export { type Booking, type BookingClientNotice, type BookingMutationResult, type BookingNotifyRecipient, type BookingSettings, 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 ListBookingsOptions, type ListCallsOptions, ReportResult, ReportSeverity, ReportType, type ServerReportOptions, type ServerReporterConfig, type ServerReporterIdentity, type SignSessionOptions, cancelBooking, captureServerErrors, configureServerReporter, deleteCall, escapeJsonForScript, getBookingSettings, getCall, getGuide, listBookings, listCalls, listGuides, reportServerError, rescheduleBooking, resetServerReporter, signSession, updateBookingSettings };
|
package/dist/server.d.ts
CHANGED
|
@@ -48,6 +48,15 @@ interface ServerReportOptions extends ServerReporterConfig {
|
|
|
48
48
|
* the synthetic URL built from `context`.
|
|
49
49
|
*/
|
|
50
50
|
pageUrl?: string;
|
|
51
|
+
/**
|
|
52
|
+
* What the job printed before it failed — lines or one string.
|
|
53
|
+
*
|
|
54
|
+
* Attached to the issue as a `.log` file: the first part is previewed in the
|
|
55
|
+
* issue body, the whole file is kept for download. A stack says where it
|
|
56
|
+
* broke; the log lines before it are usually what says why. Only the last
|
|
57
|
+
* {@link MAX_LOG_CHARS} characters are sent.
|
|
58
|
+
*/
|
|
59
|
+
logs?: string | string[];
|
|
51
60
|
}
|
|
52
61
|
/**
|
|
53
62
|
* Set the token and the defaults once, at module load, instead of passing them
|
|
@@ -359,6 +368,19 @@ interface BookingSettings {
|
|
|
359
368
|
noticeMinutes: number;
|
|
360
369
|
/** Code in the "Book on WhatsApp" link. Lower case, letters, digits and `-`; unique across projects. */
|
|
361
370
|
whatsappCode: string | null;
|
|
371
|
+
/**
|
|
372
|
+
* Who else is WhatsApped when a demo is booked, besides the project owner —
|
|
373
|
+
* sales, the founders, whoever needs the lead as it lands. At most 5; a
|
|
374
|
+
* ten-digit Indian mobile is stored with its 91. Send the whole list to
|
|
375
|
+
* change it; leave the field out and it keeps what is stored.
|
|
376
|
+
*/
|
|
377
|
+
notifyRecipients: BookingNotifyRecipient[];
|
|
378
|
+
}
|
|
379
|
+
/** One extra person alerted when a demo is booked. */
|
|
380
|
+
interface BookingNotifyRecipient {
|
|
381
|
+
name: string;
|
|
382
|
+
/** Digits only, country code included. */
|
|
383
|
+
phone: string;
|
|
362
384
|
}
|
|
363
385
|
interface BookingSettingsState {
|
|
364
386
|
settings: BookingSettings;
|
|
@@ -393,6 +415,78 @@ declare function getBookingSettings(options?: CallsOptions): Promise<BookingSett
|
|
|
393
415
|
* comes back as one.
|
|
394
416
|
*/
|
|
395
417
|
declare function updateBookingSettings(changes: Partial<BookingSettings>, options?: CallsOptions): Promise<BookingSettingsResult>;
|
|
418
|
+
/** One booked demo. Times are ISO strings in UTC; `timezone` is what the prospect picked in. */
|
|
419
|
+
interface Booking {
|
|
420
|
+
id: string;
|
|
421
|
+
/** Who booked. */
|
|
422
|
+
name: string;
|
|
423
|
+
email: string;
|
|
424
|
+
/** Digits only, country code included. */
|
|
425
|
+
phone: string;
|
|
426
|
+
startsAt: string;
|
|
427
|
+
endsAt: string;
|
|
428
|
+
/** IANA zone the prospect booked in, e.g. `"Asia/Kolkata"`. */
|
|
429
|
+
timezone: string | null;
|
|
430
|
+
/** What they typed when booking, if anything. */
|
|
431
|
+
note: string | null;
|
|
432
|
+
/** `CONFIRMED` or `CANCELLED`. Unverified holds are never returned. */
|
|
433
|
+
status: string;
|
|
434
|
+
/** The Google Meet room. Null until the booking is confirmed. */
|
|
435
|
+
meetUrl: string | null;
|
|
436
|
+
createdAt: string;
|
|
437
|
+
}
|
|
438
|
+
interface ListBookingsOptions extends CallsOptions {
|
|
439
|
+
/** `"upcoming"` (default) or `"past"`. */
|
|
440
|
+
scope?: "upcoming" | "past";
|
|
441
|
+
/** Up to 100. Defaults to 50. */
|
|
442
|
+
limit?: number;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Whether the prospect was told. A move re-sends the approved confirmation
|
|
446
|
+
* template, so `"sent"` is real. A cancellation can only go as free text, which
|
|
447
|
+
* WhatsApp delivers only inside its 24-hour window and reports nothing about —
|
|
448
|
+
* `"attempted"` means exactly that, and your panel should say so rather than
|
|
449
|
+
* telling an admin the client knows.
|
|
450
|
+
*/
|
|
451
|
+
type BookingClientNotice = "sent" | "attempted" | "none";
|
|
452
|
+
type BookingMutationResult = {
|
|
453
|
+
ok: true;
|
|
454
|
+
booking: Booking | null;
|
|
455
|
+
clientNotice: BookingClientNotice;
|
|
456
|
+
} | {
|
|
457
|
+
ok: false;
|
|
458
|
+
error: string;
|
|
459
|
+
code: string | null;
|
|
460
|
+
};
|
|
461
|
+
/**
|
|
462
|
+
* The project's booked demos, soonest first. Never throws — an empty list on
|
|
463
|
+
* any failure, so a panel renders "no demos" instead of a stack trace.
|
|
464
|
+
*
|
|
465
|
+
* ```ts
|
|
466
|
+
* const demos = await listBookings(); // GLITCHGRAB_CALLS_KEY=ggc_…
|
|
467
|
+
* ```
|
|
468
|
+
*/
|
|
469
|
+
declare function listBookings(options?: ListBookingsOptions): Promise<Booking[]>;
|
|
470
|
+
/**
|
|
471
|
+
* Move a demo to a new start time. The Google event is patched, never
|
|
472
|
+
* recreated, so the Meet link in every message already sent stays alive, and
|
|
473
|
+
* the prospect is re-sent the confirmation with the new time.
|
|
474
|
+
*
|
|
475
|
+
* `{ ok: false, code: "SLOT_TAKEN" }` when another booking holds that slot,
|
|
476
|
+
* `"PAST"` for a time that has gone, `"CALENDAR"` when Google refused — in the
|
|
477
|
+
* last case nothing was changed and the demo still stands at its old time.
|
|
478
|
+
*/
|
|
479
|
+
declare function rescheduleBooking(id: string, startsAt: Date | string, options?: CallsOptions): Promise<BookingMutationResult>;
|
|
480
|
+
/**
|
|
481
|
+
* Call a demo off: the Google event is deleted, the recorder is stood down, and
|
|
482
|
+
* the prospect is messaged if WhatsApp will carry it (see
|
|
483
|
+
* {@link BookingClientNotice}).
|
|
484
|
+
*
|
|
485
|
+
* `reason` is included in that message. Nothing is marked cancelled unless the
|
|
486
|
+
* calendar agreed first, so `{ ok: false, code: "CALENDAR" }` means the demo is
|
|
487
|
+
* still on.
|
|
488
|
+
*/
|
|
489
|
+
declare function cancelBooking(id: string, reason?: string, options?: CallsOptions): Promise<BookingMutationResult>;
|
|
396
490
|
/**
|
|
397
491
|
* `JSON.stringify` that is safe inside `<script type="application/ld+json">`.
|
|
398
492
|
*
|
|
@@ -413,4 +507,4 @@ declare function updateBookingSettings(changes: Partial<BookingSettings>, option
|
|
|
413
507
|
*/
|
|
414
508
|
declare function escapeJsonForScript(value: unknown): string;
|
|
415
509
|
|
|
416
|
-
export { type BookingSettings, 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 ListCallsOptions, ReportResult, ReportSeverity, ReportType, type ServerReportOptions, type ServerReporterConfig, type ServerReporterIdentity, type SignSessionOptions, captureServerErrors, configureServerReporter, deleteCall, escapeJsonForScript, getBookingSettings, getCall, getGuide, listCalls, listGuides, reportServerError, resetServerReporter, signSession, updateBookingSettings };
|
|
510
|
+
export { type Booking, type BookingClientNotice, type BookingMutationResult, type BookingNotifyRecipient, type BookingSettings, 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 ListBookingsOptions, type ListCallsOptions, ReportResult, ReportSeverity, ReportType, type ServerReportOptions, type ServerReporterConfig, type ServerReporterIdentity, type SignSessionOptions, cancelBooking, captureServerErrors, configureServerReporter, deleteCall, escapeJsonForScript, getBookingSettings, getCall, getGuide, listBookings, listCalls, listGuides, reportServerError, rescheduleBooking, resetServerReporter, signSession, updateBookingSettings };
|
package/dist/server.js
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/server.ts
|
|
21
21
|
var server_exports = {};
|
|
22
22
|
__export(server_exports, {
|
|
23
|
+
cancelBooking: () => cancelBooking,
|
|
23
24
|
captureServerErrors: () => captureServerErrors,
|
|
24
25
|
configureServerReporter: () => configureServerReporter,
|
|
25
26
|
deleteCall: () => deleteCall,
|
|
@@ -27,9 +28,11 @@ __export(server_exports, {
|
|
|
27
28
|
getBookingSettings: () => getBookingSettings,
|
|
28
29
|
getCall: () => getCall,
|
|
29
30
|
getGuide: () => getGuide,
|
|
31
|
+
listBookings: () => listBookings,
|
|
30
32
|
listCalls: () => listCalls,
|
|
31
33
|
listGuides: () => listGuides,
|
|
32
34
|
reportServerError: () => reportServerError,
|
|
35
|
+
rescheduleBooking: () => rescheduleBooking,
|
|
33
36
|
resetServerReporter: () => resetServerReporter,
|
|
34
37
|
signSession: () => signSession,
|
|
35
38
|
updateBookingSettings: () => updateBookingSettings
|
|
@@ -90,6 +93,7 @@ async function sendReport(payload, baseUrl) {
|
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
// src/server.ts
|
|
96
|
+
var MAX_LOG_CHARS = 2e5;
|
|
93
97
|
var DEV_BLOCKED_MESSAGE = "development";
|
|
94
98
|
function nodeProcess() {
|
|
95
99
|
try {
|
|
@@ -142,6 +146,22 @@ function contextUrl(context) {
|
|
|
142
146
|
if (!context) return void 0;
|
|
143
147
|
return `server://${context.replace(/^\/+/, "")}`;
|
|
144
148
|
}
|
|
149
|
+
function logsAttachment(logs, context) {
|
|
150
|
+
try {
|
|
151
|
+
const text = Array.isArray(logs) ? logs.join("\n") : logs;
|
|
152
|
+
if (!text || !text.trim()) return null;
|
|
153
|
+
const tail = text.length > MAX_LOG_CHARS ? text.slice(-MAX_LOG_CHARS) : text;
|
|
154
|
+
const bytes = new TextEncoder().encode(tail);
|
|
155
|
+
let binary = "";
|
|
156
|
+
for (let i = 0; i < bytes.length; i += 32768) {
|
|
157
|
+
binary += String.fromCharCode(...bytes.subarray(i, i + 32768));
|
|
158
|
+
}
|
|
159
|
+
const name = `${(context != null ? context : "server").replace(/[^a-z0-9._-]+/gi, "-").replace(/^-+|-+$/g, "") || "server"}.log`;
|
|
160
|
+
return JSON.stringify([{ name, dataUrl: `data:text/plain;base64,${btoa(binary)}` }]);
|
|
161
|
+
} catch (e) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
145
165
|
function runtimeMetadata() {
|
|
146
166
|
var _a, _b;
|
|
147
167
|
try {
|
|
@@ -189,6 +209,8 @@ async function reportServerError(error, options = {}) {
|
|
|
189
209
|
...reporter.phone ? { sessionUserPhone: reporter.phone } : {}
|
|
190
210
|
}
|
|
191
211
|
};
|
|
212
|
+
const attachments = logsAttachment(options.logs, context);
|
|
213
|
+
if (attachments && payload.metadata) payload.metadata.attachments = attachments;
|
|
192
214
|
return await sendReport(payload, (_m = (_l = options.baseUrl) != null ? _l : defaults.baseUrl) != null ? _m : readEnv("GLITCHGRAB_BASE_URL"));
|
|
193
215
|
} catch (e) {
|
|
194
216
|
return null;
|
|
@@ -470,7 +492,14 @@ function readBookingSettingsState(value) {
|
|
|
470
492
|
hostAvatarUrl: stringOrNull(s.hostAvatarUrl),
|
|
471
493
|
horizonDays: (_c = numberOrNull(s.horizonDays)) != null ? _c : 15,
|
|
472
494
|
noticeMinutes: (_d = numberOrNull(s.noticeMinutes)) != null ? _d : 120,
|
|
473
|
-
whatsappCode: stringOrNull(s.whatsappCode)
|
|
495
|
+
whatsappCode: stringOrNull(s.whatsappCode),
|
|
496
|
+
notifyRecipients: Array.isArray(s.notifyRecipients) ? s.notifyRecipients.filter(isRecord).map((row) => {
|
|
497
|
+
var _a2, _b2;
|
|
498
|
+
return {
|
|
499
|
+
name: (_a2 = stringOrNull(row.name)) != null ? _a2 : "",
|
|
500
|
+
phone: (_b2 = stringOrNull(row.phone)) != null ? _b2 : ""
|
|
501
|
+
};
|
|
502
|
+
}).filter((row) => row.phone !== "") : []
|
|
474
503
|
},
|
|
475
504
|
saved: value.saved === true,
|
|
476
505
|
calendarConnected: value.calendarConnected === true
|
|
@@ -502,6 +531,85 @@ async function updateBookingSettings(changes, options = {}) {
|
|
|
502
531
|
return { ok: false, error: "Could not save booking settings" };
|
|
503
532
|
}
|
|
504
533
|
}
|
|
534
|
+
function readBooking(value) {
|
|
535
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
536
|
+
if (!isRecord(value) || typeof value.id !== "string") return null;
|
|
537
|
+
return {
|
|
538
|
+
id: value.id,
|
|
539
|
+
name: (_a = stringOrNull(value.name)) != null ? _a : "",
|
|
540
|
+
email: (_b = stringOrNull(value.email)) != null ? _b : "",
|
|
541
|
+
phone: (_c = stringOrNull(value.phone)) != null ? _c : "",
|
|
542
|
+
startsAt: (_d = stringOrNull(value.startsAt)) != null ? _d : "",
|
|
543
|
+
endsAt: (_e = stringOrNull(value.endsAt)) != null ? _e : "",
|
|
544
|
+
timezone: stringOrNull(value.timezone),
|
|
545
|
+
note: stringOrNull(value.note),
|
|
546
|
+
status: (_f = stringOrNull(value.status)) != null ? _f : "CONFIRMED",
|
|
547
|
+
meetUrl: stringOrNull(value.meetUrl),
|
|
548
|
+
createdAt: (_g = stringOrNull(value.createdAt)) != null ? _g : ""
|
|
549
|
+
};
|
|
550
|
+
}
|
|
551
|
+
async function listBookings(options = {}) {
|
|
552
|
+
try {
|
|
553
|
+
const key = callsKey(options);
|
|
554
|
+
if (!key) return [];
|
|
555
|
+
const query = new URLSearchParams();
|
|
556
|
+
if (options.scope === "past") query.set("scope", "past");
|
|
557
|
+
setNumber(query, "limit", options.limit);
|
|
558
|
+
const qs = query.toString();
|
|
559
|
+
const { data } = await callSdkApi(`/api/v1/sdk/bookings${qs ? `?${qs}` : ""}`, key, options, {
|
|
560
|
+
cache: "no-store"
|
|
561
|
+
});
|
|
562
|
+
if (!Array.isArray(data)) return [];
|
|
563
|
+
return data.map(readBooking).filter((booking) => booking !== null);
|
|
564
|
+
} catch (e) {
|
|
565
|
+
return [];
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
function readMutation(data, error) {
|
|
569
|
+
if (error !== null) return { ok: false, error, code: null };
|
|
570
|
+
const record = isRecord(data) ? data : {};
|
|
571
|
+
const notice = stringOrNull(record.clientNotice);
|
|
572
|
+
return {
|
|
573
|
+
ok: true,
|
|
574
|
+
booking: readBooking(record.booking),
|
|
575
|
+
clientNotice: notice === "sent" || notice === "attempted" ? notice : "none"
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
async function rescheduleBooking(id, startsAt, options = {}) {
|
|
579
|
+
try {
|
|
580
|
+
const wanted = typeof id === "string" ? id.trim() : "";
|
|
581
|
+
const key = callsKey(options);
|
|
582
|
+
if (!wanted) return { ok: false, error: "No booking id", code: null };
|
|
583
|
+
if (!key) return { ok: false, error: NO_KEY_ERROR, code: null };
|
|
584
|
+
const when = startsAt instanceof Date ? startsAt.toISOString() : String(startsAt);
|
|
585
|
+
const { data, error } = await callSdkApi(
|
|
586
|
+
`/api/v1/sdk/bookings?id=${encodeURIComponent(wanted)}`,
|
|
587
|
+
key,
|
|
588
|
+
options,
|
|
589
|
+
{ method: "PATCH", body: { startsAt: when }, cache: "no-store" }
|
|
590
|
+
);
|
|
591
|
+
return readMutation(data, error);
|
|
592
|
+
} catch (e) {
|
|
593
|
+
return { ok: false, error: "Could not move that demo", code: null };
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
async function cancelBooking(id, reason, options = {}) {
|
|
597
|
+
try {
|
|
598
|
+
const wanted = typeof id === "string" ? id.trim() : "";
|
|
599
|
+
const key = callsKey(options);
|
|
600
|
+
if (!wanted) return { ok: false, error: "No booking id", code: null };
|
|
601
|
+
if (!key) return { ok: false, error: NO_KEY_ERROR, code: null };
|
|
602
|
+
const query = new URLSearchParams({ id: wanted });
|
|
603
|
+
if (typeof reason === "string" && reason.trim()) query.set("reason", reason.trim().slice(0, 200));
|
|
604
|
+
const { data, error } = await callSdkApi(`/api/v1/sdk/bookings?${query.toString()}`, key, options, {
|
|
605
|
+
method: "DELETE",
|
|
606
|
+
cache: "no-store"
|
|
607
|
+
});
|
|
608
|
+
return readMutation(data, error);
|
|
609
|
+
} catch (e) {
|
|
610
|
+
return { ok: false, error: "Could not cancel that demo", code: null };
|
|
611
|
+
}
|
|
612
|
+
}
|
|
505
613
|
function escapeJsonForScript(value) {
|
|
506
614
|
try {
|
|
507
615
|
const json = JSON.stringify(value);
|
|
@@ -513,6 +621,7 @@ function escapeJsonForScript(value) {
|
|
|
513
621
|
}
|
|
514
622
|
// Annotate the CommonJS export names for ESM import in node:
|
|
515
623
|
0 && (module.exports = {
|
|
624
|
+
cancelBooking,
|
|
516
625
|
captureServerErrors,
|
|
517
626
|
configureServerReporter,
|
|
518
627
|
deleteCall,
|
|
@@ -520,9 +629,11 @@ function escapeJsonForScript(value) {
|
|
|
520
629
|
getBookingSettings,
|
|
521
630
|
getCall,
|
|
522
631
|
getGuide,
|
|
632
|
+
listBookings,
|
|
523
633
|
listCalls,
|
|
524
634
|
listGuides,
|
|
525
635
|
reportServerError,
|
|
636
|
+
rescheduleBooking,
|
|
526
637
|
resetServerReporter,
|
|
527
638
|
signSession,
|
|
528
639
|
updateBookingSettings
|