@contractspec/integration.providers-impls 3.8.9 → 3.8.11

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.
Files changed (147) hide show
  1. package/dist/analytics.js +1 -2
  2. package/dist/calendar.js +1 -2
  3. package/dist/database.js +1 -2
  4. package/dist/email.js +1 -2
  5. package/dist/embedding.js +1 -2
  6. package/dist/health.js +1 -2
  7. package/dist/impls/async-event-queue.js +1 -48
  8. package/dist/impls/composio-fallback-resolver.js +1 -579
  9. package/dist/impls/composio-mcp.js +1 -163
  10. package/dist/impls/composio-proxies.js +1 -310
  11. package/dist/impls/composio-sdk.js +1 -77
  12. package/dist/impls/composio-types.js +1 -53
  13. package/dist/impls/elevenlabs-voice.js +1 -104
  14. package/dist/impls/fal-voice.js +1 -117
  15. package/dist/impls/fathom-meeting-recorder.js +2 -289
  16. package/dist/impls/fathom-meeting-recorder.mapper.js +1 -107
  17. package/dist/impls/fathom-meeting-recorder.utils.js +1 -74
  18. package/dist/impls/fathom-meeting-recorder.webhooks.js +1 -31
  19. package/dist/impls/fireflies-meeting-recorder.js +5 -203
  20. package/dist/impls/fireflies-meeting-recorder.queries.js +4 -14
  21. package/dist/impls/fireflies-meeting-recorder.utils.js +1 -44
  22. package/dist/impls/gcs-storage.js +1 -99
  23. package/dist/impls/gmail-inbound.js +1 -229
  24. package/dist/impls/gmail-outbound.js +25 -137
  25. package/dist/impls/google-calendar.js +1 -193
  26. package/dist/impls/gradium-voice.js +1 -95
  27. package/dist/impls/granola-meeting-recorder.js +3 -514
  28. package/dist/impls/granola-meeting-recorder.mcp.js +1 -280
  29. package/dist/impls/health/base-health-provider.js +1 -617
  30. package/dist/impls/health/hybrid-health-providers.js +1 -1089
  31. package/dist/impls/health/official-health-providers.js +1 -969
  32. package/dist/impls/health/provider-normalizers.js +1 -288
  33. package/dist/impls/health/providers.js +1 -1095
  34. package/dist/impls/health-provider-factory.js +1 -1309
  35. package/dist/impls/index.js +42 -7448
  36. package/dist/impls/jira.js +1 -126
  37. package/dist/impls/linear.js +1 -85
  38. package/dist/impls/messaging-github.js +1 -111
  39. package/dist/impls/messaging-slack.js +1 -81
  40. package/dist/impls/messaging-telegram.js +1 -48
  41. package/dist/impls/messaging-whatsapp-meta.js +1 -53
  42. package/dist/impls/messaging-whatsapp-twilio.js +1 -83
  43. package/dist/impls/mistral-conversational.js +2 -477
  44. package/dist/impls/mistral-conversational.session.js +2 -207
  45. package/dist/impls/mistral-embedding.js +1 -45
  46. package/dist/impls/mistral-llm.js +1 -271
  47. package/dist/impls/mistral-stt.js +1 -168
  48. package/dist/impls/notion.js +1 -162
  49. package/dist/impls/posthog-reader.js +1 -161
  50. package/dist/impls/posthog-utils.js +1 -40
  51. package/dist/impls/posthog.js +1 -324
  52. package/dist/impls/postmark-email.js +1 -62
  53. package/dist/impls/powens-client.js +1 -197
  54. package/dist/impls/powens-openbanking.js +1 -428
  55. package/dist/impls/provider-factory.js +18 -6268
  56. package/dist/impls/qdrant-vector.js +1 -80
  57. package/dist/impls/stripe-payments.js +1 -230
  58. package/dist/impls/supabase-psql.js +1 -152
  59. package/dist/impls/supabase-vector.js +9 -298
  60. package/dist/impls/tldv-meeting-recorder.js +2 -147
  61. package/dist/impls/twilio-sms.js +1 -67
  62. package/dist/index.js +42 -7495
  63. package/dist/llm.js +1 -2
  64. package/dist/meeting-recorder.js +1 -2
  65. package/dist/messaging.js +1 -2
  66. package/dist/node/analytics.js +1 -2
  67. package/dist/node/calendar.js +1 -2
  68. package/dist/node/database.js +1 -2
  69. package/dist/node/email.js +1 -2
  70. package/dist/node/embedding.js +1 -2
  71. package/dist/node/health.js +1 -2
  72. package/dist/node/impls/async-event-queue.js +1 -49
  73. package/dist/node/impls/composio-fallback-resolver.js +1 -580
  74. package/dist/node/impls/composio-mcp.js +1 -164
  75. package/dist/node/impls/composio-proxies.js +1 -311
  76. package/dist/node/impls/composio-sdk.js +1 -78
  77. package/dist/node/impls/composio-types.js +1 -54
  78. package/dist/node/impls/elevenlabs-voice.js +1 -105
  79. package/dist/node/impls/fal-voice.js +1 -118
  80. package/dist/node/impls/fathom-meeting-recorder.js +2 -290
  81. package/dist/node/impls/fathom-meeting-recorder.mapper.js +1 -108
  82. package/dist/node/impls/fathom-meeting-recorder.utils.js +1 -75
  83. package/dist/node/impls/fathom-meeting-recorder.webhooks.js +1 -32
  84. package/dist/node/impls/fireflies-meeting-recorder.js +5 -204
  85. package/dist/node/impls/fireflies-meeting-recorder.queries.js +4 -15
  86. package/dist/node/impls/fireflies-meeting-recorder.utils.js +1 -45
  87. package/dist/node/impls/gcs-storage.js +1 -100
  88. package/dist/node/impls/gmail-inbound.js +1 -230
  89. package/dist/node/impls/gmail-outbound.js +25 -138
  90. package/dist/node/impls/google-calendar.js +1 -194
  91. package/dist/node/impls/gradium-voice.js +1 -96
  92. package/dist/node/impls/granola-meeting-recorder.js +3 -515
  93. package/dist/node/impls/granola-meeting-recorder.mcp.js +1 -281
  94. package/dist/node/impls/health/base-health-provider.js +1 -618
  95. package/dist/node/impls/health/hybrid-health-providers.js +1 -1090
  96. package/dist/node/impls/health/official-health-providers.js +1 -970
  97. package/dist/node/impls/health/provider-normalizers.js +1 -289
  98. package/dist/node/impls/health/providers.js +1 -1096
  99. package/dist/node/impls/health-provider-factory.js +1 -1310
  100. package/dist/node/impls/index.js +42 -7449
  101. package/dist/node/impls/jira.js +1 -127
  102. package/dist/node/impls/linear.js +1 -86
  103. package/dist/node/impls/messaging-github.js +1 -112
  104. package/dist/node/impls/messaging-slack.js +1 -82
  105. package/dist/node/impls/messaging-telegram.js +1 -49
  106. package/dist/node/impls/messaging-whatsapp-meta.js +1 -54
  107. package/dist/node/impls/messaging-whatsapp-twilio.js +1 -84
  108. package/dist/node/impls/mistral-conversational.js +2 -478
  109. package/dist/node/impls/mistral-conversational.session.js +2 -208
  110. package/dist/node/impls/mistral-embedding.js +1 -46
  111. package/dist/node/impls/mistral-llm.js +1 -272
  112. package/dist/node/impls/mistral-stt.js +1 -169
  113. package/dist/node/impls/notion.js +1 -163
  114. package/dist/node/impls/posthog-reader.js +1 -162
  115. package/dist/node/impls/posthog-utils.js +1 -41
  116. package/dist/node/impls/posthog.js +1 -325
  117. package/dist/node/impls/postmark-email.js +1 -63
  118. package/dist/node/impls/powens-client.js +1 -198
  119. package/dist/node/impls/powens-openbanking.js +1 -429
  120. package/dist/node/impls/provider-factory.js +18 -6269
  121. package/dist/node/impls/qdrant-vector.js +1 -81
  122. package/dist/node/impls/stripe-payments.js +1 -231
  123. package/dist/node/impls/supabase-psql.js +1 -153
  124. package/dist/node/impls/supabase-vector.js +9 -299
  125. package/dist/node/impls/tldv-meeting-recorder.js +2 -148
  126. package/dist/node/impls/twilio-sms.js +1 -68
  127. package/dist/node/index.js +42 -7496
  128. package/dist/node/llm.js +1 -2
  129. package/dist/node/meeting-recorder.js +1 -2
  130. package/dist/node/messaging.js +1 -2
  131. package/dist/node/openbanking.js +1 -2
  132. package/dist/node/payments.js +1 -2
  133. package/dist/node/project-management.js +1 -2
  134. package/dist/node/secrets/provider.js +1 -14
  135. package/dist/node/sms.js +1 -2
  136. package/dist/node/storage.js +1 -2
  137. package/dist/node/vector-store.js +1 -2
  138. package/dist/node/voice.js +1 -2
  139. package/dist/openbanking.js +1 -2
  140. package/dist/payments.js +1 -2
  141. package/dist/project-management.js +1 -2
  142. package/dist/secrets/provider.js +1 -13
  143. package/dist/sms.js +1 -2
  144. package/dist/storage.js +1 -2
  145. package/dist/vector-store.js +1 -2
  146. package/dist/voice.js +1 -2
  147. package/package.json +16 -16
