glitchgrab 1.56.0 → 1.58.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/dist/server.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { k as ReportType, j as ReportSeverity, i as ReportResult } from './types-DcDF1mXc.mjs';
1
+ import { l as ReportType, k as ReportSeverity, j as ReportResult } from './types-DfVtKZcp.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. */
@@ -375,6 +375,44 @@ interface BookingSettings {
375
375
  * change it; leave the field out and it keeps what is stored.
376
376
  */
377
377
  notifyRecipients: BookingNotifyRecipient[];
378
+ /**
379
+ * What a prospect is asked before they see the calendar — in the booking
380
+ * dialog and over WhatsApp — so the right person takes the demo. At most 5.
381
+ * Send the whole list to change it (`[]` asks nothing); leave the field out
382
+ * and it keeps what is stored. The answers come back on {@link Booking.answers}.
383
+ */
384
+ questions: BookingQuestion[];
385
+ }
386
+ /** One question asked before a demo is booked. The prospect taps one of `options`. */
387
+ interface BookingQuestion {
388
+ /**
389
+ * Stable name for the question, e.g. `"language"` — lower case letters,
390
+ * digits, `-` and `_`. Leave it out on a new question and one is made from
391
+ * the label; keep it when rewording so earlier answers still line up.
392
+ */
393
+ id: string;
394
+ /** What is asked, up to 80 characters. */
395
+ label: string;
396
+ /** 2–9 choices, up to 40 characters each. */
397
+ options: string[];
398
+ /** False lets the prospect skip it. */
399
+ required: boolean;
400
+ }
401
+ /** A question as you send it: `id` and `required` may be left out on a new one. */
402
+ type BookingQuestionInput = Omit<BookingQuestion, "id" | "required"> & {
403
+ id?: string;
404
+ required?: boolean;
405
+ };
406
+ /** What {@link updateBookingSettings} accepts — any subset of the settings. */
407
+ type BookingSettingsChanges = Partial<Omit<BookingSettings, "questions">> & {
408
+ questions?: BookingQuestionInput[];
409
+ };
410
+ /** One answer a prospect gave, with the question as it was worded when they booked. */
411
+ interface BookingAnswer {
412
+ /** The {@link BookingQuestion.id} it answers. */
413
+ id: string;
414
+ question: string;
415
+ answer: string;
378
416
  }
379
417
  /** One extra person alerted when a demo is booked. */
