@contractspec/integration.providers-impls 1.56.0 → 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.
Files changed (154) hide show
  1. package/README.md +115 -1
  2. package/dist/_virtual/{rolldown_runtime.js → _rolldown/runtime.js} +3 -3
  3. package/dist/analytics.d.ts +9 -0
  4. package/dist/analytics.d.ts.map +1 -0
  5. package/dist/analytics.js +3 -0
  6. package/dist/calendar.d.ts +1 -0
  7. package/dist/calendar.d.ts.map +1 -1
  8. package/dist/calendar.js +1 -1
  9. package/dist/database.d.ts +9 -0
  10. package/dist/database.d.ts.map +1 -0
  11. package/dist/database.js +3 -0
  12. package/dist/email.d.ts +1 -0
  13. package/dist/email.d.ts.map +1 -1
  14. package/dist/email.js +1 -1
  15. package/dist/embedding.d.ts +1 -0
  16. package/dist/embedding.d.ts.map +1 -1
  17. package/dist/embedding.js +1 -1
  18. package/dist/impls/elevenlabs-voice.d.ts.map +1 -1
  19. package/dist/impls/fal-voice.d.ts +29 -0
  20. package/dist/impls/fal-voice.d.ts.map +1 -0
  21. package/dist/impls/fal-voice.js +88 -0
  22. package/dist/impls/fal-voice.js.map +1 -0
  23. package/dist/impls/fathom-meeting-recorder.d.ts +42 -0
  24. package/dist/impls/fathom-meeting-recorder.d.ts.map +1 -0
  25. package/dist/impls/fathom-meeting-recorder.js +145 -0
  26. package/dist/impls/fathom-meeting-recorder.js.map +1 -0
  27. package/dist/impls/fathom-meeting-recorder.mapper.d.ts +9 -0
  28. package/dist/impls/fathom-meeting-recorder.mapper.d.ts.map +1 -0
  29. package/dist/impls/fathom-meeting-recorder.mapper.js +42 -0
  30. package/dist/impls/fathom-meeting-recorder.mapper.js.map +1 -0
  31. package/dist/impls/fathom-meeting-recorder.types.d.ts +24 -0
  32. package/dist/impls/fathom-meeting-recorder.types.d.ts.map +1 -0
  33. package/dist/impls/fathom-meeting-recorder.types.js +0 -0
  34. package/dist/impls/fathom-meeting-recorder.utils.d.ts +15 -0
  35. package/dist/impls/fathom-meeting-recorder.utils.d.ts.map +1 -0
  36. package/dist/impls/fathom-meeting-recorder.utils.js +56 -0
  37. package/dist/impls/fathom-meeting-recorder.utils.js.map +1 -0
  38. package/dist/impls/fathom-meeting-recorder.webhooks.d.ts +8 -0
  39. package/dist/impls/fathom-meeting-recorder.webhooks.d.ts.map +1 -0
  40. package/dist/impls/fathom-meeting-recorder.webhooks.js +25 -0
  41. package/dist/impls/fathom-meeting-recorder.webhooks.js.map +1 -0
  42. package/dist/impls/fireflies-meeting-recorder.d.ts +28 -0
  43. package/dist/impls/fireflies-meeting-recorder.d.ts.map +1 -0
  44. package/dist/impls/fireflies-meeting-recorder.js +152 -0
  45. package/dist/impls/fireflies-meeting-recorder.js.map +1 -0
  46. package/dist/impls/fireflies-meeting-recorder.queries.d.ts +7 -0
  47. package/dist/impls/fireflies-meeting-recorder.queries.d.ts.map +1 -0
  48. package/dist/impls/fireflies-meeting-recorder.queries.js +84 -0
  49. package/dist/impls/fireflies-meeting-recorder.queries.js.map +1 -0
  50. package/dist/impls/fireflies-meeting-recorder.types.d.ts +35 -0
  51. package/dist/impls/fireflies-meeting-recorder.types.d.ts.map +1 -0
  52. package/dist/impls/fireflies-meeting-recorder.types.js +0 -0
  53. package/dist/impls/fireflies-meeting-recorder.utils.d.ts +8 -0
  54. package/dist/impls/fireflies-meeting-recorder.utils.d.ts.map +1 -0
  55. package/dist/impls/fireflies-meeting-recorder.utils.js +36 -0
  56. package/dist/impls/fireflies-meeting-recorder.utils.js.map +1 -0
  57. package/dist/impls/gcs-storage.d.ts.map +1 -1
  58. package/dist/impls/gmail-inbound.d.ts.map +1 -1
  59. package/dist/impls/gmail-outbound.d.ts.map +1 -1
  60. package/dist/impls/google-calendar.d.ts.map +1 -1
  61. package/dist/impls/gradium-voice.d.ts +26 -0
  62. package/dist/impls/gradium-voice.d.ts.map +1 -0
  63. package/dist/impls/gradium-voice.js +80 -0
  64. package/dist/impls/gradium-voice.js.map +1 -0
  65. package/dist/impls/granola-meeting-recorder.d.ts +27 -0
  66. package/dist/impls/granola-meeting-recorder.d.ts.map +1 -0
  67. package/dist/impls/granola-meeting-recorder.js +145 -0
  68. package/dist/impls/granola-meeting-recorder.js.map +1 -0
  69. package/dist/impls/granola-meeting-recorder.types.d.ts +50 -0
  70. package/dist/impls/granola-meeting-recorder.types.d.ts.map +1 -0
  71. package/dist/impls/granola-meeting-recorder.types.js +0 -0
  72. package/dist/impls/index.d.ts +15 -2
  73. package/dist/impls/index.js +18 -5
  74. package/dist/impls/jira.d.ts +25 -0
  75. package/dist/impls/jira.d.ts.map +1 -0
  76. package/dist/impls/jira.js +114 -0
  77. package/dist/impls/jira.js.map +1 -0
  78. package/dist/impls/linear.d.ts +24 -0
  79. package/dist/impls/linear.d.ts.map +1 -0
  80. package/dist/impls/linear.js +75 -0
  81. package/dist/impls/linear.js.map +1 -0
  82. package/dist/impls/mistral-embedding.d.ts.map +1 -1
  83. package/dist/impls/mistral-llm.d.ts.map +1 -1
  84. package/dist/impls/notion.d.ts +27 -0
  85. package/dist/impls/notion.d.ts.map +1 -0
  86. package/dist/impls/notion.js +126 -0
  87. package/dist/impls/notion.js.map +1 -0
  88. package/dist/impls/posthog-reader.d.ts +26 -0
  89. package/dist/impls/posthog-reader.d.ts.map +1 -0
  90. package/dist/impls/posthog-reader.js +141 -0
  91. package/dist/impls/posthog-reader.js.map +1 -0
  92. package/dist/impls/posthog-utils.d.ts +8 -0
  93. package/dist/impls/posthog-utils.d.ts.map +1 -0
  94. package/dist/impls/posthog-utils.js +30 -0
  95. package/dist/impls/posthog-utils.js.map +1 -0
  96. package/dist/impls/posthog.d.ts +40 -0
  97. package/dist/impls/posthog.d.ts.map +1 -0
  98. package/dist/impls/posthog.js +122 -0
  99. package/dist/impls/posthog.js.map +1 -0
  100. package/dist/impls/postmark-email.d.ts.map +1 -1
  101. package/dist/impls/powens-client.d.ts.map +1 -1
  102. package/dist/impls/powens-openbanking.d.ts +1 -1
  103. package/dist/impls/powens-openbanking.d.ts.map +1 -1
  104. package/dist/impls/provider-factory.d.ts +10 -2
  105. package/dist/impls/provider-factory.d.ts.map +1 -1
  106. package/dist/impls/provider-factory.js +143 -2
  107. package/dist/impls/provider-factory.js.map +1 -1
  108. package/dist/impls/qdrant-vector.d.ts.map +1 -1
  109. package/dist/impls/stripe-payments.d.ts.map +1 -1
  110. package/dist/impls/supabase-psql.d.ts +28 -0
  111. package/dist/impls/supabase-psql.d.ts.map +1 -0
  112. package/dist/impls/supabase-psql.js +111 -0
  113. package/dist/impls/supabase-psql.js.map +1 -0
  114. package/dist/impls/supabase-vector.d.ts +36 -0
  115. package/dist/impls/supabase-vector.d.ts.map +1 -0
  116. package/dist/impls/supabase-vector.js +149 -0
  117. package/dist/impls/supabase-vector.js.map +1 -0
  118. package/dist/impls/tldv-meeting-recorder.d.ts +25 -0
  119. package/dist/impls/tldv-meeting-recorder.d.ts.map +1 -0
  120. package/dist/impls/tldv-meeting-recorder.js +131 -0
  121. package/dist/impls/tldv-meeting-recorder.js.map +1 -0
  122. package/dist/impls/twilio-sms.d.ts.map +1 -1
  123. package/dist/index.d.ts +29 -8
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +44 -6
  126. package/dist/index.js.map +1 -1
  127. package/dist/llm.d.ts +1 -0
  128. package/dist/llm.d.ts.map +1 -1
  129. package/dist/llm.js +1 -1
  130. package/dist/meeting-recorder.d.ts +9 -0
  131. package/dist/meeting-recorder.d.ts.map +1 -0
  132. package/dist/meeting-recorder.js +3 -0
  133. package/dist/openbanking.d.ts +1 -0
  134. package/dist/openbanking.d.ts.map +1 -1
  135. package/dist/openbanking.js +1 -1
  136. package/dist/payments.d.ts +1 -0
  137. package/dist/payments.d.ts.map +1 -1
  138. package/dist/payments.js +1 -1
  139. package/dist/project-management.d.ts +9 -0
  140. package/dist/project-management.d.ts.map +1 -0
  141. package/dist/project-management.js +3 -0
  142. package/dist/sms.d.ts +1 -0
  143. package/dist/sms.d.ts.map +1 -1
  144. package/dist/sms.js +1 -1
  145. package/dist/storage.d.ts +1 -0
  146. package/dist/storage.d.ts.map +1 -1
  147. package/dist/storage.js +1 -1
  148. package/dist/vector-store.d.ts +1 -0
  149. package/dist/vector-store.d.ts.map +1 -1
  150. package/dist/vector-store.js +1 -1
  151. package/dist/voice.d.ts +1 -0
  152. package/dist/voice.d.ts.map +1 -1
  153. package/dist/voice.js +1 -1
  154. package/package.json +64 -12