@@ -1,105 +1,2 @@
1
1
  // @bun
2
- var __require = import.meta.require;
3
-
4
- // src/impls/elevenlabs-voice.ts
5
- import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
6
- var FORMAT_MAP = {
7
- mp3: "mp3_44100_128",
8
- wav: "pcm_44100",
9
- ogg: "mp3_44100_128",
10
- pcm: "pcm_16000",
11
- opus: "mp3_44100_128"
12
- };
13
- var SAMPLE_RATE = {
14
- mp3_22050_32: 22050,
15
- mp3_44100_32: 44100,
16
- mp3_44100_64: 44100,
17
- mp3_44100_96: 44100,
18
- mp3_44100_128: 44100,
19
- mp3_44100_192: 44100,
20
- pcm_16000: 16000,
21
- pcm_22050: 22050,
22
- pcm_24000: 24000,
23
- pcm_44100: 44100,
24
- ulaw_8000: 8000
25
- };
26
-
27
- class ElevenLabsVoiceProvider {
28
- client;
29
- defaultVoiceId;
30
- modelId;
31
- constructor(options) {
32
- this.client = options.client ?? new ElevenLabsClient({
33
- apiKey: options.apiKey
34
- });
35
- this.defaultVoiceId = options.defaultVoiceId;
36
- this.modelId = options.modelId;
37
- }
38
- async listVoices() {
39
- const response = await this.client.voices.getAll();
40
- return (response.voices ?? []).map((voice) => ({
41
- id: voice.voiceId ?? "",
42
- name: voice.name ?? "",
43
- description: voice.description ?? undefined,
44
- language: voice.labels?.language ?? undefined,
45
- metadata: {
46
- category: voice.category ?? "",
47
- ...voice.previewUrl ? { previewUrl: voice.previewUrl } : {},
48
- ...(() => {
49
- const { language, ...rest } = voice.labels ?? {};
50
- return rest;
51
- })()
52
- }
53
- }));
54
- }
55
- async synthesize(input) {
56
- const voiceId = input.voiceId ?? this.defaultVoiceId;
57
- if (!voiceId) {
58
- throw new Error("Voice ID is required for ElevenLabs synthesis.");
59
- }
60
- const formatKey = input.format ?? "mp3";
61
- const outputFormat = FORMAT_MAP[formatKey] ?? FORMAT_MAP.mp3;
62
- const sampleRate = input.sampleRateHz ?? SAMPLE_RATE[outputFormat] ?? SAMPLE_RATE.mp3_44100_128 ?? 44100;
63
- const voiceSettings = input.stability != null || input.style != null ? {
64
- ...input.stability != null ? { stability: input.stability } : {},
65
- ...input.style != null ? { style: input.style } : {}
66
- } : undefined;
67
- const stream = await this.client.textToSpeech.convert(voiceId, {
68
- text: input.text,
69
- modelId: this.modelId,
70
- outputFormat,
71
- voiceSettings
72
- });
73
- const rawAudio = await readWebStream(stream);
74
- return {
75
- audio: {
76
- data: rawAudio,
77
- format: formatKey,
78
- sampleRateHz: sampleRate
79
- }
80
- };
81
- }
82
- }
83
- async function readWebStream(stream) {
84
- const reader = stream.getReader();
85
- const chunks = [];
86
- while (true) {
87
- const { done, value } = await reader.read();
88
- if (done)
89
- break;
90
- if (value) {
91
- chunks.push(value);
92
- }
93
- }
94
- const length = chunks.reduce((total, chunk) => total + chunk.length, 0);
95
- const result = new Uint8Array(length);
96
- let offset = 0;
97
- for (const chunk of chunks) {
98
- result.set(chunk, offset);
99
- offset += chunk.length;
100
- }
101
- return result;
102
- }
103
- export {
104
- ElevenLabsVoiceProvider
105
- };
2
+ var u=import.meta.require;import{ElevenLabsClient as d}from"@elevenlabs/elevenlabs-js";var l={mp3:"mp3_44100_128",wav:"pcm_44100",ogg:"mp3_44100_128",pcm:"pcm_16000",opus:"mp3_44100_128"},c={mp3_22050_32:22050,mp3_44100_32:44100,mp3_44100_64:44100,mp3_44100_96:44100,mp3_44100_128:44100,mp3_44100_192:44100,pcm_16000:16000,pcm_22050:22050,pcm_24000:24000,pcm_44100:44100,ulaw_8000:8000};class m{client;defaultVoiceId;modelId;constructor(e){this.client=e.client??new d({apiKey:e.apiKey}),this.defaultVoiceId=e.defaultVoiceId,this.modelId=e.modelId}async listVoices(){return((await this.client.voices.getAll()).voices??[]).map((t)=>({id:t.voiceId??"",name:t.name??"",description:t.description??void 0,language:t.labels?.language??void 0,metadata:{category:t.category??"",...t.previewUrl?{previewUrl:t.previewUrl}:{},...(()=>{let{language:s,...a}=t.labels??{};return a})()}}))}async synthesize(e){let t=e.voiceId??this.defaultVoiceId;if(!t)throw Error("Voice ID is required for ElevenLabs synthesis.");let s=e.format??"mp3",a=l[s]??l.mp3,o=e.sampleRateHz??c[a]??c.mp3_44100_128??44100,i=e.stability!=null||e.style!=null?{...e.stability!=null?{stability:e.stability}:{},...e.style!=null?{style:e.style}:{}}:void 0,r=await this.client.textToSpeech.convert(t,{text:e.text,modelId:this.modelId,outputFormat:a,voiceSettings:i});return{audio:{data:await p(r),format:s,sampleRateHz:o}}}}async function p(e){let t=e.getReader(),s=[];while(!0){let{done:r,value:n}=await t.read();if(r)break;if(n)s.push(n)}let a=s.reduce((r,n)=>r+n.length,0),o=new Uint8Array(a),i=0;for(let r of s)o.set(r,i),i+=r.length;return o}export{m as ElevenLabsVoiceProvider};
@@ -1,118 +1,2 @@
1
1
  // @bun
