@squadbase/vite-server 0.1.10-dev.5aa0720 → 0.1.10-dev.5b0c0a8

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.
@@ -0,0 +1,879 @@
1
+ // ../connectors/src/parameter-definition.ts
2
+ var ParameterDefinition = class {
3
+ slug;
4
+ name;
5
+ description;
6
+ envVarBaseKey;
7
+ type;
8
+ secret;
9
+ required;
10
+ constructor(config) {
11
+ this.slug = config.slug;
12
+ this.name = config.name;
13
+ this.description = config.description;
14
+ this.envVarBaseKey = config.envVarBaseKey;
15
+ this.type = config.type;
16
+ this.secret = config.secret;
17
+ this.required = config.required;
18
+ }
19
+ /**
20
+ * Get the parameter value from a ConnectorConnectionObject.
21
+ */
22
+ getValue(connection2) {
23
+ const param = connection2.parameters.find(
24
+ (p) => p.parameterSlug === this.slug
25
+ );
26
+ if (!param || param.value == null) {
27
+ throw new Error(
28
+ `Parameter "${this.slug}" not found or has no value in connection "${connection2.id}"`
29
+ );
30
+ }
31
+ return param.value;
32
+ }
33
+ /**
34
+ * Try to get the parameter value. Returns undefined if not found (for optional params).
35
+ */
36
+ tryGetValue(connection2) {
37
+ const param = connection2.parameters.find(
38
+ (p) => p.parameterSlug === this.slug
39
+ );
40
+ if (!param || param.value == null) return void 0;
41
+ return param.value;
42
+ }
43
+ };
44
+
45
+ // ../connectors/src/connectors/mongodb/parameters.ts
46
+ var parameters = {
47
+ connectionUrl: new ParameterDefinition({
48
+ slug: "connection-url",
49
+ name: "MongoDB Connection URL",
50
+ description: "The MongoDB connection string (e.g., mongodb+srv://user:password@cluster.mongodb.net or mongodb://user:password@host:27017).",
51
+ envVarBaseKey: "MONGODB_URL",
52
+ type: "text",
53
+ secret: true,
54
+ required: true
55
+ }),
56
+ database: new ParameterDefinition({
57
+ slug: "database",
58
+ name: "MongoDB Database",
59
+ description: "The database name to connect to.",
60
+ envVarBaseKey: "MONGODB_DATABASE",
61
+ type: "text",
62
+ secret: false,
63
+ required: true
64
+ })
65
+ };
66
+
67
+ // ../connectors/src/connectors/mongodb/sdk/index.ts
68
+ var CONNECT_TIMEOUT_MS = 1e4;
69
+ var QUERY_TIMEOUT_MS = 6e4;
70
+ function createClient(params) {
71
+ const connectionUrl = params[parameters.connectionUrl.slug];
72
+ if (!connectionUrl) {
73
+ throw new Error(
74
+ `mongodb: missing required parameter: ${parameters.connectionUrl.slug}`
75
+ );
76
+ }
77
+ const database = params[parameters.database.slug];
78
+ if (!database) {
79
+ throw new Error(
80
+ `mongodb: missing required parameter: ${parameters.database.slug}`
81
+ );
82
+ }
83
+ function redact(message) {
84
+ return message.replaceAll(connectionUrl, "***");
85
+ }
86
+ function serializeDocument(doc) {
87
+ const out = {};
88
+ for (const [key, value] of Object.entries(doc)) {
89
+ out[key] = value !== null && typeof value === "object" && "toHexString" in value && typeof value.toHexString === "function" ? String(value) : value;
90
+ }
91
+ return out;
92
+ }
93
+ async function withDb(fn) {
94
+ const { MongoClient } = await import("mongodb");
95
+ const client = new MongoClient(connectionUrl, {
96
+ connectTimeoutMS: CONNECT_TIMEOUT_MS,
97
+ serverSelectionTimeoutMS: CONNECT_TIMEOUT_MS,
98
+ socketTimeoutMS: QUERY_TIMEOUT_MS
99
+ });
100
+ try {
101
+ await client.connect();
102
+ return await fn(client.db(database));
103
+ } catch (err) {
104
+ const msg = err instanceof Error ? err.message : String(err);
105
+ throw new Error(redact(msg));
106
+ } finally {
107
+ await client.close();
108
+ }
109
+ }
110
+ async function aggregate(collection, pipeline, options) {
111
+ return withDb(async (db) => {
112
+ const cursor = db.collection(collection).aggregate(pipeline, options);
113
+ const documents = await cursor.toArray();
114
+ return documents.map(serializeDocument);
115
+ });
116
+ }
117
+ async function find(collection, filter = {}, options = {}) {
118
+ return withDb(async (db) => {
119
+ let cursor = db.collection(collection).find(filter);
120
+ if (options.projection) cursor = cursor.project(options.projection);
121
+ if (options.sort) cursor = cursor.sort(options.sort);
122
+ if (options.skip != null) cursor = cursor.skip(options.skip);
123
+ if (options.limit != null) cursor = cursor.limit(options.limit);
124
+ const documents = await cursor.toArray();
125
+ return documents.map(serializeDocument);
126
+ });
127
+ }
128
+ async function findOne(collection, filter = {}, options = {}) {
129
+ const docs = await find(collection, filter, { ...options, limit: 1 });
130
+ return docs.length > 0 ? docs[0] : null;
131
+ }
132
+ async function countDocuments(collection, filter = {}) {
133
+ return withDb(async (db) => {
134
+ return db.collection(collection).countDocuments(filter);
135
+ });
136
+ }
137
+ async function listCollections() {
138
+ return withDb(async (db) => {
139
+ const list = await db.listCollections().toArray();
140
+ return list.map((c) => ({ name: c.name, type: c.type ?? "collection" }));
141
+ });
142
+ }
143
+ return {
144
+ aggregate,
145
+ find,
146
+ findOne,
147
+ countDocuments,
148
+ listCollections
149
+ };
150
+ }
151
+
152
+ // ../connectors/src/connector-onboarding.ts
153
+ var ConnectorOnboarding = class {
154
+ /** Phase 1: Connection setup instructions (optional — some connectors don't need this) */
155
+ connectionSetupInstructions;
156
+ /** Phase 2: Data overview instructions */
157
+ dataOverviewInstructions;
158
+ constructor(config) {
159
+ this.connectionSetupInstructions = config.connectionSetupInstructions;
160
+ this.dataOverviewInstructions = config.dataOverviewInstructions;
161
+ }
162
+ getConnectionSetupPrompt(language) {
163
+ return this.connectionSetupInstructions?.[language] ?? null;
164
+ }
165
+ getDataOverviewInstructions(language) {
166
+ return this.dataOverviewInstructions[language];
167
+ }
168
+ };
169
+
170
+ // ../connectors/src/connector-tool.ts
171
+ var ConnectorTool = class {
172
+ name;
173
+ description;
174
+ inputSchema;
175
+ outputSchema;
176
+ _execute;
177
+ constructor(config) {
178
+ this.name = config.name;
179
+ this.description = config.description;
180
+ this.inputSchema = config.inputSchema;
181
+ this.outputSchema = config.outputSchema;
182
+ this._execute = config.execute;
183
+ }
184
+ createTool(connections, config) {
185
+ return {
186
+ description: this.description,
187
+ inputSchema: this.inputSchema,
188
+ outputSchema: this.outputSchema,
189
+ execute: (input) => this._execute(input, connections, config)
190
+ };
191
+ }
192
+ };
193
+
194
+ // ../connectors/src/connector-plugin.ts
195
+ var ConnectorPlugin = class _ConnectorPlugin {
196
+ slug;
197
+ authType;
198
+ name;
199
+ description;
200
+ iconUrl;
201
+ parameters;
202
+ releaseFlag;
203
+ proxyPolicy;
204
+ experimentalAttributes;
205
+ categories;
206
+ onboarding;
207
+ systemPrompt;
208
+ tools;
209
+ query;
210
+ checkConnection;
211
+ constructor(config) {
212
+ this.slug = config.slug;
213
+ this.authType = config.authType;
214
+ this.name = config.name;
215
+ this.description = config.description;
216
+ this.iconUrl = config.iconUrl;
217
+ this.parameters = config.parameters;
218
+ this.releaseFlag = config.releaseFlag;
219
+ this.proxyPolicy = config.proxyPolicy;
220
+ this.experimentalAttributes = config.experimentalAttributes;
221
+ this.categories = config.categories ?? [];
222
+ this.onboarding = config.onboarding;
223
+ this.systemPrompt = config.systemPrompt;
224
+ this.tools = config.tools;
225
+ this.query = config.query;
226
+ this.checkConnection = config.checkConnection;
227
+ }
228
+ get connectorKey() {
229
+ return _ConnectorPlugin.deriveKey(this.slug, this.authType);
230
+ }
231
+ /**
232
+ * Create tools for connections that belong to this connector.
233
+ * Filters connections by connectorKey internally.
234
+ * Returns tools keyed as `${connectorKey}_${toolName}`.
235
+ */
236
+ createTools(connections, config, opts) {
237
+ const myConnections = connections.filter(
238
+ (c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
239
+ );
240
+ const result = {};
241
+ for (const t of Object.values(this.tools)) {
242
+ const tool = t.createTool(myConnections, config);
243
+ const originalToModelOutput = tool.toModelOutput;
244
+ result[`${this.connectorKey}_${t.name}`] = {
245
+ ...tool,
246
+ toModelOutput: async (options) => {
247
+ if (!originalToModelOutput) {
248
+ return opts.truncateOutput(options.output);
249
+ }
250
+ const modelOutput = await originalToModelOutput(options);
251
+ if (modelOutput.type === "text" || modelOutput.type === "json") {
252
+ return opts.truncateOutput(modelOutput.value);
253
+ }
254
+ return modelOutput;
255
+ }
256
+ };
257
+ }
258
+ return result;
259
+ }
260
+ static deriveKey(slug, authType) {
261
+ if (authType) return `${slug}-${authType}`;
262
+ const LEGACY_NULL_AUTH_TYPE_MAP = {
263
+ // user-password
264
+ "postgresql": "user-password",
265
+ "mysql": "user-password",
266
+ "clickhouse": "user-password",
267
+ "kintone": "user-password",
268
+ "squadbase-db": "user-password",
269
+ // service-account
270
+ "snowflake": "service-account",
271
+ "bigquery": "service-account",
272
+ "google-analytics": "service-account",
273
+ "google-calendar": "service-account",
274
+ "aws-athena": "service-account",
275
+ "redshift": "service-account",
276
+ // api-key
277
+ "databricks": "api-key",
278
+ "dbt": "api-key",
279
+ "airtable": "api-key",
280
+ "openai": "api-key",
281
+ "gemini": "api-key",
282
+ "anthropic": "api-key",
283
+ "wix-store": "api-key"
284
+ };
285
+ const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
286
+ if (fallbackAuthType) return `${slug}-${fallbackAuthType}`;
287
+ return slug;
288
+ }
289
+ };
290
+
291
+ // ../connectors/src/auth-types.ts
292
+ var AUTH_TYPES = {
293
+ OAUTH: "oauth",
294
+ API_KEY: "api-key",
295
+ JWT: "jwt",
296
+ SERVICE_ACCOUNT: "service-account",
297
+ PAT: "pat",
298
+ USER_PASSWORD: "user-password"
299
+ };
300
+
301
+ // ../connectors/src/connectors/mongodb/setup.ts
302
+ var mongodbOnboarding = new ConnectorOnboarding({
303
+ dataOverviewInstructions: {
304
+ en: `1. Use listCollections to list all collections in the database
305
+ 2. For key collections, use find with limit to sample documents: collection="users", filter="{}", limit=5
306
+ 3. Examine the document structure to understand the schema (MongoDB is schema-flexible, so documents in the same collection may have different fields)
307
+ 4. Use aggregate with $group to understand data distribution if needed: pipeline='[{"$group": {"_id": "$fieldName", "count": {"$sum": 1}}}, {"$limit": 20}]'`,
308
+ ja: `1. listCollections \u3067\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u5185\u306E\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u4E00\u89A7\u3092\u53D6\u5F97
309
+ 2. \u4E3B\u8981\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u306B\u3064\u3044\u3066 find \u3067\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0: collection="users", filter="{}", limit=5
310
+ 3. \u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u69CB\u9020\u3092\u78BA\u8A8D\u3057\u3066\u30B9\u30AD\u30FC\u30DE\u3092\u628A\u63E1\uFF08MongoDB\u306F\u30B9\u30AD\u30FC\u30DE\u304C\u67D4\u8EDF\u306A\u305F\u3081\u3001\u540C\u3058\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u5185\u3067\u3082\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u304C\u7570\u306A\u308B\u5834\u5408\u304C\u3042\u308A\u307E\u3059\uFF09
311
+ 4. \u5FC5\u8981\u306B\u5FDC\u3058\u3066 aggregate \u306E $group \u3067\u30C7\u30FC\u30BF\u5206\u5E03\u3092\u78BA\u8A8D: pipeline='[{"$group": {"_id": "$fieldName", "count": {"$sum": 1}}}, {"$limit": 20}]'`
312
+ }
313
+ });
314
+
315
+ // ../connectors/src/connectors/mongodb/tools/find-documents.ts
316
+ import { z } from "zod";
317
+ var MAX_DOCUMENTS = 500;
318
+ var CONNECT_TIMEOUT_MS2 = 1e4;
319
+ var QUERY_TIMEOUT_MS2 = 6e4;
320
+ var inputSchema = z.object({
321
+ toolUseIntent: z.string().optional().describe(
322
+ "Brief description of what you intend to accomplish with this tool call"
323
+ ),
324
+ connectionId: z.string().describe("ID of the MongoDB connection to use"),
325
+ collection: z.string().describe("The name of the collection to query"),
326
+ filter: z.string().optional().describe(
327
+ `MongoDB filter query as a JSON string (e.g., '{"status": "active"}', '{"age": {"$gt": 25}}'). Defaults to '{}' (all documents).`
328
+ ),
329
+ projection: z.string().optional().describe(
330
+ `MongoDB projection as a JSON string to include/exclude fields (e.g., '{"name": 1, "email": 1}' to include only name and email).`
331
+ ),
332
+ sort: z.string().optional().describe(
333
+ `MongoDB sort specification as a JSON string (e.g., '{"createdAt": -1}' for descending by createdAt).`
334
+ ),
335
+ limit: z.number().optional().describe(
336
+ `Maximum number of documents to return. Defaults to ${MAX_DOCUMENTS}. Cannot exceed ${MAX_DOCUMENTS}.`
337
+ )
338
+ });
339
+ var outputSchema = z.discriminatedUnion("success", [
340
+ z.object({
341
+ success: z.literal(true),
342
+ documentCount: z.number(),
343
+ truncated: z.boolean(),
344
+ documents: z.array(z.record(z.string(), z.unknown()))
345
+ }),
346
+ z.object({
347
+ success: z.literal(false),
348
+ error: z.string()
349
+ })
350
+ ]);
351
+ var findDocumentsTool = new ConnectorTool({
352
+ name: "find",
353
+ description: `Find documents in a MongoDB collection. Returns up to ${MAX_DOCUMENTS} documents.
354
+ Use for: querying documents with filters, projecting specific fields, sorting results, and data sampling.
355
+ Pass filter, projection, and sort as JSON strings. Always use limit to avoid loading large amounts of data.
356
+ For listing collections, use the aggregate tool with an empty pipeline on the special collection name "$cmd.listCollections".`,
357
+ inputSchema,
358
+ outputSchema,
359
+ async execute({ connectionId, collection, filter, projection, sort, limit }, connections) {
360
+ const connection2 = connections.find((c) => c.id === connectionId);
361
+ if (!connection2) {
362
+ return {
363
+ success: false,
364
+ error: `Connection ${connectionId} not found`
365
+ };
366
+ }
367
+ console.log(
368
+ `[connector-query] mongodb/${connection2.name}: find in ${collection}`
369
+ );
370
+ let connectionUrl;
371
+ try {
372
+ const { MongoClient } = await import("mongodb");
373
+ connectionUrl = parameters.connectionUrl.getValue(connection2);
374
+ const database = parameters.database.getValue(connection2);
375
+ const client = new MongoClient(connectionUrl, {
376
+ connectTimeoutMS: CONNECT_TIMEOUT_MS2,
377
+ serverSelectionTimeoutMS: CONNECT_TIMEOUT_MS2,
378
+ socketTimeoutMS: QUERY_TIMEOUT_MS2
379
+ });
380
+ try {
381
+ await client.connect();
382
+ const db = client.db(database);
383
+ const coll = db.collection(collection);
384
+ const parsedFilter = filter ? JSON.parse(filter) : {};
385
+ const parsedProjection = projection ? JSON.parse(projection) : void 0;
386
+ const parsedSort = sort ? JSON.parse(sort) : void 0;
387
+ const effectiveLimit = Math.min(limit ?? MAX_DOCUMENTS, MAX_DOCUMENTS);
388
+ let cursor = coll.find(parsedFilter);
389
+ if (parsedProjection) cursor = cursor.project(parsedProjection);
390
+ if (parsedSort) cursor = cursor.sort(parsedSort);
391
+ cursor = cursor.limit(effectiveLimit + 1);
392
+ const documents = await cursor.toArray();
393
+ const truncated = documents.length > effectiveLimit;
394
+ const resultDocs = documents.slice(0, effectiveLimit).map((doc) => {
395
+ const obj = {};
396
+ for (const [key, value] of Object.entries(doc)) {
397
+ obj[key] = value instanceof Object && "toHexString" in value ? String(value) : value;
398
+ }
399
+ return obj;
400
+ });
401
+ return {
402
+ success: true,
403
+ documentCount: resultDocs.length,
404
+ truncated,
405
+ documents: resultDocs
406
+ };
407
+ } finally {
408
+ await client.close();
409
+ }
410
+ } catch (err) {
411
+ let msg = err instanceof Error ? err.message : String(err);
412
+ if (connectionUrl) {
413
+ msg = msg.replaceAll(connectionUrl, "***");
414
+ }
415
+ return { success: false, error: msg };
416
+ }
417
+ }
418
+ });
419
+
420
+ // ../connectors/src/connectors/mongodb/tools/aggregate.ts
421
+ import { z as z2 } from "zod";
422
+ var MAX_DOCUMENTS2 = 500;
423
+ var CONNECT_TIMEOUT_MS3 = 1e4;
424
+ var QUERY_TIMEOUT_MS3 = 6e4;
425
+ var inputSchema2 = z2.object({
426
+ toolUseIntent: z2.string().optional().describe(
427
+ "Brief description of what you intend to accomplish with this tool call"
428
+ ),
429
+ connectionId: z2.string().describe("ID of the MongoDB connection to use"),
430
+ collection: z2.string().describe("The name of the collection to run the aggregation pipeline on"),
431
+ pipeline: z2.string().describe(
432
+ `MongoDB aggregation pipeline as a JSON string. An array of stage objects (e.g., '[{"$match": {"status": "active"}}, {"$group": {"_id": "$category", "count": {"$sum": 1}}}]'). Always include a $limit stage to avoid returning too many documents.`
433
+ )
434
+ });
435
+ var outputSchema2 = z2.discriminatedUnion("success", [
436
+ z2.object({
437
+ success: z2.literal(true),
438
+ documentCount: z2.number(),
439
+ truncated: z2.boolean(),
440
+ documents: z2.array(z2.record(z2.string(), z2.unknown()))
441
+ }),
442
+ z2.object({
443
+ success: z2.literal(false),
444
+ error: z2.string()
445
+ })
446
+ ]);
447
+ var aggregateTool = new ConnectorTool({
448
+ name: "aggregate",
449
+ description: `Run a MongoDB aggregation pipeline on a collection. Returns up to ${MAX_DOCUMENTS2} documents.
450
+ Use for: complex data transformations, grouping, filtering, joining (via $lookup), statistical calculations, and data analysis.
451
+ Pass the pipeline as a JSON string representing an array of aggregation stages.
452
+ Always include a $limit stage in the pipeline to avoid loading large amounts of data.
453
+ Common stages: $match (filter), $group (aggregate), $sort (order), $project (reshape), $lookup (join), $unwind (flatten arrays).`,
454
+ inputSchema: inputSchema2,
455
+ outputSchema: outputSchema2,
456
+ async execute({ connectionId, collection, pipeline }, connections) {
457
+ const connection2 = connections.find((c) => c.id === connectionId);
458
+ if (!connection2) {
459
+ return {
460
+ success: false,
461
+ error: `Connection ${connectionId} not found`
462
+ };
463
+ }
464
+ console.log(
465
+ `[connector-query] mongodb/${connection2.name}: aggregate on ${collection}`
466
+ );
467
+ let connectionUrl;
468
+ try {
469
+ const { MongoClient } = await import("mongodb");
470
+ connectionUrl = parameters.connectionUrl.getValue(connection2);
471
+ const database = parameters.database.getValue(connection2);
472
+ const client = new MongoClient(connectionUrl, {
473
+ connectTimeoutMS: CONNECT_TIMEOUT_MS3,
474
+ serverSelectionTimeoutMS: CONNECT_TIMEOUT_MS3,
475
+ socketTimeoutMS: QUERY_TIMEOUT_MS3
476
+ });
477
+ try {
478
+ await client.connect();
479
+ const db = client.db(database);
480
+ const coll = db.collection(collection);
481
+ const parsedPipeline = JSON.parse(pipeline);
482
+ const documents = await coll.aggregate(parsedPipeline).toArray();
483
+ const truncated = documents.length > MAX_DOCUMENTS2;
484
+ const resultDocs = documents.slice(0, MAX_DOCUMENTS2).map((doc) => {
485
+ const obj = {};
486
+ for (const [key, value] of Object.entries(doc)) {
487
+ obj[key] = value instanceof Object && "toHexString" in value ? String(value) : value;
488
+ }
489
+ return obj;
490
+ });
491
+ return {
492
+ success: true,
493
+ documentCount: resultDocs.length,
494
+ truncated,
495
+ documents: resultDocs
496
+ };
497
+ } finally {
498
+ await client.close();
499
+ }
500
+ } catch (err) {
501
+ let msg = err instanceof Error ? err.message : String(err);
502
+ if (connectionUrl) {
503
+ msg = msg.replaceAll(connectionUrl, "***");
504
+ }
505
+ return { success: false, error: msg };
506
+ }
507
+ }
508
+ });
509
+
510
+ // ../connectors/src/connectors/mongodb/tools/list-collections.ts
511
+ import { z as z3 } from "zod";
512
+ var CONNECT_TIMEOUT_MS4 = 1e4;
513
+ var inputSchema3 = z3.object({
514
+ toolUseIntent: z3.string().optional().describe(
515
+ "Brief description of what you intend to accomplish with this tool call"
516
+ ),
517
+ connectionId: z3.string().describe("ID of the MongoDB connection to use")
518
+ });
519
+ var outputSchema3 = z3.discriminatedUnion("success", [
520
+ z3.object({
521
+ success: z3.literal(true),
522
+ collections: z3.array(z3.object({
523
+ name: z3.string(),
524
+ type: z3.string()
525
+ }))
526
+ }),
527
+ z3.object({
528
+ success: z3.literal(false),
529
+ error: z3.string()
530
+ })
531
+ ]);
532
+ var listCollectionsTool = new ConnectorTool({
533
+ name: "listCollections",
534
+ description: `List all collections in the MongoDB database.
535
+ Use this as the first step to explore the data structure. Returns collection names and types.
536
+ After listing collections, use the find tool to sample documents and understand the schema of each collection.`,
537
+ inputSchema: inputSchema3,
538
+ outputSchema: outputSchema3,
539
+ async execute({ connectionId }, connections) {
540
+ const connection2 = connections.find((c) => c.id === connectionId);
541
+ if (!connection2) {
542
+ return {
543
+ success: false,
544
+ error: `Connection ${connectionId} not found`
545
+ };
546
+ }
547
+ console.log(
548
+ `[connector-query] mongodb/${connection2.name}: listCollections`
549
+ );
550
+ let connectionUrl;
551
+ try {
552
+ const { MongoClient } = await import("mongodb");
553
+ connectionUrl = parameters.connectionUrl.getValue(connection2);
554
+ const database = parameters.database.getValue(connection2);
555
+ const client = new MongoClient(connectionUrl, {
556
+ connectTimeoutMS: CONNECT_TIMEOUT_MS4,
557
+ serverSelectionTimeoutMS: CONNECT_TIMEOUT_MS4
558
+ });
559
+ try {
560
+ await client.connect();
561
+ const db = client.db(database);
562
+ const collections = await db.listCollections().toArray();
563
+ return {
564
+ success: true,
565
+ collections: collections.map((c) => ({
566
+ name: c.name,
567
+ type: c.type || "collection"
568
+ }))
569
+ };
570
+ } finally {
571
+ await client.close();
572
+ }
573
+ } catch (err) {
574
+ let msg = err instanceof Error ? err.message : String(err);
575
+ if (connectionUrl) {
576
+ msg = msg.replaceAll(connectionUrl, "***");
577
+ }
578
+ return { success: false, error: msg };
579
+ }
580
+ }
581
+ });
582
+
583
+ // ../connectors/src/connectors/mongodb/index.ts
584
+ var tools = {
585
+ find: findDocumentsTool,
586
+ aggregate: aggregateTool,
587
+ listCollections: listCollectionsTool
588
+ };
589
+ var mongodbConnector = new ConnectorPlugin({
590
+ slug: "mongodb",
591
+ authType: AUTH_TYPES.USER_PASSWORD,
592
+ name: "MongoDB",
593
+ description: "Connect to MongoDB for document-oriented data storage and querying.",
594
+ iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/48JSUx9HE6oSa9JrHGg2E1/12b4cac65924cac3641d4bafcef37dbe/mongodb-icon.webp",
595
+ parameters,
596
+ releaseFlag: { dev1: true, dev2: true, prod: true },
597
+ categories: ["database"],
598
+ onboarding: mongodbOnboarding,
599
+ systemPrompt: {
600
+ en: `### Tools
601
+
602
+ - \`mongodb_listCollections\`: Lists all collections in the database. Use this first to explore available data.
603
+ - \`mongodb_find\`: Finds documents in a collection with optional filter, projection, sort, and limit. Use for data sampling and querying specific documents. Pass filter, projection, and sort as JSON strings.
604
+ - \`mongodb_aggregate\`: Runs a MongoDB aggregation pipeline on a collection. Use for complex data analysis, grouping, joining, and transformations. Pass pipeline as a JSON string.
605
+
606
+ ### Business Logic
607
+
608
+ The business logic type for this connector is "typescript". Write handler code using the connector SDK shown below. Do NOT access credentials directly from environment variables, and do NOT \`import { MongoClient } from "mongodb"\` in handler code \u2014 the \`mongodb\` driver is not part of the user dashboard's runtime, only of the connector SDK.
609
+
610
+ \u26A0\uFE0F **The client returned by \`connection(connectionId)\` is NOT a raw \`mongodb\` \`MongoClient\`.** It is a thin wrapper that opens a fresh connection per call, runs the requested operation against the database configured on the connection, and converts BSON \`ObjectId\` values to their hex string for JSON-safe responses. The methods are:
611
+
612
+ - \`client.aggregate<T>(collection, pipeline, options?) => Promise<T[]>\` \u2014 runs an aggregation pipeline and returns the document array. Always include a \`$limit\` stage.
613
+ - \`client.find<T>(collection, filter?, options?) => Promise<T[]>\` \u2014 \`options\` accepts \`{ projection?, sort?, limit?, skip? }\`. Always pass \`limit\`.
614
+ - \`client.findOne<T>(collection, filter?, options?) => Promise<T | null>\` \u2014 convenience wrapper around \`find\` with \`limit: 1\`.
615
+ - \`client.countDocuments(collection, filter?) => Promise<number>\` \u2014 accurate count (not \`estimatedDocumentCount\`).
616
+ - \`client.listCollections() => Promise<{ name: string; type: string }[]>\` \u2014 collections in the configured database.
617
+
618
+ There is **no** \`client.db(...)\`, \`client.connect()\`, or raw cursor / \`MongoClient\` API exposed through this client \u2014 those calls fail with \`X is not a function\`.
619
+
620
+ \`\`\`ts
621
+ import type { Context } from "hono";
622
+ import { connection } from "@squadbase/vite-server/connectors/mongodb";
623
+
624
+ const mongo = connection("<connectionId>");
625
+
626
+ export default async function handler(_c: Context) {
627
+ const rows = await mongo.aggregate<{ country: string; count: number }>(
628
+ "<collectionName>",
629
+ [
630
+ { $match: { country: { $nin: [null, ""] } } },
631
+ { $group: { _id: "$country", count: { $sum: 1 } } },
632
+ { $sort: { count: -1 } },
633
+ { $limit: 20 },
634
+ { $project: { _id: 0, country: "$_id", count: 1 } },
635
+ ],
636
+ );
637
+
638
+ return new Response(JSON.stringify(rows), {
639
+ headers: { "Content-Type": "application/json" },
640
+ });
641
+ }
642
+ \`\`\`
643
+
644
+ ### MongoDB Reference
645
+ - MongoDB stores data as flexible JSON-like documents (BSON)
646
+ - Documents in the same collection can have different fields
647
+ - Query filter operators: \`$eq\`, \`$gt\`, \`$gte\`, \`$lt\`, \`$lte\`, \`$ne\`, \`$in\`, \`$nin\`, \`$and\`, \`$or\`, \`$not\`, \`$regex\`
648
+ - Aggregation stages: \`$match\` (filter), \`$group\` (aggregate), \`$sort\` (order), \`$project\` (reshape), \`$lookup\` (join), \`$unwind\` (flatten arrays), \`$limit\`, \`$skip\`, \`$count\`
649
+ - Aggregation operators: \`$sum\`, \`$avg\`, \`$min\`, \`$max\`, \`$first\`, \`$last\`, \`$push\`, \`$addToSet\`
650
+ - Data exploration pattern:
651
+ 1. listCollections to see available data
652
+ 2. find with limit to sample documents and understand schema
653
+ 3. aggregate with $group to analyze data distribution
654
+ - Always include limit in find queries and $limit in aggregation pipelines`,
655
+ ja: `### \u30C4\u30FC\u30EB
656
+
657
+ - \`mongodb_listCollections\`: \u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u5185\u306E\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u4E00\u89A7\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002\u30C7\u30FC\u30BF\u63A2\u7D22\u306E\u6700\u521D\u306E\u30B9\u30C6\u30C3\u30D7\u3068\u3057\u3066\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002
658
+ - \`mongodb_find\`: \u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u5185\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u691C\u7D22\u3057\u307E\u3059\u3002\u30D5\u30A3\u30EB\u30BF\u30FC\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30B7\u30E7\u30F3\u3001\u30BD\u30FC\u30C8\u3001\u5236\u9650\u3092\u30AA\u30D7\u30B7\u30E7\u30F3\u3067\u6307\u5B9A\u53EF\u80FD\u3002\u30C7\u30FC\u30BF\u306E\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u3084\u7279\u5B9A\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002filter\u3001projection\u3001sort\u306FJSON\u6587\u5B57\u5217\u3067\u6E21\u3057\u3066\u304F\u3060\u3055\u3044\u3002
659
+ - \`mongodb_aggregate\`: \u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u4E0A\u3067MongoDB\u96C6\u7D04\u30D1\u30A4\u30D7\u30E9\u30A4\u30F3\u3092\u5B9F\u884C\u3057\u307E\u3059\u3002\u8907\u96D1\u306A\u30C7\u30FC\u30BF\u5206\u6790\u3001\u30B0\u30EB\u30FC\u30D7\u5316\u3001\u7D50\u5408\u3001\u5909\u63DB\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002pipeline\u306FJSON\u6587\u5B57\u5217\u3067\u6E21\u3057\u3066\u304F\u3060\u3055\u3044\u3002
660
+
661
+ ### Business Logic
662
+
663
+ \u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\u4EE5\u4E0B\u306B\u793A\u3059\u30B3\u30CD\u30AF\u30BFSDK\u3092\u4F7F\u7528\u3057\u3066\u30CF\u30F3\u30C9\u30E9\u30B3\u30FC\u30C9\u3092\u8A18\u8FF0\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u74B0\u5883\u5909\u6570\u304B\u3089\u76F4\u63A5\u8A8D\u8A3C\u60C5\u5831\u306B\u30A2\u30AF\u30BB\u30B9\u3057\u305F\u308A\u3001\u30CF\u30F3\u30C9\u30E9\u30B3\u30FC\u30C9\u3067 \`import { MongoClient } from "mongodb"\` \u3092\u884C\u3063\u305F\u308A\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044 \u2014 \`mongodb\` \u30C9\u30E9\u30A4\u30D0\u306F\u30E6\u30FC\u30B6\u30FC\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u306E\u30E9\u30F3\u30BF\u30A4\u30E0\u306B\u306F\u542B\u307E\u308C\u305A\u3001\u30B3\u30CD\u30AF\u30BFSDK\u5185\u90E8\u306B\u306E\u307F\u5B58\u5728\u3057\u307E\u3059\u3002
664
+
665
+ \u26A0\uFE0F **\`connection(connectionId)\` \u304C\u8FD4\u3059\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u306F \`mongodb\` \u306E \`MongoClient\` \u305D\u306E\u3082\u306E\u3067\u306F\u3042\u308A\u307E\u305B\u3093\u3002** \u547C\u3073\u51FA\u3057\u3054\u3068\u306B\u65B0\u3057\u3044\u63A5\u7D9A\u3092\u958B\u304D\u3001\u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306B\u8A2D\u5B9A\u3055\u308C\u305F\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u5BFE\u3057\u3066\u64CD\u4F5C\u3092\u5B9F\u884C\u3057\u3001BSON \u306E \`ObjectId\` \u3092 JSON \u5316\u306B\u5B89\u5168\u306A hex \u6587\u5B57\u5217\u306B\u5909\u63DB\u3059\u308B\u8584\u3044\u30E9\u30C3\u30D1\u30FC\u3067\u3059\u3002\u516C\u958B\u30E1\u30BD\u30C3\u30C9\u306F\u6B21\u306E\u3068\u304A\u308A\u3067\u3059\uFF1A
666
+
667
+ - \`client.aggregate<T>(collection, pipeline, options?) => Promise<T[]>\` \u2014 \u96C6\u7D04\u30D1\u30A4\u30D7\u30E9\u30A4\u30F3\u3092\u5B9F\u884C\u3057\u3066\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u914D\u5217\u3092\u8FD4\u3059\u3002\`$limit\` \u30B9\u30C6\u30FC\u30B8\u3092\u5FC5\u305A\u542B\u3081\u308B\u3053\u3068\u3002
668
+ - \`client.find<T>(collection, filter?, options?) => Promise<T[]>\` \u2014 \`options\` \u306F \`{ projection?, sort?, limit?, skip? }\`\u3002\`limit\` \u3092\u5FC5\u305A\u6307\u5B9A\u3059\u308B\u3053\u3068\u3002
669
+ - \`client.findOne<T>(collection, filter?, options?) => Promise<T | null>\` \u2014 \`limit: 1\` \u3067\u306E \`find\` \u306E\u30E9\u30C3\u30D1\u30FC\u3002
670
+ - \`client.countDocuments(collection, filter?) => Promise<number>\` \u2014 \u6B63\u78BA\u306A\u30AB\u30A6\u30F3\u30C8\uFF08\`estimatedDocumentCount\` \u3067\u306F\u306A\u3044\uFF09\u3002
671
+ - \`client.listCollections() => Promise<{ name: string; type: string }[]>\` \u2014 \u8A2D\u5B9A\u3055\u308C\u305F\u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u5185\u306E\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u4E00\u89A7\u3002
672
+
673
+ \`client.db(...)\`\u3001\`client.connect()\`\u3001\u751F\u306E\u30AB\u30FC\u30BD\u30EB\u3084 \`MongoClient\` API \u306F **\u5B58\u5728\u3057\u306A\u3044** \u2014 \`X is not a function\` \u3067\u5931\u6557\u3059\u308B\u3002
674
+
675
+ \`\`\`ts
676
+ import type { Context } from "hono";
677
+ import { connection } from "@squadbase/vite-server/connectors/mongodb";
678
+
679
+ const mongo = connection("<connectionId>");
680
+
681
+ export default async function handler(_c: Context) {
682
+ const rows = await mongo.aggregate<{ country: string; count: number }>(
683
+ "<collectionName>",
684
+ [
685
+ { $match: { country: { $nin: [null, ""] } } },
686
+ { $group: { _id: "$country", count: { $sum: 1 } } },
687
+ { $sort: { count: -1 } },
688
+ { $limit: 20 },
689
+ { $project: { _id: 0, country: "$_id", count: 1 } },
690
+ ],
691
+ );
692
+
693
+ return new Response(JSON.stringify(rows), {
694
+ headers: { "Content-Type": "application/json" },
695
+ });
696
+ }
697
+ \`\`\`
698
+
699
+ ### MongoDB \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
700
+ - MongoDB\u306F\u30D5\u30EC\u30AD\u30B7\u30D6\u30EB\u306AJSON\u5F62\u5F0F\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\uFF08BSON\uFF09\u3068\u3057\u3066\u30C7\u30FC\u30BF\u3092\u683C\u7D0D\u3057\u307E\u3059
701
+ - \u540C\u3058\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u5185\u306E\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u306F\u7570\u306A\u308B\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u6301\u3064\u3053\u3068\u304C\u3067\u304D\u307E\u3059
702
+ - \u30AF\u30A8\u30EA\u30D5\u30A3\u30EB\u30BF\u30FC\u6F14\u7B97\u5B50: \`$eq\`, \`$gt\`, \`$gte\`, \`$lt\`, \`$lte\`, \`$ne\`, \`$in\`, \`$nin\`, \`$and\`, \`$or\`, \`$not\`, \`$regex\`
703
+ - \u96C6\u7D04\u30B9\u30C6\u30FC\u30B8: \`$match\`\uFF08\u30D5\u30A3\u30EB\u30BF\u30FC\uFF09, \`$group\`\uFF08\u96C6\u7D04\uFF09, \`$sort\`\uFF08\u30BD\u30FC\u30C8\uFF09, \`$project\`\uFF08\u5909\u63DB\uFF09, \`$lookup\`\uFF08\u7D50\u5408\uFF09, \`$unwind\`\uFF08\u914D\u5217\u5C55\u958B\uFF09, \`$limit\`, \`$skip\`, \`$count\`
704
+ - \u96C6\u7D04\u6F14\u7B97\u5B50: \`$sum\`, \`$avg\`, \`$min\`, \`$max\`, \`$first\`, \`$last\`, \`$push\`, \`$addToSet\`
705
+ - \u30C7\u30FC\u30BF\u63A2\u7D22\u30D1\u30BF\u30FC\u30F3:
706
+ 1. listCollections \u3067\u5229\u7528\u53EF\u80FD\u306A\u30C7\u30FC\u30BF\u3092\u78BA\u8A8D
707
+ 2. find \u3068 limit \u3067\u30C9\u30AD\u30E5\u30E1\u30F3\u30C8\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u3057\u3066\u30B9\u30AD\u30FC\u30DE\u3092\u628A\u63E1
708
+ 3. aggregate \u306E $group \u3067\u30C7\u30FC\u30BF\u5206\u5E03\u3092\u5206\u6790
709
+ - find \u30AF\u30A8\u30EA\u306B\u306F\u5FC5\u305A limit \u3092\u3001\u96C6\u7D04\u30D1\u30A4\u30D7\u30E9\u30A4\u30F3\u306B\u306F $limit \u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044`
710
+ },
711
+ tools,
712
+ async checkConnection(params, _config) {
713
+ try {
714
+ const { MongoClient } = await import("mongodb");
715
+ const client = new MongoClient(params[parameters.connectionUrl.slug], {
716
+ connectTimeoutMS: 1e4,
717
+ serverSelectionTimeoutMS: 1e4
718
+ });
719
+ try {
720
+ await client.connect();
721
+ const db = client.db(params[parameters.database.slug]);
722
+ await db.command({ ping: 1 });
723
+ return { success: true };
724
+ } finally {
725
+ await client.close();
726
+ }
727
+ } catch (error) {
728
+ return { success: false, error: error instanceof Error ? error.message : String(error) };
729
+ }
730
+ }
731
+ });
732
+
733
+ // src/connectors/create-connector-sdk.ts
734
+ import { readFileSync } from "fs";
735
+ import path from "path";
736
+
737
+ // src/connector-client/env.ts
738
+ function resolveEnvVar(entry, key, connectionId) {
739
+ const envVarName = entry.envVars[key];
740
+ if (!envVarName) {
741
+ throw new Error(`Connection "${connectionId}" is missing envVars mapping for key "${key}"`);
742
+ }
743
+ const value = process.env[envVarName];
744
+ if (!value) {
745
+ throw new Error(`Environment variable "${envVarName}" (for connection "${connectionId}", key "${key}") is not set`);
746
+ }
747
+ return value;
748
+ }
749
+ function resolveEnvVarOptional(entry, key) {
750
+ const envVarName = entry.envVars[key];
751
+ if (!envVarName) return void 0;
752
+ return process.env[envVarName] || void 0;
753
+ }
754
+
755
+ // src/connector-client/proxy-fetch.ts
756
+ import { getContext } from "hono/context-storage";
757
+ import { getCookie } from "hono/cookie";
758
+ var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
759
+ function normalizeHeaders(input) {
760
+ const out = {};
761
+ if (!input) return out;
762
+ new Headers(input).forEach((value, key) => {
763
+ out[key] = value;
764
+ });
765
+ return out;
766
+ }
767
+ function createSandboxProxyFetch(connectionId) {
768
+ return async (input, init) => {
769
+ const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
770
+ const sandboxId = process.env.INTERNAL_SQUADBASE_SANDBOX_ID;
771
+ if (!token || !sandboxId) {
772
+ throw new Error(
773
+ "Connection proxy is not configured. Please check your deployment settings."
774
+ );
775
+ }
776
+ const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
777
+ const originalMethod = init?.method ?? "GET";
778
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
779
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
780
+ const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
781
+ return fetch(proxyUrl, {
782
+ method: "POST",
783
+ headers: {
784
+ "Content-Type": "application/json",
785
+ Authorization: `Bearer ${token}`
786
+ },
787
+ body: JSON.stringify({
788
+ url: originalUrl,
789
+ method: originalMethod,
790
+ headers: normalizeHeaders(init?.headers),
791
+ body: originalBody
792
+ })
793
+ });
794
+ };
795
+ }
796
+ function createDeployedAppProxyFetch(connectionId) {
797
+ const projectId = process.env["SQUADBASE_PROJECT_ID"];
798
+ if (!projectId) {
799
+ throw new Error(
800
+ "Connection proxy is not configured. Please check your deployment settings."
801
+ );
802
+ }
803
+ const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
804
+ const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
805
+ return async (input, init) => {
806
+ const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
807
+ const originalMethod = init?.method ?? "GET";
808
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
809
+ const c = getContext();
810
+ const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
811
+ if (!appSession) {
812
+ throw new Error(
813
+ "No authentication method available for connection proxy."
814
+ );
815
+ }
816
+ return fetch(proxyUrl, {
817
+ method: "POST",
818
+ headers: {
819
+ "Content-Type": "application/json",
820
+ Authorization: `Bearer ${appSession}`
821
+ },
822
+ body: JSON.stringify({
823
+ url: originalUrl,
824
+ method: originalMethod,
825
+ headers: normalizeHeaders(init?.headers),
826
+ body: originalBody
827
+ })
828
+ });
829
+ };
830
+ }
831
+ function createProxyFetch(connectionId) {
832
+ if (process.env.INTERNAL_SQUADBASE_SANDBOX_ID) {
833
+ return createSandboxProxyFetch(connectionId);
834
+ }
835
+ return createDeployedAppProxyFetch(connectionId);
836
+ }
837
+
838
+ // src/connectors/create-connector-sdk.ts
839
+ function loadConnectionsSync() {
840
+ const filePath = process.env.CONNECTIONS_PATH ?? path.join(process.cwd(), ".squadbase/connections.json");
841
+ try {
842
+ const raw = readFileSync(filePath, "utf-8");
843
+ return JSON.parse(raw);
844
+ } catch {
845
+ return {};
846
+ }
847
+ }
848
+ function createConnectorSdk(plugin, createClient2) {
849
+ return (connectionId) => {
850
+ const connections = loadConnectionsSync();
851
+ const entry = connections[connectionId];
852
+ if (!entry) {
853
+ throw new Error(
854
+ `Connection "${connectionId}" not found in .squadbase/connections.json`
855
+ );
856
+ }
857
+ if (entry.connector.slug !== plugin.slug) {
858
+ throw new Error(
859
+ `Connection "${connectionId}" is not a ${plugin.slug} connection (got "${entry.connector.slug}")`
860
+ );
861
+ }
862
+ const params = {};
863
+ for (const param of Object.values(plugin.parameters)) {
864
+ if (param.required) {
865
+ params[param.slug] = resolveEnvVar(entry, param.slug, connectionId);
866
+ } else {
867
+ const val = resolveEnvVarOptional(entry, param.slug);
868
+ if (val !== void 0) params[param.slug] = val;
869
+ }
870
+ }
871
+ return createClient2(params, createProxyFetch(connectionId));
872
+ };
873
+ }
874
+
875
+ // src/connectors/entries/mongodb.ts
876
+ var connection = createConnectorSdk(mongodbConnector, createClient);
877
+ export {
878
+ connection
879
+ };