@contractspec/integration.providers-impls 1.56.1 → 1.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/README.md +115 -1
  2. package/dist/analytics.d.ts +2 -0
  3. package/dist/analytics.d.ts.map +1 -0
  4. package/dist/analytics.js +3 -0
  5. package/dist/calendar.d.ts +1 -7
  6. package/dist/calendar.d.ts.map +1 -1
  7. package/dist/calendar.js +3 -3
  8. package/dist/database.d.ts +2 -0
  9. package/dist/database.d.ts.map +1 -0
  10. package/dist/database.js +3 -0
  11. package/dist/email.d.ts +1 -7
  12. package/dist/email.d.ts.map +1 -1
  13. package/dist/email.js +3 -3
  14. package/dist/embedding.d.ts +1 -7
  15. package/dist/embedding.d.ts.map +1 -1
  16. package/dist/embedding.js +3 -3
  17. package/dist/impls/elevenlabs-voice.d.ts +14 -18
  18. package/dist/impls/elevenlabs-voice.d.ts.map +1 -1
  19. package/dist/impls/elevenlabs-voice.js +98 -88
  20. package/dist/impls/fal-voice.d.ts +25 -0
  21. package/dist/impls/fal-voice.d.ts.map +1 -0
  22. package/dist/impls/fal-voice.js +113 -0
  23. package/dist/impls/fathom-meeting-recorder.d.ts +38 -0
  24. package/dist/impls/fathom-meeting-recorder.d.ts.map +1 -0
  25. package/dist/impls/fathom-meeting-recorder.js +288 -0
  26. package/dist/impls/fathom-meeting-recorder.mapper.d.ts +5 -0
  27. package/dist/impls/fathom-meeting-recorder.mapper.d.ts.map +1 -0
  28. package/dist/impls/fathom-meeting-recorder.mapper.js +106 -0
  29. package/dist/impls/fathom-meeting-recorder.types.d.ts +20 -0
  30. package/dist/impls/fathom-meeting-recorder.types.d.ts.map +1 -0
  31. package/dist/impls/fathom-meeting-recorder.types.js +1 -0
  32. package/dist/impls/fathom-meeting-recorder.utils.d.ts +11 -0
  33. package/dist/impls/fathom-meeting-recorder.utils.d.ts.map +1 -0
  34. package/dist/impls/fathom-meeting-recorder.utils.js +73 -0
  35. package/dist/impls/fathom-meeting-recorder.webhooks.d.ts +4 -0
  36. package/dist/impls/fathom-meeting-recorder.webhooks.d.ts.map +1 -0
  37. package/dist/impls/fathom-meeting-recorder.webhooks.js +30 -0
  38. package/dist/impls/fireflies-meeting-recorder.d.ts +24 -0
  39. package/dist/impls/fireflies-meeting-recorder.d.ts.map +1 -0
  40. package/dist/impls/fireflies-meeting-recorder.js +275 -0
  41. package/dist/impls/fireflies-meeting-recorder.queries.d.ts +4 -0
  42. package/dist/impls/fireflies-meeting-recorder.queries.d.ts.map +1 -0
  43. package/dist/impls/fireflies-meeting-recorder.queries.js +86 -0
  44. package/dist/impls/fireflies-meeting-recorder.types.d.ts +32 -0
  45. package/dist/impls/fireflies-meeting-recorder.types.d.ts.map +1 -0
  46. package/dist/impls/fireflies-meeting-recorder.types.js +1 -0
  47. package/dist/impls/fireflies-meeting-recorder.utils.d.ts +5 -0
  48. package/dist/impls/fireflies-meeting-recorder.utils.d.ts.map +1 -0
  49. package/dist/impls/fireflies-meeting-recorder.utils.js +43 -0
  50. package/dist/impls/gcs-storage.d.ts +18 -22
  51. package/dist/impls/gcs-storage.d.ts.map +1 -1
  52. package/dist/impls/gcs-storage.js +92 -84
  53. package/dist/impls/gmail-inbound.d.ts +20 -24
  54. package/dist/impls/gmail-inbound.d.ts.map +1 -1
  55. package/dist/impls/gmail-inbound.js +212 -185
  56. package/dist/impls/gmail-outbound.d.ts +12 -16
  57. package/dist/impls/gmail-outbound.d.ts.map +1 -1
  58. package/dist/impls/gmail-outbound.js +126 -92
  59. package/dist/impls/google-calendar.d.ts +17 -21
  60. package/dist/impls/google-calendar.d.ts.map +1 -1
  61. package/dist/impls/google-calendar.js +182 -145
  62. package/dist/impls/gradium-voice.d.ts +24 -0
  63. package/dist/impls/gradium-voice.d.ts.map +1 -0
  64. package/dist/impls/gradium-voice.js +91 -0
  65. package/dist/impls/granola-meeting-recorder.d.ts +34 -0
  66. package/dist/impls/granola-meeting-recorder.d.ts.map +1 -0
  67. package/dist/impls/granola-meeting-recorder.js +513 -0
  68. package/dist/impls/granola-meeting-recorder.mcp.d.ts +25 -0
  69. package/dist/impls/granola-meeting-recorder.mcp.d.ts.map +1 -0
  70. package/dist/impls/granola-meeting-recorder.mcp.js +279 -0
  71. package/dist/impls/granola-meeting-recorder.types.d.ts +61 -0
  72. package/dist/impls/granola-meeting-recorder.types.d.ts.map +1 -0
  73. package/dist/impls/granola-meeting-recorder.types.js +1 -0
  74. package/dist/impls/index.d.ts +28 -15
  75. package/dist/impls/index.d.ts.map +1 -0
  76. package/dist/impls/index.js +4659 -16
  77. package/dist/impls/jira.d.ts +21 -0
  78. package/dist/impls/jira.d.ts.map +1 -0
  79. package/dist/impls/jira.js +125 -0
  80. package/dist/impls/linear.d.ts +20 -0
  81. package/dist/impls/linear.d.ts.map +1 -0
  82. package/dist/impls/linear.js +84 -0
  83. package/dist/impls/mistral-embedding.d.ts +17 -21
  84. package/dist/impls/mistral-embedding.d.ts.map +1 -1
  85. package/dist/impls/mistral-embedding.js +41 -39
  86. package/dist/impls/mistral-llm.d.ts +25 -29
  87. package/dist/impls/mistral-llm.d.ts.map +1 -1
  88. package/dist/impls/mistral-llm.js +266 -244
  89. package/dist/impls/notion.d.ts +23 -0
  90. package/dist/impls/notion.d.ts.map +1 -0
  91. package/dist/impls/notion.js +161 -0
  92. package/dist/impls/posthog-reader.d.ts +22 -0
  93. package/dist/impls/posthog-reader.d.ts.map +1 -0
  94. package/dist/impls/posthog-reader.js +160 -0
  95. package/dist/impls/posthog-utils.d.ts +5 -0
  96. package/dist/impls/posthog-utils.d.ts.map +1 -0
  97. package/dist/impls/posthog-utils.js +39 -0
  98. package/dist/impls/posthog.d.ts +36 -0
  99. package/dist/impls/posthog.d.ts.map +1 -0
  100. package/dist/impls/posthog.js +323 -0
  101. package/dist/impls/postmark-email.d.ts +13 -17
  102. package/dist/impls/postmark-email.d.ts.map +1 -1
  103. package/dist/impls/postmark-email.js +55 -50
  104. package/dist/impls/powens-client.d.ts +111 -114
  105. package/dist/impls/powens-client.d.ts.map +1 -1
  106. package/dist/impls/powens-client.js +194 -170
  107. package/dist/impls/powens-openbanking.d.ts +22 -26
  108. package/dist/impls/powens-openbanking.d.ts.map +1 -1
  109. package/dist/impls/powens-openbanking.js +425 -217
  110. package/dist/impls/provider-factory.d.ts +29 -25
  111. package/dist/impls/provider-factory.d.ts.map +1 -1
  112. package/dist/impls/provider-factory.js +4074 -136
  113. package/dist/impls/qdrant-vector.d.ts +18 -22
  114. package/dist/impls/qdrant-vector.d.ts.map +1 -1
  115. package/dist/impls/qdrant-vector.js +76 -69
  116. package/dist/impls/stripe-payments.d.ts +22 -26
  117. package/dist/impls/stripe-payments.d.ts.map +1 -1
  118. package/dist/impls/stripe-payments.js +219 -193
  119. package/dist/impls/supabase-psql.d.ts +24 -0
  120. package/dist/impls/supabase-psql.d.ts.map +1 -0
  121. package/dist/impls/supabase-psql.js +151 -0
  122. package/dist/impls/supabase-vector.d.ts +32 -0
  123. package/dist/impls/supabase-vector.d.ts.map +1 -0
  124. package/dist/impls/supabase-vector.js +324 -0
  125. package/dist/impls/tldv-meeting-recorder.d.ts +21 -0
  126. package/dist/impls/tldv-meeting-recorder.d.ts.map +1 -0
  127. package/dist/impls/tldv-meeting-recorder.js +146 -0
  128. package/dist/impls/twilio-sms.d.ts +14 -17
  129. package/dist/impls/twilio-sms.d.ts.map +1 -1
  130. package/dist/impls/twilio-sms.js +62 -55
  131. package/dist/index.d.ts +15 -43
  132. package/dist/index.d.ts.map +1 -1
  133. package/dist/index.js +4700 -69
  134. package/dist/llm.d.ts +1 -7
  135. package/dist/llm.d.ts.map +1 -1
  136. package/dist/llm.js +3 -3
  137. package/dist/meeting-recorder.d.ts +2 -0
  138. package/dist/meeting-recorder.d.ts.map +1 -0
  139. package/dist/meeting-recorder.js +3 -0
  140. package/dist/node/analytics.js +2 -0
  141. package/dist/node/calendar.js +2 -0
  142. package/dist/node/database.js +2 -0
  143. package/dist/node/email.js +2 -0
  144. package/dist/node/embedding.js +2 -0
  145. package/dist/node/impls/elevenlabs-voice.js +102 -0
  146. package/dist/node/impls/fal-voice.js +112 -0
  147. package/dist/node/impls/fathom-meeting-recorder.js +287 -0
  148. package/dist/node/impls/fathom-meeting-recorder.mapper.js +105 -0
  149. package/dist/node/impls/fathom-meeting-recorder.types.js +0 -0
  150. package/dist/node/impls/fathom-meeting-recorder.utils.js +72 -0
  151. package/dist/node/impls/fathom-meeting-recorder.webhooks.js +29 -0
  152. package/dist/node/impls/fireflies-meeting-recorder.js +274 -0
  153. package/dist/node/impls/fireflies-meeting-recorder.queries.js +85 -0
  154. package/dist/node/impls/fireflies-meeting-recorder.types.js +0 -0
  155. package/dist/node/impls/fireflies-meeting-recorder.utils.js +42 -0
  156. package/dist/node/impls/gcs-storage.js +97 -0
  157. package/dist/node/impls/gmail-inbound.js +227 -0
  158. package/dist/node/impls/gmail-outbound.js +139 -0
  159. package/dist/node/impls/google-calendar.js +191 -0
  160. package/dist/node/impls/gradium-voice.js +90 -0
  161. package/dist/node/impls/granola-meeting-recorder.js +512 -0
  162. package/dist/node/impls/granola-meeting-recorder.mcp.js +278 -0
  163. package/dist/node/impls/granola-meeting-recorder.types.js +0 -0
  164. package/dist/node/impls/index.js +4658 -0
  165. package/dist/node/impls/jira.js +124 -0
  166. package/dist/node/impls/linear.js +83 -0
  167. package/dist/node/impls/mistral-embedding.js +43 -0
  168. package/dist/node/impls/mistral-llm.js +269 -0
  169. package/dist/node/impls/notion.js +160 -0
  170. package/dist/node/impls/posthog-reader.js +159 -0
  171. package/dist/node/impls/posthog-utils.js +38 -0
  172. package/dist/node/impls/posthog.js +322 -0
  173. package/dist/node/impls/postmark-email.js +60 -0
  174. package/dist/node/impls/powens-client.js +195 -0
  175. package/dist/node/impls/powens-openbanking.js +426 -0
  176. package/dist/node/impls/provider-factory.js +4080 -0
  177. package/dist/node/impls/qdrant-vector.js +78 -0
  178. package/dist/node/impls/stripe-payments.js +228 -0
  179. package/dist/node/impls/supabase-psql.js +150 -0
  180. package/dist/node/impls/supabase-vector.js +323 -0
  181. package/dist/node/impls/tldv-meeting-recorder.js +145 -0
  182. package/dist/node/impls/twilio-sms.js +65 -0
  183. package/dist/node/index.js +4699 -0
  184. package/dist/node/llm.js +2 -0
  185. package/dist/node/meeting-recorder.js +2 -0
  186. package/dist/node/openbanking.js +2 -0
  187. package/dist/node/payments.js +2 -0
  188. package/dist/node/project-management.js +2 -0
  189. package/dist/node/runtime.js +0 -0
  190. package/dist/node/secrets/provider.js +11 -0
  191. package/dist/node/sms.js +2 -0
  192. package/dist/node/storage.js +2 -0
  193. package/dist/node/vector-store.js +2 -0
  194. package/dist/node/voice.js +2 -0
  195. package/dist/openbanking.d.ts +1 -7
  196. package/dist/openbanking.d.ts.map +1 -1
  197. package/dist/openbanking.js +3 -3
  198. package/dist/payments.d.ts +1 -7
  199. package/dist/payments.d.ts.map +1 -1
  200. package/dist/payments.js +3 -3
  201. package/dist/project-management.d.ts +2 -0
  202. package/dist/project-management.d.ts.map +1 -0
  203. package/dist/project-management.js +3 -0
  204. package/dist/runtime.d.ts +2 -2
  205. package/dist/runtime.d.ts.map +1 -0
  206. package/dist/runtime.js +1 -0
  207. package/dist/secrets/provider.d.ts +3 -2
  208. package/dist/secrets/provider.d.ts.map +1 -0
  209. package/dist/secrets/provider.js +12 -3
  210. package/dist/sms.d.ts +1 -7
  211. package/dist/sms.d.ts.map +1 -1
  212. package/dist/sms.js +3 -3
  213. package/dist/storage.d.ts +1 -7
  214. package/dist/storage.d.ts.map +1 -1
  215. package/dist/storage.js +3 -3
  216. package/dist/vector-store.d.ts +1 -7
  217. package/dist/vector-store.d.ts.map +1 -1
  218. package/dist/vector-store.js +3 -3
  219. package/dist/voice.d.ts +1 -7
  220. package/dist/voice.d.ts.map +1 -1
  221. package/dist/voice.js +3 -3
  222. package/package.json +419 -76
  223. package/dist/_virtual/rolldown_runtime.js +0 -36
  224. package/dist/impls/elevenlabs-voice.js.map +0 -1
  225. package/dist/impls/gcs-storage.js.map +0 -1
  226. package/dist/impls/gmail-inbound.js.map +0 -1
  227. package/dist/impls/gmail-outbound.js.map +0 -1
  228. package/dist/impls/google-calendar.js.map +0 -1
  229. package/dist/impls/mistral-embedding.js.map +0 -1
  230. package/dist/impls/mistral-llm.js.map +0 -1
  231. package/dist/impls/postmark-email.js.map +0 -1
  232. package/dist/impls/powens-client.js.map +0 -1
  233. package/dist/impls/powens-openbanking.js.map +0 -1
  234. package/dist/impls/provider-factory.js.map +0 -1
  235. package/dist/impls/qdrant-vector.js.map +0 -1
  236. package/dist/impls/stripe-payments.js.map +0 -1
  237. package/dist/impls/twilio-sms.js.map +0 -1
  238. package/dist/index.js.map +0 -1