2
- var __require = import.meta.require;
3
-
4
- // src/impls/fal-voice.ts
5
- import { createFalClient } from "@fal-ai/client";
6
- var DEFAULT_MODEL_ID = "fal-ai/chatterbox/text-to-speech";
7
-
8
- class FalVoiceProvider {
9
- client;
10
- modelId;
11
- defaultVoiceUrl;
12
- defaultExaggeration;
13
- defaultTemperature;
14
- defaultCfg;
15
- pollIntervalMs;
16
- constructor(options) {
17
- this.client = options.client ?? createFalClient({
18
- credentials: options.apiKey
19
- });
20
- this.modelId = options.modelId ?? DEFAULT_MODEL_ID;
21
- this.defaultVoiceUrl = options.defaultVoiceUrl;
22
- this.defaultExaggeration = options.defaultExaggeration;
23
- this.defaultTemperature = options.defaultTemperature;
24
- this.defaultCfg = options.defaultCfg;
25
- this.pollIntervalMs = options.pollIntervalMs;
26
- }
27
- async listVoices() {
28
- const voices = [
29
- {
30
- id: "default",
31
- name: "Default Chatterbox Voice",
32
- description: "Uses the default model voice (or configured default reference audio URL).",
33
- metadata: {
34
- modelId: this.modelId
35
- }
36
- }
37
- ];
38
- if (this.defaultVoiceUrl) {
39
- voices.push({
40
- id: this.defaultVoiceUrl,
41
- name: "Configured Reference Voice",
42
- description: "Reference voice configured at provider setup and used when voiceId is default.",
43
- previewUrl: this.defaultVoiceUrl,
44
- metadata: {
45
- modelId: this.modelId,
46
- source: "config.defaultVoiceUrl"
47
- }
48
- });
49
- }
50
- return voices;
51
- }
52
- async synthesize(input) {
53
- const referenceVoiceUrl = resolveVoiceUrl(input.voiceId, this.defaultVoiceUrl);
54
- const result = await this.client.subscribe(this.modelId, {
55
- input: {
56
- text: input.text,
57
- ...referenceVoiceUrl ? { audio_url: referenceVoiceUrl } : {},
58
- ...this.defaultExaggeration != null ? { exaggeration: this.defaultExaggeration } : {},
59
- ...this.defaultTemperature != null ? { temperature: this.defaultTemperature } : {},
60
- ...this.defaultCfg != null ? { cfg: this.defaultCfg } : {}
61
- },
62
- pollInterval: this.pollIntervalMs
63
- });
64
- const audioUrl = extractAudioUrl(result.data);
65
- if (!audioUrl) {
66
- throw new Error("Fal synthesis completed without an audio URL in response.");
67
- }
68
- const response = await fetch(audioUrl);
69
- if (!response.ok) {
70
- throw new Error(`Fal audio download failed (${response.status}).`);
71
- }
72
- const rawAudio = new Uint8Array(await response.arrayBuffer());
73
- const format = input.format ?? inferFormatFromUrl(audioUrl) ?? "wav";
74
- return {
75
- audio: {
76
- data: rawAudio,
77
- format,
78
- sampleRateHz: input.sampleRateHz ?? 24000
79
- }
80
- };
81
- }
82
- }
83
- function resolveVoiceUrl(voiceId, defaultVoiceUrl) {
84
- if (!voiceId || voiceId === "default")
85
- return defaultVoiceUrl;
86
- if (isHttpUrl(voiceId))
87
- return voiceId;
88
- throw new Error('Fal voiceId must be "default" or a public reference audio URL.');
89
- }
90
- function extractAudioUrl(output) {
91
- if (output.audio?.url)
92
- return output.audio.url;
93
- if (typeof output.audio_url === "string")
94
- return output.audio_url;
95
- if (typeof output.url === "string")
96
- return output.url;
97
- return;
98
- }
99
- function inferFormatFromUrl(url) {
100
- const normalized = url.toLowerCase();
101
- if (normalized.endsWith(".wav"))
102
- return "wav";
103
- if (normalized.endsWith(".mp3"))
104
- return "mp3";
105
- if (normalized.endsWith(".ogg"))
106
- return "ogg";
107
- if (normalized.endsWith(".opus"))
108
- return "opus";
109
- if (normalized.endsWith(".pcm"))
110
- return "pcm";
111
- return;
112
- }
113
- function isHttpUrl(value) {
114
- return value.startsWith("https://") || value.startsWith("http://");
115
- }
116
- export {
117
- FalVoiceProvider
118
- };
2
+ var h=import.meta.require;import{createFalClient as o}from"@fal-ai/client";var d="fal-ai/chatterbox/text-to-speech";class u{client;modelId;defaultVoiceUrl;defaultExaggeration;defaultTemperature;defaultCfg;pollIntervalMs;constructor(e){this.client=e.client??o({credentials:e.apiKey}),this.modelId=e.modelId??d,this.defaultVoiceUrl=e.defaultVoiceUrl,this.defaultExaggeration=e.defaultExaggeration,this.defaultTemperature=e.defaultTemperature,this.defaultCfg=e.defaultCfg,this.pollIntervalMs=e.pollIntervalMs}async listVoices(){let e=[{id:"default",name:"Default Chatterbox Voice",description:"Uses the default model voice (or configured default reference audio URL).",metadata:{modelId:this.modelId}}];if(this.defaultVoiceUrl)e.push({id:this.defaultVoiceUrl,name:"Configured Reference Voice",description:"Reference voice configured at provider setup and used when voiceId is default.",previewUrl:this.defaultVoiceUrl,metadata:{modelId:this.modelId,source:"config.defaultVoiceUrl"}});return e}async synthesize(e){let t=s(e.voiceId,this.defaultVoiceUrl),a=await this.client.subscribe(this.modelId,{input:{text:e.text,...t?{audio_url:t}:{},...this.defaultExaggeration!=null?{exaggeration:this.defaultExaggeration}:{},...this.defaultTemperature!=null?{temperature:this.defaultTemperature}:{},...this.defaultCfg!=null?{cfg:this.defaultCfg}:{}},pollInterval:this.pollIntervalMs}),r=f(a.data);if(!r)throw Error("Fal synthesis completed without an audio URL in response.");let i=await fetch(r);if(!i.ok)throw Error(`Fal audio download failed (${i.status}).`);let n=new Uint8Array(await i.arrayBuffer()),l=e.format??c(r)??"wav";return{audio:{data:n,format:l,sampleRateHz:e.sampleRateHz??24000}}}}function s(e,t){if(!e||e==="default")return t;if(m(e))return e;throw Error('Fal voiceId must be "default" or a public reference audio URL.')}function f(e){if(e.audio?.url)return e.audio.url;if(typeof e.audio_url==="string")return e.audio_url;if(typeof e.url==="string")return e.url;return}function c(e){let t=e.toLowerCase();if(t.endsWith(".wav"))return"wav";if(t.endsWith(".mp3"))return"mp3";if(t.endsWith(".ogg"))return"ogg";if(t.endsWith(".opus"))return"opus";if(t.endsWith(".pcm"))return"pcm";return}function m(e){return e.startsWith("https://")||e.startsWith("http://")}export{u as FalVoiceProvider};
@@ -1,290 +1,3 @@
1
1
  // @bun
