@contractspec/integration.providers-impls 1.56.1 → 1.57.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 +115 -1
- package/dist/_virtual/{rolldown_runtime.js → _rolldown/runtime.js} +3 -3
- package/dist/analytics.d.ts +9 -0
- package/dist/analytics.d.ts.map +1 -0
- package/dist/analytics.js +3 -0
- package/dist/calendar.d.ts +1 -0
- package/dist/calendar.d.ts.map +1 -1
- package/dist/calendar.js +1 -1
- package/dist/database.d.ts +9 -0
- package/dist/database.d.ts.map +1 -0
- package/dist/database.js +3 -0
- package/dist/email.d.ts +1 -0
- package/dist/email.d.ts.map +1 -1
- package/dist/email.js +1 -1
- package/dist/embedding.d.ts +1 -0
- package/dist/embedding.d.ts.map +1 -1
- package/dist/embedding.js +1 -1
- package/dist/impls/elevenlabs-voice.d.ts.map +1 -1
- package/dist/impls/fal-voice.d.ts +29 -0
- package/dist/impls/fal-voice.d.ts.map +1 -0
- package/dist/impls/fal-voice.js +88 -0
- package/dist/impls/fal-voice.js.map +1 -0
- package/dist/impls/fathom-meeting-recorder.d.ts +42 -0
- package/dist/impls/fathom-meeting-recorder.d.ts.map +1 -0
- package/dist/impls/fathom-meeting-recorder.js +145 -0
- package/dist/impls/fathom-meeting-recorder.js.map +1 -0
- package/dist/impls/fathom-meeting-recorder.mapper.d.ts +9 -0
- package/dist/impls/fathom-meeting-recorder.mapper.d.ts.map +1 -0
- package/dist/impls/fathom-meeting-recorder.mapper.js +42 -0
- package/dist/impls/fathom-meeting-recorder.mapper.js.map +1 -0
- package/dist/impls/fathom-meeting-recorder.types.d.ts +24 -0
- package/dist/impls/fathom-meeting-recorder.types.d.ts.map +1 -0
- package/dist/impls/fathom-meeting-recorder.types.js +0 -0
- package/dist/impls/fathom-meeting-recorder.utils.d.ts +15 -0
- package/dist/impls/fathom-meeting-recorder.utils.d.ts.map +1 -0
- package/dist/impls/fathom-meeting-recorder.utils.js +56 -0
- package/dist/impls/fathom-meeting-recorder.utils.js.map +1 -0
- package/dist/impls/fathom-meeting-recorder.webhooks.d.ts +8 -0
- package/dist/impls/fathom-meeting-recorder.webhooks.d.ts.map +1 -0
- package/dist/impls/fathom-meeting-recorder.webhooks.js +25 -0
- package/dist/impls/fathom-meeting-recorder.webhooks.js.map +1 -0
- package/dist/impls/fireflies-meeting-recorder.d.ts +28 -0
- package/dist/impls/fireflies-meeting-recorder.d.ts.map +1 -0
- package/dist/impls/fireflies-meeting-recorder.js +152 -0
- package/dist/impls/fireflies-meeting-recorder.js.map +1 -0
- package/dist/impls/fireflies-meeting-recorder.queries.d.ts +7 -0
- package/dist/impls/fireflies-meeting-recorder.queries.d.ts.map +1 -0
- package/dist/impls/fireflies-meeting-recorder.queries.js +84 -0
- package/dist/impls/fireflies-meeting-recorder.queries.js.map +1 -0
- package/dist/impls/fireflies-meeting-recorder.types.d.ts +35 -0
- package/dist/impls/fireflies-meeting-recorder.types.d.ts.map +1 -0
- package/dist/impls/fireflies-meeting-recorder.types.js +0 -0
- package/dist/impls/fireflies-meeting-recorder.utils.d.ts +8 -0
- package/dist/impls/fireflies-meeting-recorder.utils.d.ts.map +1 -0
- package/dist/impls/fireflies-meeting-recorder.utils.js +36 -0
- package/dist/impls/fireflies-meeting-recorder.utils.js.map +1 -0
- package/dist/impls/gcs-storage.d.ts.map +1 -1
- package/dist/impls/gmail-inbound.d.ts.map +1 -1
- package/dist/impls/gmail-outbound.d.ts.map +1 -1
- package/dist/impls/google-calendar.d.ts.map +1 -1
- package/dist/impls/gradium-voice.d.ts +26 -0
- package/dist/impls/gradium-voice.d.ts.map +1 -0
- package/dist/impls/gradium-voice.js +80 -0
- package/dist/impls/gradium-voice.js.map +1 -0
- package/dist/impls/granola-meeting-recorder.d.ts +27 -0
- package/dist/impls/granola-meeting-recorder.d.ts.map +1 -0
- package/dist/impls/granola-meeting-recorder.js +145 -0
- package/dist/impls/granola-meeting-recorder.js.map +1 -0
- package/dist/impls/granola-meeting-recorder.types.d.ts +50 -0
- package/dist/impls/granola-meeting-recorder.types.d.ts.map +1 -0
- package/dist/impls/granola-meeting-recorder.types.js +0 -0
- package/dist/impls/index.d.ts +15 -2
- package/dist/impls/index.js +18 -5
- package/dist/impls/jira.d.ts +25 -0
- package/dist/impls/jira.d.ts.map +1 -0
- package/dist/impls/jira.js +114 -0
- package/dist/impls/jira.js.map +1 -0
- package/dist/impls/linear.d.ts +24 -0
- package/dist/impls/linear.d.ts.map +1 -0
- package/dist/impls/linear.js +75 -0
- package/dist/impls/linear.js.map +1 -0
- package/dist/impls/mistral-embedding.d.ts.map +1 -1
- package/dist/impls/mistral-llm.d.ts.map +1 -1
- package/dist/impls/notion.d.ts +27 -0
- package/dist/impls/notion.d.ts.map +1 -0
- package/dist/impls/notion.js +126 -0
- package/dist/impls/notion.js.map +1 -0
- package/dist/impls/posthog-reader.d.ts +26 -0
- package/dist/impls/posthog-reader.d.ts.map +1 -0
- package/dist/impls/posthog-reader.js +141 -0
- package/dist/impls/posthog-reader.js.map +1 -0
- package/dist/impls/posthog-utils.d.ts +8 -0
- package/dist/impls/posthog-utils.d.ts.map +1 -0
- package/dist/impls/posthog-utils.js +30 -0
- package/dist/impls/posthog-utils.js.map +1 -0
- package/dist/impls/posthog.d.ts +40 -0
- package/dist/impls/posthog.d.ts.map +1 -0
- package/dist/impls/posthog.js +122 -0
- package/dist/impls/posthog.js.map +1 -0
- package/dist/impls/postmark-email.d.ts.map +1 -1
- package/dist/impls/powens-client.d.ts.map +1 -1
- package/dist/impls/powens-openbanking.d.ts +1 -1
- package/dist/impls/powens-openbanking.d.ts.map +1 -1
- package/dist/impls/provider-factory.d.ts +10 -2
- package/dist/impls/provider-factory.d.ts.map +1 -1
- package/dist/impls/provider-factory.js +143 -2
- package/dist/impls/provider-factory.js.map +1 -1
- package/dist/impls/qdrant-vector.d.ts.map +1 -1
- package/dist/impls/stripe-payments.d.ts.map +1 -1
- package/dist/impls/supabase-psql.d.ts +28 -0
- package/dist/impls/supabase-psql.d.ts.map +1 -0
- package/dist/impls/supabase-psql.js +111 -0
- package/dist/impls/supabase-psql.js.map +1 -0
- package/dist/impls/supabase-vector.d.ts +36 -0
- package/dist/impls/supabase-vector.d.ts.map +1 -0
- package/dist/impls/supabase-vector.js +149 -0
- package/dist/impls/supabase-vector.js.map +1 -0
- package/dist/impls/tldv-meeting-recorder.d.ts +25 -0
- package/dist/impls/tldv-meeting-recorder.d.ts.map +1 -0
- package/dist/impls/tldv-meeting-recorder.js +131 -0
- package/dist/impls/tldv-meeting-recorder.js.map +1 -0
- package/dist/impls/twilio-sms.d.ts.map +1 -1
- package/dist/index.d.ts +29 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -6
- package/dist/index.js.map +1 -1
- package/dist/llm.d.ts +1 -0
- package/dist/llm.d.ts.map +1 -1
- package/dist/llm.js +1 -1
- package/dist/meeting-recorder.d.ts +9 -0
- package/dist/meeting-recorder.d.ts.map +1 -0
- package/dist/meeting-recorder.js +3 -0
- package/dist/openbanking.d.ts +1 -0
- package/dist/openbanking.d.ts.map +1 -1
- package/dist/openbanking.js +1 -1
- package/dist/payments.d.ts +1 -0
- package/dist/payments.d.ts.map +1 -1
- package/dist/payments.js +1 -1
- package/dist/project-management.d.ts +9 -0
- package/dist/project-management.d.ts.map +1 -0
- package/dist/project-management.js +3 -0
- package/dist/sms.d.ts +1 -0
- package/dist/sms.d.ts.map +1 -1
- package/dist/sms.js +1 -1
- package/dist/storage.d.ts +1 -0
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +1 -1
- package/dist/vector-store.d.ts +1 -0
- package/dist/vector-store.d.ts.map +1 -1
- package/dist/vector-store.js +1 -1
- package/dist/voice.d.ts +1 -0
- package/dist/voice.d.ts.map +1 -1
- package/dist/voice.js +1 -1
- package/package.json +64 -12
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { durationSeconds } from "./fathom-meeting-recorder.utils.js";
|
|
2
|
+
|
|
3
|
+
//#region src/impls/fathom-meeting-recorder.mapper.ts
|
|
4
|
+
const mapFathomMeetingInvites = (invitees) => {
|
|
5
|
+
return invitees.map((invitee) => ({
|
|
6
|
+
...invitee,
|
|
7
|
+
name: invitee.name ?? void 0,
|
|
8
|
+
email: invitee.email ?? void 0
|
|
9
|
+
}));
|
|
10
|
+
};
|
|
11
|
+
function mapFathomMeeting(meeting, params) {
|
|
12
|
+
const connectionId = params.connectionId ?? "unknown";
|
|
13
|
+
return {
|
|
14
|
+
id: meeting.recordingId.toString(),
|
|
15
|
+
tenantId: params.tenantId,
|
|
16
|
+
connectionId,
|
|
17
|
+
externalId: meeting.recordingId.toString(),
|
|
18
|
+
title: meeting.title ?? meeting.meetingTitle,
|
|
19
|
+
organizer: meeting.recordedBy ? {
|
|
20
|
+
name: meeting.recordedBy.name ?? void 0,
|
|
21
|
+
email: meeting.recordedBy.email ?? void 0,
|
|
22
|
+
role: "organizer"
|
|
23
|
+
} : void 0,
|
|
24
|
+
invitees: meeting.calendarInvitees.length ? mapFathomMeetingInvites(meeting.calendarInvitees) : void 0,
|
|
25
|
+
participants: meeting.calendarInvitees.length ? mapFathomMeetingInvites(meeting.calendarInvitees) : void 0,
|
|
26
|
+
scheduledStartAt: meeting.scheduledStartTime?.toISOString(),
|
|
27
|
+
scheduledEndAt: meeting.scheduledEndTime?.toISOString(),
|
|
28
|
+
recordingStartAt: meeting.recordingStartTime?.toISOString(),
|
|
29
|
+
recordingEndAt: meeting.recordingEndTime?.toISOString(),
|
|
30
|
+
durationSeconds: durationSeconds(meeting.recordingStartTime, meeting.recordingEndTime),
|
|
31
|
+
meetingUrl: meeting.url ?? void 0,
|
|
32
|
+
shareUrl: meeting.shareUrl ?? void 0,
|
|
33
|
+
transcriptAvailable: Array.isArray(meeting.transcript),
|
|
34
|
+
sourcePlatform: "fathom",
|
|
35
|
+
language: meeting.transcriptLanguage,
|
|
36
|
+
metadata: { calendarInviteesDomainsType: meeting.calendarInviteesDomainsType }
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//#endregion
|
|
41
|
+
export { mapFathomMeeting, mapFathomMeetingInvites };
|
|
42
|
+
//# sourceMappingURL=fathom-meeting-recorder.mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fathom-meeting-recorder.mapper.js","names":[],"sources":["../../src/impls/fathom-meeting-recorder.mapper.ts"],"sourcesContent":["import type {\n MeetingParticipant,\n MeetingRecord,\n MeetingRecorderGetMeetingParams,\n MeetingRecorderListMeetingsParams,\n} from '../meeting-recorder';\nimport type {\n FathomMeeting,\n FathomMeetingInvitee,\n} from './fathom-meeting-recorder.types';\nimport { durationSeconds } from './fathom-meeting-recorder.utils';\n\nexport const mapFathomMeetingInvites = (\n invitees: FathomMeetingInvitee[]\n): MeetingParticipant[] => {\n return invitees.map((invitee) => ({\n ...invitee,\n name: invitee.name ?? undefined,\n email: invitee.email ?? undefined,\n }));\n};\n\nexport function mapFathomMeeting(\n meeting: FathomMeeting,\n params: MeetingRecorderListMeetingsParams | MeetingRecorderGetMeetingParams\n): MeetingRecord {\n const connectionId = params.connectionId ?? 'unknown';\n return {\n id: meeting.recordingId.toString(),\n tenantId: params.tenantId,\n connectionId,\n externalId: meeting.recordingId.toString(),\n title: meeting.title ?? meeting.meetingTitle,\n organizer: meeting.recordedBy\n ? {\n name: meeting.recordedBy.name ?? undefined,\n email: meeting.recordedBy.email ?? undefined,\n role: 'organizer',\n }\n : undefined,\n invitees: meeting.calendarInvitees.length\n ? mapFathomMeetingInvites(meeting.calendarInvitees)\n : undefined,\n participants: meeting.calendarInvitees.length\n ? mapFathomMeetingInvites(meeting.calendarInvitees)\n : undefined,\n scheduledStartAt: meeting.scheduledStartTime?.toISOString(),\n scheduledEndAt: meeting.scheduledEndTime?.toISOString(),\n recordingStartAt: meeting.recordingStartTime?.toISOString(),\n recordingEndAt: meeting.recordingEndTime?.toISOString(),\n durationSeconds: durationSeconds(\n meeting.recordingStartTime,\n meeting.recordingEndTime\n ),\n meetingUrl: meeting.url ?? undefined,\n shareUrl: meeting.shareUrl ?? undefined,\n transcriptAvailable: Array.isArray(meeting.transcript),\n sourcePlatform: 'fathom',\n language: meeting.transcriptLanguage,\n metadata: {\n calendarInviteesDomainsType: meeting.calendarInviteesDomainsType,\n },\n };\n}\n"],"mappings":";;;AAYA,MAAa,2BACX,aACyB;AACzB,QAAO,SAAS,KAAK,aAAa;EAChC,GAAG;EACH,MAAM,QAAQ,QAAQ;EACtB,OAAO,QAAQ,SAAS;EACzB,EAAE;;AAGL,SAAgB,iBACd,SACA,QACe;CACf,MAAM,eAAe,OAAO,gBAAgB;AAC5C,QAAO;EACL,IAAI,QAAQ,YAAY,UAAU;EAClC,UAAU,OAAO;EACjB;EACA,YAAY,QAAQ,YAAY,UAAU;EAC1C,OAAO,QAAQ,SAAS,QAAQ;EAChC,WAAW,QAAQ,aACf;GACE,MAAM,QAAQ,WAAW,QAAQ;GACjC,OAAO,QAAQ,WAAW,SAAS;GACnC,MAAM;GACP,GACD;EACJ,UAAU,QAAQ,iBAAiB,SAC/B,wBAAwB,QAAQ,iBAAiB,GACjD;EACJ,cAAc,QAAQ,iBAAiB,SACnC,wBAAwB,QAAQ,iBAAiB,GACjD;EACJ,kBAAkB,QAAQ,oBAAoB,aAAa;EAC3D,gBAAgB,QAAQ,kBAAkB,aAAa;EACvD,kBAAkB,QAAQ,oBAAoB,aAAa;EAC3D,gBAAgB,QAAQ,kBAAkB,aAAa;EACvD,iBAAiB,gBACf,QAAQ,oBACR,QAAQ,iBACT;EACD,YAAY,QAAQ,OAAO;EAC3B,UAAU,QAAQ,YAAY;EAC9B,qBAAqB,MAAM,QAAQ,QAAQ,WAAW;EACtD,gBAAgB;EAChB,UAAU,QAAQ;EAClB,UAAU,EACR,6BAA6B,QAAQ,6BACtC;EACF"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Invitee, Meeting } from "fathom-typescript/sdk/models/shared";
|
|
2
|
+
|
|
3
|
+
//#region src/impls/fathom-meeting-recorder.types.d.ts
|
|
4
|
+
type FathomMeeting = Meeting;
|
|
5
|
+
type FathomMeetingInvitee = Invitee;
|
|
6
|
+
interface FathomMeetingListPage {
|
|
7
|
+
items?: FathomMeeting[];
|
|
8
|
+
nextCursor?: string | null;
|
|
9
|
+
next_cursor?: string | null;
|
|
10
|
+
}
|
|
11
|
+
interface FathomTranscriptResponse {
|
|
12
|
+
transcript?: FathomTranscriptSegment[];
|
|
13
|
+
}
|
|
14
|
+
interface FathomTranscriptSegment {
|
|
15
|
+
speaker?: {
|
|
16
|
+
display_name?: string;
|
|
17
|
+
matched_calendar_invitee_email?: string;
|
|
18
|
+
};
|
|
19
|
+
text: string;
|
|
20
|
+
timestamp: string;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
export { FathomMeeting, FathomMeetingInvitee, FathomMeetingListPage, FathomTranscriptResponse, FathomTranscriptSegment };
|
|
24
|
+
//# sourceMappingURL=fathom-meeting-recorder.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fathom-meeting-recorder.types.d.ts","names":[],"sources":["../../src/impls/fathom-meeting-recorder.types.ts"],"mappings":";;;KAEY,aAAA,GAAgB,OAAA;AAAA,KAChB,oBAAA,GAAuB,OAAA;AAAA,UAElB,qBAAA;EACf,KAAA,GAAQ,aAAA;EACR,UAAA;EACA,WAAA;AAAA;AAAA,UAGe,wBAAA;EACf,UAAA,GAAa,uBAAA;AAAA;AAAA,UAGE,uBAAA;EACf,OAAA;IAAY,YAAA;IAAuB,8BAAA;EAAA;EACnC,IAAA;EACA,SAAA;AAAA"}
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { meeting_recorder_d_exports } from "../meeting-recorder.js";
|
|
2
|
+
import { FathomMeeting, FathomMeetingListPage, FathomTranscriptSegment } from "./fathom-meeting-recorder.types.js";
|
|
3
|
+
|
|
4
|
+
//#region src/impls/fathom-meeting-recorder.utils.d.ts
|
|
5
|
+
declare function extractItems(page: FathomMeetingListPage): FathomMeeting[];
|
|
6
|
+
declare function extractNextCursor(page: FathomMeetingListPage): string | null | undefined;
|
|
7
|
+
declare function mapInvitee(invitee: Record<string, unknown>): meeting_recorder_d_exports.MeetingParticipant | undefined;
|
|
8
|
+
declare function matchRecordingId(meeting: FathomMeeting, targetId: number): boolean;
|
|
9
|
+
declare function durationSeconds(start?: Date | string | null, end?: Date | string | null): number | undefined;
|
|
10
|
+
declare function mapTranscriptSegment(segment: FathomTranscriptSegment, index: number): meeting_recorder_d_exports.MeetingTranscriptSegment;
|
|
11
|
+
declare function parseTimestamp(value: string): number | undefined;
|
|
12
|
+
declare function safeReadError(response: Response): Promise<string>;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { durationSeconds, extractItems, extractNextCursor, mapInvitee, mapTranscriptSegment, matchRecordingId, parseTimestamp, safeReadError };
|
|
15
|
+
//# sourceMappingURL=fathom-meeting-recorder.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fathom-meeting-recorder.utils.d.ts","names":[],"sources":["../../src/impls/fathom-meeting-recorder.utils.ts"],"mappings":";;;;iBAUgB,YAAA,CAAa,IAAA,EAAM,qBAAA,GAAwB,aAAA;AAAA,iBAQ3C,iBAAA,CACd,IAAA,EAAM,qBAAA;AAAA,iBAKQ,UAAA,CACd,OAAA,EAAS,MAAA,oBACR,0BAAA,CAAA,kBAAA;AAAA,iBAYa,gBAAA,CACd,OAAA,EAAS,aAAA,EACT,QAAA;AAAA,iBAKc,eAAA,CACd,KAAA,GAAQ,IAAA,kBACR,GAAA,GAAM,IAAA;AAAA,iBAWQ,oBAAA,CACd,OAAA,EAAS,uBAAA,EACT,KAAA,WACC,0BAAA,CAAA,wBAAA;AAAA,iBAUa,cAAA,CAAe,KAAA;AAAA,iBAST,aAAA,CAAc,QAAA,EAAU,QAAA,GAAW,OAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
//#region src/impls/fathom-meeting-recorder.utils.ts
|
|
2
|
+
function extractItems(page) {
|
|
3
|
+
if (Array.isArray(page.items)) return page.items;
|
|
4
|
+
if (Array.isArray(page.data)) return page.data;
|
|
5
|
+
return [];
|
|
6
|
+
}
|
|
7
|
+
function extractNextCursor(page) {
|
|
8
|
+
return page.nextCursor ?? page.next_cursor ?? void 0;
|
|
9
|
+
}
|
|
10
|
+
function mapInvitee(invitee) {
|
|
11
|
+
const email = invitee.email;
|
|
12
|
+
const name = invitee.name;
|
|
13
|
+
if (!email && !name) return void 0;
|
|
14
|
+
return {
|
|
15
|
+
email,
|
|
16
|
+
name,
|
|
17
|
+
role: "attendee",
|
|
18
|
+
isExternal: invitee.is_external
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function matchRecordingId(meeting, targetId) {
|
|
22
|
+
return meeting.recordingId === targetId;
|
|
23
|
+
}
|
|
24
|
+
function durationSeconds(start, end) {
|
|
25
|
+
if (!start || !end) return void 0;
|
|
26
|
+
const startDate = start instanceof Date ? start : new Date(start);
|
|
27
|
+
const endDate = end instanceof Date ? end : new Date(end);
|
|
28
|
+
if (Number.isNaN(startDate.valueOf()) || Number.isNaN(endDate.valueOf())) return;
|
|
29
|
+
return Math.max(0, (endDate.valueOf() - startDate.valueOf()) / 1e3);
|
|
30
|
+
}
|
|
31
|
+
function mapTranscriptSegment(segment, index) {
|
|
32
|
+
return {
|
|
33
|
+
index,
|
|
34
|
+
speakerName: segment.speaker?.display_name ?? void 0,
|
|
35
|
+
speakerEmail: segment.speaker?.matched_calendar_invitee_email ?? void 0,
|
|
36
|
+
text: segment.text,
|
|
37
|
+
startTimeMs: parseTimestamp(segment.timestamp)
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
function parseTimestamp(value) {
|
|
41
|
+
const parts = value.split(":").map((part) => Number(part));
|
|
42
|
+
if (parts.length !== 3 || parts.some((part) => Number.isNaN(part))) return;
|
|
43
|
+
const [hours = 0, minutes = 0, seconds = 0] = parts;
|
|
44
|
+
return (hours * 3600 + minutes * 60 + seconds) * 1e3;
|
|
45
|
+
}
|
|
46
|
+
async function safeReadError(response) {
|
|
47
|
+
try {
|
|
48
|
+
return (await response.json())?.message ?? response.statusText;
|
|
49
|
+
} catch {
|
|
50
|
+
return response.statusText;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//#endregion
|
|
55
|
+
export { durationSeconds, extractItems, extractNextCursor, mapInvitee, mapTranscriptSegment, matchRecordingId, parseTimestamp, safeReadError };
|
|
56
|
+
//# sourceMappingURL=fathom-meeting-recorder.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fathom-meeting-recorder.utils.js","names":[],"sources":["../../src/impls/fathom-meeting-recorder.utils.ts"],"sourcesContent":["import type {\n MeetingParticipant,\n MeetingTranscriptSegment,\n} from '../meeting-recorder';\nimport type {\n FathomMeeting,\n FathomMeetingListPage,\n FathomTranscriptSegment,\n} from './fathom-meeting-recorder.types';\n\nexport function extractItems(page: FathomMeetingListPage): FathomMeeting[] {\n if (Array.isArray(page.items)) return page.items;\n if (Array.isArray((page as { data?: unknown }).data)) {\n return (page as { data: FathomMeeting[] }).data;\n }\n return [];\n}\n\nexport function extractNextCursor(\n page: FathomMeetingListPage\n): string | null | undefined {\n return page.nextCursor ?? page.next_cursor ?? undefined;\n}\n\nexport function mapInvitee(\n invitee: Record<string, unknown>\n): MeetingParticipant | undefined {\n const email = invitee.email as string | undefined;\n const name = invitee.name as string | undefined;\n if (!email && !name) return undefined;\n return {\n email,\n name,\n role: 'attendee',\n isExternal: invitee.is_external as boolean | undefined,\n };\n}\n\nexport function matchRecordingId(\n meeting: FathomMeeting,\n targetId: number\n): boolean {\n return meeting.recordingId === targetId;\n}\n\nexport function durationSeconds(\n start?: Date | string | null,\n end?: Date | string | null\n): number | undefined {\n if (!start || !end) return undefined;\n const startDate = start instanceof Date ? start : new Date(start);\n const endDate = end instanceof Date ? end : new Date(end);\n if (Number.isNaN(startDate.valueOf()) || Number.isNaN(endDate.valueOf())) {\n return undefined;\n }\n return Math.max(0, (endDate.valueOf() - startDate.valueOf()) / 1000);\n}\n\nexport function mapTranscriptSegment(\n segment: FathomTranscriptSegment,\n index: number\n): MeetingTranscriptSegment {\n return {\n index,\n speakerName: segment.speaker?.display_name ?? undefined,\n speakerEmail: segment.speaker?.matched_calendar_invitee_email ?? undefined,\n text: segment.text,\n startTimeMs: parseTimestamp(segment.timestamp),\n };\n}\n\nexport function parseTimestamp(value: string): number | undefined {\n const parts = value.split(':').map((part) => Number(part));\n if (parts.length !== 3 || parts.some((part) => Number.isNaN(part))) {\n return undefined;\n }\n const [hours = 0, minutes = 0, seconds = 0] = parts;\n return (hours * 3600 + minutes * 60 + seconds) * 1000;\n}\n\nexport async function safeReadError(response: Response): Promise<string> {\n try {\n const data = (await response.json()) as { message?: string };\n return data?.message ?? response.statusText;\n } catch {\n return response.statusText;\n }\n}\n"],"mappings":";AAUA,SAAgB,aAAa,MAA8C;AACzE,KAAI,MAAM,QAAQ,KAAK,MAAM,CAAE,QAAO,KAAK;AAC3C,KAAI,MAAM,QAAS,KAA4B,KAAK,CAClD,QAAQ,KAAmC;AAE7C,QAAO,EAAE;;AAGX,SAAgB,kBACd,MAC2B;AAC3B,QAAO,KAAK,cAAc,KAAK,eAAe;;AAGhD,SAAgB,WACd,SACgC;CAChC,MAAM,QAAQ,QAAQ;CACtB,MAAM,OAAO,QAAQ;AACrB,KAAI,CAAC,SAAS,CAAC,KAAM,QAAO;AAC5B,QAAO;EACL;EACA;EACA,MAAM;EACN,YAAY,QAAQ;EACrB;;AAGH,SAAgB,iBACd,SACA,UACS;AACT,QAAO,QAAQ,gBAAgB;;AAGjC,SAAgB,gBACd,OACA,KACoB;AACpB,KAAI,CAAC,SAAS,CAAC,IAAK,QAAO;CAC3B,MAAM,YAAY,iBAAiB,OAAO,QAAQ,IAAI,KAAK,MAAM;CACjE,MAAM,UAAU,eAAe,OAAO,MAAM,IAAI,KAAK,IAAI;AACzD,KAAI,OAAO,MAAM,UAAU,SAAS,CAAC,IAAI,OAAO,MAAM,QAAQ,SAAS,CAAC,CACtE;AAEF,QAAO,KAAK,IAAI,IAAI,QAAQ,SAAS,GAAG,UAAU,SAAS,IAAI,IAAK;;AAGtE,SAAgB,qBACd,SACA,OAC0B;AAC1B,QAAO;EACL;EACA,aAAa,QAAQ,SAAS,gBAAgB;EAC9C,cAAc,QAAQ,SAAS,kCAAkC;EACjE,MAAM,QAAQ;EACd,aAAa,eAAe,QAAQ,UAAU;EAC/C;;AAGH,SAAgB,eAAe,OAAmC;CAChE,MAAM,QAAQ,MAAM,MAAM,IAAI,CAAC,KAAK,SAAS,OAAO,KAAK,CAAC;AAC1D,KAAI,MAAM,WAAW,KAAK,MAAM,MAAM,SAAS,OAAO,MAAM,KAAK,CAAC,CAChE;CAEF,MAAM,CAAC,QAAQ,GAAG,UAAU,GAAG,UAAU,KAAK;AAC9C,SAAQ,QAAQ,OAAO,UAAU,KAAK,WAAW;;AAGnD,eAAsB,cAAc,UAAqC;AACvE,KAAI;AAEF,UADc,MAAM,SAAS,MAAM,GACtB,WAAW,SAAS;SAC3B;AACN,SAAO,SAAS"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { TriggeredFor } from "fathom-typescript/sdk/models/operations";
|
|
2
|
+
|
|
3
|
+
//#region src/impls/fathom-meeting-recorder.webhooks.d.ts
|
|
4
|
+
declare function normalizeWebhookHeaders(headers: Record<string, string | string[] | undefined>): Record<string, string>;
|
|
5
|
+
declare function normalizeTriggeredFor(values?: string[]): TriggeredFor[] | undefined;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { normalizeTriggeredFor, normalizeWebhookHeaders };
|
|
8
|
+
//# sourceMappingURL=fathom-meeting-recorder.webhooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fathom-meeting-recorder.webhooks.d.ts","names":[],"sources":["../../src/impls/fathom-meeting-recorder.webhooks.ts"],"mappings":";;;iBAEgB,uBAAA,CACd,OAAA,EAAS,MAAA,0CACR,MAAA;AAAA,iBAea,qBAAA,CACd,MAAA,cACC,YAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { TriggeredFor } from "fathom-typescript/sdk/models/operations";
|
|
2
|
+
|
|
3
|
+
//#region src/impls/fathom-meeting-recorder.webhooks.ts
|
|
4
|
+
function normalizeWebhookHeaders(headers) {
|
|
5
|
+
const normalized = {};
|
|
6
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
7
|
+
if (value == null) continue;
|
|
8
|
+
const normalizedKey = key.toLowerCase();
|
|
9
|
+
if (Array.isArray(value)) {
|
|
10
|
+
if (value.length === 0) continue;
|
|
11
|
+
normalized[normalizedKey] = value.join(", ");
|
|
12
|
+
} else normalized[normalizedKey] = value;
|
|
13
|
+
}
|
|
14
|
+
return normalized;
|
|
15
|
+
}
|
|
16
|
+
function normalizeTriggeredFor(values) {
|
|
17
|
+
if (!values) return void 0;
|
|
18
|
+
const allowed = new Set(Object.values(TriggeredFor));
|
|
19
|
+
const normalized = values.map((value) => value.trim()).filter((value) => allowed.has(value));
|
|
20
|
+
return normalized.length ? normalized : void 0;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
//#endregion
|
|
24
|
+
export { normalizeTriggeredFor, normalizeWebhookHeaders };
|
|
25
|
+
//# sourceMappingURL=fathom-meeting-recorder.webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fathom-meeting-recorder.webhooks.js","names":[],"sources":["../../src/impls/fathom-meeting-recorder.webhooks.ts"],"sourcesContent":["import { TriggeredFor } from 'fathom-typescript/sdk/models/operations';\n\nexport function normalizeWebhookHeaders(\n headers: Record<string, string | string[] | undefined>\n): Record<string, string> {\n const normalized: Record<string, string> = {};\n for (const [key, value] of Object.entries(headers)) {\n if (value == null) continue;\n const normalizedKey = key.toLowerCase();\n if (Array.isArray(value)) {\n if (value.length === 0) continue;\n normalized[normalizedKey] = value.join(', ');\n } else {\n normalized[normalizedKey] = value;\n }\n }\n return normalized;\n}\n\nexport function normalizeTriggeredFor(\n values?: string[]\n): TriggeredFor[] | undefined {\n if (!values) return undefined;\n const allowed = new Set(Object.values(TriggeredFor));\n const normalized = values\n .map((value) => value.trim())\n .filter((value): value is TriggeredFor =>\n allowed.has(value as TriggeredFor)\n );\n return normalized.length ? normalized : undefined;\n}\n"],"mappings":";;;AAEA,SAAgB,wBACd,SACwB;CACxB,MAAM,aAAqC,EAAE;AAC7C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,EAAE;AAClD,MAAI,SAAS,KAAM;EACnB,MAAM,gBAAgB,IAAI,aAAa;AACvC,MAAI,MAAM,QAAQ,MAAM,EAAE;AACxB,OAAI,MAAM,WAAW,EAAG;AACxB,cAAW,iBAAiB,MAAM,KAAK,KAAK;QAE5C,YAAW,iBAAiB;;AAGhC,QAAO;;AAGT,SAAgB,sBACd,QAC4B;AAC5B,KAAI,CAAC,OAAQ,QAAO;CACpB,MAAM,UAAU,IAAI,IAAI,OAAO,OAAO,aAAa,CAAC;CACpD,MAAM,aAAa,OAChB,KAAK,UAAU,MAAM,MAAM,CAAC,CAC5B,QAAQ,UACP,QAAQ,IAAI,MAAsB,CACnC;AACH,QAAO,WAAW,SAAS,aAAa"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { meeting_recorder_d_exports } from "../meeting-recorder.js";
|
|
2
|
+
|
|
3
|
+
//#region src/impls/fireflies-meeting-recorder.d.ts
|
|
4
|
+
interface FirefliesMeetingRecorderProviderOptions {
|
|
5
|
+
apiKey: string;
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
pageSize?: number;
|
|
8
|
+
webhookSecret?: string;
|
|
9
|
+
}
|
|
10
|
+
declare class FirefliesMeetingRecorderProvider implements meeting_recorder_d_exports.MeetingRecorderProvider {
|
|
11
|
+
private readonly apiKey;
|
|
12
|
+
private readonly baseUrl;
|
|
13
|
+
private readonly defaultPageSize?;
|
|
14
|
+
private readonly webhookSecret?;
|
|
15
|
+
constructor(options: FirefliesMeetingRecorderProviderOptions);
|
|
16
|
+
listMeetings(params: meeting_recorder_d_exports.MeetingRecorderListMeetingsParams): Promise<meeting_recorder_d_exports.MeetingRecorderListMeetingsResult>;
|
|
17
|
+
getMeeting(params: meeting_recorder_d_exports.MeetingRecorderGetMeetingParams): Promise<meeting_recorder_d_exports.MeetingRecord>;
|
|
18
|
+
getTranscript(params: meeting_recorder_d_exports.MeetingRecorderGetTranscriptParams): Promise<meeting_recorder_d_exports.MeetingTranscriptRecord>;
|
|
19
|
+
parseWebhook(request: meeting_recorder_d_exports.MeetingRecorderWebhookRequest): Promise<meeting_recorder_d_exports.MeetingRecorderWebhookEvent>;
|
|
20
|
+
verifyWebhook(request: meeting_recorder_d_exports.MeetingRecorderWebhookRequest): Promise<boolean>;
|
|
21
|
+
private mapTranscriptToMeeting;
|
|
22
|
+
private mapAttendee;
|
|
23
|
+
private mapSentence;
|
|
24
|
+
private query;
|
|
25
|
+
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { FirefliesMeetingRecorderProvider, FirefliesMeetingRecorderProviderOptions };
|
|
28
|
+
//# sourceMappingURL=fireflies-meeting-recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fireflies-meeting-recorder.d.ts","names":[],"sources":["../../src/impls/fireflies-meeting-recorder.ts"],"mappings":";;;UAkCiB,uCAAA;EACf,MAAA;EACA,OAAA;EACA,QAAA;EACA,aAAA;AAAA;AAAA,cAKW,gCAAA,YAA4C,0BAAA,CAAA,uBAAA;EAAA,iBACtC,MAAA;EAAA,iBACA,OAAA;EAAA,iBACA,eAAA;EAAA,iBACA,aAAA;cAEL,OAAA,EAAS,uCAAA;EAOf,YAAA,CACJ,MAAA,EAAQ,0BAAA,CAAA,iCAAA,GACP,OAAA,CAAQ,0BAAA,CAAA,iCAAA;EA0BL,UAAA,CACJ,MAAA,EAAQ,0BAAA,CAAA,+BAAA,GACP,OAAA,CAAQ,0BAAA,CAAA,aAAA;EAUL,aAAA,CACJ,MAAA,EAAQ,0BAAA,CAAA,kCAAA,GACP,OAAA,CAAQ,0BAAA,CAAA,uBAAA;EA4BL,YAAA,CACJ,OAAA,EAAS,0BAAA,CAAA,6BAAA,GACR,OAAA,CAAQ,0BAAA,CAAA,2BAAA;EAuBL,aAAA,CACJ,OAAA,EAAS,0BAAA,CAAA,6BAAA,GACR,OAAA;EAAA,QAWK,sBAAA;EAAA,QAqCA,WAAA;EAAA,QAQA,WAAA;EAAA,QAWM,KAAA;AAAA"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { TRANSCRIPTS_QUERY, TRANSCRIPT_QUERY, TRANSCRIPT_WITH_SEGMENTS_QUERY } from "./fireflies-meeting-recorder.queries.js";
|
|
2
|
+
import { normalizeHeader, parseSeconds, safeCompareHex, safeReadError } from "./fireflies-meeting-recorder.utils.js";
|
|
3
|
+
import { createHmac } from "crypto";
|
|
4
|
+
|
|
5
|
+
//#region src/impls/fireflies-meeting-recorder.ts
|
|
6
|
+
const DEFAULT_BASE_URL = "https://api.fireflies.ai/graphql";
|
|
7
|
+
var FirefliesMeetingRecorderProvider = class {
|
|
8
|
+
apiKey;
|
|
9
|
+
baseUrl;
|
|
10
|
+
defaultPageSize;
|
|
11
|
+
webhookSecret;
|
|
12
|
+
constructor(options) {
|
|
13
|
+
this.apiKey = options.apiKey;
|
|
14
|
+
this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
|
|
15
|
+
this.defaultPageSize = options.pageSize;
|
|
16
|
+
this.webhookSecret = options.webhookSecret;
|
|
17
|
+
}
|
|
18
|
+
async listMeetings(params) {
|
|
19
|
+
const limit = params.pageSize ?? this.defaultPageSize ?? 25;
|
|
20
|
+
const skip = params.cursor ? Number(params.cursor) : 0;
|
|
21
|
+
const meetings = (await this.query(TRANSCRIPTS_QUERY, {
|
|
22
|
+
limit,
|
|
23
|
+
skip: Number.isFinite(skip) ? skip : 0,
|
|
24
|
+
fromDate: params.from,
|
|
25
|
+
toDate: params.to,
|
|
26
|
+
keyword: params.query,
|
|
27
|
+
scope: params.query ? "all" : void 0
|
|
28
|
+
})).transcripts.map((transcript) => this.mapTranscriptToMeeting(transcript, params));
|
|
29
|
+
const nextCursor = meetings.length === limit ? String(skip + limit) : void 0;
|
|
30
|
+
return {
|
|
31
|
+
meetings,
|
|
32
|
+
nextCursor,
|
|
33
|
+
hasMore: Boolean(nextCursor)
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async getMeeting(params) {
|
|
37
|
+
const data = await this.query(TRANSCRIPT_QUERY, { transcriptId: params.meetingId });
|
|
38
|
+
return this.mapTranscriptToMeeting(data.transcript, params);
|
|
39
|
+
}
|
|
40
|
+
async getTranscript(params) {
|
|
41
|
+
const transcript = (await this.query(TRANSCRIPT_WITH_SEGMENTS_QUERY, { transcriptId: params.meetingId })).transcript;
|
|
42
|
+
const segments = (transcript.sentences ?? []).map((segment) => this.mapSentence(segment));
|
|
43
|
+
return {
|
|
44
|
+
id: transcript.id,
|
|
45
|
+
meetingId: transcript.id,
|
|
46
|
+
tenantId: params.tenantId,
|
|
47
|
+
connectionId: params.connectionId ?? "unknown",
|
|
48
|
+
externalId: transcript.id,
|
|
49
|
+
format: "segments",
|
|
50
|
+
text: segments.map((segment) => segment.text).join("\n"),
|
|
51
|
+
segments,
|
|
52
|
+
generatedAt: transcript.dateString ?? void 0,
|
|
53
|
+
sourceUrl: transcript.transcript_url ?? void 0,
|
|
54
|
+
metadata: {
|
|
55
|
+
meetingLink: transcript.meeting_link,
|
|
56
|
+
durationMinutes: transcript.duration
|
|
57
|
+
},
|
|
58
|
+
raw: transcript
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
async parseWebhook(request) {
|
|
62
|
+
const payload = request.parsedBody ?? JSON.parse(request.rawBody);
|
|
63
|
+
const body = payload;
|
|
64
|
+
const verified = this.webhookSecret ? await this.verifyWebhook(request) : void 0;
|
|
65
|
+
return {
|
|
66
|
+
providerKey: "meeting-recorder.fireflies",
|
|
67
|
+
eventType: body.eventType,
|
|
68
|
+
meetingId: body.meetingId,
|
|
69
|
+
transcriptId: body.meetingId,
|
|
70
|
+
verified,
|
|
71
|
+
payload,
|
|
72
|
+
metadata: { clientReferenceId: body.clientReferenceId }
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
async verifyWebhook(request) {
|
|
76
|
+
if (!this.webhookSecret) return true;
|
|
77
|
+
const signatureHeader = normalizeHeader(request.headers, "x-hub-signature");
|
|
78
|
+
if (!signatureHeader) return false;
|
|
79
|
+
const signature = signatureHeader.replace(/^sha256=/, "");
|
|
80
|
+
return safeCompareHex(createHmac("sha256", this.webhookSecret).update(request.rawBody).digest("hex"), signature);
|
|
81
|
+
}
|
|
82
|
+
mapTranscriptToMeeting(transcript, params) {
|
|
83
|
+
const connectionId = params.connectionId ?? "unknown";
|
|
84
|
+
const organizer = transcript.organizer_email ? {
|
|
85
|
+
email: transcript.organizer_email,
|
|
86
|
+
role: "organizer"
|
|
87
|
+
} : void 0;
|
|
88
|
+
const attendees = transcript.meeting_attendees?.length ? transcript.meeting_attendees.map((attendee) => this.mapAttendee(attendee)) : transcript.participants?.map((email) => ({
|
|
89
|
+
email,
|
|
90
|
+
role: "attendee"
|
|
91
|
+
}));
|
|
92
|
+
return {
|
|
93
|
+
id: transcript.id,
|
|
94
|
+
tenantId: params.tenantId,
|
|
95
|
+
connectionId,
|
|
96
|
+
externalId: transcript.id,
|
|
97
|
+
title: transcript.title ?? void 0,
|
|
98
|
+
organizer,
|
|
99
|
+
invitees: attendees,
|
|
100
|
+
participants: attendees,
|
|
101
|
+
scheduledStartAt: transcript.dateString ?? void 0,
|
|
102
|
+
recordingStartAt: transcript.dateString ?? void 0,
|
|
103
|
+
durationSeconds: transcript.duration ? transcript.duration * 60 : void 0,
|
|
104
|
+
meetingUrl: transcript.meeting_link ?? transcript.transcript_url ?? void 0,
|
|
105
|
+
transcriptAvailable: Boolean(transcript.transcript_url),
|
|
106
|
+
sourcePlatform: "fireflies",
|
|
107
|
+
metadata: { transcriptUrl: transcript.transcript_url }
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
mapAttendee(attendee) {
|
|
111
|
+
return {
|
|
112
|
+
name: attendee.name ?? attendee.displayName ?? void 0,
|
|
113
|
+
email: attendee.email ?? void 0,
|
|
114
|
+
role: "attendee"
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
mapSentence(segment) {
|
|
118
|
+
return {
|
|
119
|
+
index: segment.index ?? void 0,
|
|
120
|
+
speakerId: segment.speaker_id ?? void 0,
|
|
121
|
+
speakerName: segment.speaker_name ?? void 0,
|
|
122
|
+
text: segment.text,
|
|
123
|
+
startTimeMs: parseSeconds(segment.start_time),
|
|
124
|
+
endTimeMs: parseSeconds(segment.end_time)
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async query(query, variables) {
|
|
128
|
+
const response = await fetch(this.baseUrl, {
|
|
129
|
+
method: "POST",
|
|
130
|
+
headers: {
|
|
131
|
+
"Content-Type": "application/json",
|
|
132
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
133
|
+
},
|
|
134
|
+
body: JSON.stringify({
|
|
135
|
+
query,
|
|
136
|
+
variables
|
|
137
|
+
})
|
|
138
|
+
});
|
|
139
|
+
if (!response.ok) {
|
|
140
|
+
const message = await safeReadError(response);
|
|
141
|
+
throw new Error(`Fireflies API error (${response.status}): ${message}`);
|
|
142
|
+
}
|
|
143
|
+
const result = await response.json();
|
|
144
|
+
if (result.errors?.length) throw new Error(result.errors.map((error) => error.message).join("; "));
|
|
145
|
+
if (!result.data) throw new Error("Fireflies API returned empty data payload.");
|
|
146
|
+
return result.data;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
//#endregion
|
|
151
|
+
export { FirefliesMeetingRecorderProvider };
|
|
152
|
+
//# sourceMappingURL=fireflies-meeting-recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fireflies-meeting-recorder.js","names":[],"sources":["../../src/impls/fireflies-meeting-recorder.ts"],"sourcesContent":["import { createHmac } from 'crypto';\n\nimport type {\n MeetingParticipant,\n MeetingRecord,\n MeetingRecorderGetMeetingParams,\n MeetingRecorderGetTranscriptParams,\n MeetingRecorderListMeetingsParams,\n MeetingRecorderListMeetingsResult,\n MeetingRecorderProvider,\n MeetingRecorderWebhookEvent,\n MeetingRecorderWebhookRequest,\n MeetingTranscriptRecord,\n MeetingTranscriptSegment,\n} from '../meeting-recorder';\nimport {\n TRANSCRIPT_QUERY,\n TRANSCRIPTS_QUERY,\n TRANSCRIPT_WITH_SEGMENTS_QUERY,\n} from './fireflies-meeting-recorder.queries';\nimport type {\n FirefliesMeetingAttendee,\n FirefliesSentence,\n FirefliesTranscript,\n FirefliesTranscriptResponse,\n FirefliesTranscriptsResponse,\n} from './fireflies-meeting-recorder.types';\nimport {\n normalizeHeader,\n parseSeconds,\n safeCompareHex,\n safeReadError,\n} from './fireflies-meeting-recorder.utils';\n\nexport interface FirefliesMeetingRecorderProviderOptions {\n apiKey: string;\n baseUrl?: string;\n pageSize?: number;\n webhookSecret?: string;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.fireflies.ai/graphql';\n\nexport class FirefliesMeetingRecorderProvider implements MeetingRecorderProvider {\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly defaultPageSize?: number;\n private readonly webhookSecret?: string;\n\n constructor(options: FirefliesMeetingRecorderProviderOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n this.defaultPageSize = options.pageSize;\n this.webhookSecret = options.webhookSecret;\n }\n\n async listMeetings(\n params: MeetingRecorderListMeetingsParams\n ): Promise<MeetingRecorderListMeetingsResult> {\n const limit = params.pageSize ?? this.defaultPageSize ?? 25;\n const skip = params.cursor ? Number(params.cursor) : 0;\n const data = await this.query<FirefliesTranscriptsResponse>(\n TRANSCRIPTS_QUERY,\n {\n limit,\n skip: Number.isFinite(skip) ? skip : 0,\n fromDate: params.from,\n toDate: params.to,\n keyword: params.query,\n scope: params.query ? 'all' : undefined,\n }\n );\n const meetings = data.transcripts.map((transcript) =>\n this.mapTranscriptToMeeting(transcript, params)\n );\n const nextCursor =\n meetings.length === limit ? String(skip + limit) : undefined;\n return {\n meetings,\n nextCursor,\n hasMore: Boolean(nextCursor),\n };\n }\n\n async getMeeting(\n params: MeetingRecorderGetMeetingParams\n ): Promise<MeetingRecord> {\n const data = await this.query<FirefliesTranscriptResponse>(\n TRANSCRIPT_QUERY,\n {\n transcriptId: params.meetingId,\n }\n );\n return this.mapTranscriptToMeeting(data.transcript, params);\n }\n\n async getTranscript(\n params: MeetingRecorderGetTranscriptParams\n ): Promise<MeetingTranscriptRecord> {\n const data = await this.query<FirefliesTranscriptResponse>(\n TRANSCRIPT_WITH_SEGMENTS_QUERY,\n { transcriptId: params.meetingId }\n );\n const transcript = data.transcript;\n const segments = (transcript.sentences ?? []).map((segment) =>\n this.mapSentence(segment)\n );\n return {\n id: transcript.id,\n meetingId: transcript.id,\n tenantId: params.tenantId,\n connectionId: params.connectionId ?? 'unknown',\n externalId: transcript.id,\n format: 'segments',\n text: segments.map((segment) => segment.text).join('\\n'),\n segments,\n generatedAt: transcript.dateString ?? undefined,\n sourceUrl: transcript.transcript_url ?? undefined,\n metadata: {\n meetingLink: transcript.meeting_link,\n durationMinutes: transcript.duration,\n },\n raw: transcript,\n };\n }\n\n async parseWebhook(\n request: MeetingRecorderWebhookRequest\n ): Promise<MeetingRecorderWebhookEvent> {\n const payload = request.parsedBody ?? JSON.parse(request.rawBody);\n const body = payload as {\n meetingId?: string;\n eventType?: string;\n clientReferenceId?: string;\n };\n const verified = this.webhookSecret\n ? await this.verifyWebhook(request)\n : undefined;\n return {\n providerKey: 'meeting-recorder.fireflies',\n eventType: body.eventType,\n meetingId: body.meetingId,\n transcriptId: body.meetingId,\n verified,\n payload,\n metadata: {\n clientReferenceId: body.clientReferenceId,\n },\n };\n }\n\n async verifyWebhook(\n request: MeetingRecorderWebhookRequest\n ): Promise<boolean> {\n if (!this.webhookSecret) return true;\n const signatureHeader = normalizeHeader(request.headers, 'x-hub-signature');\n if (!signatureHeader) return false;\n const signature = signatureHeader.replace(/^sha256=/, '');\n const digest = createHmac('sha256', this.webhookSecret)\n .update(request.rawBody)\n .digest('hex');\n return safeCompareHex(digest, signature);\n }\n\n private mapTranscriptToMeeting(\n transcript: FirefliesTranscript,\n params: MeetingRecorderListMeetingsParams | MeetingRecorderGetMeetingParams\n ): MeetingRecord {\n const connectionId = params.connectionId ?? 'unknown';\n const organizer = transcript.organizer_email\n ? { email: transcript.organizer_email, role: 'organizer' }\n : undefined;\n const attendees = transcript.meeting_attendees?.length\n ? transcript.meeting_attendees.map((attendee) =>\n this.mapAttendee(attendee)\n )\n : transcript.participants?.map((email) => ({ email, role: 'attendee' }));\n return {\n id: transcript.id,\n tenantId: params.tenantId,\n connectionId,\n externalId: transcript.id,\n title: transcript.title ?? undefined,\n organizer,\n invitees: attendees,\n participants: attendees,\n scheduledStartAt: transcript.dateString ?? undefined,\n recordingStartAt: transcript.dateString ?? undefined,\n durationSeconds: transcript.duration\n ? transcript.duration * 60\n : undefined,\n meetingUrl:\n transcript.meeting_link ?? transcript.transcript_url ?? undefined,\n transcriptAvailable: Boolean(transcript.transcript_url),\n sourcePlatform: 'fireflies',\n metadata: {\n transcriptUrl: transcript.transcript_url,\n },\n };\n }\n\n private mapAttendee(attendee: FirefliesMeetingAttendee): MeetingParticipant {\n return {\n name: attendee.name ?? attendee.displayName ?? undefined,\n email: attendee.email ?? undefined,\n role: 'attendee',\n };\n }\n\n private mapSentence(segment: FirefliesSentence): MeetingTranscriptSegment {\n return {\n index: segment.index ?? undefined,\n speakerId: segment.speaker_id ?? undefined,\n speakerName: segment.speaker_name ?? undefined,\n text: segment.text,\n startTimeMs: parseSeconds(segment.start_time),\n endTimeMs: parseSeconds(segment.end_time),\n };\n }\n\n private async query<T>(query: string, variables: Record<string, unknown>) {\n const response = await fetch(this.baseUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify({ query, variables }),\n });\n if (!response.ok) {\n const message = await safeReadError(response);\n throw new Error(`Fireflies API error (${response.status}): ${message}`);\n }\n const result = (await response.json()) as {\n data?: T;\n errors?: { message: string }[];\n };\n if (result.errors?.length) {\n throw new Error(result.errors.map((error) => error.message).join('; '));\n }\n if (!result.data) {\n throw new Error('Fireflies API returned empty data payload.');\n }\n return result.data;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/impls/fireflies-meeting-recorder.queries.d.ts
|
|
2
|
+
declare const TRANSCRIPTS_QUERY = "\n query Transcripts(\n $limit: Int\n $skip: Int\n $fromDate: DateTime\n $toDate: DateTime\n $keyword: String\n $scope: TranscriptsQueryScope\n ) {\n transcripts(\n limit: $limit\n skip: $skip\n fromDate: $fromDate\n toDate: $toDate\n keyword: $keyword\n scope: $scope\n ) {\n id\n title\n organizer_email\n participants\n meeting_attendees {\n name\n email\n displayName\n }\n dateString\n duration\n meeting_link\n transcript_url\n }\n }\n";
|
|
3
|
+
declare const TRANSCRIPT_QUERY = "\n query Transcript($transcriptId: String!) {\n transcript(id: $transcriptId) {\n id\n title\n organizer_email\n participants\n meeting_attendees {\n name\n email\n displayName\n }\n dateString\n duration\n meeting_link\n transcript_url\n }\n }\n";
|
|
4
|
+
declare const TRANSCRIPT_WITH_SEGMENTS_QUERY = "\n query Transcript($transcriptId: String!) {\n transcript(id: $transcriptId) {\n id\n title\n organizer_email\n participants\n meeting_attendees {\n name\n email\n displayName\n }\n dateString\n duration\n meeting_link\n transcript_url\n sentences {\n index\n speaker_name\n speaker_id\n text\n start_time\n end_time\n }\n }\n }\n";
|
|
5
|
+
//#endregion
|
|
6
|
+
export { TRANSCRIPTS_QUERY, TRANSCRIPT_QUERY, TRANSCRIPT_WITH_SEGMENTS_QUERY };
|
|
7
|
+
//# sourceMappingURL=fireflies-meeting-recorder.queries.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fireflies-meeting-recorder.queries.d.ts","names":[],"sources":["../../src/impls/fireflies-meeting-recorder.queries.ts"],"mappings":";cAAa,iBAAA;AAAA,cAkCA,gBAAA;AAAA,cAoBA,8BAAA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
//#region src/impls/fireflies-meeting-recorder.queries.ts
|
|
2
|
+
const TRANSCRIPTS_QUERY = `
|
|
3
|
+
query Transcripts(
|
|
4
|
+
$limit: Int
|
|
5
|
+
$skip: Int
|
|
6
|
+
$fromDate: DateTime
|
|
7
|
+
$toDate: DateTime
|
|
8
|
+
$keyword: String
|
|
9
|
+
$scope: TranscriptsQueryScope
|
|
10
|
+
) {
|
|
11
|
+
transcripts(
|
|
12
|
+
limit: $limit
|
|
13
|
+
skip: $skip
|
|
14
|
+
fromDate: $fromDate
|
|
15
|
+
toDate: $toDate
|
|
16
|
+
keyword: $keyword
|
|
17
|
+
scope: $scope
|
|
18
|
+
) {
|
|
19
|
+
id
|
|
20
|
+
title
|
|
21
|
+
organizer_email
|
|
22
|
+
participants
|
|
23
|
+
meeting_attendees {
|
|
24
|
+
name
|
|
25
|
+
email
|
|
26
|
+
displayName
|
|
27
|
+
}
|
|
28
|
+
dateString
|
|
29
|
+
duration
|
|
30
|
+
meeting_link
|
|
31
|
+
transcript_url
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
const TRANSCRIPT_QUERY = `
|
|
36
|
+
query Transcript($transcriptId: String!) {
|
|
37
|
+
transcript(id: $transcriptId) {
|
|
38
|
+
id
|
|
39
|
+
title
|
|
40
|
+
organizer_email
|
|
41
|
+
participants
|
|
42
|
+
meeting_attendees {
|
|
43
|
+
name
|
|
44
|
+
email
|
|
45
|
+
displayName
|
|
46
|
+
}
|
|
47
|
+
dateString
|
|
48
|
+
duration
|
|
49
|
+
meeting_link
|
|
50
|
+
transcript_url
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
`;
|
|
54
|
+
const TRANSCRIPT_WITH_SEGMENTS_QUERY = `
|
|
55
|
+
query Transcript($transcriptId: String!) {
|
|
56
|
+
transcript(id: $transcriptId) {
|
|
57
|
+
id
|
|
58
|
+
title
|
|
59
|
+
organizer_email
|
|
60
|
+
participants
|
|
61
|
+
meeting_attendees {
|
|
62
|
+
name
|
|
63
|
+
email
|
|
64
|
+
displayName
|
|
65
|
+
}
|
|
66
|
+
dateString
|
|
67
|
+
duration
|
|
68
|
+
meeting_link
|
|
69
|
+
transcript_url
|
|
70
|
+
sentences {
|
|
71
|
+
index
|
|
72
|
+
speaker_name
|
|
73
|
+
speaker_id
|
|
74
|
+
text
|
|
75
|
+
start_time
|
|
76
|
+
end_time
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
`;
|
|
81
|
+
|
|
82
|
+
//#endregion
|
|
83
|
+
export { TRANSCRIPTS_QUERY, TRANSCRIPT_QUERY, TRANSCRIPT_WITH_SEGMENTS_QUERY };
|
|
84
|
+
//# sourceMappingURL=fireflies-meeting-recorder.queries.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fireflies-meeting-recorder.queries.js","names":[],"sources":["../../src/impls/fireflies-meeting-recorder.queries.ts"],"sourcesContent":["export const TRANSCRIPTS_QUERY = `\n query Transcripts(\n $limit: Int\n $skip: Int\n $fromDate: DateTime\n $toDate: DateTime\n $keyword: String\n $scope: TranscriptsQueryScope\n ) {\n transcripts(\n limit: $limit\n skip: $skip\n fromDate: $fromDate\n toDate: $toDate\n keyword: $keyword\n scope: $scope\n ) {\n id\n title\n organizer_email\n participants\n meeting_attendees {\n name\n email\n displayName\n }\n dateString\n duration\n meeting_link\n transcript_url\n }\n }\n`;\n\nexport const TRANSCRIPT_QUERY = `\n query Transcript($transcriptId: String!) {\n transcript(id: $transcriptId) {\n id\n title\n organizer_email\n participants\n meeting_attendees {\n name\n email\n displayName\n }\n dateString\n duration\n meeting_link\n transcript_url\n }\n }\n`;\n\nexport const TRANSCRIPT_WITH_SEGMENTS_QUERY = `\n query Transcript($transcriptId: String!) {\n transcript(id: $transcriptId) {\n id\n title\n organizer_email\n participants\n meeting_attendees {\n name\n email\n displayName\n }\n dateString\n duration\n meeting_link\n transcript_url\n sentences {\n index\n speaker_name\n speaker_id\n text\n start_time\n end_time\n }\n }\n }\n`;\n"],"mappings":";AAAA,MAAa,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCjC,MAAa,mBAAmB;;;;;;;;;;;;;;;;;;;AAoBhC,MAAa,iCAAiC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/impls/fireflies-meeting-recorder.types.d.ts
|
|
2
|
+
interface FirefliesTranscriptsResponse {
|
|
3
|
+
transcripts: FirefliesTranscript[];
|
|
4
|
+
}
|
|
5
|
+
interface FirefliesTranscriptResponse {
|
|
6
|
+
transcript: FirefliesTranscript;
|
|
7
|
+
}
|
|
8
|
+
interface FirefliesTranscript {
|
|
9
|
+
id: string;
|
|
10
|
+
title?: string | null;
|
|
11
|
+
organizer_email?: string | null;
|
|
12
|
+
participants?: string[] | null;
|
|
13
|
+
meeting_attendees?: FirefliesMeetingAttendee[] | null;
|
|
14
|
+
dateString?: string | null;
|
|
15
|
+
duration?: number | null;
|
|
16
|
+
meeting_link?: string | null;
|
|
17
|
+
transcript_url?: string | null;
|
|
18
|
+
sentences?: FirefliesSentence[] | null;
|
|
19
|
+
}
|
|
20
|
+
interface FirefliesMeetingAttendee {
|
|
21
|
+
name?: string | null;
|
|
22
|
+
displayName?: string | null;
|
|
23
|
+
email?: string | null;
|
|
24
|
+
}
|
|
25
|
+
interface FirefliesSentence {
|
|
26
|
+
index?: number | null;
|
|
27
|
+
speaker_id?: string | null;
|
|
28
|
+
speaker_name?: string | null;
|
|
29
|
+
text: string;
|
|
30
|
+
start_time?: string | number | null;
|
|
31
|
+
end_time?: string | number | null;
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
34
|
+
export { FirefliesMeetingAttendee, FirefliesSentence, FirefliesTranscript, FirefliesTranscriptResponse, FirefliesTranscriptsResponse };
|
|
35
|
+
//# sourceMappingURL=fireflies-meeting-recorder.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fireflies-meeting-recorder.types.d.ts","names":[],"sources":["../../src/impls/fireflies-meeting-recorder.types.ts"],"mappings":";UAAiB,4BAAA;EACf,WAAA,EAAa,mBAAA;AAAA;AAAA,UAGE,2BAAA;EACf,UAAA,EAAY,mBAAA;AAAA;AAAA,UAGG,mBAAA;EACf,EAAA;EACA,KAAA;EACA,eAAA;EACA,YAAA;EACA,iBAAA,GAAoB,wBAAA;EACpB,UAAA;EACA,QAAA;EACA,YAAA;EACA,cAAA;EACA,SAAA,GAAY,iBAAA;AAAA;AAAA,UAGG,wBAAA;EACf,IAAA;EACA,WAAA;EACA,KAAA;AAAA;AAAA,UAGe,iBAAA;EACf,KAAA;EACA,UAAA;EACA,YAAA;EACA,IAAA;EACA,UAAA;EACA,QAAA;AAAA"}
|
|
File without changes
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/impls/fireflies-meeting-recorder.utils.d.ts
|
|
2
|
+
declare function parseSeconds(value?: string | number | null): number | undefined;
|
|
3
|
+
declare function normalizeHeader(headers: Record<string, string | string[] | undefined>, key: string): string | undefined;
|
|
4
|
+
declare function safeCompareHex(a: string, b: string): boolean;
|
|
5
|
+
declare function safeReadError(response: Response): Promise<string>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { normalizeHeader, parseSeconds, safeCompareHex, safeReadError };
|
|
8
|
+
//# sourceMappingURL=fireflies-meeting-recorder.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fireflies-meeting-recorder.utils.d.ts","names":[],"sources":["../../src/impls/fireflies-meeting-recorder.utils.ts"],"mappings":";iBAGgB,YAAA,CACd,KAAA;AAAA,iBAQc,eAAA,CACd,OAAA,EAAS,MAAA,yCACT,GAAA;AAAA,iBAQc,cAAA,CAAe,CAAA,UAAW,CAAA;AAAA,iBAWpB,aAAA,CAAc,QAAA,EAAU,QAAA,GAAW,OAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import { timingSafeEqual } from "crypto";
|
|
3
|
+
|
|
4
|
+
//#region src/impls/fireflies-meeting-recorder.utils.ts
|
|
5
|
+
function parseSeconds(value) {
|
|
6
|
+
if (value == null) return void 0;
|
|
7
|
+
const num = typeof value === "number" ? value : Number(value);
|
|
8
|
+
if (!Number.isFinite(num)) return void 0;
|
|
9
|
+
return num * 1e3;
|
|
10
|
+
}
|
|
11
|
+
function normalizeHeader(headers, key) {
|
|
12
|
+
const header = headers[key] ?? headers[key.toLowerCase()] ?? headers[key.toUpperCase()];
|
|
13
|
+
if (Array.isArray(header)) return header[0];
|
|
14
|
+
return header;
|
|
15
|
+
}
|
|
16
|
+
function safeCompareHex(a, b) {
|
|
17
|
+
try {
|
|
18
|
+
const aBuffer = Buffer.from(a, "hex");
|
|
19
|
+
const bBuffer = Buffer.from(b, "hex");
|
|
20
|
+
if (aBuffer.length !== bBuffer.length) return false;
|
|
21
|
+
return timingSafeEqual(aBuffer, bBuffer);
|
|
22
|
+
} catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
async function safeReadError(response) {
|
|
27
|
+
try {
|
|
28
|
+
return (await response.json())?.message ?? response.statusText;
|
|
29
|
+
} catch {
|
|
30
|
+
return response.statusText;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { normalizeHeader, parseSeconds, safeCompareHex, safeReadError };
|
|
36
|
+
//# sourceMappingURL=fireflies-meeting-recorder.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fireflies-meeting-recorder.utils.js","names":[],"sources":["../../src/impls/fireflies-meeting-recorder.utils.ts"],"sourcesContent":["import { Buffer } from 'node:buffer';\nimport { timingSafeEqual } from 'crypto';\n\nexport function parseSeconds(\n value?: string | number | null\n): number | undefined {\n if (value == null) return undefined;\n const num = typeof value === 'number' ? value : Number(value);\n if (!Number.isFinite(num)) return undefined;\n return num * 1000;\n}\n\nexport function normalizeHeader(\n headers: Record<string, string | string[] | undefined>,\n key: string\n): string | undefined {\n const header =\n headers[key] ?? headers[key.toLowerCase()] ?? headers[key.toUpperCase()];\n if (Array.isArray(header)) return header[0];\n return header;\n}\n\nexport function safeCompareHex(a: string, b: string): boolean {\n try {\n const aBuffer = Buffer.from(a, 'hex');\n const bBuffer = Buffer.from(b, 'hex');\n if (aBuffer.length !== bBuffer.length) return false;\n return timingSafeEqual(aBuffer, bBuffer);\n } catch {\n return false;\n }\n}\n\nexport async function safeReadError(response: Response): Promise<string> {\n try {\n const data = (await response.json()) as { message?: string };\n return data?.message ?? response.statusText;\n } catch {\n return response.statusText;\n }\n}\n"],"mappings":";;;;AAGA,SAAgB,aACd,OACoB;AACpB,KAAI,SAAS,KAAM,QAAO;CAC1B,MAAM,MAAM,OAAO,UAAU,WAAW,QAAQ,OAAO,MAAM;AAC7D,KAAI,CAAC,OAAO,SAAS,IAAI,CAAE,QAAO;AAClC,QAAO,MAAM;;AAGf,SAAgB,gBACd,SACA,KACoB;CACpB,MAAM,SACJ,QAAQ,QAAQ,QAAQ,IAAI,aAAa,KAAK,QAAQ,IAAI,aAAa;AACzE,KAAI,MAAM,QAAQ,OAAO,CAAE,QAAO,OAAO;AACzC,QAAO;;AAGT,SAAgB,eAAe,GAAW,GAAoB;AAC5D,KAAI;EACF,MAAM,UAAU,OAAO,KAAK,GAAG,MAAM;EACrC,MAAM,UAAU,OAAO,KAAK,GAAG,MAAM;AACrC,MAAI,QAAQ,WAAW,QAAQ,OAAQ,QAAO;AAC9C,SAAO,gBAAgB,SAAS,QAAQ;SAClC;AACN,SAAO;;;AAIX,eAAsB,cAAc,UAAqC;AACvE,KAAI;AAEF,UADc,MAAM,SAAS,MAAM,GACtB,WAAW,SAAS;SAC3B;AACN,SAAO,SAAS"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcs-storage.d.ts","names":[],"sources":["../../src/impls/gcs-storage.ts"],"
|
|
1
|
+
{"version":3,"file":"gcs-storage.d.ts","names":[],"sources":["../../src/impls/gcs-storage.ts"],"mappings":";;;;UAaiB,iCAAA;EACf,MAAA;EACA,OAAA,GAAU,OAAA;EACV,aAAA,GAAgB,cAAA;AAAA;AAAA,cAGL,0BAAA,YAAsC,iBAAA,CAAA,qBAAA;EAAA,iBAChC,OAAA;EAAA,iBACA,UAAA;cAEL,OAAA,EAAS,iCAAA;EAMf,SAAA,CAAU,KAAA,EAAO,iBAAA,CAAA,cAAA,GAAiB,OAAA,CAAQ,iBAAA,CAAA,qBAAA;EAiB1C,SAAA,CAAU,KAAA,EAAO,iBAAA,CAAA,iBAAA,GAAoB,OAAA,CAAQ,iBAAA,CAAA,eAAA;EAc7C,YAAA,CAAa,KAAA,EAAO,iBAAA,CAAA,iBAAA,GAAoB,OAAA;EAOxC,iBAAA,CAAkB,OAAA,EAAS,iBAAA,CAAA,gBAAA,GAAmB,OAAA;IAClD,GAAA;IACA,SAAA,EAAW,IAAA;EAAA;EAeP,WAAA,CAAY,KAAA,EAAO,iBAAA,CAAA,gBAAA,GAAmB,OAAA,CAAQ,iBAAA,CAAA,iBAAA;AAAA"}
|