package/README.md CHANGED
@@ -2,19 +2,133 @@
2
2
 
3
3
  Website: https://contractspec.io/
4
4
 
5
-
6
5
  SDK-backed implementations of ContractSpec integration provider interfaces.
7
6
 
8
7
  Depends on:
8
+
9
9
  - `@contractspec/lib.contracts` for provider interface types and IntegrationSpec declarations
10
10
  - `@contractspec/integration.runtime` for secret/guard helpers (when needed)
11
11
 
12
+ ## PostHog analytics
13
+
14
+ This package ships a PostHog analytics provider:
15
+
16
+ - `analytics.posthog` via `PosthogAnalyticsProvider`
17
+
18
+ Connection config example:
19
+
20
+ ```json
21
+ {
22
+ "host": "https://app.posthog.com",
23
+ "projectId": "12345",
24
+ "mcpUrl": "https://your-mcp-endpoint"
25
+ }
26
+ ```
27
+
28
+ Secret payload example (`secretRef` target value):
29
+
30
+ ```json
31
+ {
32
+ "personalApiKey": "phx_personal_api_key",
33
+ "projectApiKey": "phc_project_api_key"
34
+ }
35
+ ```
36
+
37
+ Factory usage:
38
+
39
+ ```ts
40
+ import { IntegrationProviderFactory } from "@contractspec/integration.providers-impls/impls/provider-factory";
41
+
42
+ const factory = new IntegrationProviderFactory();
43
+ const analytics = await factory.createAnalyticsProvider(context); // key: analytics.posthog
44
+ ```
45
+
46
+ ## Supabase integrations
47
+
48
+ This package now ships two Supabase providers:
49
+
50
+ - `vectordb.supabase` via `SupabaseVectorProvider`
51
+ - `database.supabase` via `SupabasePostgresProvider`
52
+
53
+ Both providers are available through `IntegrationProviderFactory` and can also be instantiated directly.
54
+
55
+ ### 1) Connection shapes
56
+
57
+ #### Vector store (`vectordb.supabase`)
58
+
59
+ `IntegrationConnection.config` example:
60
+
61
+ ```json
62
+ {
63
+ "schema": "public",
64
+ "table": "contractspec_vectors",
65
+ "createTableIfMissing": true,
66
+ "distanceMetric": "cosine",
67
+ "maxConnections": 5,
68
+ "sslMode": "require"
69
+ }
70
+ ```
71
+
72
+ Secret payload example (`secretRef` target value):
73
+
74
+ ```json
75
+ {
76
+ "databaseUrl": "postgresql://postgres.<project-ref>:<password>@aws-0-<region>.pooler.supabase.com:6543/postgres"
77
+ }
78
+ ```
79
+
80
+ #### Database (`database.supabase`)
81
+
82
+ `IntegrationConnection.config` example:
83
+
84
+ ```json
85
+ {
86
+ "maxConnections": 10,
87
+ "sslMode": "require"
88
+ }
89
+ ```
90
+
91
+ Secret payload example (`secretRef` target value):
92
+
93
+ ```json
94
+ {
95
+ "databaseUrl": "postgresql://postgres.<project-ref>:<password>@aws-0-<region>.pooler.supabase.com:6543/postgres"
96
+ }
97
+ ```
98
+
99
+ ### 2) Factory usage
12
100
 
101
+ ```ts
102
+ import { IntegrationProviderFactory } from "@contractspec/integration.providers-impls/impls/provider-factory";
13
103
 
104
+ const factory = new IntegrationProviderFactory();
14
105
 
106
+ const vectorProvider = await factory.createVectorStoreProvider(vectorContext); // key: vectordb.supabase
107
+ const dbProvider = await factory.createDatabaseProvider(databaseContext); // key: database.supabase
108
+ ```
15
109
 
110
+ ### 3) Direct provider usage
16
111
 
112
+ ```ts
113
+ import { SupabaseVectorProvider } from "@contractspec/integration.providers-impls/impls/supabase-vector";
114
+ import { SupabasePostgresProvider } from "@contractspec/integration.providers-impls/impls/supabase-psql";
17
115
 
116
+ const vector = new SupabaseVectorProvider({
117
+ connectionString: process.env.SUPABASE_DATABASE_URL,
118
+ schema: "public",
119
+ table: "contractspec_vectors",
120
+ distanceMetric: "cosine",
121
+ });
18
122
 
123
+ const database = new SupabasePostgresProvider({
124
+ connectionString: process.env.SUPABASE_DATABASE_URL,
125
+ maxConnections: 10,
126
+ sslMode: "require",
127
+ });
128
+ ```
19
129
 