2
- var __require = import.meta.require;
3
-
4
- // src/impls/fathom-meeting-recorder.utils.ts
5
- function extractItems(page) {
6
- if (Array.isArray(page.items))
7
- return page.items;
8
- if (Array.isArray(page.data)) {
9
- return page.data;
10
- }
11
- return [];
12
- }
13
- function extractNextCursor(page) {
14
- return page.nextCursor ?? page.next_cursor ?? undefined;
15
- }
16
- function mapInvitee(invitee) {
17
- const email = invitee.email;
18
- const name = invitee.name;
19
- if (!email && !name)
20
- return;
21
- return {
22
- email,
23
- name,
24
- role: "attendee",
25
- isExternal: invitee.is_external
26
- };
27
- }
28
- function matchRecordingId(meeting, targetId) {
29
- return meeting.recordingId === targetId;
30
- }
31
- function durationSeconds(start, end) {
32
- if (!start || !end)
33
- return;
34
- const startDate = start instanceof Date ? start : new Date(start);
35
- const endDate = end instanceof Date ? end : new Date(end);
36
- if (Number.isNaN(startDate.valueOf()) || Number.isNaN(endDate.valueOf())) {
37
- return;
38
- }
39
- return Math.max(0, (endDate.valueOf() - startDate.valueOf()) / 1000);
40
- }
41
- function mapTranscriptSegment(segment, index) {
42
- return {
43
- index,
44
- speakerName: segment.speaker?.display_name ?? undefined,
45
- speakerEmail: segment.speaker?.matched_calendar_invitee_email ?? undefined,
46
- text: segment.text,
47
- startTimeMs: parseTimestamp(segment.timestamp)
48
- };
49
- }
50
- function parseTimestamp(value) {
51
- const parts = value.split(":").map((part) => Number(part));
52
- if (parts.length !== 3 || parts.some((part) => Number.isNaN(part))) {
53
- return;
54
- }
55
- const [hours = 0, minutes = 0, seconds = 0] = parts;
56
- return (hours * 3600 + minutes * 60 + seconds) * 1000;
57
- }
58
- async function safeReadError(response) {
59
- try {
60
- const data = await response.json();
61
- return data?.message ?? response.statusText;
62
- } catch {
63
- return response.statusText;
64
- }
65
- }
66
-
67
- // src/impls/fathom-meeting-recorder.mapper.ts
68
- var mapFathomMeetingInvites = (invitees) => {
69
- return invitees.map((invitee) => ({
70
- ...invitee,
71
- name: invitee.name ?? undefined,
72
- email: invitee.email ?? undefined
73
- }));
74
- };
75
- function mapFathomMeeting(meeting, params) {
76
- const connectionId = params.connectionId ?? "unknown";
77
- return {
78
- id: meeting.recordingId.toString(),
79
- tenantId: params.tenantId,
80
- connectionId,
81
- externalId: meeting.recordingId.toString(),
82
- title: meeting.title ?? meeting.meetingTitle,
83
- organizer: meeting.recordedBy ? {
84
- name: meeting.recordedBy.name ?? undefined,
85
- email: meeting.recordedBy.email ?? undefined,
86
- role: "organizer"
87
- } : undefined,
88
- invitees: meeting.calendarInvitees.length ? mapFathomMeetingInvites(meeting.calendarInvitees) : undefined,
89
- participants: meeting.calendarInvitees.length ? mapFathomMeetingInvites(meeting.calendarInvitees) : undefined,
90
- scheduledStartAt: meeting.scheduledStartTime?.toISOString(),
91
- scheduledEndAt: meeting.scheduledEndTime?.toISOString(),
92
- recordingStartAt: meeting.recordingStartTime?.toISOString(),
93
- recordingEndAt: meeting.recordingEndTime?.toISOString(),
94
- durationSeconds: durationSeconds(meeting.recordingStartTime, meeting.recordingEndTime),
95
- meetingUrl: meeting.url ?? undefined,
96
- shareUrl: meeting.shareUrl ?? undefined,
97
- transcriptAvailable: Array.isArray(meeting.transcript),
98
- sourcePlatform: "fathom",
99
- language: meeting.transcriptLanguage,
100
- metadata: {
101
- calendarInviteesDomainsType: meeting.calendarInviteesDomainsType
102
- }
103
- };
104
- }
105
-
106
- // src/impls/fathom-meeting-recorder.webhooks.ts
107
- import { TriggeredFor } from "fathom-typescript/sdk/models/operations";
108
- function normalizeWebhookHeaders(headers) {
109
- const normalized = {};
110
- for (const [key, value] of Object.entries(headers)) {
111
- if (value == null)
112
- continue;
113
- const normalizedKey = key.toLowerCase();
114
- if (Array.isArray(value)) {
115
- if (value.length === 0)
116
- continue;
117
- normalized[normalizedKey] = value.join(", ");
118
- } else {
119
- normalized[normalizedKey] = value;
120
- }
121
- }
122
- return normalized;
123
- }
124
- function normalizeTriggeredFor(values) {
125
- if (!values)
126
- return;
127
- const allowed = new Set(Object.values(TriggeredFor));
128
- const normalized = values.map((value) => value.trim()).filter((value) => allowed.has(value));
129
- return normalized.length ? normalized : undefined;
130
- }
131
-
132
- // src/impls/fathom-meeting-recorder.ts
133
- import { Fathom } from "fathom-typescript";
134
- import { TriggeredFor as TriggeredFor2 } from "fathom-typescript/sdk/models/operations";
135
- var DEFAULT_BASE_URL = "https://api.fathom.ai/external/v1";
136
-
137
- class FathomMeetingRecorderProvider {
138
- client;
139
- apiKey;
140
- baseUrl;
141
- includeTranscript;
142
- includeSummary;
143
- includeActionItems;
144
- includeCrmMatches;
145
- triggeredFor;
146
- webhookSecret;
147
- maxPages;
148
- constructor(options) {
149
- this.apiKey = options.apiKey;
150
- this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
151
- this.includeTranscript = options.includeTranscript ?? false;
152
- this.includeSummary = options.includeSummary ?? false;
153
- this.includeActionItems = options.includeActionItems ?? false;
154
- this.includeCrmMatches = options.includeCrmMatches ?? false;
155
- this.triggeredFor = options.triggeredFor;
156
- this.webhookSecret = options.webhookSecret;
157
- this.maxPages = options.maxPages ?? 5;
158
- this.client = options.client ?? new Fathom({
159
- serverURL: this.baseUrl,
160
- security: {
161
- apiKeyAuth: this.apiKey
162
- }
163
- });
164
- }
165
- async listMeetings(params) {
166
- const request = {
167
- cursor: params.cursor,
168
- createdAfter: params.from,
169
- createdBefore: params.to,
170
- includeTranscript: params.includeTranscript ?? this.includeTranscript,
171
- includeSummary: params.includeSummary ?? this.includeSummary,
172
- includeActionItems: this.includeActionItems,
173
- includeCrmMatches: this.includeCrmMatches
174
- };
175
- const result = await this.client.listMeetings(request);
176
- let firstPage;
177
- for await (const page of result) {
178
- firstPage = page;
179
- break;
180
- }
181
- if (!firstPage) {
182
- return { meetings: [] };
183
- }
184
- const rawItems = extractItems(firstPage);
185
- const meetings = rawItems.map((meeting) => mapFathomMeeting(meeting, params));
186
- return {
187
- meetings,
188
- nextCursor: extractNextCursor(firstPage) ?? undefined,
189
- hasMore: Boolean(extractNextCursor(firstPage))
190
- };
191
- }
192
- async getMeeting(params) {
193
- const result = await this.client.listMeetings({
194
- includeTranscript: params.includeTranscript ?? this.includeTranscript,
195
- includeSummary: params.includeSummary ?? this.includeSummary,
196
- includeActionItems: this.includeActionItems,
197
- includeCrmMatches: this.includeCrmMatches
198
- });
199
- let pageCount = 0;
200
- const targetId = Number.parseInt(params.meetingId, 10);
201
- for await (const page of result) {
202
- pageCount += 1;
203
- const match = extractItems(page).find((meeting) => matchRecordingId(meeting, targetId));
204
- if (match) {
205
- return mapFathomMeeting(match, params);
206
- }
207
- if (pageCount >= this.maxPages) {
208
- break;
209
- }
210
- }
211
- throw new Error(`Fathom meeting "${targetId}" not found.`);
212
- }
213
- async getTranscript(params) {
214
- const response = await this.request(`/recordings/${encodeURIComponent(params.meetingId)}/transcript`);
215
- if (!Array.isArray(response.transcript)) {
216
- throw new Error("Fathom transcript response did not include transcript.");
217
- }
218
- const segments = response.transcript.map((segment, index) => mapTranscriptSegment(segment, index));
219
- return {
220
- id: params.meetingId,
221
- meetingId: params.meetingId,
222
- tenantId: params.tenantId,
223
- connectionId: params.connectionId ?? "unknown",
224
- externalId: params.meetingId,
225
- format: "segments",
226
- text: segments.map((segment) => segment.text).join(`
227
- `),
228
- segments,
229
- metadata: {
230
- provider: "fathom"
231
- },
232
- raw: response.transcript
233
- };
234
- }
235
- async parseWebhook(request) {
236
- const payload = request.parsedBody ?? JSON.parse(request.rawBody);
237
- const body = payload;
238
- const recordingId = body.recording_id ?? body.recordingId ?? body.meeting_id ?? body.meetingId;
239
- const verified = this.webhookSecret ? await this.verifyWebhook(request) : undefined;
240
- return {
241
- providerKey: "meeting-recorder.fathom",
242
- eventType: body.event_type ?? body.eventType,
243
- meetingId: recordingId,
244
- recordingId,
245
- verified,
246
- payload
247
- };
248
- }
249
- async verifyWebhook(request) {
250
- if (!this.webhookSecret)
251
- return true;
252
- const headers = normalizeWebhookHeaders(request.headers);
253
- try {
254
- return Boolean(Fathom.verifyWebhook(this.webhookSecret, headers, request.rawBody));
255
- } catch {
256
- return false;
257
- }
258
- }
259
- async registerWebhook(registration) {
260
- const triggeredFor = normalizeTriggeredFor(registration.triggeredFor) ?? normalizeTriggeredFor(this.triggeredFor) ?? [TriggeredFor2.MyRecordings];
261
- const webhook = await this.client.createWebhook({
262
- destinationUrl: registration.url,
263
- includeTranscript: registration.includeTranscript ?? true,
264
- includeSummary: registration.includeSummary ?? false,
265
- includeActionItems: registration.includeActionItems ?? false,
266
- includeCrmMatches: registration.includeCrmMatches ?? false,
267
- triggeredFor
268
- });
269
- return {
270
- id: webhook.id,
271
- secret: webhook.secret
272
- };
273
- }
274
- async request(path) {
275
- const response = await fetch(`${this.baseUrl}${path}`, {
276
- headers: {
277
- "Content-Type": "application/json",
278
- "X-Api-Key": this.apiKey
279
- }
280
- });
281
- if (!response.ok) {
282
- const message = await safeReadError(response);
283
- throw new Error(`Fathom API error (${response.status}): ${message}`);
284
- }
285
- return await response.json();
286
- }
287
- }
288
- export {
289
- FathomMeetingRecorderProvider
290
- };
2
+ var P=import.meta.require;function u(n){if(Array.isArray(n.items))return n.items;if(Array.isArray(n.data))return n.data;return[]}function f(n){return n.nextCursor??n.next_cursor??void 0}function E(n){let{email:e,name:t}=n;if(!e&&!t)return;return{email:e,name:t,role:"attendee",isExternal:n.is_external}}function l(n,e){return n.recordingId===e}function S(n,e){if(!n||!e)return;let t=n instanceof Date?n:new Date(n),d=e instanceof Date?e:new Date(e);if(Number.isNaN(t.valueOf())||Number.isNaN(d.valueOf()))return;return Math.max(0,(d.valueOf()-t.valueOf())/1000)}function I(n,e){return{index:e,speakerName:n.speaker?.display_name??void 0,speakerEmail:n.speaker?.matched_calendar_invitee_email??void 0,text:n.text,startTimeMs:N(n.timestamp)}}function N(n){let e=n.split(":").map((r)=>Number(r));if(e.length!==3||e.some((r)=>Number.isNaN(r)))return;let[t=0,d=0,i=0]=e;return(t*3600+d*60+i)*1000}async function x(n){try{return(await n.json())?.message??n.statusText}catch{return n.statusText}}var h=(n)=>{return n.map((e)=>({...e,name:e.name??void 0,email:e.email??void 0}))};function a(n,e){let t=e.connectionId??"unknown";return{id:n.recordingId.toString(),tenantId:e.tenantId,connectionId:t,externalId:n.recordingId.toString(),title:n.title??n.meetingTitle,organizer:n.recordedBy?{name:n.recordedBy.name??void 0,email:n.recordedBy.email??void 0,role:"organizer"}:void 0,invitees:n.calendarInvitees.length?h(n.calendarInvitees):void 0,participants:n.calendarInvitees.length?h(n.calendarInvitees):void 0,scheduledStartAt:n.scheduledStartTime?.toISOString(),scheduledEndAt:n.scheduledEndTime?.toISOString(),recordingStartAt:n.recordingStartTime?.toISOString(),recordingEndAt:n.recordingEndTime?.toISOString(),durationSeconds:S(n.recordingStartTime,n.recordingEndTime),meetingUrl:n.url??void 0,shareUrl:n.shareUrl??void 0,transcriptAvailable:Array.isArray(n.transcript),sourcePlatform:"fathom",language:n.transcriptLanguage,metadata:{calendarInviteesDomainsType:n.calendarInviteesDomainsType}}}import{TriggeredFor as A}from"fathom-typescript/sdk/models/operations";function o(n){let e={};for(let[t,d]of Object.entries(n)){if(d==null)continue;let i=t.toLowerCase();if(Array.isArray(d)){if(d.length===0)continue;e[i]=d.join(", ")}else e[i]=d}return e}function M(n){if(!n)return;let e=new Set(Object.values(A)),t=n.map((d)=>d.trim()).filter((d)=>e.has(d));return t.length?t:void 0}import{Fathom as T}from"fathom-typescript";import{TriggeredFor as D}from"fathom-typescript/sdk/models/operations";var y="https://api.fathom.ai/external/v1";class O{client;apiKey;baseUrl;includeTranscript;includeSummary;includeActionItems;includeCrmMatches;triggeredFor;webhookSecret;maxPages;constructor(n){this.apiKey=n.apiKey,this.baseUrl=n.baseUrl??y,this.includeTranscript=n.includeTranscript??!1,this.includeSummary=n.includeSummary??!1,this.includeActionItems=n.includeActionItems??!1,this.includeCrmMatches=n.includeCrmMatches??!1,this.triggeredFor=n.triggeredFor,this.webhookSecret=n.webhookSecret,this.maxPages=n.maxPages??5,this.client=n.client??new T({serverURL:this.baseUrl,security:{apiKeyAuth:this.apiKey}})}async listMeetings(n){let e={cursor:n.cursor,createdAfter:n.from,createdBefore:n.to,includeTranscript:n.includeTranscript??this.includeTranscript,includeSummary:n.includeSummary??this.includeSummary,includeActionItems:this.includeActionItems,includeCrmMatches:this.includeCrmMatches},t=await this.client.listMeetings(e),d;for await(let c of t){d=c;break}if(!d)return{meetings:[]};return{meetings:u(d).map((c)=>a(c,n)),nextCursor:f(d)??void 0,hasMore:Boolean(f(d))}}async getMeeting(n){let e=await this.client.listMeetings({includeTranscript:n.includeTranscript??this.includeTranscript,includeSummary:n.includeSummary??this.includeSummary,includeActionItems:this.includeActionItems,includeCrmMatches:this.includeCrmMatches}),t=0,d=Number.parseInt(n.meetingId,10);for await(let i of e){t+=1;let r=u(i).find((c)=>l(c,d));if(r)return a(r,n);if(t>=this.maxPages)break}throw Error(`Fathom meeting "${d}" not found.`)}async getTranscript(n){let e=await this.request(`/recordings/${encodeURIComponent(n.meetingId)}/transcript`);if(!Array.isArray(e.transcript))throw Error("Fathom transcript response did not include transcript.");let t=e.transcript.map((d,i)=>I(d,i));return{id:n.meetingId,meetingId:n.meetingId,tenantId:n.tenantId,connectionId:n.connectionId??"unknown",externalId:n.meetingId,format:"segments",text:t.map((d)=>d.text).join(`
3
+ `),segments:t,metadata:{provider:"fathom"},raw:e.transcript}}async parseWebhook(n){let e=n.parsedBody??JSON.parse(n.rawBody),t=e,d=t.recording_id??t.recordingId??t.meeting_id??t.meetingId,i=this.webhookSecret?await this.verifyWebhook(n):void 0;return{providerKey:"meeting-recorder.fathom",eventType:t.event_type??t.eventType,meetingId:d,recordingId:d,verified:i,payload:e}}async verifyWebhook(n){if(!this.webhookSecret)return!0;let e=o(n.headers);try{return Boolean(T.verifyWebhook(this.webhookSecret,e,n.rawBody))}catch{return!1}}async registerWebhook(n){let e=M(n.triggeredFor)??M(this.triggeredFor)??[D.MyRecordings],t=await this.client.createWebhook({destinationUrl:n.url,includeTranscript:n.includeTranscript??!0,includeSummary:n.includeSummary??!1,includeActionItems:n.includeActionItems??!1,includeCrmMatches:n.includeCrmMatches??!1,triggeredFor:e});return{id:t.id,secret:t.secret}}async request(n){let e=await fetch(`${this.baseUrl}${n}`,{headers:{"Content-Type":"application/json","X-Api-Key":this.apiKey}});if(!e.ok){let t=await x(e);throw Error(`Fathom API error (${e.status}): ${t}`)}return await e.json()}}export{O as FathomMeetingRecorderProvider};
@@ -1,108 +1,2 @@
1
1
  // @bun