380
418
  interface BookingNotifyRecipient {
@@ -414,7 +452,7 @@ declare function getBookingSettings(options?: CallsOptions): Promise<BookingSett
414
452
  * `error` is worth showing: a WhatsApp code already taken by another project
415
453
  * comes back as one.
416
454
  */
417
- declare function updateBookingSettings(changes: Partial<BookingSettings>, options?: CallsOptions): Promise<BookingSettingsResult>;
455
+ declare function updateBookingSettings(changes: BookingSettingsChanges, options?: CallsOptions): Promise<BookingSettingsResult>;
418
456
  /** One booked demo. Times are ISO strings in UTC; `timezone` is what the prospect picked in. */
419
457
  interface Booking {
420
458
  id: string;
@@ -429,6 +467,8 @@ interface Booking {
429
467
  timezone: string | null;
430
468
  /** What they typed when booking, if anything. */
431
469
  note: string | null;
470
+ /** What they answered to the project's {@link BookingSettings.questions}. Empty when nothing was asked. */
471
+ answers: BookingAnswer[];
432
472
  /** `CONFIRMED` or `CANCELLED`. Unverified holds are never returned. */
433
473
  status: string;
434
474
  /** The Google Meet room. Null until the booking is confirmed. */
@@ -506,5 +546,49 @@ declare function cancelBooking(id: string, reason?: string, options?: CallsOptio
506
546
  * Never throws: a value JSON cannot represent (circular, `undefined`) becomes `null`.
507
547
  */
508
548
  declare function escapeJsonForScript(value: unknown): string;
549
+ /** One lead. One per phone number per project; a repeat submission updates it. */
550
+ interface Lead {
551
+ id: string;
552
+ name: string;
553
+ /** Digits only, country code included. */
554
+ phone: string;
555
+ email: string | null;
556
+ company: string | null;
557
+ address: string | null;
558
+ /** What your form passed as `source`, e.g. `"demo"`. */
559
+ source: string;
560
+ metadata: Record<string, string | number | boolean> | null;
561
+ /** The page the lead was left on. */
562
+ pageUrl: string | null;
563
+ /** How many times this phone submitted. */
564
+ submissions: number;
565
+ /** First submission. */
566
+ createdAt: string;
567
+ /** Latest submission. */
568
+ updatedAt: string;
569
+ /** The demo this lead went on to book, matched by phone or email. */
570
+ booking: {
571
+ id: string;
572
+ startsAt: string;
573
+ status: string;
574
+ } | null;
575
+ }
576
+ interface ListLeadsOptions extends CallsOptions {
577
+ /** Only leads with this `source`. */
578
+ source?: string;
579
+ /** Only leads first left at or after this time. */
580
+ since?: Date | string;
581
+ /** Up to 200. Defaults to 100. */
582
+ limit?: number;
583
+ }
584
+ /**
585
+ * The project's leads, newest first. Never throws — an empty list on any
586
+ * failure.
587
+ *
588
+ * ```ts
589
+ * const leads = await listLeads({ source: "demo" }); // GLITCHGRAB_CALLS_KEY=ggc_…
590
+ * ```
591
+ */
592
+ declare function listLeads(options?: ListLeadsOptions): Promise<Lead[]>;
509
593
 
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 };
594
+ 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 };
package/dist/server.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { k as ReportType, j as ReportSeverity, i as ReportResult } from './types-DcDF1mXc.js';
1
+ import { l as ReportType, k as ReportSeverity, j as ReportResult } from './types-DfVtKZcp.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. */
@@ -375,6 +375,44 @@ interface BookingSettings {
375
375
  * change it; leave the field out and it keeps what is stored.
376
376
  */
377
377
  notifyRecipients: BookingNotifyRecipient[];
378
+ /**
379
+ * What a prospect is asked before they see the calendar — in the booking
380
+ * dialog and over WhatsApp — so the right person takes the demo. At most 5.
381
+ * Send the whole list to change it (`[]` asks nothing); leave the field out
382
+ * and it keeps what is stored. The answers come back on {@link Booking.answers}.
383
+ */
384
+ questions: BookingQuestion[];
385
+ }
386
+ /** One question asked before a demo is booked. The prospect taps one of `options`. */
387
+ interface BookingQuestion {
388
+ /**
389
+ * Stable name for the question, e.g. `"language"` — lower case letters,
390
+ * digits, `-` and `_`. Leave it out on a new question and one is made from
391
+ * the label; keep it when rewording so earlier answers still line up.
392
+ */
393
+ id: string;
394
+ /** What is asked, up to 80 characters. */
395
+ label: string;
396
+ /** 2–9 choices, up to 40 characters each. */
397
+ options: string[];
398
+ /** False lets the prospect skip it. */
399
+ required: boolean;
400
+ }
401
+ /** A question as you send it: `id` and `required` may be left out on a new one. */
402
+ type BookingQuestionInput = Omit<BookingQuestion, "id" | "required"> & {
403
+ id?: string;
404
+ required?: boolean;
405
+ };
406
+ /** What {@link updateBookingSettings} accepts — any subset of the settings. */
407
+ type BookingSettingsChanges = Partial<Omit<BookingSettings, "questions">> & {
408
+ questions?: BookingQuestionInput[];
409
+ };
410
+ /** One answer a prospect gave, with the question as it was worded when they booked. */
411
+ interface BookingAnswer {
412
+ /** The {@link BookingQuestion.id} it answers. */
413
+ id: string;
414
+ question: string;
415
+ answer: string;
378
416
  }
379
417
  /** One extra person alerted when a demo is booked. */
380
418
  interface BookingNotifyRecipient {
@@ -414,7 +452,7 @@ declare function getBookingSettings(options?: CallsOptions): Promise<BookingSett
414
452
  * `error` is worth showing: a WhatsApp code already taken by another project
415
453
  * comes back as one.
416
454
  */
417
- declare function updateBookingSettings(changes: Partial<BookingSettings>, options?: CallsOptions): Promise<BookingSettingsResult>;
455
+ declare function updateBookingSettings(changes: BookingSettingsChanges, options?: CallsOptions): Promise<BookingSettingsResult>;
418
456
  /** One booked demo. Times are ISO strings in UTC; `timezone` is what the prospect picked in. */
419
457
  interface Booking {
420
458
  id: string;
@@ -429,6 +467,8 @@ interface Booking {
429
467
  timezone: string | null;
430
468
  /** What they typed when booking, if anything. */
431
469
  note: string | null;
470
+ /** What they answered to the project's {@link BookingSettings.questions}. Empty when nothing was asked. */
471
+ answers: BookingAnswer[];
432
472
  /** `CONFIRMED` or `CANCELLED`. Unverified holds are never returned. */
433
473
  status: string;
434
474
  /** The Google Meet room. Null until the booking is confirmed. */
@@ -506,5 +546,49 @@ declare function cancelBooking(id: string, reason?: string, options?: CallsOptio
506
546
  * Never throws: a value JSON cannot represent (circular, `undefined`) becomes `null`.
507
547
  */
508
548
  declare function escapeJsonForScript(value: unknown): string;
549
+ /** One lead. One per phone number per project; a repeat submission updates it. */
550
+ interface Lead {
551
+ id: string;
552
+ name: string;
553
+ /** Digits only, country code included. */
554
+ phone: string;
555
+ email: string | null;
556
+ company: string | null;
557
+ address: string | null;
558
+ /** What your form passed as `source`, e.g. `"demo"`. */
559
+ source: string;
560
+ metadata: Record<string, string | number | boolean> | null;
561
+ /** The page the lead was left on. */
562
+ pageUrl: string | null;
563
+ /** How many times this phone submitted. */
564
+ submissions: number;
565
+ /** First submission. */
566
+ createdAt: string;
567
+ /** Latest submission. */
568
+ updatedAt: string;
569
+ /** The demo this lead went on to book, matched by phone or email. */
570
+ booking: {
571
+ id: string;
572
+ startsAt: string;
573
+ status: string;
574
+ } | null;
575
+ }
576
+ interface ListLeadsOptions extends CallsOptions {
577
+ /** Only leads with this `source`. */
578
+ source?: string;
579
+ /** Only leads first left at or after this time. */
580
+ since?: Date | string;
581
+ /** Up to 200. Defaults to 100. */
582
+ limit?: number;
583
+ }
584
+ /**
585
+ * The project's leads, newest first. Never throws — an empty list on any
586
+ * failure.
587
+ *
588
+ * ```ts
589
+ * const leads = await listLeads({ source: "demo" }); // GLITCHGRAB_CALLS_KEY=ggc_…
590
+ * ```
591
+ */
592
+ declare function listLeads(options?: ListLeadsOptions): Promise<Lead[]>;
509
593
 
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 };
594
+ 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 };
package/dist/server.js CHANGED
@@ -31,6 +31,7 @@ __export(server_exports, {
31
31
  listBookings: () => listBookings,
32
32
  listCalls: () => listCalls,
33
33
  listGuides: () => listGuides,
34
+ listLeads: () => listLeads,
34
35
  reportServerError: () => reportServerError,
35
36
  rescheduleBooking: () => rescheduleBooking,
36
37
  resetServerReporter: () => resetServerReporter,
@@ -499,7 +500,16 @@ function readBookingSettingsState(value) {
499
500
  name: (_a2 = stringOrNull(row.name)) != null ? _a2 : "",
500
501
  phone: (_b2 = stringOrNull(row.phone)) != null ? _b2 : ""
501
502
  };
502
- }).filter((row) => row.phone !== "") : []
503
+ }).filter((row) => row.phone !== "") : [],
504
+ questions: Array.isArray(s.questions) ? s.questions.filter(isRecord).map((row) => {
505
+ var _a2, _b2;
506
+ return {
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 !== "") : []
503
513
  },
504
514
  saved: value.saved === true,
505
515
  calendarConnected: value.calendarConnected === true
@@ -543,6 +553,14 @@ function readBooking(value) {
543
553
  endsAt: (_e = stringOrNull(value.endsAt)) != null ? _e : "",
544
554
  timezone: stringOrNull(value.timezone),
545
555
  note: stringOrNull(value.note),
556
+ answers: Array.isArray(value.answers) ? value.answers.filter(isRecord).map((row) => {
557
+ var _a2, _b2, _c2;
558
+ return {
559
+ id: (_a2 = stringOrNull(row.id)) != null ? _a2 : "",
560
+ question: (_b2 = stringOrNull(row.question)) != null ? _b2 : "",
561
+ answer: (_c2 = stringOrNull(row.answer)) != null ? _c2 : ""
562
+ };
563
+ }).filter((row) => row.answer !== "") : [],
546
564
  status: (_f = stringOrNull(value.status)) != null ? _f : "CONFIRMED",
547
565
  meetUrl: stringOrNull(value.meetUrl),
548
566
  createdAt: (_g = stringOrNull(value.createdAt)) != null ? _g : ""
@@ -619,6 +637,52 @@ function escapeJsonForScript(value) {
619
637
  return "null";
620
638
  }
621
639
  }
640
+ function readLead(value) {
641
+ var _a, _b, _c, _d, _e, _f, _g;
642
+ if (!isRecord(value) || typeof value.id !== "string") return null;
643
+ const metadata = isRecord(value.metadata) ? value.metadata : null;
644
+ const booking = isRecord(value.booking) && typeof value.booking.id === "string" ? {
645
+ id: value.booking.id,
646
+ startsAt: (_a = stringOrNull(value.booking.startsAt)) != null ? _a : "",
647
+ status: (_b = stringOrNull(value.booking.status)) != null ? _b : "CONFIRMED"
648
+ } : null;
649
+ return {
650
+ id: value.id,
651
+ name: (_c = stringOrNull(value.name)) != null ? _c : "",
652
+ phone: (_d = stringOrNull(value.phone)) != null ? _d : "",
653
+ email: stringOrNull(value.email),
654
+ company: stringOrNull(value.company),
655
+ address: stringOrNull(value.address),
656
+ source: (_e = stringOrNull(value.source)) != null ? _e : "",
657
+ metadata,
658
+ pageUrl: stringOrNull(value.pageUrl),
659
+ submissions: typeof value.submissions === "number" ? value.submissions : 1,
660
+ createdAt: (_f = stringOrNull(value.createdAt)) != null ? _f : "",
661
+ updatedAt: (_g = stringOrNull(value.updatedAt)) != null ? _g : "",
662
+ booking
663
+ };
664
+ }
665
+ async function listLeads(options = {}) {
666
+ try {
667
+ const key = callsKey(options);
668
+ if (!key) return [];
669
+ const query = new URLSearchParams();
670
+ if (options.source) query.set("source", options.source);
671
+ if (options.since) {
672
+ const since = options.since instanceof Date ? options.since : new Date(options.since);
673
+ if (!Number.isNaN(since.getTime())) query.set("since", since.toISOString());
674
+ }
675
+ setNumber(query, "limit", options.limit);
676
+ const qs = query.toString();
677
+ const { data } = await callSdkApi(`/api/v1/sdk/leads${qs ? `?${qs}` : ""}`, key, options, {
678
+ cache: "no-store"
679
+ });
680
+ if (!Array.isArray(data)) return [];
681
+ return data.map(readLead).filter((lead) => lead !== null);
682
+ } catch (e) {
683
+ return [];
684
+ }
685
+ }
622
686
  // Annotate the CommonJS export names for ESM import in node:
623
687
  0 && (module.exports = {
624
688
  cancelBooking,
@@ -632,6 +696,7 @@ function escapeJsonForScript(value) {
632
696
  listBookings,
633
697
  listCalls,
634
698
  listGuides,
699
+ listLeads,
635
700
  reportServerError,
636
701
  rescheduleBooking,
637
702
  resetServerReporter,