@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.
- 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
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
|
|
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,
|
|
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 (
|
|
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":""}
|
package/dist/calendar.d.ts
CHANGED
package/dist/calendar.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calendar.d.ts","names":[],"sources":["../src/calendar.ts"],"
|
|
1
|
+
{"version":3,"file":"calendar.d.ts","names":[],"sources":["../src/calendar.ts"],"mappings":""}
|
package/dist/calendar.js
CHANGED
|
@@ -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":""}
|
package/dist/database.js
ADDED
package/dist/email.d.ts
CHANGED
package/dist/email.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"email.d.ts","names":[],"sources":["../src/email.ts"],"
|
|
1
|
+
{"version":3,"file":"email.d.ts","names":[],"sources":["../src/email.ts"],"mappings":""}
|
package/dist/email.js
CHANGED
package/dist/embedding.d.ts
CHANGED
package/dist/embedding.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embedding.d.ts","names":[],"sources":["../src/embedding.ts"],"
|
|
1
|
+
{"version":3,"file":"embedding.d.ts","names":[],"sources":["../src/embedding.ts"],"mappings":""}
|
package/dist/embedding.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elevenlabs-voice.d.ts","names":[],"sources":["../../src/impls/elevenlabs-voice.ts"],"
|
|
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"}
|