2
- var __require = import.meta.require;
3
-
4
- // src/impls/fathom-meeting-recorder.utils.ts
5
- function extractItems(page) {
6
- if (Array.isArray(page.items))
7
- return page.items;
8
- if (Array.isArray(page.data)) {
9
- return page.data;
10
- }
11
- return [];
12
- }
13
- function extractNextCursor(page) {
14
- return page.nextCursor ?? page.next_cursor ?? undefined;
15
- }
16
- function mapInvitee(invitee) {
17
- const email = invitee.email;
18
- const name = invitee.name;
19
- if (!email && !name)
20
- return;
21
- return {
22
- email,
23
- name,
24
- role: "attendee",
25
- isExternal: invitee.is_external
26
- };
27
- }
28
- function matchRecordingId(meeting, targetId) {
29
- return meeting.recordingId === targetId;
30
- }
31
- function durationSeconds(start, end) {
32
- if (!start || !end)
33
- return;
34
- const startDate = start instanceof Date ? start : new Date(start);
35
- const endDate = end instanceof Date ? end : new Date(end);
36
- if (Number.isNaN(startDate.valueOf()) || Number.isNaN(endDate.valueOf())) {
37
- return;
38
- }
39
- return Math.max(0, (endDate.valueOf() - startDate.valueOf()) / 1000);
40
- }
41
- function mapTranscriptSegment(segment, index) {
42
- return {
43
- index,
44
- speakerName: segment.speaker?.display_name ?? undefined,
45
- speakerEmail: segment.speaker?.matched_calendar_invitee_email ?? undefined,
46
- text: segment.text,
47
- startTimeMs: parseTimestamp(segment.timestamp)
48
- };
49
- }
50
- function parseTimestamp(value) {
51
- const parts = value.split(":").map((part) => Number(part));
52
- if (parts.length !== 3 || parts.some((part) => Number.isNaN(part))) {
53
- return;
54
- }
55
- const [hours = 0, minutes = 0, seconds = 0] = parts;
56
- return (hours * 3600 + minutes * 60 + seconds) * 1000;
57
- }
58
- async function safeReadError(response) {
59
- try {
60
- const data = await response.json();
61
- return data?.message ?? response.statusText;
62
- } catch {
63
- return response.statusText;
64
- }
65
- }
66
-
67
- // src/impls/fathom-meeting-recorder.mapper.ts
68
- var mapFathomMeetingInvites = (invitees) => {
69
- return invitees.map((invitee) => ({
70
- ...invitee,
71
- name: invitee.name ?? undefined,
72
- email: invitee.email ?? undefined
73
- }));
74
- };
75
- function mapFathomMeeting(meeting, params) {
76
- const connectionId = params.connectionId ?? "unknown";
77
- return {
78
- id: meeting.recordingId.toString(),
79
- tenantId: params.tenantId,
80
- connectionId,
81
- externalId: meeting.recordingId.toString(),
82
- title: meeting.title ?? meeting.meetingTitle,
83
- organizer: meeting.recordedBy ? {
84
- name: meeting.recordedBy.name ?? undefined,
85
- email: meeting.recordedBy.email ?? undefined,
86
- role: "organizer"
87
- } : undefined,
88
- invitees: meeting.calendarInvitees.length ? mapFathomMeetingInvites(meeting.calendarInvitees) : undefined,
89
- participants: meeting.calendarInvitees.length ? mapFathomMeetingInvites(meeting.calendarInvitees) : undefined,
90
- scheduledStartAt: meeting.scheduledStartTime?.toISOString(),
91
- scheduledEndAt: meeting.scheduledEndTime?.toISOString(),
92
- recordingStartAt: meeting.recordingStartTime?.toISOString(),
93
- recordingEndAt: meeting.recordingEndTime?.toISOString(),
94
- durationSeconds: durationSeconds(meeting.recordingStartTime, meeting.recordingEndTime),
95
- meetingUrl: meeting.url ?? undefined,
96
- shareUrl: meeting.shareUrl ?? undefined,
97
- transcriptAvailable: Array.isArray(meeting.transcript),
98
- sourcePlatform: "fathom",
99
- language: meeting.transcriptLanguage,
100
- metadata: {
101
- calendarInviteesDomainsType: meeting.calendarInviteesDomainsType
102
- }
103
- };
104
- }
105
- export {
106
- mapFathomMeetingInvites,
107
- mapFathomMeeting
108
- };
2
+ var c=import.meta.require;function m(e){if(Array.isArray(e.items))return e.items;if(Array.isArray(e.data))return e.data;return[]}function f(e){return e.nextCursor??e.next_cursor??void 0}function l(e){let{email:t,name:n}=e;if(!t&&!n)return;return{email:t,name:n,role:"attendee",isExternal:e.is_external}}function g(e,t){return e.recordingId===t}function i(e,t){if(!e||!t)return;let n=e instanceof Date?e:new Date(e),r=t instanceof Date?t:new Date(t);if(Number.isNaN(n.valueOf())||Number.isNaN(r.valueOf()))return;return Math.max(0,(r.valueOf()-n.valueOf())/1000)}function p(e,t){return{index:t,speakerName:e.speaker?.display_name??void 0,speakerEmail:e.speaker?.matched_calendar_invitee_email??void 0,text:e.text,startTimeMs:s(e.timestamp)}}function s(e){let t=e.split(":").map((a)=>Number(a));if(t.length!==3||t.some((a)=>Number.isNaN(a)))return;let[n=0,r=0,d=0]=t;return(n*3600+r*60+d)*1000}async function h(e){try{return(await e.json())?.message??e.statusText}catch{return e.statusText}}var o=(e)=>{return e.map((t)=>({...t,name:t.name??void 0,email:t.email??void 0}))};function x(e,t){let n=t.connectionId??"unknown";return{id:e.recordingId.toString(),tenantId:t.tenantId,connectionId:n,externalId:e.recordingId.toString(),title:e.title??e.meetingTitle,organizer:e.recordedBy?{name:e.recordedBy.name??void 0,email:e.recordedBy.email??void 0,role:"organizer"}:void 0,invitees:e.calendarInvitees.length?o(e.calendarInvitees):void 0,participants:e.calendarInvitees.length?o(e.calendarInvitees):void 0,scheduledStartAt:e.scheduledStartTime?.toISOString(),scheduledEndAt:e.scheduledEndTime?.toISOString(),recordingStartAt:e.recordingStartTime?.toISOString(),recordingEndAt:e.recordingEndTime?.toISOString(),durationSeconds:i(e.recordingStartTime,e.recordingEndTime),meetingUrl:e.url??void 0,shareUrl:e.shareUrl??void 0,transcriptAvailable:Array.isArray(e.transcript),sourcePlatform:"fathom",language:e.transcriptLanguage,metadata:{calendarInviteesDomainsType:e.calendarInviteesDomainsType}}}export{o as mapFathomMeetingInvites,x as mapFathomMeeting};