130
+ ### 4) Notes
20
131
 
132
+ - `SupabaseVectorProvider` creates `vector` extension/table/indexes automatically when `createTableIfMissing=true`.
133
+ - `SupabaseVectorProvider` maps scores from pgvector distances (`cosine`, `l2`, `inner_product`) to `VectorSearchResult.score`.
134
+ - `SupabasePostgresProvider` supports `$1`, `$2`, ... placeholders, transactions, and clean connection shutdown through `close()`.
@@ -1,9 +1,9 @@
1
- //#region rolldown:runtime
1
+ //#region \0rolldown/runtime.js
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __exportAll = (all, symbols) => {
6
+ var __exportAll = (all, no_symbols) => {
7
7
  let target = {};
8
8
  for (var name in all) {
9
9
  __defProp(target, name, {
@@ -11,7 +11,7 @@ var __exportAll = (all, symbols) => {
11
11
  enumerable: true
12
12
  });
13
13
  }
14
- if (symbols) {
14
+ if (!no_symbols) {
15
15
  __defProp(target, Symbol.toStringTag, { value: "Module" });
16
16
  }
17
17
  return target;
@@ -0,0 +1,9 @@
1
+ import { __exportAll, __reExport } from "./_virtual/_rolldown/runtime.js";
2
+ export * from "@contractspec/lib.contracts/integrations/providers/analytics";
3
+
4
+ //#region src/analytics.d.ts
5
+
6
+ import * as import__contractspec_lib_contracts_integrations_providers_analytics from "@contractspec/lib.contracts/integrations/providers/analytics";
7
+ //#endregion
8
+ export { import__contractspec_lib_contracts_integrations_providers_analytics as analytics_d_exports };
9
+ //# sourceMappingURL=analytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analytics.d.ts","names":[],"sources":["../src/analytics.ts"],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { __exportAll, __reExport } from "./_virtual/_rolldown/runtime.js";
2
+
3
+ export * from "@contractspec/lib.contracts/integrations/providers/analytics"
@@ -1,3 +1,4 @@
1
+ import { __exportAll, __reExport } from "./_virtual/_rolldown/runtime.js";
1
2
  export * from "@contractspec/lib.contracts/integrations/providers/calendar";
2
3
 
3
4
  //#region src/calendar.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"calendar.d.ts","names":[],"sources":["../src/calendar.ts"],"sourcesContent":[],"mappings":""}
1
+ {"version":3,"file":"calendar.d.ts","names":[],"sources":["../src/calendar.ts"],"mappings":""}
package/dist/calendar.js CHANGED
@@ -1,3 +1,3 @@
1
- import { __reExport } from "./_virtual/rolldown_runtime.js";
1
+ import { __exportAll, __reExport } from "./_virtual/_rolldown/runtime.js";
2
2
 
3
3
  export * from "@contractspec/lib.contracts/integrations/providers/calendar"
@@ -0,0 +1,9 @@
1
+ import { __exportAll, __reExport } from "./_virtual/_rolldown/runtime.js";
2
+ export * from "@contractspec/lib.contracts/integrations/providers/database";
3
+
4
+ //#region src/database.d.ts
5
+
6
+ import * as import__contractspec_lib_contracts_integrations_providers_database from "@contractspec/lib.contracts/integrations/providers/database";
7
+ //#endregion
8
+ export { import__contractspec_lib_contracts_integrations_providers_database as database_d_exports };
9
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","names":[],"sources":["../src/database.ts"],"mappings":""}
@@ -0,0 +1,3 @@
1
+ import { __exportAll, __reExport } from "./_virtual/_rolldown/runtime.js";
2
+
3
+ export * from "@contractspec/lib.contracts/integrations/providers/database"
package/dist/email.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { __exportAll, __reExport } from "./_virtual/_rolldown/runtime.js";
1
2
  export * from "@contractspec/lib.contracts/integrations/providers/email";
2
3
 
3
4
  //#region src/email.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"email.d.ts","names":[],"sources":["../src/email.ts"],"sourcesContent":[],"mappings":""}
1
+ {"version":3,"file":"email.d.ts","names":[],"sources":["../src/email.ts"],"mappings":""}
package/dist/email.js CHANGED
@@ -1,3 +1,3 @@
1
- import { __reExport } from "./_virtual/rolldown_runtime.js";
1
+ import { __exportAll, __reExport } from "./_virtual/_rolldown/runtime.js";
2
2
 
3
3
  export * from "@contractspec/lib.contracts/integrations/providers/email"
@@ -1,3 +1,4 @@
1
+ import { __exportAll, __reExport } from "./_virtual/_rolldown/runtime.js";
1
2
  export * from "@contractspec/lib.contracts/integrations/providers/embedding";
2
3
 
3
4
  //#region src/embedding.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"embedding.d.ts","names":[],"sources":["../src/embedding.ts"],"sourcesContent":[],"mappings":""}
1
+ {"version":3,"file":"embedding.d.ts","names":[],"sources":["../src/embedding.ts"],"mappings":""}
package/dist/embedding.js CHANGED
@@ -1,3 +1,3 @@
1
- import { __reExport } from "./_virtual/rolldown_runtime.js";
1
+ import { __exportAll, __reExport } from "./_virtual/_rolldown/runtime.js";
2
2
 
3
3
  export * from "@contractspec/lib.contracts/integrations/providers/embedding"
@@ -1 +1 @@
1
- {"version":3,"file":"elevenlabs-voice.d.ts","names":[],"sources":["../../src/impls/elevenlabs-voice.ts"],"sourcesContent":[],"mappings":";;;;UAUiB,8BAAA;;EAAA,cAAA,CAAA,EAAA,MAAA;EAiCJ,OAAA,CAAA,EAAA,MAAA;EAKU,MAAA,CAAA,EAlCZ,gBAkCY;;AAUD,cAfT,uBAAA,YAAmC,eAAA,CAAA,aAe1B,CAAA;EAkBI,iBAAA,MAAA;EAA8B,iBAAA,cAAA;EAAR,iBAAA,OAAA;EAjCA,WAAA,CAAA,OAAA,EAKzB,8BALyB;EAAa,UAAA,CAAA,CAAA,EAevC,OAfuC,CAe/B,eAAA,CAAA,KAf+B,EAAA,CAAA;oBAiCnC,eAAA,CAAA,sBAAsB,QAAQ,eAAA,CAAA"}
1
+ {"version":3,"file":"elevenlabs-voice.d.ts","names":[],"sources":["../../src/impls/elevenlabs-voice.ts"],"mappings":";;;;UAUiB,8BAAA;EACf,MAAA;EACA,cAAA;EACA,OAAA;EACA,MAAA,GAAS,gBAAA;AAAA;AAAA,cA6BE,uBAAA,YAAmC,eAAA,CAAA,aAAA;EAAA,iBAC7B,MAAA;EAAA,iBACA,cAAA;EAAA,iBACA,OAAA;cAEL,OAAA,EAAS,8BAAA;EAUf,UAAA,CAAA,GAAc,OAAA,CAAQ,eAAA,CAAA,KAAA;EAkBtB,UAAA,CAAW,KAAA,EAAO,eAAA,CAAA,mBAAA,GAAsB,OAAA,CAAQ,eAAA,CAAA,oBAAA;AAAA"}
@@ -0,0 +1,29 @@
1
+ import { voice_d_exports } from "../voice.js";
2
+ import { FalClient } from "@fal-ai/client";
3
+
4
+ //#region src/impls/fal-voice.d.ts
5
+ interface FalVoiceProviderOptions {
6
+ apiKey: string;
7
+ modelId?: string;
8
+ defaultVoiceUrl?: string;
9
+ defaultExaggeration?: number;
10
+ defaultTemperature?: number;
11
+ defaultCfg?: number;
12
+ pollIntervalMs?: number;
13
+ client?: FalClient;
14
+ }
15
+ declare class FalVoiceProvider implements voice_d_exports.VoiceProvider {
16
+ private readonly client;
17
+ private readonly modelId;
18
+ private readonly defaultVoiceUrl?;
19
+ private readonly defaultExaggeration?;
20
+ private readonly defaultTemperature?;
21
+ private readonly defaultCfg?;
22
+ private readonly pollIntervalMs?;
23
+ constructor(options: FalVoiceProviderOptions);
24
+ listVoices(): Promise<voice_d_exports.Voice[]>;
25
+ synthesize(input: voice_d_exports.VoiceSynthesisInput): Promise<voice_d_exports.VoiceSynthesisResult>;
26
+ }
27
+ //#endregion
28
+ export { FalVoiceProvider, FalVoiceProviderOptions };
29
+ //# sourceMappingURL=fal-voice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fal-voice.d.ts","names":[],"sources":["../../src/impls/fal-voice.ts"],"mappings":";;;;UAkBiB,uBAAA;EACf,MAAA;EACA,OAAA;EACA,eAAA;EACA,mBAAA;EACA,kBAAA;EACA,UAAA;EACA,cAAA;EACA,MAAA,GAAS,SAAA;AAAA;AAAA,cAGE,gBAAA,YAA4B,eAAA,CAAA,aAAA;EAAA,iBACtB,MAAA;EAAA,iBACA,OAAA;EAAA,iBACA,eAAA;EAAA,iBACA,mBAAA;EAAA,iBACA,kBAAA;EAAA,iBACA,UAAA;EAAA,iBACA,cAAA;cAEL,OAAA,EAAS,uBAAA;EAcf,UAAA,CAAA,GAAc,OAAA,CAAQ,eAAA,CAAA,KAAA;EA8BtB,UAAA,CAAW,KAAA,EAAO,eAAA,CAAA,mBAAA,GAAsB,OAAA,CAAQ,eAAA,CAAA,oBAAA;AAAA"}
@@ -0,0 +1,88 @@
1
+ import { createFalClient } from "@fal-ai/client";
2
+
3
+ //#region src/impls/fal-voice.ts
4
+ const DEFAULT_MODEL_ID = "fal-ai/chatterbox/text-to-speech";
5
+ var FalVoiceProvider = class {
6
+ client;
7
+ modelId;
8
+ defaultVoiceUrl;
9
+ defaultExaggeration;
10
+ defaultTemperature;
11
+ defaultCfg;
12
+ pollIntervalMs;
13
+ constructor(options) {
14
+ this.client = options.client ?? createFalClient({ credentials: options.apiKey });
15
+ this.modelId = options.modelId ?? DEFAULT_MODEL_ID;
16
+ this.defaultVoiceUrl = options.defaultVoiceUrl;
17
+ this.defaultExaggeration = options.defaultExaggeration;
18
+ this.defaultTemperature = options.defaultTemperature;
19
+ this.defaultCfg = options.defaultCfg;
20
+ this.pollIntervalMs = options.pollIntervalMs;
21
+ }
22
+ async listVoices() {
23
+ const voices = [{
24
+ id: "default",
25
+ name: "Default Chatterbox Voice",
26
+ description: "Uses the default model voice (or configured default reference audio URL).",
27
+ metadata: { modelId: this.modelId }
28
+ }];
29
+ if (this.defaultVoiceUrl) voices.push({
30
+ id: this.defaultVoiceUrl,
31
+ name: "Configured Reference Voice",
32
+ description: "Reference voice configured at provider setup and used when voiceId is default.",
33
+ previewUrl: this.defaultVoiceUrl,
34
+ metadata: {
35
+ modelId: this.modelId,
36
+ source: "config.defaultVoiceUrl"
37
+ }
38
+ });
39
+ return voices;
40
+ }
41
+ async synthesize(input) {
42
+ const referenceVoiceUrl = resolveVoiceUrl(input.voiceId, this.defaultVoiceUrl);
43
+ const audioUrl = extractAudioUrl((await this.client.subscribe(this.modelId, {
44
+ input: {
45
+ text: input.text,
46
+ ...referenceVoiceUrl ? { audio_url: referenceVoiceUrl } : {},
47
+ ...this.defaultExaggeration != null ? { exaggeration: this.defaultExaggeration } : {},
48
+ ...this.defaultTemperature != null ? { temperature: this.defaultTemperature } : {},
49
+ ...this.defaultCfg != null ? { cfg: this.defaultCfg } : {}
50
+ },
51
+ pollInterval: this.pollIntervalMs
52
+ })).data);
53
+ if (!audioUrl) throw new Error("Fal synthesis completed without an audio URL in response.");
54
+ const response = await fetch(audioUrl);
55
+ if (!response.ok) throw new Error(`Fal audio download failed (${response.status}).`);
56
+ return {
57
+ audio: new Uint8Array(await response.arrayBuffer()),
58
+ format: input.format ?? inferFormatFromUrl(audioUrl) ?? "wav",
59
+ sampleRateHz: input.sampleRateHz ?? 24e3,
60
+ durationSeconds: void 0,
61
+ url: audioUrl
62
+ };
63
+ }
64
+ };
65
+ function resolveVoiceUrl(voiceId, defaultVoiceUrl) {
66
+ if (!voiceId || voiceId === "default") return defaultVoiceUrl;
67
+ if (isHttpUrl(voiceId)) return voiceId;
68
+ throw new Error("Fal voiceId must be \"default\" or a public reference audio URL.");
69
+ }
70
+ function extractAudioUrl(output) {
71
+ if (output.audio?.url) return output.audio.url;
72
+ if (typeof output.audio_url === "string") return output.audio_url;
73
+ if (typeof output.url === "string") return output.url;
74
+ }
75
+ function inferFormatFromUrl(url) {
76
+ const normalized = url.toLowerCase();
77
+ if (normalized.endsWith(".wav")) return "wav";
78
+ if (normalized.endsWith(".mp3")) return "mp3";
79
+ if (normalized.endsWith(".ogg") || normalized.endsWith(".opus")) return "ogg";
80
+ if (normalized.endsWith(".pcm")) return "pcm";
81
+ }
82
+ function isHttpUrl(value) {
83
+ return value.startsWith("https://") || value.startsWith("http://");
84
+ }
85
+
86
+ //#endregion
87
+ export { FalVoiceProvider };
88
+ //# sourceMappingURL=fal-voice.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fal-voice.js","names":[],"sources":["../../src/impls/fal-voice.ts"],"sourcesContent":["import { createFalClient } from '@fal-ai/client';\nimport type { FalClient } from '@fal-ai/client';\n\nimport type {\n Voice,\n VoiceProvider,\n VoiceSynthesisInput,\n VoiceSynthesisResult,\n} from '../voice';\n\nconst DEFAULT_MODEL_ID = 'fal-ai/chatterbox/text-to-speech';\n\ninterface FalSynthesisOutput {\n audio?: { url?: string } | null;\n audio_url?: string;\n url?: string;\n}\n\nexport interface FalVoiceProviderOptions {\n apiKey: string;\n modelId?: string;\n defaultVoiceUrl?: string;\n defaultExaggeration?: number;\n defaultTemperature?: number;\n defaultCfg?: number;\n pollIntervalMs?: number;\n client?: FalClient;\n}\n\nexport class FalVoiceProvider implements VoiceProvider {\n private readonly client: FalClient;\n private readonly modelId: string;\n private readonly defaultVoiceUrl?: string;\n private readonly defaultExaggeration?: number;\n private readonly defaultTemperature?: number;\n private readonly defaultCfg?: number;\n private readonly pollIntervalMs?: number;\n\n constructor(options: FalVoiceProviderOptions) {\n this.client =\n options.client ??\n createFalClient({\n credentials: options.apiKey,\n });\n this.modelId = options.modelId ?? DEFAULT_MODEL_ID;\n this.defaultVoiceUrl = options.defaultVoiceUrl;\n this.defaultExaggeration = options.defaultExaggeration;\n this.defaultTemperature = options.defaultTemperature;\n this.defaultCfg = options.defaultCfg;\n this.pollIntervalMs = options.pollIntervalMs;\n }\n\n async listVoices(): Promise<Voice[]> {\n const voices: Voice[] = [\n {\n id: 'default',\n name: 'Default Chatterbox Voice',\n description:\n 'Uses the default model voice (or configured default reference audio URL).',\n metadata: {\n modelId: this.modelId,\n },\n },\n ];\n\n if (this.defaultVoiceUrl) {\n voices.push({\n id: this.defaultVoiceUrl,\n name: 'Configured Reference Voice',\n description:\n 'Reference voice configured at provider setup and used when voiceId is default.',\n previewUrl: this.defaultVoiceUrl,\n metadata: {\n modelId: this.modelId,\n source: 'config.defaultVoiceUrl',\n },\n });\n }\n\n return voices;\n }\n\n async synthesize(input: VoiceSynthesisInput): Promise<VoiceSynthesisResult> {\n const referenceVoiceUrl = resolveVoiceUrl(\n input.voiceId,\n this.defaultVoiceUrl\n );\n const result = await this.client.subscribe(this.modelId, {\n input: {\n text: input.text,\n ...(referenceVoiceUrl ? { audio_url: referenceVoiceUrl } : {}),\n ...(this.defaultExaggeration != null\n ? { exaggeration: this.defaultExaggeration }\n : {}),\n ...(this.defaultTemperature != null\n ? { temperature: this.defaultTemperature }\n : {}),\n ...(this.defaultCfg != null ? { cfg: this.defaultCfg } : {}),\n },\n pollInterval: this.pollIntervalMs,\n });\n\n const audioUrl = extractAudioUrl(result.data as FalSynthesisOutput);\n if (!audioUrl) {\n throw new Error(\n 'Fal synthesis completed without an audio URL in response.'\n );\n }\n\n const response = await fetch(audioUrl);\n if (!response.ok) {\n throw new Error(`Fal audio download failed (${response.status}).`);\n }\n\n const audio = new Uint8Array(await response.arrayBuffer());\n\n return {\n audio,\n format: input.format ?? inferFormatFromUrl(audioUrl) ?? 'wav',\n sampleRateHz: input.sampleRateHz ?? 24000,\n durationSeconds: undefined,\n url: audioUrl,\n };\n }\n}\n\nfunction resolveVoiceUrl(\n voiceId: string | undefined,\n defaultVoiceUrl: string | undefined\n): string | undefined {\n if (!voiceId || voiceId === 'default') return defaultVoiceUrl;\n if (isHttpUrl(voiceId)) return voiceId;\n throw new Error(\n 'Fal voiceId must be \"default\" or a public reference audio URL.'\n );\n}\n\nfunction extractAudioUrl(output: FalSynthesisOutput): string | undefined {\n if (output.audio?.url) return output.audio.url;\n if (typeof output.audio_url === 'string') return output.audio_url;\n if (typeof output.url === 'string') return output.url;\n return undefined;\n}\n\nfunction inferFormatFromUrl(url: string): string | undefined {\n const normalized = url.toLowerCase();\n if (normalized.endsWith('.wav')) return 'wav';\n if (normalized.endsWith('.mp3')) return 'mp3';\n if (normalized.endsWith('.ogg') || normalized.endsWith('.opus')) return 'ogg';\n if (normalized.endsWith('.pcm')) return 'pcm';\n return undefined;\n}\n\nfunction isHttpUrl(value: string): boolean {\n return value.startsWith('https://') || value.startsWith('http://');\n}\n"],"mappings":";;;AAUA,MAAM,mBAAmB;AAmBzB,IAAa,mBAAb,MAAuD;CACrD,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CAEjB,YAAY,SAAkC;AAC5C,OAAK,SACH,QAAQ,UACR,gBAAgB,EACd,aAAa,QAAQ,QACtB,CAAC;AACJ,OAAK,UAAU,QAAQ,WAAW;AAClC,OAAK,kBAAkB,QAAQ;AAC/B,OAAK,sBAAsB,QAAQ;AACnC,OAAK,qBAAqB,QAAQ;AAClC,OAAK,aAAa,QAAQ;AAC1B,OAAK,iBAAiB,QAAQ;;CAGhC,MAAM,aAA+B;EACnC,MAAM,SAAkB,CACtB;GACE,IAAI;GACJ,MAAM;GACN,aACE;GACF,UAAU,EACR,SAAS,KAAK,SACf;GACF,CACF;AAED,MAAI,KAAK,gBACP,QAAO,KAAK;GACV,IAAI,KAAK;GACT,MAAM;GACN,aACE;GACF,YAAY,KAAK;GACjB,UAAU;IACR,SAAS,KAAK;IACd,QAAQ;IACT;GACF,CAAC;AAGJ,SAAO;;CAGT,MAAM,WAAW,OAA2D;EAC1E,MAAM,oBAAoB,gBACxB,MAAM,SACN,KAAK,gBACN;EAgBD,MAAM,WAAW,iBAfF,MAAM,KAAK,OAAO,UAAU,KAAK,SAAS;GACvD,OAAO;IACL,MAAM,MAAM;IACZ,GAAI,oBAAoB,EAAE,WAAW,mBAAmB,GAAG,EAAE;IAC7D,GAAI,KAAK,uBAAuB,OAC5B,EAAE,cAAc,KAAK,qBAAqB,GAC1C,EAAE;IACN,GAAI,KAAK,sBAAsB,OAC3B,EAAE,aAAa,KAAK,oBAAoB,GACxC,EAAE;IACN,GAAI,KAAK,cAAc,OAAO,EAAE,KAAK,KAAK,YAAY,GAAG,EAAE;IAC5D;GACD,cAAc,KAAK;GACpB,CAAC,EAEsC,KAA2B;AACnE,MAAI,CAAC,SACH,OAAM,IAAI,MACR,4DACD;EAGH,MAAM,WAAW,MAAM,MAAM,SAAS;AACtC,MAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MAAM,8BAA8B,SAAS,OAAO,IAAI;AAKpE,SAAO;GACL,OAHY,IAAI,WAAW,MAAM,SAAS,aAAa,CAAC;GAIxD,QAAQ,MAAM,UAAU,mBAAmB,SAAS,IAAI;GACxD,cAAc,MAAM,gBAAgB;GACpC,iBAAiB;GACjB,KAAK;GACN;;;AAIL,SAAS,gBACP,SACA,iBACoB;AACpB,KAAI,CAAC,WAAW,YAAY,UAAW,QAAO;AAC9C,KAAI,UAAU,QAAQ,CAAE,QAAO;AAC/B,OAAM,IAAI,MACR,mEACD;;AAGH,SAAS,gBAAgB,QAAgD;AACvE,KAAI,OAAO,OAAO,IAAK,QAAO,OAAO,MAAM;AAC3C,KAAI,OAAO,OAAO,cAAc,SAAU,QAAO,OAAO;AACxD,KAAI,OAAO,OAAO,QAAQ,SAAU,QAAO,OAAO;;AAIpD,SAAS,mBAAmB,KAAiC;CAC3D,MAAM,aAAa,IAAI,aAAa;AACpC,KAAI,WAAW,SAAS,OAAO,CAAE,QAAO;AACxC,KAAI,WAAW,SAAS,OAAO,CAAE,QAAO;AACxC,KAAI,WAAW,SAAS,OAAO,IAAI,WAAW,SAAS,QAAQ,CAAE,QAAO;AACxE,KAAI,WAAW,SAAS,OAAO,CAAE,QAAO;;AAI1C,SAAS,UAAU,OAAwB;AACzC,QAAO,MAAM,WAAW,WAAW,IAAI,MAAM,WAAW,UAAU"}
@@ -0,0 +1,42 @@
1
+ import { meeting_recorder_d_exports } from "../meeting-recorder.js";
2
+ import { Fathom } from "fathom-typescript";
3
+
4
+ //#region src/impls/fathom-meeting-recorder.d.ts
5
+ interface FathomMeetingRecorderProviderOptions {
6
+ apiKey: string;
7
+ baseUrl?: string;
8
+ includeTranscript?: boolean;
9
+ includeSummary?: boolean;
10
+ includeActionItems?: boolean;
11
+ includeCrmMatches?: boolean;
12
+ triggeredFor?: string[];
13
+ webhookSecret?: string;
14
+ maxPages?: number;
15
+ client?: Fathom;
16
+ }
17
+ declare class FathomMeetingRecorderProvider implements meeting_recorder_d_exports.MeetingRecorderProvider {
18
+ private readonly client;
19
+ private readonly apiKey;
20
+ private readonly baseUrl;
21
+ private readonly includeTranscript;
22
+ private readonly includeSummary;
23
+ private readonly includeActionItems;
24
+ private readonly includeCrmMatches;
25
+ private readonly triggeredFor?;
26
+ private readonly webhookSecret?;
27
+ private readonly maxPages;
28
+ constructor(options: FathomMeetingRecorderProviderOptions);
29
+ listMeetings(params: meeting_recorder_d_exports.MeetingRecorderListMeetingsParams): Promise<meeting_recorder_d_exports.MeetingRecorderListMeetingsResult>;
30
+ getMeeting(params: meeting_recorder_d_exports.MeetingRecorderGetMeetingParams): Promise<meeting_recorder_d_exports.MeetingRecord>;
31
+ getTranscript(params: meeting_recorder_d_exports.MeetingRecorderGetTranscriptParams): Promise<meeting_recorder_d_exports.MeetingTranscriptRecord>;
32
+ parseWebhook(request: meeting_recorder_d_exports.MeetingRecorderWebhookRequest): Promise<meeting_recorder_d_exports.MeetingRecorderWebhookEvent>;
33
+ verifyWebhook(request: meeting_recorder_d_exports.MeetingRecorderWebhookRequest): Promise<boolean>;
34
+ registerWebhook(registration: meeting_recorder_d_exports.MeetingRecorderWebhookRegistration): Promise<{
35
+ id: string;
36
+ secret?: string;
37
+ }>;
38
+ private request;
39
+ }
40
+ //#endregion
41
+ export { FathomMeetingRecorderProvider, FathomMeetingRecorderProviderOptions };
42
+ //# sourceMappingURL=fathom-meeting-recorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fathom-meeting-recorder.d.ts","names":[],"sources":["../../src/impls/fathom-meeting-recorder.ts"],"mappings":";;;;UAgCiB,oCAAA;EACf,MAAA;EACA,OAAA;EACA,iBAAA;EACA,cAAA;EACA,kBAAA;EACA,iBAAA;EACA,YAAA;EACA,aAAA;EACA,QAAA;EACA,MAAA,GAAS,MAAA;AAAA;AAAA,cAKE,6BAAA,YAAyC,0BAAA,CAAA,uBAAA;EAAA,iBACnC,MAAA;EAAA,iBACA,MAAA;EAAA,iBACA,OAAA;EAAA,iBACA,iBAAA;EAAA,iBACA,cAAA;EAAA,iBACA,kBAAA;EAAA,iBACA,iBAAA;EAAA,iBACA,YAAA;EAAA,iBACA,aAAA;EAAA,iBACA,QAAA;cAEL,OAAA,EAAS,oCAAA;EAoBf,YAAA,CACJ,MAAA,EAAQ,0BAAA,CAAA,iCAAA,GACP,OAAA,CAAQ,0BAAA,CAAA,iCAAA;EA8BL,UAAA,CACJ,MAAA,EAAQ,0BAAA,CAAA,+BAAA,GACP,OAAA,CAAQ,0BAAA,CAAA,aAAA;EAwBL,aAAA,CACJ,MAAA,EAAQ,0BAAA,CAAA,kCAAA,GACP,OAAA,CAAQ,0BAAA,CAAA,uBAAA;EA0BL,YAAA,CACJ,OAAA,EAAS,0BAAA,CAAA,6BAAA,GACR,OAAA,CAAQ,0BAAA,CAAA,2BAAA;EAuBL,aAAA,CACJ,OAAA,EAAS,0BAAA,CAAA,6BAAA,GACR,OAAA;EAYG,eAAA,CACJ,YAAA,EAAc,0BAAA,CAAA,kCAAA,GACb,OAAA;IAAU,EAAA;IAAY,MAAA;EAAA;EAAA,QAiBX,OAAA;AAAA"}
@@ -0,0 +1,145 @@
1
+ import { extractItems, extractNextCursor, mapTranscriptSegment, matchRecordingId, safeReadError } from "./fathom-meeting-recorder.utils.js";
2
+ import { mapFathomMeeting } from "./fathom-meeting-recorder.mapper.js";
3
+ import { normalizeTriggeredFor, normalizeWebhookHeaders } from "./fathom-meeting-recorder.webhooks.js";
4
+ import { Fathom } from "fathom-typescript";
5
+ import { TriggeredFor } from "fathom-typescript/sdk/models/operations";
6
+
7
+ //#region src/impls/fathom-meeting-recorder.ts
8
+ const DEFAULT_BASE_URL = "https://api.fathom.ai/external/v1";
9
+ var FathomMeetingRecorderProvider = class {
10
+ client;
11
+ apiKey;
12
+ baseUrl;
13
+ includeTranscript;
14
+ includeSummary;
15
+ includeActionItems;
16
+ includeCrmMatches;
17
+ triggeredFor;
18
+ webhookSecret;
19
+ maxPages;
20
+ constructor(options) {
21
+ this.apiKey = options.apiKey;
22
+ this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
23
+ this.includeTranscript = options.includeTranscript ?? false;
24
+ this.includeSummary = options.includeSummary ?? false;
25
+ this.includeActionItems = options.includeActionItems ?? false;
26
+ this.includeCrmMatches = options.includeCrmMatches ?? false;
27
+ this.triggeredFor = options.triggeredFor;
28
+ this.webhookSecret = options.webhookSecret;
29
+ this.maxPages = options.maxPages ?? 5;
30
+ this.client = options.client ?? new Fathom({
31
+ serverURL: this.baseUrl,
32
+ security: { apiKeyAuth: this.apiKey }
33
+ });
34
+ }
35
+ async listMeetings(params) {
36
+ const request = {
37
+ cursor: params.cursor,
38
+ createdAfter: params.from,
39
+ createdBefore: params.to,
40
+ includeTranscript: params.includeTranscript ?? this.includeTranscript,
41
+ includeSummary: params.includeSummary ?? this.includeSummary,
42
+ includeActionItems: this.includeActionItems,
43
+ includeCrmMatches: this.includeCrmMatches
44
+ };
45
+ const result = await this.client.listMeetings(request);
46
+ let firstPage;
47
+ for await (const page of result) {
48
+ firstPage = page;
49
+ break;
50
+ }
51
+ if (!firstPage) return { meetings: [] };
52
+ return {
53
+ meetings: extractItems(firstPage).map((meeting) => mapFathomMeeting(meeting, params)),
54
+ nextCursor: extractNextCursor(firstPage) ?? void 0,
55
+ hasMore: Boolean(extractNextCursor(firstPage))
56
+ };
57
+ }
58
+ async getMeeting(params) {
59
+ const result = await this.client.listMeetings({
60
+ includeTranscript: params.includeTranscript ?? this.includeTranscript,
61
+ includeSummary: params.includeSummary ?? this.includeSummary,
62
+ includeActionItems: this.includeActionItems,
63
+ includeCrmMatches: this.includeCrmMatches
64
+ });
65
+ let pageCount = 0;
66
+ const targetId = Number.parseInt(params.meetingId, 10);
67
+ for await (const page of result) {
68
+ pageCount += 1;
69
+ const match = extractItems(page).find((meeting) => matchRecordingId(meeting, targetId));
70
+ if (match) return mapFathomMeeting(match, params);
71
+ if (pageCount >= this.maxPages) break;
72
+ }
73
+ throw new Error(`Fathom meeting "${targetId}" not found.`);
74
+ }
75
+ async getTranscript(params) {
76
+ const response = await this.request(`/recordings/${encodeURIComponent(params.meetingId)}/transcript`);
77
+ if (!Array.isArray(response.transcript)) throw new Error("Fathom transcript response did not include transcript.");
78
+ const segments = response.transcript.map((segment, index) => mapTranscriptSegment(segment, index));
79
+ return {
80
+ id: params.meetingId,
81
+ meetingId: params.meetingId,
82
+ tenantId: params.tenantId,
83
+ connectionId: params.connectionId ?? "unknown",
84
+ externalId: params.meetingId,
85
+ format: "segments",
86
+ text: segments.map((segment) => segment.text).join("\n"),
87
+ segments,
88
+ metadata: { provider: "fathom" },
89
+ raw: response.transcript
90
+ };
91
+ }
92
+ async parseWebhook(request) {
93
+ const payload = request.parsedBody ?? JSON.parse(request.rawBody);
94
+ const body = payload;
95
+ const recordingId = body.recording_id ?? body.recordingId ?? body.meeting_id ?? body.meetingId;
96
+ const verified = this.webhookSecret ? await this.verifyWebhook(request) : void 0;
97
+ return {
98
+ providerKey: "meeting-recorder.fathom",
99
+ eventType: body.event_type ?? body.eventType,
100
+ meetingId: recordingId,
101
+ recordingId,
102
+ verified,
103
+ payload
104
+ };
105
+ }
106
+ async verifyWebhook(request) {
107
+ if (!this.webhookSecret) return true;
108
+ const headers = normalizeWebhookHeaders(request.headers);
109
+ try {
110
+ return Boolean(Fathom.verifyWebhook(this.webhookSecret, headers, request.rawBody));
111
+ } catch {
112
+ return false;
113
+ }
114
+ }
115
+ async registerWebhook(registration) {
116
+ const triggeredFor = normalizeTriggeredFor(registration.triggeredFor) ?? normalizeTriggeredFor(this.triggeredFor) ?? [TriggeredFor.MyRecordings];
117
+ const webhook = await this.client.createWebhook({
118
+ destinationUrl: registration.url,
119
+ includeTranscript: registration.includeTranscript ?? true,
120
+ includeSummary: registration.includeSummary ?? false,
121
+ includeActionItems: registration.includeActionItems ?? false,
122
+ includeCrmMatches: registration.includeCrmMatches ?? false,
123
+ triggeredFor
124
+ });
125
+ return {
126
+ id: webhook.id,
127
+ secret: webhook.secret
128
+ };
129
+ }
130
+ async request(path) {
131
+ const response = await fetch(`${this.baseUrl}${path}`, { headers: {
132
+ "Content-Type": "application/json",
133
+ "X-Api-Key": this.apiKey
134
+ } });
135
+ if (!response.ok) {
136
+ const message = await safeReadError(response);
137
+ throw new Error(`Fathom API error (${response.status}): ${message}`);
138
+ }
139
+ return await response.json();
140
+ }
141
+ };
142
+
143
+ //#endregion
144
+ export { FathomMeetingRecorderProvider };
145
+ //# sourceMappingURL=fathom-meeting-recorder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fathom-meeting-recorder.js","names":[],"sources":["../../src/impls/fathom-meeting-recorder.ts"],"sourcesContent":["import { Fathom } from 'fathom-typescript';\nimport { TriggeredFor } from 'fathom-typescript/sdk/models/operations';\n\nimport type {\n MeetingRecord,\n MeetingRecorderGetMeetingParams,\n MeetingRecorderGetTranscriptParams,\n MeetingRecorderListMeetingsParams,\n MeetingRecorderListMeetingsResult,\n MeetingRecorderProvider,\n MeetingRecorderWebhookEvent,\n MeetingRecorderWebhookRegistration,\n MeetingRecorderWebhookRequest,\n MeetingTranscriptRecord,\n} from '../meeting-recorder';\nimport type {\n FathomMeetingListPage,\n FathomTranscriptResponse,\n} from './fathom-meeting-recorder.types';\nimport {\n extractItems,\n extractNextCursor,\n mapTranscriptSegment,\n matchRecordingId,\n safeReadError,\n} from './fathom-meeting-recorder.utils';\nimport { mapFathomMeeting } from './fathom-meeting-recorder.mapper';\nimport {\n normalizeTriggeredFor,\n normalizeWebhookHeaders,\n} from './fathom-meeting-recorder.webhooks';\n\nexport interface FathomMeetingRecorderProviderOptions {\n apiKey: string;\n baseUrl?: string;\n includeTranscript?: boolean;\n includeSummary?: boolean;\n includeActionItems?: boolean;\n includeCrmMatches?: boolean;\n triggeredFor?: string[];\n webhookSecret?: string;\n maxPages?: number;\n client?: Fathom;\n}\n\nconst DEFAULT_BASE_URL = 'https://api.fathom.ai/external/v1';\n\nexport class FathomMeetingRecorderProvider implements MeetingRecorderProvider {\n private readonly client: Fathom;\n private readonly apiKey: string;\n private readonly baseUrl: string;\n private readonly includeTranscript: boolean;\n private readonly includeSummary: boolean;\n private readonly includeActionItems: boolean;\n private readonly includeCrmMatches: boolean;\n private readonly triggeredFor?: string[];\n private readonly webhookSecret?: string;\n private readonly maxPages: number;\n\n constructor(options: FathomMeetingRecorderProviderOptions) {\n this.apiKey = options.apiKey;\n this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;\n this.includeTranscript = options.includeTranscript ?? false;\n this.includeSummary = options.includeSummary ?? false;\n this.includeActionItems = options.includeActionItems ?? false;\n this.includeCrmMatches = options.includeCrmMatches ?? false;\n this.triggeredFor = options.triggeredFor;\n this.webhookSecret = options.webhookSecret;\n this.maxPages = options.maxPages ?? 5;\n this.client =\n options.client ??\n new Fathom({\n serverURL: this.baseUrl,\n security: {\n apiKeyAuth: this.apiKey,\n },\n });\n }\n\n async listMeetings(\n params: MeetingRecorderListMeetingsParams\n ): Promise<MeetingRecorderListMeetingsResult> {\n const request = {\n cursor: params.cursor,\n createdAfter: params.from,\n createdBefore: params.to,\n includeTranscript: params.includeTranscript ?? this.includeTranscript,\n includeSummary: params.includeSummary ?? this.includeSummary,\n includeActionItems: this.includeActionItems,\n includeCrmMatches: this.includeCrmMatches,\n };\n const result = await this.client.listMeetings(request);\n let firstPage: FathomMeetingListPage | undefined;\n for await (const page of result as AsyncIterable<FathomMeetingListPage>) {\n firstPage = page;\n break;\n }\n if (!firstPage) {\n return { meetings: [] };\n }\n const rawItems = extractItems(firstPage);\n const meetings = rawItems.map((meeting) =>\n mapFathomMeeting(meeting, params)\n );\n return {\n meetings,\n nextCursor: extractNextCursor(firstPage) ?? undefined,\n hasMore: Boolean(extractNextCursor(firstPage)),\n };\n }\n\n async getMeeting(\n params: MeetingRecorderGetMeetingParams\n ): Promise<MeetingRecord> {\n const result = await this.client.listMeetings({\n includeTranscript: params.includeTranscript ?? this.includeTranscript,\n includeSummary: params.includeSummary ?? this.includeSummary,\n includeActionItems: this.includeActionItems,\n includeCrmMatches: this.includeCrmMatches,\n });\n let pageCount = 0;\n const targetId = Number.parseInt(params.meetingId, 10);\n for await (const page of result as AsyncIterable<FathomMeetingListPage>) {\n pageCount += 1;\n const match = extractItems(page).find((meeting) =>\n matchRecordingId(meeting, targetId)\n );\n if (match) {\n return mapFathomMeeting(match, params);\n }\n if (pageCount >= this.maxPages) {\n break;\n }\n }\n throw new Error(`Fathom meeting \"${targetId}\" not found.`);\n }\n\n async getTranscript(\n params: MeetingRecorderGetTranscriptParams\n ): Promise<MeetingTranscriptRecord> {\n const response = await this.request<FathomTranscriptResponse>(\n `/recordings/${encodeURIComponent(params.meetingId)}/transcript`\n );\n if (!Array.isArray(response.transcript)) {\n throw new Error('Fathom transcript response did not include transcript.');\n }\n const segments = response.transcript.map((segment, index) =>\n mapTranscriptSegment(segment, index)\n );\n return {\n id: params.meetingId,\n meetingId: params.meetingId,\n tenantId: params.tenantId,\n connectionId: params.connectionId ?? 'unknown',\n externalId: params.meetingId,\n format: 'segments',\n text: segments.map((segment) => segment.text).join('\\n'),\n segments,\n metadata: {\n provider: 'fathom',\n },\n raw: response.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 Record<string, unknown>;\n const recordingId =\n (body.recording_id as string | undefined) ??\n (body.recordingId as string | undefined) ??\n (body.meeting_id as string | undefined) ??\n (body.meetingId as string | undefined);\n const verified = this.webhookSecret\n ? await this.verifyWebhook(request)\n : undefined;\n return {\n providerKey: 'meeting-recorder.fathom',\n eventType:\n (body.event_type as string | undefined) ??\n (body.eventType as string | undefined),\n meetingId: recordingId,\n recordingId,\n verified,\n payload,\n };\n }\n\n async verifyWebhook(\n request: MeetingRecorderWebhookRequest\n ): Promise<boolean> {\n if (!this.webhookSecret) return true;\n const headers = normalizeWebhookHeaders(request.headers);\n try {\n return Boolean(\n Fathom.verifyWebhook(this.webhookSecret, headers, request.rawBody)\n );\n } catch {\n return false;\n }\n }\n\n async registerWebhook(\n registration: MeetingRecorderWebhookRegistration\n ): Promise<{ id: string; secret?: string }> {\n const triggeredFor = normalizeTriggeredFor(registration.triggeredFor) ??\n normalizeTriggeredFor(this.triggeredFor) ?? [TriggeredFor.MyRecordings];\n const webhook = await this.client.createWebhook({\n destinationUrl: registration.url,\n includeTranscript: registration.includeTranscript ?? true,\n includeSummary: registration.includeSummary ?? false,\n includeActionItems: registration.includeActionItems ?? false,\n includeCrmMatches: registration.includeCrmMatches ?? false,\n triggeredFor,\n });\n return {\n id: (webhook as { id: string }).id,\n secret: (webhook as { secret?: string }).secret,\n };\n }\n\n private async request<T>(path: string): Promise<T> {\n const response = await fetch(`${this.baseUrl}${path}`, {\n headers: {\n 'Content-Type': 'application/json',\n 'X-Api-Key': this.apiKey,\n },\n });\n if (!response.ok) {\n const message = await safeReadError(response);\n throw new Error(`Fathom API error (${response.status}): ${message}`);\n }\n return (await response.json()) as T;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { meeting_recorder_d_exports } from "../meeting-recorder.js";
2
+ import { FathomMeeting, FathomMeetingInvitee } from "./fathom-meeting-recorder.types.js";
3
+
4
+ //#region src/impls/fathom-meeting-recorder.mapper.d.ts
5
+ declare const mapFathomMeetingInvites: (invitees: FathomMeetingInvitee[]) => meeting_recorder_d_exports.MeetingParticipant[];
6
+ declare function mapFathomMeeting(meeting: FathomMeeting, params: meeting_recorder_d_exports.MeetingRecorderListMeetingsParams | meeting_recorder_d_exports.MeetingRecorderGetMeetingParams): meeting_recorder_d_exports.MeetingRecord;
7
+ //#endregion
8
+ export { mapFathomMeeting, mapFathomMeetingInvites };
9
+ //# sourceMappingURL=fathom-meeting-recorder.mapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fathom-meeting-recorder.mapper.d.ts","names":[],"sources":["../../src/impls/fathom-meeting-recorder.mapper.ts"],"mappings":";;;;cAYa,uBAAA,GACX,QAAA,EAAU,oBAAA,OACT,0BAAA,CAAA,kBAAA;AAAA,iBAQa,gBAAA,CACd,OAAA,EAAS,aAAA,EACT,MAAA,EAAQ,0BAAA,CAAA,iCAAA,GAAoC,0BAAA,CAAA,+BAAA,GAC3C,0BAAA,CAAA,aAAA"}