@@ -0,0 +1,323 @@
1
+ // src/impls/supabase-psql.ts
2
+ import { Buffer } from "node:buffer";
3
+ import { sql as drizzleSql } from "drizzle-orm";
4
+ import { drizzle } from "drizzle-orm/postgres-js";
5
+ import postgres from "postgres";
6
+
7
+ class SupabasePostgresProvider {
8
+ client;
9
+ db;
10
+ ownsClient;
11
+ createDrizzle;
12
+ constructor(options = {}) {
13
+ this.createDrizzle = options.createDrizzle ?? ((client) => drizzle(client));
14
+ if (options.db) {
15
+ if (!options.client) {
16
+ throw new Error("SupabasePostgresProvider requires a postgres client when db is provided.");
17
+ }
18
+ this.client = options.client;
19
+ this.db = options.db;
20
+ this.ownsClient = false;
21
+ return;
22
+ }
23
+ if (options.client) {
24
+ this.client = options.client;
25
+ this.ownsClient = false;
26
+ } else {
27
+ if (!options.connectionString) {
28
+ throw new Error("SupabasePostgresProvider requires either a connectionString or a client.");
29
+ }
30
+ this.client = postgres(options.connectionString, {
31
+ max: options.maxConnections,
32
+ prepare: false,
33
+ ssl: resolveSslMode(options.sslMode)
34
+ });
35
+ this.ownsClient = true;
36
+ }
37
+ this.db = this.createDrizzle(this.client);
38
+ }
39
+ async query(statement, params = []) {
40
+ const query = buildParameterizedSql(statement, params);
41
+ const result = await this.db.execute(query);
42
+ const rows = asRows(result);
43
+ return {
44
+ rows,
45
+ rowCount: rows.length
46
+ };
47
+ }
48
+ async execute(statement, params = []) {
49
+ const query = buildParameterizedSql(statement, params);
50
+ await this.db.execute(query);
51
+ }
52
+ async transaction(run) {
53
+ const transactionResult = this.client.begin(async (transactionClient) => {
54
+ const transactionalProvider = new SupabasePostgresProvider({
55
+ client: transactionClient,
56
+ db: this.createDrizzle(transactionClient),
57
+ createDrizzle: this.createDrizzle
58
+ });
59
+ return run(transactionalProvider);
60
+ });
61
+ return transactionResult;
62
+ }
63
+ async close() {
64
+ if (this.ownsClient) {
65
+ await this.client.end({ timeout: 5 });
66
+ }
67
+ }
68
+ }
69
+ function buildParameterizedSql(statement, params) {
70
+ const segments = [];
71
+ const pattern = /\$(\d+)/g;
72
+ let cursor = 0;
73
+ for (const match of statement.matchAll(pattern)) {
74
+ const token = match[0];
75
+ const indexPart = match[1];
76
+ const start = match.index;
77
+ if (indexPart == null || start == null)
78
+ continue;
79
+ const parameterIndex = Number(indexPart) - 1;
80
+ if (!Number.isInteger(parameterIndex) || parameterIndex < 0 || parameterIndex >= params.length) {
81
+ throw new Error(`SQL placeholder ${token} is out of bounds for ${params.length} parameter(s).`);
82
+ }
83
+ const staticSegment = statement.slice(cursor, start);
84
+ if (staticSegment.length > 0) {
85
+ segments.push(drizzleSql.raw(staticSegment));
86
+ }
87
+ const parameterValue = params[parameterIndex];
88
+ if (parameterValue === undefined) {
89
+ throw new Error(`SQL placeholder ${token} is missing a parameter value.`);
90
+ }
91
+ const normalizedValue = normalizeParam(parameterValue);
92
+ segments.push(drizzleSql`${normalizedValue}`);
93
+ cursor = start + token.length;
94
+ }
95
+ const tailSegment = statement.slice(cursor);
96
+ if (tailSegment.length > 0) {
97
+ segments.push(drizzleSql.raw(tailSegment));
98
+ }
99
+ if (segments.length === 0) {
100
+ return drizzleSql.raw("");
101
+ }
102
+ return drizzleSql.join(segments);
103
+ }
104
+ function normalizeParam(value) {
105
+ if (typeof value === "bigint") {
106
+ return value.toString();
107
+ }
108
+ if (value instanceof Uint8Array) {
109
+ return Buffer.from(value);
110
+ }
111
+ if (isPlainObject(value)) {
112
+ return JSON.stringify(value);
113
+ }
114
+ return value;
115
+ }
116
+ function asRows(result) {
117
+ if (!Array.isArray(result)) {
118
+ return [];
119
+ }
120
+ return result;
121
+ }
122
+ function isPlainObject(value) {
123
+ if (value == null || typeof value !== "object") {
124
+ return false;
125
+ }
126
+ if (Array.isArray(value)) {
127
+ return false;
128
+ }
129
+ if (value instanceof Date) {
130
+ return false;
131
+ }
132
+ if (value instanceof Uint8Array) {
133
+ return false;
134
+ }
135
+ return true;
136
+ }
137
+ function resolveSslMode(mode) {
138
+ switch (mode) {
139
+ case "allow":
140
+ return false;
141
+ case "prefer":
142
+ return "prefer";
143
+ case "require":
144
+ default:
145
+ return "require";
146
+ }
147
+ }
148
+
149
+ // src/impls/supabase-vector.ts
150
+ class SupabaseVectorProvider {
151
+ database;
152
+ createTableIfMissing;
153
+ distanceMetric;
154
+ quotedSchema;
155
+ qualifiedTable;
156
+ collectionIndex;
157
+ namespaceIndex;
158
+ ensureTablePromise;
159
+ constructor(options) {
160
+ this.database = options.database ?? new SupabasePostgresProvider({
161
+ connectionString: options.connectionString,
162
+ maxConnections: options.maxConnections,
163
+ sslMode: options.sslMode
164
+ });
165
+ this.createTableIfMissing = options.createTableIfMissing ?? true;
166
+ this.distanceMetric = options.distanceMetric ?? "cosine";
167
+ const schema = sanitizeIdentifier(options.schema ?? "public", "schema");
168
+ const table = sanitizeIdentifier(options.table ?? "contractspec_vectors", "table");
169
+ this.quotedSchema = quoteIdentifier(schema);
170
+ this.qualifiedTable = `${this.quotedSchema}.${quoteIdentifier(table)}`;
171
+ this.collectionIndex = quoteIdentifier(`${table}_collection_idx`);
172
+ this.namespaceIndex = quoteIdentifier(`${table}_namespace_idx`);
173
+ }
174
+ async upsert(request) {
175
+ if (request.documents.length === 0) {
176
+ return;
177
+ }
178
+ if (this.createTableIfMissing) {
179
+ await this.ensureTable();
180
+ }
181
+ for (const document of request.documents) {
182
+ await this.database.execute(`INSERT INTO ${this.qualifiedTable}
183
+ (collection, id, embedding, payload, namespace, expires_at, updated_at)
184
+ VALUES ($1, $2, $3::vector, $4::jsonb, $5, $6, now())
185
+ ON CONFLICT (collection, id)
186
+ DO UPDATE SET
187
+ embedding = EXCLUDED.embedding,
188
+ payload = EXCLUDED.payload,
189
+ namespace = EXCLUDED.namespace,
190
+ expires_at = EXCLUDED.expires_at,
191
+ updated_at = now();`, [
192
+ request.collection,
193
+ document.id,
194
+ toVectorLiteral(document.vector),
195
+ document.payload ? JSON.stringify(document.payload) : null,
196
+ document.namespace ?? null,
197
+ document.expiresAt ?? null
198
+ ]);
199
+ }
200
+ }
201
+ async search(query) {
202
+ const operator = this.distanceOperator;
203
+ const results = await this.database.query(`SELECT
204
+ id,
205
+ payload,
206
+ namespace,
207
+ (embedding ${operator} $3::vector) AS distance
208
+ FROM ${this.qualifiedTable}
209
+ WHERE collection = $1
210
+ AND ($2::text IS NULL OR namespace = $2)
211
+ AND (expires_at IS NULL OR expires_at > now())
212
+ AND ($4::jsonb IS NULL OR payload @> $4::jsonb)
213
+ ORDER BY embedding ${operator} $3::vector
214
+ LIMIT $5;`, [
215
+ query.collection,
216
+ query.namespace ?? null,
217
+ toVectorLiteral(query.vector),
218
+ query.filter ? JSON.stringify(query.filter) : null,
219
+ query.topK
220
+ ]);
221
+ const mapped = results.rows.map((row) => {
222
+ const distance = Number(row.distance);
223
+ return {
224
+ id: row.id,
225
+ score: distanceToScore(distance, this.distanceMetric),
226
+ payload: isRecord(row.payload) ? row.payload : undefined,
227
+ namespace: row.namespace ?? undefined
228
+ };
229
+ });
230
+ const scoreThreshold = query.scoreThreshold;
231
+ if (scoreThreshold == null) {
232
+ return mapped;
233
+ }
234
+ return mapped.filter((result) => result.score >= scoreThreshold);
235
+ }
236
+ async delete(request) {
237
+ if (request.ids.length === 0) {
238
+ return;
239
+ }
240
+ const params = [
241
+ request.collection,
242
+ request.ids,
243
+ request.namespace ?? null
244
+ ];
245
+ await this.database.execute(`DELETE FROM ${this.qualifiedTable}
246
+ WHERE collection = $1
247
+ AND id = ANY($2::text[])
248
+ AND ($3::text IS NULL OR namespace = $3);`, params);
249
+ }
250
+ async ensureTable() {
251
+ if (!this.ensureTablePromise) {
252
+ this.ensureTablePromise = this.createTable();
253
+ }
254
+ await this.ensureTablePromise;
255
+ }
256
+ async createTable() {
257
+ await this.database.execute("CREATE EXTENSION IF NOT EXISTS vector;");
258
+ await this.database.execute(`CREATE SCHEMA IF NOT EXISTS ${this.quotedSchema};`);
259
+ await this.database.execute(`CREATE TABLE IF NOT EXISTS ${this.qualifiedTable} (
260
+ collection text NOT NULL,
261
+ id text NOT NULL,
262
+ embedding vector NOT NULL,
263
+ payload jsonb,
264
+ namespace text,
265
+ expires_at timestamptz,
266
+ created_at timestamptz NOT NULL DEFAULT now(),
267
+ updated_at timestamptz NOT NULL DEFAULT now(),
268
+ PRIMARY KEY (collection, id)
269
+ );`);
270
+ await this.database.execute(`CREATE INDEX IF NOT EXISTS ${this.collectionIndex}
271
+ ON ${this.qualifiedTable} (collection);`);
272
+ await this.database.execute(`CREATE INDEX IF NOT EXISTS ${this.namespaceIndex}
273
+ ON ${this.qualifiedTable} (namespace);`);
274
+ }
275
+ get distanceOperator() {
276
+ switch (this.distanceMetric) {
277
+ case "l2":
278
+ return "<->";
279
+ case "inner_product":
280
+ return "<#>";
281
+ case "cosine":
282
+ default:
283
+ return "<=>";
284
+ }
285
+ }
286
+ }
287
+ function sanitizeIdentifier(value, label) {
288
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(value)) {
289
+ throw new Error(`SupabaseVectorProvider ${label} "${value}" is invalid.`);
290
+ }
291
+ return value;
292
+ }
293
+ function quoteIdentifier(value) {
294
+ return `"${value.replaceAll('"', '""')}"`;
295
+ }
296
+ function toVectorLiteral(vector) {
297
+ if (vector.length === 0) {
298
+ throw new Error("Supabase vectors must contain at least one dimension.");
299
+ }
300
+ for (const value of vector) {
301
+ if (!Number.isFinite(value)) {
302
+ throw new Error(`Supabase vectors must be finite numbers. Found "${value}".`);
303
+ }
304
+ }
305
+ return `[${vector.join(",")}]`;
306
+ }
307
+ function isRecord(value) {
308
+ return typeof value === "object" && value !== null && !Array.isArray(value);
309
+ }
310
+ function distanceToScore(distance, metric) {
311
+ switch (metric) {
312
+ case "inner_product":
313
+ return -distance;
314
+ case "l2":
315
+ return 1 / (1 + distance);
316
+ case "cosine":
317
+ default:
318
+ return 1 - distance;
319
+ }
320
+ }
321
+ export {
322
+ SupabaseVectorProvider
323
+ };
@@ -0,0 +1,145 @@
1
+ // src/impls/tldv-meeting-recorder.ts
2
+ var DEFAULT_BASE_URL = "https://pasta.tldv.io/v1alpha1";
3
+
4
+ class TldvMeetingRecorderProvider {
5
+ apiKey;
6
+ baseUrl;
7
+ defaultPageSize;
8
+ constructor(options) {
9
+ this.apiKey = options.apiKey;
10
+ this.baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
11
+ this.defaultPageSize = options.pageSize;
12
+ }
13
+ async listMeetings(params) {
14
+ const page = params.cursor ? Number(params.cursor) : 1;
15
+ const limit = params.pageSize ?? this.defaultPageSize ?? 50;
16
+ const query = new URLSearchParams;
17
+ query.set("page", String(Number.isFinite(page) ? page : 1));
18
+ query.set("limit", String(limit));
19
+ if (params.query)
20
+ query.set("query", params.query);
21
+ if (params.from)
22
+ query.set("from", params.from);
23
+ if (params.to)
24
+ query.set("to", params.to);
25
+ if (params.organizerEmail)
26
+ query.set("organizer", params.organizerEmail);
27
+ if (params.participantEmail)
28
+ query.set("participant", params.participantEmail);
29
+ const data = await this.request(`/meetings?${query.toString()}`);
30
+ const nextPage = data.page < data.pages ? data.page + 1 : undefined;
31
+ return {
32
+ meetings: data.results.map((meeting) => this.mapMeeting(meeting, params)),
33
+ nextCursor: nextPage ? String(nextPage) : undefined,
34
+ hasMore: Boolean(nextPage)
35
+ };
36
+ }
37
+ async getMeeting(params) {
38
+ const meeting = await this.request(`/meetings/${encodeURIComponent(params.meetingId)}`);
39
+ return this.mapMeeting(meeting, params);
40
+ }
41
+ async getTranscript(params) {
42
+ const response = await this.request(`/meetings/${encodeURIComponent(params.meetingId)}/transcript`);
43
+ const segments = response.data.map((segment, index) => this.mapTranscriptSegment(segment, index));
44
+ return {
45
+ id: response.id,
46
+ meetingId: response.meetingId,
47
+ tenantId: params.tenantId,
48
+ connectionId: params.connectionId ?? "unknown",
49
+ externalId: response.id,
50
+ format: "segments",
51
+ text: segments.map((segment) => segment.text).join(`
52
+ `),
53
+ segments,
54
+ metadata: {
55
+ providerMeetingId: response.meetingId
56
+ },
57
+ raw: response.data
58
+ };
59
+ }
60
+ async parseWebhook(request) {
61
+ const payload = request.parsedBody ?? JSON.parse(request.rawBody);
62
+ const body = payload;
63
+ return {
64
+ providerKey: "meeting-recorder.tldv",
65
+ eventType: body.event,
66
+ meetingId: body.data?.id ?? body.data?.meetingId,
67
+ receivedAt: body.executedAt,
68
+ payload
69
+ };
70
+ }
71
+ mapMeeting(meeting, params) {
72
+ const connectionId = params.connectionId ?? "unknown";
73
+ const invitees = meeting.invitees?.map((invitee) => this.mapInvitee(invitee)).filter(Boolean);
74
+ return {
75
+ id: meeting.id,
76
+ tenantId: params.tenantId,
77
+ connectionId,
78
+ externalId: meeting.id,
79
+ title: meeting.name,
80
+ organizer: this.mapInvitee(meeting.organizer, "organizer"),
81
+ invitees: invitees?.length ? invitees : undefined,
82
+ participants: invitees?.length ? invitees : undefined,
83
+ scheduledStartAt: meeting.happenedAt,
84
+ recordingStartAt: meeting.happenedAt,
85
+ durationSeconds: meeting.duration,
86
+ meetingUrl: meeting.url,
87
+ transcriptAvailable: true,
88
+ sourcePlatform: "tldv",
89
+ metadata: {
90
+ template: meeting.template,
91
+ extraProperties: meeting.extraProperties
92
+ }
93
+ };
94
+ }
95
+ mapInvitee(invitee, role = "attendee") {
96
+ if (!invitee)
97
+ return;
98
+ return {
99
+ name: invitee.name ?? undefined,
100
+ email: invitee.email ?? undefined,
101
+ role
102
+ };
103
+ }
104
+ mapTranscriptSegment(segment, index) {
105
+ return {
106
+ index,
107
+ speakerName: segment.speaker ?? undefined,
108
+ text: segment.text,
109
+ startTimeMs: parseSeconds(segment.startTime),
110
+ endTimeMs: parseSeconds(segment.endTime)
111
+ };
112
+ }
113
+ async request(path) {
114
+ const response = await fetch(`${this.baseUrl}${path}`, {
115
+ headers: {
116
+ "Content-Type": "application/json",
117
+ "x-api-key": this.apiKey
118
+ }
119
+ });
120
+ if (!response.ok) {
121
+ const message = await safeReadError(response);
122
+ throw new Error(`tl;dv API error (${response.status}): ${message}`);
123
+ }
124
+ return await response.json();
125
+ }
126
+ }
127
+ function parseSeconds(value) {
128
+ if (value == null)
129
+ return;
130
+ const num = typeof value === "number" ? value : Number(value);
131
+ if (!Number.isFinite(num))
132
+ return;
133
+ return num * 1000;
134
+ }
135
+ async function safeReadError(response) {
136
+ try {
137
+ const data = await response.json();
138
+ return data?.message ?? response.statusText;
139
+ } catch {
140
+ return response.statusText;
141
+ }
142
+ }
143
+ export {
144
+ TldvMeetingRecorderProvider
145
+ };
@@ -0,0 +1,65 @@
1
+ // src/impls/twilio-sms.ts
2
+ import Twilio from "twilio";
3
+
4
+ class TwilioSmsProvider {
5
+ client;
6
+ fromNumber;
7
+ constructor(options) {
8
+ this.client = options.client ?? Twilio(options.accountSid, options.authToken);
9
+ this.fromNumber = options.fromNumber;
10
+ }
11
+ async sendSms(input) {
12
+ const message = await this.client.messages.create({
13
+ to: input.to,
14
+ from: input.from ?? this.fromNumber,
15
+ body: input.body
16
+ });
17
+ return {
18
+ id: message.sid,
19
+ to: message.to ?? input.to,
20
+ from: message.from ?? input.from ?? this.fromNumber ?? "",
21
+ body: message.body ?? input.body,
22
+ status: mapStatus(message.status),
23
+ sentAt: message.dateCreated ? new Date(message.dateCreated) : undefined,
24
+ deliveredAt: message.status === "delivered" && message.dateUpdated ? new Date(message.dateUpdated) : undefined,
25
+ price: message.price ? Number(message.price) : undefined,
26
+ priceCurrency: message.priceUnit ?? undefined,
27
+ errorCode: message.errorCode ? String(message.errorCode) : undefined,
28
+ errorMessage: message.errorMessage ?? undefined
29
+ };
30
+ }
31
+ async getDeliveryStatus(messageId) {
32
+ const message = await this.client.messages(messageId).fetch();
33
+ return {
34
+ status: mapStatus(message.status),
35
+ errorCode: message.errorCode ? String(message.errorCode) : undefined,
36
+ errorMessage: message.errorMessage ?? undefined,
37
+ updatedAt: message.dateUpdated ? new Date(message.dateUpdated) : new Date
38
+ };
39
+ }
40
+ }
41
+ function mapStatus(status) {
42
+ switch (status) {
43
+ case "queued":
44
+ case "accepted":
45
+ case "scheduled":
46
+ return "queued";
47
+ case "sending":
48
+ case "processing":
49
+ return "sending";
50
+ case "sent":
51
+ return "sent";
52
+ case "delivered":
53
+ return "delivered";
54
+ case "undelivered":
55
+ return "undelivered";
56
+ case "failed":
57
+ case "canceled":
58
+ return "failed";
59
+ default:
60
+ return "queued";
61
+ }
62
+ }
63
+ export {
64
+ TwilioSmsProvider
65
+ };