@synapcores/sdk 0.1.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/dist/index.mjs ADDED
@@ -0,0 +1,3055 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/client.ts
9
+ import axios from "axios";
10
+
11
+ // src/subscription.ts
12
+ import WebSocket from "ws";
13
+ import { EventEmitter } from "events";
14
+ var Subscription = class extends EventEmitter {
15
+ constructor(collection, options = {}) {
16
+ super();
17
+ this.collection = collection;
18
+ this.options = options;
19
+ this.running = false;
20
+ this.reconnectAttempts = 0;
21
+ this.maxReconnectAttempts = 5;
22
+ this.reconnectDelay = 1e3;
23
+ }
24
+ async connect() {
25
+ if (this.running) {
26
+ return;
27
+ }
28
+ this.running = true;
29
+ await this.createConnection();
30
+ }
31
+ async createConnection() {
32
+ const client = this.collection.client;
33
+ const protocol = client.config.useHttps ? "wss" : "ws";
34
+ const url = `${protocol}://${client.config.host}:${client.config.port}/v1/ws`;
35
+ const headers = {};
36
+ if (client.config.apiKey) {
37
+ headers["Authorization"] = `Bearer ${client.config.apiKey}`;
38
+ }
39
+ this.ws = new WebSocket(url, { headers });
40
+ this.ws.on("open", () => {
41
+ this.reconnectAttempts = 0;
42
+ this.subscribe();
43
+ });
44
+ this.ws.on("message", (data) => {
45
+ this.handleMessage(data.toString());
46
+ });
47
+ this.ws.on("error", (error) => {
48
+ this.emit("error", error);
49
+ });
50
+ this.ws.on("close", () => {
51
+ if (this.running) {
52
+ this.scheduleReconnect();
53
+ }
54
+ });
55
+ this.ws.on("ping", () => {
56
+ this.ws?.pong();
57
+ });
58
+ }
59
+ subscribe() {
60
+ const subscribeMessage = {
61
+ type: "subscribe",
62
+ collection: this.collection.name,
63
+ filter: this.options.filter || {}
64
+ };
65
+ this.ws?.send(JSON.stringify(subscribeMessage));
66
+ }
67
+ handleMessage(message) {
68
+ try {
69
+ const data = JSON.parse(message);
70
+ if (data.type === "error") {
71
+ this.emit("error", new Error(data.message));
72
+ return;
73
+ }
74
+ if (data.type === "change") {
75
+ const event = {
76
+ operation: data.operation,
77
+ collection: data.collection,
78
+ document: data.document,
79
+ timestamp: new Date(data.timestamp),
80
+ sequence: data.sequence
81
+ };
82
+ this.emit("change", event);
83
+ if (this.options.onChange) {
84
+ Promise.resolve(this.options.onChange(event)).catch((error) => {
85
+ this.emit("error", error);
86
+ });
87
+ }
88
+ }
89
+ } catch (error) {
90
+ this.emit("error", error);
91
+ }
92
+ }
93
+ scheduleReconnect() {
94
+ if (this.reconnectAttempts >= this.maxReconnectAttempts) {
95
+ this.emit("error", new Error("Max reconnection attempts reached"));
96
+ this.close();
97
+ return;
98
+ }
99
+ this.reconnectAttempts++;
100
+ const delay = this.reconnectDelay * Math.pow(2, this.reconnectAttempts - 1);
101
+ this.reconnectTimeout = setTimeout(() => {
102
+ this.createConnection().catch((error) => {
103
+ this.emit("error", error);
104
+ });
105
+ }, delay);
106
+ }
107
+ async close() {
108
+ this.running = false;
109
+ if (this.reconnectTimeout) {
110
+ clearTimeout(this.reconnectTimeout);
111
+ this.reconnectTimeout = void 0;
112
+ }
113
+ if (this.ws) {
114
+ this.ws.close();
115
+ this.ws = void 0;
116
+ }
117
+ this.removeAllListeners();
118
+ }
119
+ // Async iterator support
120
+ async *[Symbol.asyncIterator]() {
121
+ const events = [];
122
+ let resolver = null;
123
+ const handleChange = (event) => {
124
+ if (resolver) {
125
+ resolver({ done: false, value: event });
126
+ resolver = null;
127
+ } else {
128
+ events.push(event);
129
+ }
130
+ };
131
+ this.on("change", handleChange);
132
+ try {
133
+ while (this.running) {
134
+ if (events.length > 0) {
135
+ yield events.shift();
136
+ } else {
137
+ yield await new Promise((resolve) => {
138
+ resolver = (result) => {
139
+ if (!result.done) {
140
+ resolve(result.value);
141
+ }
142
+ };
143
+ });
144
+ }
145
+ }
146
+ } finally {
147
+ this.off("change", handleChange);
148
+ }
149
+ }
150
+ };
151
+
152
+ // src/collection.ts
153
+ var Collection = class {
154
+ constructor(client, name, schema) {
155
+ this.client = client;
156
+ this.name = name;
157
+ this.schema = schema;
158
+ }
159
+ get basePath() {
160
+ return `/collections/${this.name}`;
161
+ }
162
+ async insert(documents, _autoEmbed = true) {
163
+ const isSingle = !Array.isArray(documents);
164
+ const docs = isSingle ? [documents] : documents;
165
+ if (isSingle) {
166
+ const { data } = await this.client._getHttpClient().post(
167
+ `${this.basePath}/documents`,
168
+ documents
169
+ // Send the document directly as the body
170
+ );
171
+ return {
172
+ ids: [data.id],
173
+ inserted: 1
174
+ };
175
+ } else {
176
+ const formattedDocs = docs.map((doc) => ({
177
+ ...doc,
178
+ // Spread document fields at root level
179
+ id: null
180
+ // Optional ID field
181
+ }));
182
+ const bulkUrl = `${this.basePath}/documents/bulk`;
183
+ console.log("Calling bulk insert endpoint:", bulkUrl);
184
+ console.log("Payload:", JSON.stringify({ documents: formattedDocs }, null, 2));
185
+ const { data } = await this.client._getHttpClient().post(
186
+ bulkUrl,
187
+ {
188
+ documents: formattedDocs
189
+ }
190
+ );
191
+ return {
192
+ ids: data.ids || [],
193
+ inserted: data.inserted || docs.length
194
+ };
195
+ }
196
+ }
197
+ async get(documentId) {
198
+ try {
199
+ const { data } = await this.client._getHttpClient().get(
200
+ `${this.basePath}/documents/${documentId}`
201
+ );
202
+ return data;
203
+ } catch (error) {
204
+ if (error.code === "NOT_FOUND") {
205
+ return null;
206
+ }
207
+ throw error;
208
+ }
209
+ }
210
+ async update(documentId, data, options = {}) {
211
+ const response = await this.client._getHttpClient().patch(
212
+ `${this.basePath}/documents/${documentId}`,
213
+ {
214
+ data,
215
+ merge: options.merge !== false
216
+ }
217
+ );
218
+ return response.data;
219
+ }
220
+ async delete(documentId) {
221
+ const ids = Array.isArray(documentId) ? documentId : [documentId];
222
+ const { data } = await this.client._getHttpClient().request({
223
+ method: "DELETE",
224
+ url: `${this.basePath}/documents`,
225
+ data: { ids }
226
+ });
227
+ return { deleted: data.deleted };
228
+ }
229
+ async search(options) {
230
+ const searchUrl = `${this.basePath}/search`;
231
+ console.log("Calling search endpoint:", searchUrl);
232
+ console.log("Request body:", {
233
+ query: options.filter || {},
234
+ limit: options.topK || 10,
235
+ offset: options.offset || 0
236
+ });
237
+ const { data } = await this.client._getHttpClient().post(
238
+ searchUrl,
239
+ {
240
+ query: options.filter || {},
241
+ // Use filter as the query
242
+ limit: options.topK || 10,
243
+ offset: options.offset || 0
244
+ }
245
+ );
246
+ return {
247
+ documents: data.documents || data,
248
+ // Handle different response formats
249
+ total: data.total,
250
+ tookMs: data.took_ms,
251
+ nextOffset: data.next_offset
252
+ };
253
+ }
254
+ async vectorSearch(options) {
255
+ const { data } = await this.client._getHttpClient().post(
256
+ `${this.basePath}/vector_search`,
257
+ {
258
+ vector: options.vector,
259
+ field: options.field || "embedding",
260
+ top_k: options.topK || 10,
261
+ filter: options.filter,
262
+ distance_metric: options.distanceMetric || "cosine",
263
+ include_metadata: options.includeMetadata
264
+ }
265
+ );
266
+ return {
267
+ documents: data.documents,
268
+ total: data.total,
269
+ tookMs: data.took_ms
270
+ };
271
+ }
272
+ async query(options = {}) {
273
+ const { data } = await this.client._getHttpClient().post(
274
+ `${this.basePath}/query`,
275
+ {
276
+ filter: options.filter || {},
277
+ limit: options.limit || 100,
278
+ offset: options.offset || 0,
279
+ sort: options.sort,
280
+ projection: options.projection
281
+ }
282
+ );
283
+ return {
284
+ documents: data.documents,
285
+ total: data.total,
286
+ tookMs: data.took_ms,
287
+ nextOffset: data.next_offset
288
+ };
289
+ }
290
+ async count(filter) {
291
+ const { data } = await this.client._getHttpClient().post(
292
+ `${this.basePath}/count`,
293
+ { filter: filter || {} }
294
+ );
295
+ return data.count;
296
+ }
297
+ async stats() {
298
+ const { data } = await this.client._getHttpClient().get(
299
+ `${this.basePath}/stats`
300
+ );
301
+ return {
302
+ name: data.name,
303
+ documentCount: data.document_count,
304
+ sizeBytes: data.size_bytes,
305
+ indexCount: data.index_count,
306
+ createdAt: new Date(data.created_at),
307
+ updatedAt: new Date(data.updated_at)
308
+ };
309
+ }
310
+ async createIndex(options) {
311
+ const { data } = await this.client._getHttpClient().post(
312
+ `${this.basePath}/indexes`,
313
+ {
314
+ field: options.field,
315
+ type: options.type || "btree",
316
+ options: options.options || {}
317
+ }
318
+ );
319
+ return { created: data.created };
320
+ }
321
+ async dropIndex(field) {
322
+ const { data } = await this.client._getHttpClient().delete(
323
+ `${this.basePath}/indexes/${field}`
324
+ );
325
+ return { dropped: data.dropped };
326
+ }
327
+ async subscribe(options = {}) {
328
+ const subscription = new Subscription(this, options);
329
+ await subscription.connect();
330
+ return subscription;
331
+ }
332
+ };
333
+
334
+ // src/automl.ts
335
+ var AutoMLModel = class {
336
+ constructor(client, info) {
337
+ this.client = client;
338
+ this.info = info;
339
+ }
340
+ get id() {
341
+ return this.info.id;
342
+ }
343
+ get name() {
344
+ return this.info.name;
345
+ }
346
+ async predict(data) {
347
+ const isSingle = !Array.isArray(data);
348
+ const inputs = isSingle ? [data] : data;
349
+ const response = await this.client.synapCores._getHttpClient().post(
350
+ "/ai/predict",
351
+ {
352
+ model_id: this.id,
353
+ inputs
354
+ }
355
+ );
356
+ const predictions = response.data.predictions;
357
+ return isSingle ? predictions[0] : predictions;
358
+ }
359
+ async evaluate(testData, target) {
360
+ const payload = {
361
+ model_id: this.id
362
+ };
363
+ if (typeof testData === "string") {
364
+ payload.collection = testData;
365
+ } else {
366
+ payload.data = testData;
367
+ if (target) {
368
+ payload.target = target;
369
+ }
370
+ }
371
+ const { data } = await this.client.synapCores._getHttpClient().post(
372
+ "/ai/evaluate",
373
+ payload
374
+ );
375
+ return data;
376
+ }
377
+ async delete() {
378
+ await this.client.synapCores._getHttpClient().delete(
379
+ `/ai/models/${this.id}`
380
+ );
381
+ }
382
+ };
383
+ var AutoMLClient = class {
384
+ constructor(synapCores) {
385
+ this.synapCores = synapCores;
386
+ }
387
+ async train(options) {
388
+ const { data } = await this.synapCores._getHttpClient().post("/ai/train", {
389
+ collection: options.collection,
390
+ target: options.target,
391
+ features: options.features,
392
+ task: options.task || "auto",
393
+ name: options.name || `${options.collection}_${options.target}_model`,
394
+ config: options.config || {},
395
+ validation_split: options.validationSplit || 0.2,
396
+ max_trials: options.maxTrials || 10,
397
+ timeout_minutes: options.timeoutMinutes || 60
398
+ });
399
+ const modelInfo = {
400
+ id: data.id,
401
+ name: data.name,
402
+ task: data.task,
403
+ status: data.status,
404
+ accuracy: data.accuracy,
405
+ createdAt: new Date(data.created_at),
406
+ updatedAt: data.updated_at ? new Date(data.updated_at) : void 0,
407
+ config: data.config
408
+ };
409
+ return new AutoMLModel(this, modelInfo);
410
+ }
411
+ async getModel(modelId) {
412
+ const { data } = await this.synapCores._getHttpClient().get(
413
+ `/ai/models/${modelId}`
414
+ );
415
+ const modelInfo = {
416
+ id: data.id,
417
+ name: data.name,
418
+ task: data.task,
419
+ status: data.status,
420
+ accuracy: data.accuracy,
421
+ createdAt: new Date(data.created_at),
422
+ updatedAt: data.updated_at ? new Date(data.updated_at) : void 0,
423
+ config: data.config
424
+ };
425
+ return new AutoMLModel(this, modelInfo);
426
+ }
427
+ async listModels(filters) {
428
+ const { data } = await this.synapCores._getHttpClient().get("/ai/models", {
429
+ params: filters
430
+ });
431
+ return data.models.map((model) => ({
432
+ id: model.id,
433
+ name: model.name,
434
+ task: model.task,
435
+ status: model.status,
436
+ accuracy: model.accuracy,
437
+ createdAt: new Date(model.created_at),
438
+ updatedAt: model.updated_at ? new Date(model.updated_at) : void 0,
439
+ config: model.config
440
+ }));
441
+ }
442
+ /**
443
+ * Start async training job
444
+ */
445
+ async trainAsync(options) {
446
+ const { data } = await this.synapCores._getHttpClient().post("/ai/train/async", {
447
+ collection: options.collection,
448
+ target: options.target,
449
+ features: options.features,
450
+ task: options.task || "auto",
451
+ name: options.name || `${options.collection}_${options.target}_model`,
452
+ config: options.config || {},
453
+ validation_split: options.validationSplit || 0.2,
454
+ max_trials: options.maxTrials || 10,
455
+ timeout_minutes: options.timeoutMinutes || 60,
456
+ callback_url: options.callback_url,
457
+ webhook_url: options.webhook_url
458
+ });
459
+ return {
460
+ id: data.id || data.job_id,
461
+ name: data.name,
462
+ status: data.status,
463
+ progress: data.progress || 0,
464
+ phase: data.phase,
465
+ task: data.task,
466
+ current_trial: data.current_trial,
467
+ total_trials: data.total_trials || options.maxTrials || 10,
468
+ best_accuracy: data.best_accuracy,
469
+ eta_ms: data.eta_ms || data.estimated_time_remaining_ms,
470
+ error: data.error,
471
+ started_at: new Date(data.started_at || Date.now()),
472
+ completed_at: data.completed_at ? new Date(data.completed_at) : void 0,
473
+ model_id: data.model_id
474
+ };
475
+ }
476
+ /**
477
+ * Get training job status
478
+ */
479
+ async getTrainingJob(jobId) {
480
+ const { data } = await this.synapCores._getHttpClient().get(
481
+ `/ai/train/jobs/${jobId}`
482
+ );
483
+ return {
484
+ id: data.id || jobId,
485
+ name: data.name,
486
+ status: data.status,
487
+ progress: data.progress || 0,
488
+ phase: data.phase,
489
+ task: data.task,
490
+ current_trial: data.current_trial,
491
+ total_trials: data.total_trials,
492
+ best_accuracy: data.best_accuracy,
493
+ eta_ms: data.eta_ms || data.estimated_time_remaining_ms,
494
+ error: data.error,
495
+ started_at: new Date(data.started_at),
496
+ completed_at: data.completed_at ? new Date(data.completed_at) : void 0,
497
+ model_id: data.model_id
498
+ };
499
+ }
500
+ /**
501
+ * List training jobs
502
+ */
503
+ async listTrainingJobs(options = {}) {
504
+ const params = new URLSearchParams();
505
+ if (options.status) params.append("status", options.status);
506
+ if (options.page) params.append("page", options.page.toString());
507
+ if (options.page_size) params.append("page_size", options.page_size.toString());
508
+ const { data } = await this.synapCores._getHttpClient().get(
509
+ `/ai/train/jobs?${params.toString()}`
510
+ );
511
+ return (data.jobs || data).map((job) => ({
512
+ id: job.id,
513
+ name: job.name,
514
+ status: job.status,
515
+ progress: job.progress || 0,
516
+ phase: job.phase,
517
+ task: job.task,
518
+ current_trial: job.current_trial,
519
+ total_trials: job.total_trials,
520
+ best_accuracy: job.best_accuracy,
521
+ eta_ms: job.eta_ms || job.estimated_time_remaining_ms,
522
+ error: job.error,
523
+ started_at: new Date(job.started_at),
524
+ completed_at: job.completed_at ? new Date(job.completed_at) : void 0,
525
+ model_id: job.model_id
526
+ }));
527
+ }
528
+ /**
529
+ * Cancel a training job
530
+ */
531
+ async cancelTrainingJob(jobId) {
532
+ await this.synapCores._getHttpClient().post(`/ai/train/jobs/${jobId}/cancel`);
533
+ }
534
+ /**
535
+ * Get training metrics for a job
536
+ */
537
+ async getTrainingMetrics(jobId) {
538
+ const { data } = await this.synapCores._getHttpClient().get(
539
+ `/ai/train/jobs/${jobId}/metrics`
540
+ );
541
+ return (data.metrics || data).map((metric) => ({
542
+ trial: metric.trial,
543
+ accuracy: metric.accuracy,
544
+ loss: metric.loss,
545
+ metrics: metric.metrics,
546
+ timestamp: new Date(metric.timestamp)
547
+ }));
548
+ }
549
+ /**
550
+ * Wait for training job to complete
551
+ */
552
+ async waitForTrainingJob(jobId, options = {}) {
553
+ const pollInterval = options.pollInterval || 2e3;
554
+ const timeout = options.timeout || 36e5;
555
+ const startTime = Date.now();
556
+ while (true) {
557
+ const job = await this.getTrainingJob(jobId);
558
+ if (options.onProgress) {
559
+ options.onProgress(job);
560
+ }
561
+ if (job.status === "completed") {
562
+ if (!job.model_id) {
563
+ throw new Error("Training completed but no model ID returned");
564
+ }
565
+ return await this.getModel(job.model_id);
566
+ }
567
+ if (job.status === "failed") {
568
+ throw new Error(`Training failed: ${job.error || "Unknown error"}`);
569
+ }
570
+ if (job.status === "cancelled") {
571
+ throw new Error("Training was cancelled");
572
+ }
573
+ if (Date.now() - startTime > timeout) {
574
+ throw new Error("Timeout waiting for training job to complete");
575
+ }
576
+ await new Promise((resolve) => setTimeout(resolve, pollInterval));
577
+ }
578
+ }
579
+ };
580
+
581
+ // src/nlp.ts
582
+ var NLPClient = class {
583
+ constructor(synapCores) {
584
+ this.synapCores = synapCores;
585
+ }
586
+ async analyze(options) {
587
+ const isBatch = Array.isArray(options.text);
588
+ const texts = isBatch ? options.text : [options.text];
589
+ const { data } = await this.synapCores._getHttpClient().post("/ai/analyze", {
590
+ texts,
591
+ tasks: options.tasks || ["sentiment", "entities", "keywords"],
592
+ language: options.language
593
+ });
594
+ const results = data.results.map((r) => ({
595
+ sentiment: r.sentiment ? {
596
+ label: r.sentiment.label,
597
+ score: r.sentiment.score,
598
+ confidence: r.sentiment.confidence
599
+ } : void 0,
600
+ entities: r.entities ? r.entities.map((e) => ({
601
+ text: e.text,
602
+ type: e.type,
603
+ start: e.start,
604
+ end: e.end,
605
+ score: e.score
606
+ })) : void 0,
607
+ summary: r.summary,
608
+ keywords: r.keywords,
609
+ language: r.language
610
+ }));
611
+ return isBatch ? results : results[0];
612
+ }
613
+ async summarize(options) {
614
+ const { data } = await this.synapCores._getHttpClient().post("/ai/summarize", {
615
+ text: options.text,
616
+ max_length: options.maxLength || 150,
617
+ min_length: options.minLength || 30
618
+ });
619
+ return data.summary;
620
+ }
621
+ async extractEntities(text, entityTypes) {
622
+ const { data } = await this.synapCores._getHttpClient().post("/ai/entities", {
623
+ text,
624
+ entity_types: entityTypes
625
+ });
626
+ return data.entities.map((e) => ({
627
+ text: e.text,
628
+ type: e.type,
629
+ start: e.start,
630
+ end: e.end,
631
+ score: e.score
632
+ }));
633
+ }
634
+ async sentiment(text) {
635
+ const isBatch = Array.isArray(text);
636
+ const texts = isBatch ? text : [text];
637
+ const { data } = await this.synapCores._getHttpClient().post("/ai/sentiment", {
638
+ texts
639
+ });
640
+ const results = data.sentiments.map((s) => ({
641
+ label: s.label,
642
+ score: s.score,
643
+ confidence: s.confidence
644
+ }));
645
+ return isBatch ? results : results[0];
646
+ }
647
+ async classify(options) {
648
+ const isBatch = Array.isArray(options.text);
649
+ const texts = isBatch ? options.text : [options.text];
650
+ const { data } = await this.synapCores._getHttpClient().post("/ai/classify", {
651
+ texts,
652
+ categories: options.categories,
653
+ multi_label: options.multiLabel || false
654
+ });
655
+ return isBatch ? data.classifications : data.classifications[0];
656
+ }
657
+ };
658
+
659
+ // src/recipes.ts
660
+ var RecipeClient = class {
661
+ constructor(synapCores) {
662
+ this.synapCores = synapCores;
663
+ }
664
+ /**
665
+ * Create a new recipe
666
+ */
667
+ async create(options) {
668
+ const { data } = await this.synapCores._getHttpClient().post("/recipes", {
669
+ name: options.name,
670
+ description: options.description,
671
+ category: options.category,
672
+ content: options.content,
673
+ tags: options.tags || [],
674
+ parameters: options.parameters || []
675
+ });
676
+ return {
677
+ id: data.id,
678
+ name: data.name,
679
+ description: data.description,
680
+ category: data.category,
681
+ content: data.content,
682
+ tags: data.tags || [],
683
+ parameters: data.parameters || [],
684
+ created_at: new Date(data.created_at),
685
+ updated_at: new Date(data.updated_at),
686
+ author: data.author,
687
+ execution_count: data.execution_count,
688
+ version: data.version
689
+ };
690
+ }
691
+ /**
692
+ * List recipes with optional filters
693
+ */
694
+ async list(options = {}) {
695
+ const params = new URLSearchParams();
696
+ if (options.category) params.append("category", options.category);
697
+ if (options.search) params.append("search", options.search);
698
+ if (options.page) params.append("page", options.page.toString());
699
+ if (options.page_size) params.append("page_size", options.page_size.toString());
700
+ if (options.tags && options.tags.length > 0) {
701
+ params.append("tags", options.tags.join(","));
702
+ }
703
+ const { data } = await this.synapCores._getHttpClient().get(
704
+ `/recipes?${params.toString()}`
705
+ );
706
+ return (data.recipes || data).map((recipe) => ({
707
+ id: recipe.id,
708
+ name: recipe.name,
709
+ description: recipe.description,
710
+ category: recipe.category,
711
+ tags: recipe.tags || [],
712
+ created_at: new Date(recipe.created_at),
713
+ updated_at: new Date(recipe.updated_at),
714
+ author: recipe.author,
715
+ execution_count: recipe.execution_count
716
+ }));
717
+ }
718
+ /**
719
+ * Get a specific recipe by ID
720
+ */
721
+ async get(id) {
722
+ const { data } = await this.synapCores._getHttpClient().get(`/recipes/${id}`);
723
+ return {
724
+ id: data.id,
725
+ name: data.name,
726
+ description: data.description,
727
+ category: data.category,
728
+ content: data.content,
729
+ tags: data.tags || [],
730
+ parameters: data.parameters || [],
731
+ created_at: new Date(data.created_at),
732
+ updated_at: new Date(data.updated_at),
733
+ author: data.author,
734
+ execution_count: data.execution_count,
735
+ version: data.version
736
+ };
737
+ }
738
+ /**
739
+ * Update an existing recipe
740
+ */
741
+ async update(id, updates) {
742
+ const { data } = await this.synapCores._getHttpClient().put(`/recipes/${id}`, updates);
743
+ return {
744
+ id: data.id,
745
+ name: data.name,
746
+ description: data.description,
747
+ category: data.category,
748
+ content: data.content,
749
+ tags: data.tags || [],
750
+ parameters: data.parameters || [],
751
+ created_at: new Date(data.created_at),
752
+ updated_at: new Date(data.updated_at),
753
+ author: data.author,
754
+ execution_count: data.execution_count,
755
+ version: data.version
756
+ };
757
+ }
758
+ /**
759
+ * Delete a recipe
760
+ */
761
+ async delete(id) {
762
+ await this.synapCores._getHttpClient().delete(`/recipes/${id}`);
763
+ }
764
+ /**
765
+ * Execute a recipe
766
+ */
767
+ async execute(options) {
768
+ const { data } = await this.synapCores._getHttpClient().post(
769
+ `/recipes/${options.recipe}/execute`,
770
+ {
771
+ parameters: options.parameters || {},
772
+ dry_run: options.dry_run || false
773
+ }
774
+ );
775
+ return {
776
+ id: data.id || data.execution_id,
777
+ success: data.success,
778
+ results: data.results,
779
+ error: data.error,
780
+ execution_time_ms: data.execution_time_ms || data.took_ms,
781
+ statements_executed: data.statements_executed || 0
782
+ };
783
+ }
784
+ /**
785
+ * Generate a recipe using AI
786
+ */
787
+ async generate(options) {
788
+ const { data } = await this.synapCores._getHttpClient().post("/ai/generate-recipe", {
789
+ intent: options.intent,
790
+ category: options.category,
791
+ context: options.context
792
+ });
793
+ return {
794
+ name: data.name,
795
+ description: data.description,
796
+ content: data.content
797
+ };
798
+ }
799
+ /**
800
+ * List available recipe categories
801
+ */
802
+ async listCategories() {
803
+ const { data } = await this.synapCores._getHttpClient().get("/recipes/categories");
804
+ return data.categories || [];
805
+ }
806
+ };
807
+
808
+ // src/schema.ts
809
+ var SchemaClient = class {
810
+ constructor(synapCores) {
811
+ this.synapCores = synapCores;
812
+ }
813
+ /**
814
+ * List all tables in the database
815
+ */
816
+ async listTables(options = {}) {
817
+ const params = new URLSearchParams();
818
+ if (options.includeSystem) {
819
+ params.append("include_system", "true");
820
+ }
821
+ const { data } = await this.synapCores._getHttpClient().get(
822
+ `/schema/tables?${params.toString()}`
823
+ );
824
+ return (data.tables || data).map((table) => ({
825
+ name: table.name,
826
+ type: table.type || "table",
827
+ column_count: table.column_count || 0,
828
+ row_count: table.row_count,
829
+ size_bytes: table.size_bytes,
830
+ created_at: table.created_at ? new Date(table.created_at) : void 0,
831
+ updated_at: table.updated_at ? new Date(table.updated_at) : void 0,
832
+ comment: table.comment
833
+ }));
834
+ }
835
+ /**
836
+ * Get complete schema for a specific table
837
+ */
838
+ async getTable(tableName) {
839
+ const { data } = await this.synapCores._getHttpClient().get(
840
+ `/schema/tables/${tableName}`
841
+ );
842
+ return {
843
+ table: {
844
+ name: data.name,
845
+ type: data.type || "table",
846
+ column_count: data.columns?.length || 0,
847
+ row_count: data.row_count,
848
+ size_bytes: data.size_bytes,
849
+ created_at: data.created_at ? new Date(data.created_at) : void 0,
850
+ updated_at: data.updated_at ? new Date(data.updated_at) : void 0,
851
+ comment: data.comment
852
+ },
853
+ columns: (data.columns || []).map((col) => ({
854
+ name: col.name,
855
+ data_type: col.data_type || col.type,
856
+ nullable: col.nullable !== false,
857
+ default_value: col.default_value || col.default,
858
+ is_primary_key: col.is_primary_key || col.primary_key,
859
+ is_unique: col.is_unique || col.unique,
860
+ is_indexed: col.is_indexed || col.indexed,
861
+ foreign_key: col.foreign_key,
862
+ comment: col.comment,
863
+ ordinal_position: col.ordinal_position || col.position
864
+ })),
865
+ indexes: (data.indexes || []).map((idx) => ({
866
+ name: idx.name,
867
+ table: idx.table || tableName,
868
+ type: idx.type || "btree",
869
+ columns: idx.columns || [],
870
+ is_unique: idx.is_unique || idx.unique || false,
871
+ is_primary: idx.is_primary || idx.primary || false,
872
+ size_bytes: idx.size_bytes,
873
+ created_at: idx.created_at ? new Date(idx.created_at) : void 0
874
+ })),
875
+ constraints: data.constraints || [],
876
+ relationships: (data.relationships || []).map((rel) => ({
877
+ type: rel.type,
878
+ from_table: rel.from_table || rel.source_table,
879
+ from_column: rel.from_column || rel.source_column,
880
+ to_table: rel.to_table || rel.target_table,
881
+ to_column: rel.to_column || rel.target_column,
882
+ name: rel.name
883
+ }))
884
+ };
885
+ }
886
+ /**
887
+ * Get columns for a specific table
888
+ */
889
+ async getColumns(tableName) {
890
+ const schema = await this.getTable(tableName);
891
+ return schema.columns;
892
+ }
893
+ /**
894
+ * Get indexes for a specific table
895
+ */
896
+ async getIndexes(tableName) {
897
+ const schema = await this.getTable(tableName);
898
+ return schema.indexes;
899
+ }
900
+ /**
901
+ * Get all relationships in the database
902
+ */
903
+ async getRelationships() {
904
+ const { data } = await this.synapCores._getHttpClient().get("/schema/relationships");
905
+ return (data.relationships || data).map((rel) => ({
906
+ type: rel.type,
907
+ from_table: rel.from_table || rel.source_table,
908
+ from_column: rel.from_column || rel.source_column,
909
+ to_table: rel.to_table || rel.target_table,
910
+ to_column: rel.to_column || rel.target_column,
911
+ name: rel.name
912
+ }));
913
+ }
914
+ /**
915
+ * Get schema statistics
916
+ */
917
+ async getStatistics() {
918
+ const { data } = await this.synapCores._getHttpClient().get("/schema/statistics");
919
+ return {
920
+ table_count: data.table_count || 0,
921
+ view_count: data.view_count || 0,
922
+ index_count: data.index_count || 0,
923
+ relationship_count: data.relationship_count || 0,
924
+ total_size_bytes: data.total_size_bytes || 0,
925
+ total_rows: data.total_rows || 0,
926
+ version: data.version,
927
+ analyzed_at: data.analyzed_at ? new Date(data.analyzed_at) : void 0
928
+ };
929
+ }
930
+ /**
931
+ * Validate a schema definition
932
+ */
933
+ async validateSchema(schema) {
934
+ const { data } = await this.synapCores._getHttpClient().post("/schema/validate", {
935
+ schema
936
+ });
937
+ return {
938
+ is_valid: data.is_valid || data.valid,
939
+ errors: data.errors || [],
940
+ warnings: data.warnings || []
941
+ };
942
+ }
943
+ /**
944
+ * Compare two schemas
945
+ */
946
+ async compareSchemas(schema1, schema2) {
947
+ const { data } = await this.synapCores._getHttpClient().post("/schema/compare", {
948
+ schema1,
949
+ schema2
950
+ });
951
+ return {
952
+ differences: data.differences || [],
953
+ added: data.added || [],
954
+ removed: data.removed || [],
955
+ modified: data.modified || []
956
+ };
957
+ }
958
+ /**
959
+ * Generate SQL DDL for a table
960
+ */
961
+ async generateDDL(tableName) {
962
+ const { data } = await this.synapCores._getHttpClient().get(
963
+ `/schema/tables/${tableName}/ddl`
964
+ );
965
+ return data.ddl || data.sql;
966
+ }
967
+ /**
968
+ * Analyze table and update statistics
969
+ */
970
+ async analyzeTable(tableName) {
971
+ await this.synapCores._getHttpClient().post(`/schema/tables/${tableName}/analyze`);
972
+ }
973
+ };
974
+
975
+ // src/import.ts
976
+ var ImportExportClient = class {
977
+ constructor(synapCores) {
978
+ this.synapCores = synapCores;
979
+ }
980
+ /**
981
+ * Import data into a table
982
+ */
983
+ async import(options) {
984
+ const formData = new FormData();
985
+ formData.append("table", options.table);
986
+ formData.append("format", options.format);
987
+ if (options.mode) formData.append("mode", options.mode);
988
+ if (options.column_mapping) {
989
+ formData.append("column_mapping", JSON.stringify(options.column_mapping));
990
+ }
991
+ if (options.skip_header !== void 0) {
992
+ formData.append("skip_header", options.skip_header.toString());
993
+ }
994
+ if (options.delimiter) formData.append("delimiter", options.delimiter);
995
+ if (options.batch_size) formData.append("batch_size", options.batch_size.toString());
996
+ if (options.continue_on_error !== void 0) {
997
+ formData.append("continue_on_error", options.continue_on_error.toString());
998
+ }
999
+ if (options.primary_keys) {
1000
+ formData.append("primary_keys", JSON.stringify(options.primary_keys));
1001
+ }
1002
+ if (Buffer.isBuffer(options.data)) {
1003
+ formData.append("file", new Blob([options.data]), "data");
1004
+ } else {
1005
+ formData.append("data", options.data);
1006
+ }
1007
+ const { data } = await this.synapCores._getHttpClient().post("/import", formData, {
1008
+ headers: {
1009
+ "Content-Type": "multipart/form-data"
1010
+ }
1011
+ });
1012
+ return {
1013
+ id: data.id || data.job_id,
1014
+ success: data.success,
1015
+ rows_processed: data.rows_processed || 0,
1016
+ rows_imported: data.rows_imported || 0,
1017
+ rows_failed: data.rows_failed || 0,
1018
+ duration_ms: data.duration_ms || data.took_ms || 0,
1019
+ errors: data.errors || [],
1020
+ warnings: data.warnings || []
1021
+ };
1022
+ }
1023
+ /**
1024
+ * Export data from a table or query
1025
+ */
1026
+ async export(options) {
1027
+ const { data } = await this.synapCores._getHttpClient().post("/export", {
1028
+ source: options.source,
1029
+ format: options.format,
1030
+ destination: options.destination || "response",
1031
+ columns: options.columns,
1032
+ filter: options.filter,
1033
+ order_by: options.order_by,
1034
+ limit: options.limit,
1035
+ include_header: options.include_header,
1036
+ delimiter: options.delimiter,
1037
+ compress: options.compress
1038
+ });
1039
+ return {
1040
+ id: data.id || data.job_id,
1041
+ success: data.success,
1042
+ rows_exported: data.rows_exported || 0,
1043
+ duration_ms: data.duration_ms || data.took_ms || 0,
1044
+ file_path: data.file_path,
1045
+ data: data.data,
1046
+ size_bytes: data.size_bytes,
1047
+ download_url: data.download_url,
1048
+ expires_at: data.expires_at ? new Date(data.expires_at) : void 0
1049
+ };
1050
+ }
1051
+ /**
1052
+ * Get import job status
1053
+ */
1054
+ async getImportStatus(jobId) {
1055
+ const { data } = await this.synapCores._getHttpClient().get(`/import/${jobId}/status`);
1056
+ return {
1057
+ id: data.id || jobId,
1058
+ status: data.status,
1059
+ progress: data.progress || 0,
1060
+ phase: data.phase,
1061
+ rows_processed: data.rows_processed,
1062
+ eta_ms: data.eta_ms || data.estimated_time_remaining_ms,
1063
+ error: data.error,
1064
+ started_at: data.started_at ? new Date(data.started_at) : void 0,
1065
+ completed_at: data.completed_at ? new Date(data.completed_at) : void 0
1066
+ };
1067
+ }
1068
+ /**
1069
+ * Get export job status
1070
+ */
1071
+ async getExportStatus(jobId) {
1072
+ const { data } = await this.synapCores._getHttpClient().get(`/export/${jobId}/status`);
1073
+ return {
1074
+ id: data.id || jobId,
1075
+ status: data.status,
1076
+ progress: data.progress || 0,
1077
+ phase: data.phase,
1078
+ rows_exported: data.rows_exported,
1079
+ eta_ms: data.eta_ms || data.estimated_time_remaining_ms,
1080
+ error: data.error,
1081
+ started_at: data.started_at ? new Date(data.started_at) : void 0,
1082
+ completed_at: data.completed_at ? new Date(data.completed_at) : void 0
1083
+ };
1084
+ }
1085
+ /**
1086
+ * Cancel an import job
1087
+ */
1088
+ async cancelImport(jobId) {
1089
+ await this.synapCores._getHttpClient().post(`/import/${jobId}/cancel`);
1090
+ }
1091
+ /**
1092
+ * Cancel an export job
1093
+ */
1094
+ async cancelExport(jobId) {
1095
+ await this.synapCores._getHttpClient().post(`/export/${jobId}/cancel`);
1096
+ }
1097
+ /**
1098
+ * Import data from multiple sources in bulk
1099
+ */
1100
+ async bulkImport(options) {
1101
+ const { data } = await this.synapCores._getHttpClient().post("/import/bulk", {
1102
+ jobs: options.jobs,
1103
+ parallel: options.parallel || false,
1104
+ stop_on_error: options.stop_on_error || false
1105
+ });
1106
+ return {
1107
+ id: data.id || data.bulk_id,
1108
+ success: data.success,
1109
+ results: data.results || [],
1110
+ total_rows_imported: data.total_rows_imported || 0,
1111
+ total_duration_ms: data.total_duration_ms || data.took_ms || 0
1112
+ };
1113
+ }
1114
+ /**
1115
+ * Validate data before import
1116
+ */
1117
+ async validateData(options) {
1118
+ const { data } = await this.synapCores._getHttpClient().post("/import/validate", {
1119
+ table: options.table,
1120
+ data: options.data,
1121
+ mode: options.mode || "strict",
1122
+ check_foreign_keys: options.check_foreign_keys,
1123
+ check_unique: options.check_unique
1124
+ });
1125
+ return {
1126
+ is_valid: data.is_valid || data.valid,
1127
+ errors: data.errors || [],
1128
+ warnings: data.warnings || [],
1129
+ rows_validated: data.rows_validated || options.data.length
1130
+ };
1131
+ }
1132
+ /**
1133
+ * Get import template for a table
1134
+ */
1135
+ async getImportTemplate(tableName, format = "csv") {
1136
+ const { data } = await this.synapCores._getHttpClient().get(
1137
+ `/import/template/${tableName}?format=${format}`
1138
+ );
1139
+ return data.template || data.content || data;
1140
+ }
1141
+ /**
1142
+ * List import/export jobs
1143
+ */
1144
+ async listJobs(options = {}) {
1145
+ const params = new URLSearchParams();
1146
+ if (options.type) params.append("type", options.type);
1147
+ if (options.status) params.append("status", options.status);
1148
+ if (options.limit) params.append("limit", options.limit.toString());
1149
+ const { data } = await this.synapCores._getHttpClient().get(
1150
+ `/import/jobs?${params.toString()}`
1151
+ );
1152
+ return (data.jobs || data).map((job) => ({
1153
+ id: job.id,
1154
+ status: job.status,
1155
+ progress: job.progress || 0,
1156
+ phase: job.phase,
1157
+ rows_processed: job.rows_processed,
1158
+ rows_exported: job.rows_exported,
1159
+ eta_ms: job.eta_ms,
1160
+ error: job.error,
1161
+ started_at: job.started_at ? new Date(job.started_at) : void 0,
1162
+ completed_at: job.completed_at ? new Date(job.completed_at) : void 0
1163
+ }));
1164
+ }
1165
+ /**
1166
+ * Download exported data
1167
+ */
1168
+ async downloadExport(jobId) {
1169
+ const { data } = await this.synapCores._getHttpClient().get(`/export/${jobId}/download`, {
1170
+ responseType: "arraybuffer"
1171
+ });
1172
+ return Buffer.from(data);
1173
+ }
1174
+ /**
1175
+ * Stream import data (for large files)
1176
+ */
1177
+ async streamImport(options, onProgress) {
1178
+ const result = await this.import(options);
1179
+ const jobId = result.id;
1180
+ if (onProgress) {
1181
+ const pollInterval = setInterval(async () => {
1182
+ try {
1183
+ const status = await this.getImportStatus(jobId);
1184
+ onProgress(status);
1185
+ if (status.status === "completed" || status.status === "failed" || status.status === "cancelled") {
1186
+ clearInterval(pollInterval);
1187
+ }
1188
+ } catch (error) {
1189
+ clearInterval(pollInterval);
1190
+ }
1191
+ }, 1e3);
1192
+ }
1193
+ return result;
1194
+ }
1195
+ /**
1196
+ * Stream export data (for large datasets)
1197
+ */
1198
+ async streamExport(options, onProgress) {
1199
+ const result = await this.export(options);
1200
+ const jobId = result.id;
1201
+ if (onProgress) {
1202
+ const pollInterval = setInterval(async () => {
1203
+ try {
1204
+ const status = await this.getExportStatus(jobId);
1205
+ onProgress(status);
1206
+ if (status.status === "completed" || status.status === "failed" || status.status === "cancelled") {
1207
+ clearInterval(pollInterval);
1208
+ }
1209
+ } catch (error) {
1210
+ clearInterval(pollInterval);
1211
+ }
1212
+ }, 1e3);
1213
+ }
1214
+ return result;
1215
+ }
1216
+ };
1217
+
1218
+ // src/integrations.ts
1219
+ var IntegrationClient = class {
1220
+ constructor(synapCores) {
1221
+ this.synapCores = synapCores;
1222
+ }
1223
+ /**
1224
+ * Create a new integration
1225
+ */
1226
+ async create(options) {
1227
+ const { data } = await this.synapCores._getHttpClient().post("/integrations", {
1228
+ name: options.name,
1229
+ type: options.type,
1230
+ config: options.config,
1231
+ description: options.description,
1232
+ tags: options.tags || [],
1233
+ activate: options.activate || false
1234
+ });
1235
+ return this.mapIntegration(data);
1236
+ }
1237
+ /**
1238
+ * List integrations with optional filters
1239
+ */
1240
+ async list(options = {}) {
1241
+ const params = new URLSearchParams();
1242
+ if (options.type) params.append("type", options.type);
1243
+ if (options.status) params.append("status", options.status);
1244
+ if (options.search) params.append("search", options.search);
1245
+ if (options.page) params.append("page", options.page.toString());
1246
+ if (options.page_size) params.append("page_size", options.page_size.toString());
1247
+ if (options.tags && options.tags.length > 0) {
1248
+ params.append("tags", options.tags.join(","));
1249
+ }
1250
+ const { data } = await this.synapCores._getHttpClient().get(
1251
+ `/integrations?${params.toString()}`
1252
+ );
1253
+ return (data.integrations || data).map(
1254
+ (integration) => this.mapIntegration(integration)
1255
+ );
1256
+ }
1257
+ /**
1258
+ * Get a specific integration by ID
1259
+ */
1260
+ async get(id) {
1261
+ const { data } = await this.synapCores._getHttpClient().get(`/integrations/${id}`);
1262
+ return this.mapIntegration(data);
1263
+ }
1264
+ /**
1265
+ * Update an existing integration
1266
+ */
1267
+ async update(id, updates) {
1268
+ const { data } = await this.synapCores._getHttpClient().put(
1269
+ `/integrations/${id}`,
1270
+ updates
1271
+ );
1272
+ return this.mapIntegration(data);
1273
+ }
1274
+ /**
1275
+ * Delete an integration
1276
+ */
1277
+ async delete(id) {
1278
+ await this.synapCores._getHttpClient().delete(`/integrations/${id}`);
1279
+ }
1280
+ /**
1281
+ * Activate an integration
1282
+ */
1283
+ async activate(id) {
1284
+ const { data } = await this.synapCores._getHttpClient().post(
1285
+ `/integrations/${id}/activate`
1286
+ );
1287
+ return this.mapIntegration(data);
1288
+ }
1289
+ /**
1290
+ * Deactivate an integration
1291
+ */
1292
+ async deactivate(id) {
1293
+ const { data } = await this.synapCores._getHttpClient().post(
1294
+ `/integrations/${id}/deactivate`
1295
+ );
1296
+ return this.mapIntegration(data);
1297
+ }
1298
+ /**
1299
+ * Execute an integration
1300
+ */
1301
+ async execute(options) {
1302
+ const { data } = await this.synapCores._getHttpClient().post(
1303
+ `/integrations/${options.integration}/execute`,
1304
+ {
1305
+ payload: options.payload,
1306
+ config_override: options.config_override,
1307
+ sync: options.sync !== false
1308
+ }
1309
+ );
1310
+ return {
1311
+ id: data.id || data.execution_id,
1312
+ success: data.success,
1313
+ response: data.response,
1314
+ status_code: data.status_code,
1315
+ error: data.error,
1316
+ execution_time_ms: data.execution_time_ms || data.took_ms || 0,
1317
+ retry_count: data.retry_count || 0,
1318
+ executed_at: data.executed_at ? new Date(data.executed_at) : /* @__PURE__ */ new Date()
1319
+ };
1320
+ }
1321
+ /**
1322
+ * Test an integration without executing
1323
+ */
1324
+ async test(options) {
1325
+ const { data } = await this.synapCores._getHttpClient().post(
1326
+ `/integrations/${options.integration}/test`,
1327
+ {
1328
+ payload: options.payload,
1329
+ validate_only: options.validate_only || false
1330
+ }
1331
+ );
1332
+ return {
1333
+ success: data.success,
1334
+ validation_errors: data.validation_errors || [],
1335
+ response: data.response,
1336
+ error: data.error,
1337
+ latency_ms: data.latency_ms
1338
+ };
1339
+ }
1340
+ /**
1341
+ * Get integration execution history
1342
+ */
1343
+ async getExecutionHistory(integrationId, options = {}) {
1344
+ const params = new URLSearchParams();
1345
+ if (options.limit) params.append("limit", options.limit.toString());
1346
+ if (options.offset) params.append("offset", options.offset.toString());
1347
+ const { data } = await this.synapCores._getHttpClient().get(
1348
+ `/integrations/${integrationId}/executions?${params.toString()}`
1349
+ );
1350
+ return (data.executions || data).map((exec) => ({
1351
+ id: exec.id || exec.execution_id,
1352
+ success: exec.success,
1353
+ response: exec.response,
1354
+ status_code: exec.status_code,
1355
+ error: exec.error,
1356
+ execution_time_ms: exec.execution_time_ms || exec.took_ms || 0,
1357
+ retry_count: exec.retry_count || 0,
1358
+ executed_at: exec.executed_at ? new Date(exec.executed_at) : /* @__PURE__ */ new Date()
1359
+ }));
1360
+ }
1361
+ /**
1362
+ * Get integration statistics
1363
+ */
1364
+ async getStats(integrationId) {
1365
+ const { data } = await this.synapCores._getHttpClient().get(
1366
+ `/integrations/${integrationId}/stats`
1367
+ );
1368
+ return {
1369
+ integration_id: integrationId,
1370
+ total_executions: data.total_executions || 0,
1371
+ successful_executions: data.successful_executions || 0,
1372
+ failed_executions: data.failed_executions || 0,
1373
+ avg_execution_time_ms: data.avg_execution_time_ms || 0,
1374
+ executions_24h: data.executions_24h || 0,
1375
+ uptime_percentage: data.uptime_percentage || 0,
1376
+ last_success_at: data.last_success_at ? new Date(data.last_success_at) : void 0,
1377
+ last_error_at: data.last_error_at ? new Date(data.last_error_at) : void 0
1378
+ };
1379
+ }
1380
+ /**
1381
+ * Create a webhook for an integration
1382
+ */
1383
+ async createWebhook(options) {
1384
+ const { data } = await this.synapCores._getHttpClient().post("/integrations/webhooks", {
1385
+ integration_id: options.integration_id,
1386
+ event: options.event,
1387
+ url: options.url,
1388
+ secret: options.secret,
1389
+ activate: options.activate !== false
1390
+ });
1391
+ return {
1392
+ id: data.id,
1393
+ integration_id: data.integration_id,
1394
+ event: data.event,
1395
+ url: data.url,
1396
+ active: data.active,
1397
+ secret: data.secret,
1398
+ created_at: new Date(data.created_at)
1399
+ };
1400
+ }
1401
+ /**
1402
+ * List webhooks for an integration
1403
+ */
1404
+ async listWebhooks(integrationId) {
1405
+ const { data } = await this.synapCores._getHttpClient().get(
1406
+ `/integrations/${integrationId}/webhooks`
1407
+ );
1408
+ return (data.webhooks || data).map((webhook) => ({
1409
+ id: webhook.id,
1410
+ integration_id: webhook.integration_id,
1411
+ event: webhook.event,
1412
+ url: webhook.url,
1413
+ active: webhook.active,
1414
+ secret: webhook.secret,
1415
+ created_at: new Date(webhook.created_at)
1416
+ }));
1417
+ }
1418
+ /**
1419
+ * Delete a webhook
1420
+ */
1421
+ async deleteWebhook(webhookId) {
1422
+ await this.synapCores._getHttpClient().delete(`/integrations/webhooks/${webhookId}`);
1423
+ }
1424
+ /**
1425
+ * Get integration events
1426
+ */
1427
+ async getEvents(integrationId, options = {}) {
1428
+ const params = new URLSearchParams();
1429
+ if (options.limit) params.append("limit", options.limit.toString());
1430
+ if (options.status) params.append("status", options.status);
1431
+ const { data } = await this.synapCores._getHttpClient().get(
1432
+ `/integrations/${integrationId}/events?${params.toString()}`
1433
+ );
1434
+ return (data.events || data).map((event) => ({
1435
+ id: event.id,
1436
+ integration_id: event.integration_id,
1437
+ event: event.event,
1438
+ data: event.data,
1439
+ timestamp: new Date(event.timestamp),
1440
+ status: event.status,
1441
+ error: event.error
1442
+ }));
1443
+ }
1444
+ /**
1445
+ * Get integration logs
1446
+ */
1447
+ async getLogs(integrationId, options = {}) {
1448
+ const params = new URLSearchParams();
1449
+ if (options.limit) params.append("limit", options.limit.toString());
1450
+ if (options.level) params.append("level", options.level);
1451
+ const { data } = await this.synapCores._getHttpClient().get(
1452
+ `/integrations/${integrationId}/logs?${params.toString()}`
1453
+ );
1454
+ return (data.logs || data).map((log) => ({
1455
+ id: log.id,
1456
+ integration_id: log.integration_id,
1457
+ level: log.level,
1458
+ message: log.message,
1459
+ data: log.data,
1460
+ timestamp: new Date(log.timestamp)
1461
+ }));
1462
+ }
1463
+ /**
1464
+ * Retry a failed execution
1465
+ */
1466
+ async retryExecution(executionId) {
1467
+ const { data } = await this.synapCores._getHttpClient().post(
1468
+ `/integrations/executions/${executionId}/retry`
1469
+ );
1470
+ return {
1471
+ id: data.id || data.execution_id,
1472
+ success: data.success,
1473
+ response: data.response,
1474
+ status_code: data.status_code,
1475
+ error: data.error,
1476
+ execution_time_ms: data.execution_time_ms || data.took_ms || 0,
1477
+ retry_count: data.retry_count || 0,
1478
+ executed_at: data.executed_at ? new Date(data.executed_at) : /* @__PURE__ */ new Date()
1479
+ };
1480
+ }
1481
+ /**
1482
+ * Map raw integration data to Integration type
1483
+ */
1484
+ mapIntegration(data) {
1485
+ return {
1486
+ id: data.id,
1487
+ name: data.name,
1488
+ type: data.type,
1489
+ status: data.status,
1490
+ config: data.config,
1491
+ description: data.description,
1492
+ tags: data.tags || [],
1493
+ created_at: new Date(data.created_at),
1494
+ updated_at: new Date(data.updated_at),
1495
+ last_success_at: data.last_success_at ? new Date(data.last_success_at) : void 0,
1496
+ last_error: data.last_error,
1497
+ execution_count: data.execution_count
1498
+ };
1499
+ }
1500
+ };
1501
+
1502
+ // src/backup.ts
1503
+ var BackupClient = class {
1504
+ constructor(synapCores) {
1505
+ this.synapCores = synapCores;
1506
+ }
1507
+ /**
1508
+ * Create a new backup
1509
+ */
1510
+ async create(options = {}) {
1511
+ const { data } = await this.synapCores._getHttpClient().post("/backups", {
1512
+ name: options.name,
1513
+ description: options.description,
1514
+ type: options.type || "full",
1515
+ tables: options.tables,
1516
+ include_indexes: options.include_indexes !== false,
1517
+ include_procedures: options.include_procedures !== false,
1518
+ compression: options.compression || 6,
1519
+ encrypt: options.encrypt || false,
1520
+ encryption_key: options.encryption_key,
1521
+ storage: options.storage || "local",
1522
+ storage_config: options.storage_config,
1523
+ tags: options.tags || []
1524
+ });
1525
+ return this.mapBackup(data);
1526
+ }
1527
+ /**
1528
+ * List backups with optional filters
1529
+ */
1530
+ async list(options = {}) {
1531
+ const params = new URLSearchParams();
1532
+ if (options.type) params.append("type", options.type);
1533
+ if (options.status) params.append("status", options.status);
1534
+ if (options.sort) params.append("sort", options.sort);
1535
+ if (options.order) params.append("order", options.order);
1536
+ if (options.page) params.append("page", options.page.toString());
1537
+ if (options.page_size) params.append("page_size", options.page_size.toString());
1538
+ if (options.tags && options.tags.length > 0) {
1539
+ params.append("tags", options.tags.join(","));
1540
+ }
1541
+ const { data } = await this.synapCores._getHttpClient().get(
1542
+ `/backups?${params.toString()}`
1543
+ );
1544
+ return (data.backups || data).map((backup) => this.mapBackup(backup));
1545
+ }
1546
+ /**
1547
+ * Get a specific backup by ID
1548
+ */
1549
+ async get(id) {
1550
+ const { data } = await this.synapCores._getHttpClient().get(`/backups/${id}`);
1551
+ return this.mapBackup(data);
1552
+ }
1553
+ /**
1554
+ * Delete a backup
1555
+ */
1556
+ async delete(id) {
1557
+ await this.synapCores._getHttpClient().delete(`/backups/${id}`);
1558
+ }
1559
+ /**
1560
+ * Restore from a backup
1561
+ */
1562
+ async restore(options) {
1563
+ const { data } = await this.synapCores._getHttpClient().post("/backups/restore", {
1564
+ backup_id: options.backup_id,
1565
+ mode: options.mode || "full",
1566
+ tables: options.tables,
1567
+ target_database: options.target_database,
1568
+ overwrite: options.overwrite || false,
1569
+ skip_indexes: options.skip_indexes || false,
1570
+ skip_procedures: options.skip_procedures || false,
1571
+ decryption_key: options.decryption_key,
1572
+ point_in_time: options.point_in_time?.toISOString(),
1573
+ dry_run: options.dry_run || false
1574
+ });
1575
+ return {
1576
+ id: data.id || data.restore_id,
1577
+ success: data.success,
1578
+ tables_restored: data.tables_restored || [],
1579
+ rows_restored: data.rows_restored || 0,
1580
+ duration_ms: data.duration_ms || data.took_ms || 0,
1581
+ error: data.error,
1582
+ warnings: data.warnings || []
1583
+ };
1584
+ }
1585
+ /**
1586
+ * Get backup status
1587
+ */
1588
+ async getBackupStatus(backupId) {
1589
+ const { data } = await this.synapCores._getHttpClient().get(
1590
+ `/backups/${backupId}/status`
1591
+ );
1592
+ return {
1593
+ id: data.id || backupId,
1594
+ status: data.status,
1595
+ progress: data.progress || 0,
1596
+ phase: data.phase,
1597
+ tables_processed: data.tables_processed,
1598
+ total_tables: data.total_tables,
1599
+ bytes_processed: data.bytes_processed,
1600
+ eta_ms: data.eta_ms || data.estimated_time_remaining_ms,
1601
+ error: data.error,
1602
+ started_at: data.started_at ? new Date(data.started_at) : void 0,
1603
+ completed_at: data.completed_at ? new Date(data.completed_at) : void 0
1604
+ };
1605
+ }
1606
+ /**
1607
+ * Get restore status
1608
+ */
1609
+ async getRestoreStatus(restoreId) {
1610
+ const { data } = await this.synapCores._getHttpClient().get(
1611
+ `/backups/restore/${restoreId}/status`
1612
+ );
1613
+ return {
1614
+ id: data.id || restoreId,
1615
+ status: data.status,
1616
+ progress: data.progress || 0,
1617
+ phase: data.phase,
1618
+ tables_processed: data.tables_processed,
1619
+ total_tables: data.total_tables,
1620
+ rows_processed: data.rows_processed,
1621
+ eta_ms: data.eta_ms || data.estimated_time_remaining_ms,
1622
+ error: data.error,
1623
+ started_at: data.started_at ? new Date(data.started_at) : void 0,
1624
+ completed_at: data.completed_at ? new Date(data.completed_at) : void 0
1625
+ };
1626
+ }
1627
+ /**
1628
+ * Cancel a backup in progress
1629
+ */
1630
+ async cancelBackup(backupId) {
1631
+ await this.synapCores._getHttpClient().post(`/backups/${backupId}/cancel`);
1632
+ }
1633
+ /**
1634
+ * Cancel a restore in progress
1635
+ */
1636
+ async cancelRestore(restoreId) {
1637
+ await this.synapCores._getHttpClient().post(`/backups/restore/${restoreId}/cancel`);
1638
+ }
1639
+ /**
1640
+ * Download a backup file
1641
+ */
1642
+ async download(backupId) {
1643
+ const { data } = await this.synapCores._getHttpClient().get(
1644
+ `/backups/${backupId}/download`,
1645
+ {
1646
+ responseType: "arraybuffer"
1647
+ }
1648
+ );
1649
+ return Buffer.from(data);
1650
+ }
1651
+ /**
1652
+ * Verify backup integrity
1653
+ */
1654
+ async verify(backupId) {
1655
+ const { data } = await this.synapCores._getHttpClient().post(
1656
+ `/backups/${backupId}/verify`
1657
+ );
1658
+ return {
1659
+ is_valid: data.is_valid || data.valid,
1660
+ integrity_ok: data.integrity_ok || data.integrity,
1661
+ checksum_match: data.checksum_match,
1662
+ tables_verified: data.tables_verified || 0,
1663
+ errors: data.errors || [],
1664
+ warnings: data.warnings || [],
1665
+ verified_at: data.verified_at ? new Date(data.verified_at) : /* @__PURE__ */ new Date()
1666
+ };
1667
+ }
1668
+ /**
1669
+ * Create a backup schedule
1670
+ */
1671
+ async createSchedule(options) {
1672
+ const { data } = await this.synapCores._getHttpClient().post("/backups/schedules", {
1673
+ name: options.name,
1674
+ cron: options.cron,
1675
+ backup_options: options.backup_options,
1676
+ activate: options.activate !== false,
1677
+ tags: options.tags || []
1678
+ });
1679
+ return {
1680
+ id: data.id,
1681
+ name: data.name,
1682
+ cron: data.cron,
1683
+ backup_options: data.backup_options,
1684
+ active: data.active,
1685
+ last_run_at: data.last_run_at ? new Date(data.last_run_at) : void 0,
1686
+ next_run_at: data.next_run_at ? new Date(data.next_run_at) : void 0,
1687
+ created_at: new Date(data.created_at),
1688
+ tags: data.tags || []
1689
+ };
1690
+ }
1691
+ /**
1692
+ * List backup schedules
1693
+ */
1694
+ async listSchedules() {
1695
+ const { data } = await this.synapCores._getHttpClient().get("/backups/schedules");
1696
+ return (data.schedules || data).map((schedule) => ({
1697
+ id: schedule.id,
1698
+ name: schedule.name,
1699
+ cron: schedule.cron,
1700
+ backup_options: schedule.backup_options,
1701
+ active: schedule.active,
1702
+ last_run_at: schedule.last_run_at ? new Date(schedule.last_run_at) : void 0,
1703
+ next_run_at: schedule.next_run_at ? new Date(schedule.next_run_at) : void 0,
1704
+ created_at: new Date(schedule.created_at),
1705
+ tags: schedule.tags || []
1706
+ }));
1707
+ }
1708
+ /**
1709
+ * Get a specific schedule
1710
+ */
1711
+ async getSchedule(scheduleId) {
1712
+ const { data } = await this.synapCores._getHttpClient().get(
1713
+ `/backups/schedules/${scheduleId}`
1714
+ );
1715
+ return {
1716
+ id: data.id,
1717
+ name: data.name,
1718
+ cron: data.cron,
1719
+ backup_options: data.backup_options,
1720
+ active: data.active,
1721
+ last_run_at: data.last_run_at ? new Date(data.last_run_at) : void 0,
1722
+ next_run_at: data.next_run_at ? new Date(data.next_run_at) : void 0,
1723
+ created_at: new Date(data.created_at),
1724
+ tags: data.tags || []
1725
+ };
1726
+ }
1727
+ /**
1728
+ * Update a backup schedule
1729
+ */
1730
+ async updateSchedule(scheduleId, updates) {
1731
+ const { data } = await this.synapCores._getHttpClient().put(
1732
+ `/backups/schedules/${scheduleId}`,
1733
+ updates
1734
+ );
1735
+ return {
1736
+ id: data.id,
1737
+ name: data.name,
1738
+ cron: data.cron,
1739
+ backup_options: data.backup_options,
1740
+ active: data.active,
1741
+ last_run_at: data.last_run_at ? new Date(data.last_run_at) : void 0,
1742
+ next_run_at: data.next_run_at ? new Date(data.next_run_at) : void 0,
1743
+ created_at: new Date(data.created_at),
1744
+ tags: data.tags || []
1745
+ };
1746
+ }
1747
+ /**
1748
+ * Delete a backup schedule
1749
+ */
1750
+ async deleteSchedule(scheduleId) {
1751
+ await this.synapCores._getHttpClient().delete(`/backups/schedules/${scheduleId}`);
1752
+ }
1753
+ /**
1754
+ * Activate a schedule
1755
+ */
1756
+ async activateSchedule(scheduleId) {
1757
+ const { data } = await this.synapCores._getHttpClient().post(
1758
+ `/backups/schedules/${scheduleId}/activate`
1759
+ );
1760
+ return {
1761
+ id: data.id,
1762
+ name: data.name,
1763
+ cron: data.cron,
1764
+ backup_options: data.backup_options,
1765
+ active: data.active,
1766
+ last_run_at: data.last_run_at ? new Date(data.last_run_at) : void 0,
1767
+ next_run_at: data.next_run_at ? new Date(data.next_run_at) : void 0,
1768
+ created_at: new Date(data.created_at),
1769
+ tags: data.tags || []
1770
+ };
1771
+ }
1772
+ /**
1773
+ * Deactivate a schedule
1774
+ */
1775
+ async deactivateSchedule(scheduleId) {
1776
+ const { data } = await this.synapCores._getHttpClient().post(
1777
+ `/backups/schedules/${scheduleId}/deactivate`
1778
+ );
1779
+ return {
1780
+ id: data.id,
1781
+ name: data.name,
1782
+ cron: data.cron,
1783
+ backup_options: data.backup_options,
1784
+ active: data.active,
1785
+ last_run_at: data.last_run_at ? new Date(data.last_run_at) : void 0,
1786
+ next_run_at: data.next_run_at ? new Date(data.next_run_at) : void 0,
1787
+ created_at: new Date(data.created_at),
1788
+ tags: data.tags || []
1789
+ };
1790
+ }
1791
+ /**
1792
+ * Get backup metrics
1793
+ */
1794
+ async getMetrics() {
1795
+ const { data } = await this.synapCores._getHttpClient().get("/backups/metrics");
1796
+ return {
1797
+ total_backups: data.total_backups || 0,
1798
+ total_size_bytes: data.total_size_bytes || 0,
1799
+ successful_backups: data.successful_backups || 0,
1800
+ failed_backups: data.failed_backups || 0,
1801
+ avg_backup_size_bytes: data.avg_backup_size_bytes || 0,
1802
+ avg_duration_ms: data.avg_duration_ms || 0,
1803
+ last_backup_at: data.last_backup_at ? new Date(data.last_backup_at) : void 0,
1804
+ next_scheduled_at: data.next_scheduled_at ? new Date(data.next_scheduled_at) : void 0
1805
+ };
1806
+ }
1807
+ /**
1808
+ * Map raw backup data to Backup type
1809
+ */
1810
+ mapBackup(data) {
1811
+ return {
1812
+ id: data.id,
1813
+ name: data.name,
1814
+ description: data.description,
1815
+ type: data.type,
1816
+ status: data.status,
1817
+ size_bytes: data.size_bytes,
1818
+ compressed_size_bytes: data.compressed_size_bytes,
1819
+ table_count: data.table_count,
1820
+ created_at: new Date(data.created_at),
1821
+ completed_at: data.completed_at ? new Date(data.completed_at) : void 0,
1822
+ duration_ms: data.duration_ms || data.took_ms,
1823
+ storage: data.storage,
1824
+ storage_path: data.storage_path,
1825
+ encrypted: data.encrypted || false,
1826
+ tags: data.tags || [],
1827
+ parent_backup_id: data.parent_backup_id,
1828
+ error: data.error
1829
+ };
1830
+ }
1831
+ };
1832
+
1833
+ // src/errors.ts
1834
+ var SynapCoresError = class _SynapCoresError extends Error {
1835
+ constructor(message, code, details) {
1836
+ super(message);
1837
+ this.name = "SynapCoresError";
1838
+ this.code = code;
1839
+ this.details = details;
1840
+ if (Error.captureStackTrace) {
1841
+ Error.captureStackTrace(this, _SynapCoresError);
1842
+ }
1843
+ }
1844
+ };
1845
+ var ConnectionError = class extends SynapCoresError {
1846
+ constructor(message, details) {
1847
+ super(message, "CONNECTION_ERROR", details);
1848
+ this.name = "ConnectionError";
1849
+ }
1850
+ };
1851
+ var AuthenticationError = class extends SynapCoresError {
1852
+ constructor(message, details) {
1853
+ super(message, "AUTH_ERROR", details);
1854
+ this.name = "AuthenticationError";
1855
+ }
1856
+ };
1857
+ var ValidationError = class extends SynapCoresError {
1858
+ constructor(message, details) {
1859
+ super(message, "VALIDATION_ERROR", details);
1860
+ this.name = "ValidationError";
1861
+ }
1862
+ };
1863
+ var NotFoundError = class extends SynapCoresError {
1864
+ constructor(message, details) {
1865
+ super(message, "NOT_FOUND", details);
1866
+ this.name = "NotFoundError";
1867
+ }
1868
+ };
1869
+ var ServerError = class extends SynapCoresError {
1870
+ constructor(message, details) {
1871
+ super(message, "SERVER_ERROR", details);
1872
+ this.name = "ServerError";
1873
+ }
1874
+ };
1875
+ var TimeoutError = class extends SynapCoresError {
1876
+ constructor(message, details) {
1877
+ super(message, "TIMEOUT_ERROR", details);
1878
+ this.name = "TimeoutError";
1879
+ }
1880
+ };
1881
+ var RateLimitError = class extends SynapCoresError {
1882
+ constructor(message, retryAfter, details) {
1883
+ super(message, "RATE_LIMIT_ERROR", details);
1884
+ this.name = "RateLimitError";
1885
+ this.retryAfter = retryAfter;
1886
+ }
1887
+ };
1888
+ var SQLError = class extends SynapCoresError {
1889
+ constructor(message, code, severity = "ERROR", position, hint, detail, details) {
1890
+ super(message, code, details);
1891
+ this.name = "SQLError";
1892
+ this.severity = severity;
1893
+ this.position = position;
1894
+ this.hint = hint;
1895
+ this.detail = detail;
1896
+ }
1897
+ };
1898
+ var VectorError = class extends SynapCoresError {
1899
+ constructor(message, code, vectorDimensions, expectedDimensions, operation, details) {
1900
+ super(message, code, details);
1901
+ this.name = "VectorError";
1902
+ this.vectorDimensions = vectorDimensions;
1903
+ this.expectedDimensions = expectedDimensions;
1904
+ this.operation = operation;
1905
+ }
1906
+ };
1907
+ var TransactionError = class extends SynapCoresError {
1908
+ constructor(message, code, transactionId, transactionState, details) {
1909
+ super(message, code, details);
1910
+ this.name = "TransactionError";
1911
+ this.transactionId = transactionId;
1912
+ this.transactionState = transactionState;
1913
+ }
1914
+ };
1915
+ var BatchOperationError = class extends SynapCoresError {
1916
+ constructor(message, code, failedItems, totalProcessed, successfulCount, details) {
1917
+ super(message, code, details);
1918
+ this.name = "BatchOperationError";
1919
+ this.failedItems = failedItems;
1920
+ this.totalProcessed = totalProcessed;
1921
+ this.successfulCount = successfulCount;
1922
+ }
1923
+ };
1924
+
1925
+ // src/client.ts
1926
+ var SynapCores = class {
1927
+ constructor(config = {}) {
1928
+ this.collectionsCache = /* @__PURE__ */ new Map();
1929
+ this.currentTransaction = null;
1930
+ this.preparedStatements = /* @__PURE__ */ new Map();
1931
+ this.config = {
1932
+ host: config.host || "localhost",
1933
+ port: config.port || 8080,
1934
+ apiKey: config.apiKey || "",
1935
+ jwtToken: config.jwtToken || "",
1936
+ useHttps: config.useHttps || false,
1937
+ timeout: config.timeout || 3e4,
1938
+ maxRetries: config.maxRetries || 3,
1939
+ rejectUnauthorized: config.rejectUnauthorized !== void 0 ? config.rejectUnauthorized : true
1940
+ };
1941
+ if (this.config.apiKey && !this.config.apiKey.startsWith("ak_") && !this.config.apiKey.startsWith("aidb_")) {
1942
+ throw new Error(
1943
+ "Invalid API key format. API keys should start with 'ak_' or 'aidb_' prefix. Please create a valid API key from your AIDB dashboard."
1944
+ );
1945
+ }
1946
+ const protocol = this.config.useHttps ? "https" : "http";
1947
+ const baseURL = `${protocol}://${this.config.host}:${this.config.port}/v1`;
1948
+ const httpsAgent = this.config.useHttps && !this.config.rejectUnauthorized ? new (__require("https")).Agent({ rejectUnauthorized: false }) : void 0;
1949
+ const authHeader = {};
1950
+ if (this.config.jwtToken) {
1951
+ authHeader["Authorization"] = `Bearer ${this.config.jwtToken}`;
1952
+ } else if (this.config.apiKey) {
1953
+ authHeader["X-API-Key"] = this.config.apiKey;
1954
+ }
1955
+ this.httpClient = axios.create({
1956
+ baseURL,
1957
+ timeout: this.config.timeout,
1958
+ headers: {
1959
+ "Content-Type": "application/json",
1960
+ "User-Agent": "synapcores-nodejs/0.1.0",
1961
+ ...authHeader
1962
+ },
1963
+ ...httpsAgent && { httpsAgent }
1964
+ });
1965
+ this.httpClient.interceptors.response.use(
1966
+ (response) => response,
1967
+ (error) => this.handleError(error)
1968
+ );
1969
+ this.automl = new AutoMLClient(this);
1970
+ this.nlp = new NLPClient(this);
1971
+ this.recipes = new RecipeClient(this);
1972
+ this.schema = new SchemaClient(this);
1973
+ this.import = new ImportExportClient(this);
1974
+ this.integrations = new IntegrationClient(this);
1975
+ this.backup = new BackupClient(this);
1976
+ }
1977
+ handleError(error) {
1978
+ if (!error.response) {
1979
+ const message = error.code === "ECONNREFUSED" ? `Failed to connect to SynapCores server at ${error.config?.baseURL}. Connection refused.` : `Failed to connect to SynapCores server: ${error.message}`;
1980
+ throw new ConnectionError(message);
1981
+ }
1982
+ const { status, data } = error.response;
1983
+ const errorData = data;
1984
+ const errorInfo = errorData?.error || errorData;
1985
+ const errorCode = errorInfo?.code;
1986
+ const errorMessage = errorInfo?.message || errorData?.message || "An error occurred";
1987
+ const errorDetails = errorInfo?.details || errorData?.details || errorData;
1988
+ switch (status) {
1989
+ case 400:
1990
+ throw new ValidationError(
1991
+ errorMessage,
1992
+ errorDetails
1993
+ );
1994
+ case 401:
1995
+ throw new AuthenticationError(
1996
+ errorMessage,
1997
+ errorDetails
1998
+ );
1999
+ case 403:
2000
+ throw new AuthenticationError(
2001
+ errorMessage,
2002
+ errorDetails
2003
+ );
2004
+ case 404:
2005
+ throw new NotFoundError(
2006
+ errorMessage,
2007
+ errorDetails
2008
+ );
2009
+ case 409:
2010
+ throw new ValidationError(
2011
+ errorMessage,
2012
+ errorDetails
2013
+ );
2014
+ case 413:
2015
+ throw new ValidationError(
2016
+ errorMessage || "Payload too large",
2017
+ errorDetails
2018
+ );
2019
+ case 422:
2020
+ throw new ValidationError(
2021
+ errorMessage,
2022
+ errorDetails?.errors || errorDetails
2023
+ );
2024
+ case 429:
2025
+ const retryAfter = error.response.headers["retry-after"];
2026
+ throw new RateLimitError(
2027
+ errorMessage,
2028
+ retryAfter ? parseInt(retryAfter) : void 0,
2029
+ errorDetails
2030
+ );
2031
+ case 500:
2032
+ throw new ServerError(
2033
+ errorMessage || "Internal server error",
2034
+ errorDetails
2035
+ );
2036
+ case 503:
2037
+ throw new ServerError(
2038
+ errorMessage || "Service unavailable",
2039
+ errorDetails
2040
+ );
2041
+ default:
2042
+ if (status >= 500) {
2043
+ throw new ServerError(
2044
+ errorMessage || `Server error: ${status}`,
2045
+ errorDetails
2046
+ );
2047
+ }
2048
+ throw new SynapCoresError(
2049
+ errorMessage || `Unexpected error: ${status}`,
2050
+ errorCode || "UNEXPECTED_ERROR",
2051
+ errorDetails
2052
+ );
2053
+ }
2054
+ }
2055
+ /**
2056
+ * Create collection (legacy method for backward compatibility)
2057
+ */
2058
+ async createCollection(options) {
2059
+ const request = {
2060
+ name: options.name,
2061
+ description: options.description,
2062
+ schema: options.schema
2063
+ };
2064
+ return this.createCollectionWithSchema(request);
2065
+ }
2066
+ /**
2067
+ * Create collection matching the database integration guide format
2068
+ */
2069
+ async createCollectionWithSchema(request) {
2070
+ const { data } = await this.httpClient.post("/collections", {
2071
+ name: request.name,
2072
+ description: request.description,
2073
+ schema: request.schema
2074
+ });
2075
+ const collection = new Collection(this, request.name, data.collection.schema);
2076
+ this.collectionsCache.set(request.name, collection);
2077
+ return collection;
2078
+ }
2079
+ async getCollection(name) {
2080
+ if (this.collectionsCache.has(name)) {
2081
+ return this.collectionsCache.get(name);
2082
+ }
2083
+ const { data } = await this.httpClient.get(`/collections/${name}`);
2084
+ const collection = new Collection(this, name, data.schema);
2085
+ this.collectionsCache.set(name, collection);
2086
+ return collection;
2087
+ }
2088
+ /**
2089
+ * List collections (legacy method for backward compatibility)
2090
+ */
2091
+ async listCollections() {
2092
+ const result = await this.listCollectionsDetailed();
2093
+ return result.collections.map((c) => c.name);
2094
+ }
2095
+ /**
2096
+ * List collections with detailed information matching the database integration guide format
2097
+ */
2098
+ async listCollectionsDetailed(options) {
2099
+ const params = new URLSearchParams();
2100
+ if (options?.page) params.append("page", options.page.toString());
2101
+ if (options?.pageSize) params.append("pageSize", options.pageSize.toString());
2102
+ if (options?.search) params.append("search", options.search);
2103
+ if (options?.sortBy) params.append("sortBy", options.sortBy);
2104
+ if (options?.sortOrder) params.append("sortOrder", options.sortOrder);
2105
+ const { data } = await this.httpClient.get(
2106
+ `/collections${params.toString() ? `?${params.toString()}` : ""}`
2107
+ );
2108
+ return data;
2109
+ }
2110
+ async getDocuments(collectionName, page, pageSize) {
2111
+ const { data } = await this.httpClient.get(
2112
+ `/collections/${collectionName}/documents?page=${page}&pageSize=${pageSize}`
2113
+ );
2114
+ return data;
2115
+ }
2116
+ async deleteCollection(name) {
2117
+ await this.httpClient.delete(`/collections/${name}`);
2118
+ this.collectionsCache.delete(name);
2119
+ }
2120
+ /**
2121
+ * Execute SQL query (legacy method for backward compatibility)
2122
+ * @deprecated Use executeQuery for new code
2123
+ */
2124
+ async sql(query, params) {
2125
+ return this.executeQuery({
2126
+ sql: query,
2127
+ parameters: params ? Object.values(params) : []
2128
+ });
2129
+ }
2130
+ /**
2131
+ * Execute SQL query matching the database integration guide format
2132
+ */
2133
+ async executeQuery(request) {
2134
+ const { data } = await this.httpClient.post("/query/execute", {
2135
+ sql: request.sql,
2136
+ parameters: request.parameters || [],
2137
+ max_rows: request.max_rows || 1e3,
2138
+ timeout_secs: request.timeout_secs || 300
2139
+ });
2140
+ return {
2141
+ columns: data.columns || [],
2142
+ rows: data.rows || [],
2143
+ rows_affected: data.rows_affected,
2144
+ execution_time_ms: data.execution_time_ms || 0,
2145
+ queryPlan: data.query_plan
2146
+ };
2147
+ }
2148
+ /**
2149
+ * Execute batch queries
2150
+ */
2151
+ async executeBatchQueries(request) {
2152
+ const { data } = await this.httpClient.post("/query/execute/batch", {
2153
+ queries: request.queries,
2154
+ transactional: request.transactional || false
2155
+ });
2156
+ return {
2157
+ results: data.results || [],
2158
+ total_execution_time_ms: data.total_execution_time_ms || 0
2159
+ };
2160
+ }
2161
+ async embed(text, options = {}) {
2162
+ const isBatch = Array.isArray(text);
2163
+ const texts = isBatch ? text : [text];
2164
+ const { data } = await this.httpClient.post("/ai/embed", {
2165
+ texts,
2166
+ model: options.model || "default"
2167
+ });
2168
+ return isBatch ? data.embeddings : data.embeddings[0];
2169
+ }
2170
+ // Internal method for HTTP client access
2171
+ _getHttpClient() {
2172
+ return this.httpClient;
2173
+ }
2174
+ // =================================================================
2175
+ // TABLE MANAGEMENT OPERATIONS
2176
+ // =================================================================
2177
+ /**
2178
+ * Creates a new table with the specified columns and constraints
2179
+ * @param tableName - Name of the table to create
2180
+ * @param columns - Column definitions for the table
2181
+ * @param options - Additional table creation options
2182
+ * @returns Promise resolving to table creation result
2183
+ */
2184
+ async createTable(tableName, columns, options = {}) {
2185
+ let sql = `CREATE TABLE ${options.ifNotExists ? "IF NOT EXISTS" : ""} ${tableName} (`;
2186
+ const columnDefs = columns.map((col) => {
2187
+ let def = `${col.name} ${col.dataType}`;
2188
+ if (col.constraints) {
2189
+ for (const constraint of col.constraints) {
2190
+ switch (constraint.type) {
2191
+ case "PRIMARY_KEY":
2192
+ def += " PRIMARY KEY";
2193
+ break;
2194
+ case "UNIQUE":
2195
+ def += " UNIQUE";
2196
+ break;
2197
+ case "NOT_NULL":
2198
+ def += " NOT NULL";
2199
+ break;
2200
+ case "CHECK":
2201
+ def += ` CHECK (${constraint.expression})`;
2202
+ break;
2203
+ case "FOREIGN_KEY":
2204
+ def += ` REFERENCES ${constraint.referencedTable}(${constraint.referencedColumn})`;
2205
+ break;
2206
+ case "DEFAULT":
2207
+ def += ` DEFAULT ${col.defaultValue}`;
2208
+ break;
2209
+ }
2210
+ }
2211
+ }
2212
+ return def;
2213
+ }).join(", ");
2214
+ sql += columnDefs;
2215
+ if (options.constraints) {
2216
+ const constraintDefs = options.constraints.map((constraint) => {
2217
+ switch (constraint.type) {
2218
+ case "PRIMARY_KEY":
2219
+ return `PRIMARY KEY (${constraint.columns.join(", ")})`;
2220
+ case "UNIQUE":
2221
+ return `UNIQUE (${constraint.columns.join(", ")})`;
2222
+ case "CHECK":
2223
+ return `CHECK (${constraint.expression})`;
2224
+ case "FOREIGN_KEY":
2225
+ return `FOREIGN KEY (${constraint.columns.join(", ")}) REFERENCES ${constraint.referencedTable}(${constraint.referencedColumns?.join(", ")})`;
2226
+ default:
2227
+ return "";
2228
+ }
2229
+ }).filter((def) => def);
2230
+ if (constraintDefs.length > 0) {
2231
+ sql += ", " + constraintDefs.join(", ");
2232
+ }
2233
+ }
2234
+ sql += ")";
2235
+ if (options.partitionBy) {
2236
+ sql += ` PARTITION BY ${options.partitionBy.type} (${options.partitionBy.column})`;
2237
+ }
2238
+ return this.sql(sql);
2239
+ }
2240
+ /**
2241
+ * Alters an existing table structure
2242
+ * @param tableName - Name of the table to alter
2243
+ * @param alterOptions - Alteration options and parameters
2244
+ * @returns Promise resolving to alteration result
2245
+ */
2246
+ async alterTable(tableName, alterOptions) {
2247
+ let sql = `ALTER TABLE ${tableName} `;
2248
+ switch (alterOptions.action) {
2249
+ case "ADD_COLUMN":
2250
+ if (!alterOptions.columnDefinition) {
2251
+ throw new ValidationError("Column definition required for ADD_COLUMN");
2252
+ }
2253
+ sql += `ADD COLUMN ${alterOptions.columnDefinition.name} ${alterOptions.columnDefinition.dataType}`;
2254
+ break;
2255
+ case "DROP_COLUMN":
2256
+ sql += `DROP COLUMN ${alterOptions.columnName}`;
2257
+ break;
2258
+ case "RENAME_COLUMN":
2259
+ sql += `RENAME COLUMN ${alterOptions.columnName} TO ${alterOptions.newColumnName}`;
2260
+ break;
2261
+ case "ALTER_COLUMN":
2262
+ sql += `ALTER COLUMN ${alterOptions.columnName} TYPE ${alterOptions.newDataType}`;
2263
+ break;
2264
+ case "ADD_CONSTRAINT":
2265
+ if (!alterOptions.constraint) {
2266
+ throw new ValidationError("Constraint required for ADD_CONSTRAINT");
2267
+ }
2268
+ sql += `ADD CONSTRAINT ${alterOptions.constraint.type.toLowerCase()}_constraint`;
2269
+ break;
2270
+ case "DROP_CONSTRAINT":
2271
+ sql += `DROP CONSTRAINT ${alterOptions.constraintName}`;
2272
+ break;
2273
+ }
2274
+ return this.sql(sql);
2275
+ }
2276
+ /**
2277
+ * Drops an existing table
2278
+ * @param tableName - Name of the table to drop
2279
+ * @param options - Drop options
2280
+ * @returns Promise resolving to drop result
2281
+ */
2282
+ async dropTable(tableName, options = {}) {
2283
+ let sql = `DROP TABLE ${options.ifExists ? "IF EXISTS" : ""} ${tableName}`;
2284
+ if (options.cascade) {
2285
+ sql += " CASCADE";
2286
+ }
2287
+ return this.sql(sql);
2288
+ }
2289
+ /**
2290
+ * Describes a table structure including columns, constraints, and indexes
2291
+ * @param tableName - Name of the table to describe
2292
+ * @returns Promise resolving to table information
2293
+ */
2294
+ async describeTable(tableName) {
2295
+ const { data } = await this.httpClient.get(`/table/${tableName}/info`);
2296
+ return data;
2297
+ }
2298
+ /**
2299
+ * Lists all tables in the current database
2300
+ * @param pattern - Optional pattern to filter table names
2301
+ * @returns Promise resolving to array of table names
2302
+ */
2303
+ async showTables(pattern) {
2304
+ const sql = pattern ? `SHOW TABLES LIKE '${pattern}'` : "SHOW TABLES";
2305
+ const result = await this.sql(sql);
2306
+ return result.rows.map((row) => Object.values(row)[0]);
2307
+ }
2308
+ // =================================================================
2309
+ // INDEX MANAGEMENT OPERATIONS
2310
+ // =================================================================
2311
+ /**
2312
+ * Creates an index on a table
2313
+ * @param indexDef - Index definition with name, table, columns, and options
2314
+ * @returns Promise resolving to index creation result
2315
+ */
2316
+ async createIndex(indexDef) {
2317
+ const columns = indexDef.columns.map((col) => `${col.name} ${col.order || "ASC"}`).join(", ");
2318
+ const sql = `CREATE ${indexDef.unique ? "UNIQUE" : ""} INDEX ${indexDef.ifNotExists ? "IF NOT EXISTS" : ""} ${indexDef.name} ON ${indexDef.tableName} (${columns})`;
2319
+ return this.sql(sql);
2320
+ }
2321
+ /**
2322
+ * Drops an existing index
2323
+ * @param indexName - Name of the index to drop
2324
+ * @param options - Drop options
2325
+ * @returns Promise resolving to drop result
2326
+ */
2327
+ async dropIndex(indexName, options = {}) {
2328
+ const sql = `DROP INDEX ${options.ifExists ? "IF EXISTS" : ""} ${indexName}`;
2329
+ return this.sql(sql);
2330
+ }
2331
+ /**
2332
+ * Lists all indexes, optionally filtered by table name
2333
+ * @param tableName - Optional table name to filter indexes
2334
+ * @returns Promise resolving to array of index information
2335
+ */
2336
+ async showIndexes(tableName) {
2337
+ const sql = tableName ? `SHOW INDEXES FROM ${tableName}` : "SHOW INDEXES";
2338
+ const result = await this.sql(sql);
2339
+ const indexNameIdx = result.columns.findIndex((c) => c.name === "index_name" || c.name === "name");
2340
+ const tableNameIdx = result.columns.findIndex((c) => c.name === "table_name" || c.name === "table");
2341
+ const columnsIdx = result.columns.findIndex((c) => c.name === "columns" || c.name === "column");
2342
+ const uniqueIdx = result.columns.findIndex((c) => c.name === "is_unique" || c.name === "unique");
2343
+ return result.rows.map((row) => {
2344
+ const indexName = indexNameIdx >= 0 ? row[indexNameIdx] : "";
2345
+ const table = tableNameIdx >= 0 ? row[tableNameIdx] : "";
2346
+ const columnsStr = columnsIdx >= 0 ? row[columnsIdx] : "";
2347
+ const isUnique = uniqueIdx >= 0 ? row[uniqueIdx] : false;
2348
+ return {
2349
+ name: String(indexName),
2350
+ table: String(table),
2351
+ columns: typeof columnsStr === "string" ? columnsStr.split(",") : [],
2352
+ unique: Boolean(isUnique)
2353
+ };
2354
+ });
2355
+ }
2356
+ // =================================================================
2357
+ // TRANSACTION SUPPORT
2358
+ // =================================================================
2359
+ /**
2360
+ * Begins a new transaction
2361
+ * @param options - Transaction options including isolation level
2362
+ * @returns Promise resolving to transaction context
2363
+ */
2364
+ async beginTransaction(options = {}) {
2365
+ if (this.currentTransaction) {
2366
+ throw new Error("Transaction already in progress");
2367
+ }
2368
+ let sql = "BEGIN TRANSACTION";
2369
+ if (options.isolationLevel) {
2370
+ sql += ` ISOLATION LEVEL ${options.isolationLevel}`;
2371
+ }
2372
+ if (options.readOnly) {
2373
+ sql += " READ ONLY";
2374
+ }
2375
+ await this.sql(sql);
2376
+ this.currentTransaction = {
2377
+ id: Math.random().toString(36).substring(7),
2378
+ startTime: /* @__PURE__ */ new Date(),
2379
+ isolationLevel: options.isolationLevel || "READ_COMMITTED",
2380
+ readOnly: options.readOnly || false
2381
+ };
2382
+ if (options.timeout) {
2383
+ setTimeout(() => {
2384
+ if (this.currentTransaction) {
2385
+ this.rollbackTransaction().catch(console.error);
2386
+ }
2387
+ }, options.timeout);
2388
+ }
2389
+ return this.currentTransaction;
2390
+ }
2391
+ /**
2392
+ * Commits the current transaction
2393
+ * @returns Promise resolving when transaction is committed
2394
+ */
2395
+ async commitTransaction() {
2396
+ if (!this.currentTransaction) {
2397
+ throw new Error("No transaction in progress");
2398
+ }
2399
+ await this.sql("COMMIT");
2400
+ this.currentTransaction = null;
2401
+ }
2402
+ /**
2403
+ * Rolls back the current transaction
2404
+ * @returns Promise resolving when transaction is rolled back
2405
+ */
2406
+ async rollbackTransaction() {
2407
+ if (!this.currentTransaction) {
2408
+ throw new Error("No transaction in progress");
2409
+ }
2410
+ await this.sql("ROLLBACK");
2411
+ this.currentTransaction = null;
2412
+ }
2413
+ /**
2414
+ * Gets the current transaction context
2415
+ * @returns Current transaction context or null if no transaction
2416
+ */
2417
+ getCurrentTransaction() {
2418
+ return this.currentTransaction;
2419
+ }
2420
+ // =================================================================
2421
+ // BATCH OPERATIONS
2422
+ // =================================================================
2423
+ /**
2424
+ * Performs batch insert operations
2425
+ * @param options - Batch insert options with table, columns, and rows
2426
+ * @returns Promise resolving to batch operation result
2427
+ */
2428
+ async batchInsert(options) {
2429
+ const { data } = await this.httpClient.post("/batch/insert", {
2430
+ table_name: options.tableName,
2431
+ columns: options.columns,
2432
+ rows: options.rows,
2433
+ on_conflict: options.onConflict,
2434
+ batch_size: options.batchSize || 1e3
2435
+ });
2436
+ return {
2437
+ totalProcessed: data.total_processed,
2438
+ successful: data.successful,
2439
+ failed: data.failed,
2440
+ errors: data.errors,
2441
+ tookMs: data.took_ms
2442
+ };
2443
+ }
2444
+ /**
2445
+ * Performs batch update operations
2446
+ * @param options - Batch update options with table and update conditions
2447
+ * @returns Promise resolving to batch operation result
2448
+ */
2449
+ async batchUpdate(options) {
2450
+ const { data } = await this.httpClient.post("/batch/update", {
2451
+ table_name: options.tableName,
2452
+ updates: options.updates,
2453
+ batch_size: options.batchSize || 1e3
2454
+ });
2455
+ return {
2456
+ totalProcessed: data.total_processed,
2457
+ successful: data.successful,
2458
+ failed: data.failed,
2459
+ errors: data.errors,
2460
+ tookMs: data.took_ms
2461
+ };
2462
+ }
2463
+ /**
2464
+ * Performs batch delete operations
2465
+ * @param options - Batch delete options with table and where conditions
2466
+ * @returns Promise resolving to batch operation result
2467
+ */
2468
+ async batchDelete(options) {
2469
+ const { data } = await this.httpClient.post("/batch/delete", {
2470
+ table_name: options.tableName,
2471
+ where_conditions: options.whereConditions,
2472
+ batch_size: options.batchSize || 1e3
2473
+ });
2474
+ return {
2475
+ totalProcessed: data.total_processed,
2476
+ successful: data.successful,
2477
+ failed: data.failed,
2478
+ errors: data.errors,
2479
+ tookMs: data.took_ms
2480
+ };
2481
+ }
2482
+ // =================================================================
2483
+ // ADVANCED SQL FEATURES
2484
+ // =================================================================
2485
+ /**
2486
+ * Prepares a SQL statement for repeated execution
2487
+ * @param sql - SQL statement to prepare
2488
+ * @param options - Preparation options
2489
+ * @returns Promise resolving to prepared statement
2490
+ */
2491
+ async prepareStatement(sql, options = {}) {
2492
+ const { data } = await this.httpClient.post("/prepare", {
2493
+ sql,
2494
+ name: options.name,
2495
+ parameter_types: options.parameterTypes
2496
+ });
2497
+ const prepared = {
2498
+ id: data.statement_id,
2499
+ sql,
2500
+ parameterCount: data.parameter_count
2501
+ };
2502
+ if (options.name) {
2503
+ this.preparedStatements.set(options.name, prepared);
2504
+ }
2505
+ return prepared;
2506
+ }
2507
+ /**
2508
+ * Executes a prepared statement with parameters
2509
+ * @param statementId - ID of the prepared statement or statement name
2510
+ * @param params - Parameters for the prepared statement
2511
+ * @returns Promise resolving to query result
2512
+ */
2513
+ async executePrepared(statementId, params = []) {
2514
+ if (this.preparedStatements.has(statementId)) {
2515
+ statementId = this.preparedStatements.get(statementId).id;
2516
+ }
2517
+ const { data } = await this.httpClient.post("/execute-prepared", {
2518
+ statement_id: statementId,
2519
+ parameters: params
2520
+ });
2521
+ return {
2522
+ columns: data.columns || [],
2523
+ rows: data.rows || [],
2524
+ rows_affected: data.rows_affected,
2525
+ execution_time_ms: data.execution_time_ms || data.took_ms || 0,
2526
+ queryPlan: data.query_plan
2527
+ };
2528
+ }
2529
+ /**
2530
+ * Deallocates a prepared statement
2531
+ * @param statementId - ID of the prepared statement or statement name
2532
+ * @returns Promise resolving when statement is deallocated
2533
+ */
2534
+ async deallocatePrepared(statementId) {
2535
+ if (this.preparedStatements.has(statementId)) {
2536
+ const prepared = this.preparedStatements.get(statementId);
2537
+ await this.httpClient.delete(`/prepare/${prepared.id}`);
2538
+ this.preparedStatements.delete(statementId);
2539
+ } else {
2540
+ await this.httpClient.delete(`/prepare/${statementId}`);
2541
+ }
2542
+ }
2543
+ /**
2544
+ * Executes a query with Common Table Expressions (CTEs)
2545
+ * @param ctes - Array of CTE definitions
2546
+ * @param mainQuery - Main query that uses the CTEs
2547
+ * @param params - Optional parameters for the query
2548
+ * @returns Promise resolving to query result
2549
+ */
2550
+ async queryWithCTEs(ctes, mainQuery, params) {
2551
+ const cteSQL = ctes.map((cte) => {
2552
+ const columns = cte.columns ? `(${cte.columns.join(", ")})` : "";
2553
+ return `${cte.name}${columns} AS (${cte.query})`;
2554
+ }).join(", ");
2555
+ const sql = `WITH ${cteSQL} ${mainQuery}`;
2556
+ return this.sql(sql, params);
2557
+ }
2558
+ /**
2559
+ * Executes a query with window functions
2560
+ * @param selectQuery - Base SELECT query
2561
+ * @param windowFunctions - Array of window function definitions
2562
+ * @param params - Optional parameters for the query
2563
+ * @returns Promise resolving to query result
2564
+ */
2565
+ async queryWithWindowFunctions(selectQuery, windowFunctions, params) {
2566
+ const windowClauses = windowFunctions.map((wf) => {
2567
+ let clause = `${wf.function} OVER (`;
2568
+ if (wf.options.partitionBy) {
2569
+ clause += `PARTITION BY ${wf.options.partitionBy.join(", ")}`;
2570
+ }
2571
+ if (wf.options.orderBy) {
2572
+ const orderBy = wf.options.orderBy.map((order) => `${order.column} ${order.direction}`).join(", ");
2573
+ clause += ` ORDER BY ${orderBy}`;
2574
+ }
2575
+ if (wf.options.frame) {
2576
+ clause += ` ${wf.options.frame.type} BETWEEN ${wf.options.frame.start}`;
2577
+ if (wf.options.frame.end) {
2578
+ clause += ` AND ${wf.options.frame.end}`;
2579
+ }
2580
+ }
2581
+ clause += `) AS ${wf.alias}`;
2582
+ return clause;
2583
+ }).join(", ");
2584
+ const sql = `${selectQuery}, ${windowClauses}`;
2585
+ return this.sql(sql, params);
2586
+ }
2587
+ /**
2588
+ * Performs JSON operations on JSON/JSONB columns
2589
+ * @param tableName - Table containing JSON data
2590
+ * @param jsonColumn - Name of the JSON column
2591
+ * @param operation - JSON operation to perform
2592
+ * @param path - JSON path for the operation
2593
+ * @param value - Value for update operations
2594
+ * @param whereClause - Optional WHERE clause
2595
+ * @returns Promise resolving to query result
2596
+ */
2597
+ async jsonQuery(tableName, jsonColumn, operation, path, value, whereClause) {
2598
+ let sql;
2599
+ switch (operation) {
2600
+ case "extract":
2601
+ sql = `SELECT ${jsonColumn}->>'${path}' as extracted_value FROM ${tableName}`;
2602
+ break;
2603
+ case "update":
2604
+ sql = `UPDATE ${tableName} SET ${jsonColumn} = jsonb_set(${jsonColumn}, '{${path}}', '${JSON.stringify(value)}')`;
2605
+ break;
2606
+ case "delete":
2607
+ sql = `UPDATE ${tableName} SET ${jsonColumn} = ${jsonColumn} - '${path}'`;
2608
+ break;
2609
+ case "contains":
2610
+ sql = `SELECT * FROM ${tableName} WHERE ${jsonColumn} @> '{"${path}": ${JSON.stringify(value)}}'`;
2611
+ break;
2612
+ }
2613
+ if (whereClause && operation !== "contains") {
2614
+ sql += ` WHERE ${whereClause}`;
2615
+ }
2616
+ return this.sql(sql);
2617
+ }
2618
+ // =================================================================
2619
+ // VECTOR OPERATIONS
2620
+ // =================================================================
2621
+ /**
2622
+ * Performs vector addition
2623
+ * @param vector1 - First vector
2624
+ * @param vector2 - Second vector
2625
+ * @returns Promise resolving to vector addition result
2626
+ */
2627
+ async vectorAdd(vector1, vector2) {
2628
+ if (vector1.length !== vector2.length) {
2629
+ throw new VectorError("Vector dimensions must match", "DIMENSION_MISMATCH");
2630
+ }
2631
+ const { data } = await this.httpClient.post("/vectors/add", {
2632
+ vector1,
2633
+ vector2
2634
+ });
2635
+ return {
2636
+ result: { values: data.result, dimensions: data.result.length },
2637
+ operation: "addition",
2638
+ tookMs: data.took_ms
2639
+ };
2640
+ }
2641
+ /**
2642
+ * Performs vector subtraction
2643
+ * @param vector1 - First vector (minuend)
2644
+ * @param vector2 - Second vector (subtrahend)
2645
+ * @returns Promise resolving to vector subtraction result
2646
+ */
2647
+ async vectorSubtract(vector1, vector2) {
2648
+ if (vector1.length !== vector2.length) {
2649
+ throw new VectorError("Vector dimensions must match", "DIMENSION_MISMATCH");
2650
+ }
2651
+ const { data } = await this.httpClient.post("/vectors/subtract", {
2652
+ vector1,
2653
+ vector2
2654
+ });
2655
+ return {
2656
+ result: { values: data.result, dimensions: data.result.length },
2657
+ operation: "subtraction",
2658
+ tookMs: data.took_ms
2659
+ };
2660
+ }
2661
+ /**
2662
+ * Performs scalar multiplication on a vector
2663
+ * @param vector - Input vector
2664
+ * @param scalar - Scalar value to multiply by
2665
+ * @returns Promise resolving to scalar multiplication result
2666
+ */
2667
+ async vectorScalarMultiply(vector, scalar) {
2668
+ const { data } = await this.httpClient.post("/vectors/scalar-multiply", {
2669
+ vector,
2670
+ scalar
2671
+ });
2672
+ return {
2673
+ result: { values: data.result, dimensions: data.result.length },
2674
+ operation: "scalar_multiplication",
2675
+ tookMs: data.took_ms
2676
+ };
2677
+ }
2678
+ /**
2679
+ * Calculates the dot product of two vectors
2680
+ * @param vector1 - First vector
2681
+ * @param vector2 - Second vector
2682
+ * @returns Promise resolving to dot product result
2683
+ */
2684
+ async vectorDotProduct(vector1, vector2) {
2685
+ if (vector1.length !== vector2.length) {
2686
+ throw new VectorError("Vector dimensions must match", "DIMENSION_MISMATCH");
2687
+ }
2688
+ const { data } = await this.httpClient.post("/vectors/dot-product", {
2689
+ vector1,
2690
+ vector2
2691
+ });
2692
+ return {
2693
+ dotProduct: data.dot_product,
2694
+ tookMs: data.took_ms
2695
+ };
2696
+ }
2697
+ /**
2698
+ * Calculates cosine similarity between two vectors
2699
+ * @param vector1 - First vector
2700
+ * @param vector2 - Second vector
2701
+ * @returns Promise resolving to cosine similarity result
2702
+ */
2703
+ async cosineSimilarity(vector1, vector2) {
2704
+ if (vector1.length !== vector2.length) {
2705
+ throw new VectorError("Vector dimensions must match", "DIMENSION_MISMATCH");
2706
+ }
2707
+ const { data } = await this.httpClient.post("/vectors/cosine-similarity", {
2708
+ vector1,
2709
+ vector2
2710
+ });
2711
+ return {
2712
+ similarity: data.similarity,
2713
+ function: "cosine",
2714
+ tookMs: data.took_ms
2715
+ };
2716
+ }
2717
+ /**
2718
+ * Calculates L2 (Euclidean) distance between two vectors
2719
+ * @param vector1 - First vector
2720
+ * @param vector2 - Second vector
2721
+ * @returns Promise resolving to L2 distance result
2722
+ */
2723
+ async l2Distance(vector1, vector2) {
2724
+ if (vector1.length !== vector2.length) {
2725
+ throw new VectorError("Vector dimensions must match", "DIMENSION_MISMATCH");
2726
+ }
2727
+ const { data } = await this.httpClient.post("/vectors/l2-distance", {
2728
+ vector1,
2729
+ vector2
2730
+ });
2731
+ return {
2732
+ distance: data.distance,
2733
+ similarity: data.distance,
2734
+ // Include similarity for compatibility
2735
+ function: "l2",
2736
+ tookMs: data.took_ms
2737
+ };
2738
+ }
2739
+ /**
2740
+ * Calculates inner product between two vectors
2741
+ * @param vector1 - First vector
2742
+ * @param vector2 - Second vector
2743
+ * @returns Promise resolving to inner product result
2744
+ */
2745
+ async innerProduct(vector1, vector2) {
2746
+ if (vector1.length !== vector2.length) {
2747
+ throw new VectorError("Vector dimensions must match", "DIMENSION_MISMATCH");
2748
+ }
2749
+ const { data } = await this.httpClient.post("/vectors/inner-product", {
2750
+ vector1,
2751
+ vector2
2752
+ });
2753
+ return {
2754
+ similarity: data.inner_product,
2755
+ function: "inner_product",
2756
+ tookMs: data.took_ms
2757
+ };
2758
+ }
2759
+ /**
2760
+ * Performs K-nearest neighbors vector search
2761
+ * @param options - KNN search options
2762
+ * @returns Promise resolving to KNN search results
2763
+ */
2764
+ async knnSearch(options) {
2765
+ const { data } = await this.httpClient.post("/vectors/knn-search", {
2766
+ query_vector: options.queryVector,
2767
+ k: options.k,
2768
+ table_name: options.tableName,
2769
+ vector_column: options.vectorColumn,
2770
+ metadata_columns: options.metadataColumns,
2771
+ filter: options.filter
2772
+ });
2773
+ return data.results.map((result) => ({
2774
+ id: result.id,
2775
+ vector: result.vector,
2776
+ similarity: result.similarity,
2777
+ distance: result.distance,
2778
+ metadata: result.metadata
2779
+ }));
2780
+ }
2781
+ /**
2782
+ * Performs range-based vector similarity search
2783
+ * @param options - Range search options
2784
+ * @returns Promise resolving to range search results
2785
+ */
2786
+ async rangeSearch(options) {
2787
+ const { data } = await this.httpClient.post("/vectors/range-search", {
2788
+ query_vector: options.queryVector,
2789
+ threshold: options.threshold,
2790
+ table_name: options.tableName,
2791
+ vector_column: options.vectorColumn,
2792
+ metadata_columns: options.metadataColumns,
2793
+ filter: options.filter,
2794
+ max_results: options.maxResults
2795
+ });
2796
+ return data.results.map((result) => ({
2797
+ id: result.id,
2798
+ vector: result.vector,
2799
+ similarity: result.similarity,
2800
+ distance: result.distance,
2801
+ metadata: result.metadata
2802
+ }));
2803
+ }
2804
+ /**
2805
+ * Performs hybrid search combining vector similarity and SQL filtering
2806
+ * @param options - Hybrid search options
2807
+ * @returns Promise resolving to hybrid search results
2808
+ */
2809
+ async hybridSearch(options) {
2810
+ const { data } = await this.httpClient.post("/vectors/hybrid-search", {
2811
+ vector: options.vector,
2812
+ text_query: options.textQuery,
2813
+ sql_filter: options.sqlFilter,
2814
+ k: options.k,
2815
+ threshold: options.threshold,
2816
+ metric: options.metric,
2817
+ filter: options.filter,
2818
+ weights: options.weights
2819
+ });
2820
+ return data.results.map((result) => ({
2821
+ id: result.id,
2822
+ vector: result.vector,
2823
+ similarity: result.similarity,
2824
+ distance: result.distance,
2825
+ metadata: result.metadata
2826
+ }));
2827
+ }
2828
+ /**
2829
+ * Normalizes a vector to unit length
2830
+ * @param vector - Input vector to normalize
2831
+ * @returns Promise resolving to normalized vector
2832
+ */
2833
+ async normalizeVector(vector) {
2834
+ const { data } = await this.httpClient.post("/vectors/normalize", {
2835
+ vector
2836
+ });
2837
+ return {
2838
+ result: { values: data.result, dimensions: data.result.length },
2839
+ operation: "normalization",
2840
+ tookMs: data.took_ms
2841
+ };
2842
+ }
2843
+ /**
2844
+ * Calculates the magnitude (length) of a vector
2845
+ * @param vector - Input vector
2846
+ * @returns Promise resolving to vector magnitude
2847
+ */
2848
+ async vectorMagnitude(vector) {
2849
+ const { data } = await this.httpClient.post("/vectors/magnitude", {
2850
+ vector
2851
+ });
2852
+ return {
2853
+ magnitude: data.magnitude,
2854
+ tookMs: data.took_ms
2855
+ };
2856
+ }
2857
+ // =================================================================
2858
+ // AUTHENTICATION & USER MANAGEMENT
2859
+ // =================================================================
2860
+ /**
2861
+ * Register a new user
2862
+ */
2863
+ async registerUser(request) {
2864
+ const { data } = await this.httpClient.post("/auth/register", {
2865
+ username: request.username,
2866
+ email: request.email,
2867
+ password: request.password
2868
+ });
2869
+ return data;
2870
+ }
2871
+ /**
2872
+ * Login with username and password
2873
+ */
2874
+ async login(request) {
2875
+ const { data } = await this.httpClient.post("/auth/login", {
2876
+ username: request.username,
2877
+ password: request.password
2878
+ });
2879
+ if (data.access_token) {
2880
+ this.config.jwtToken = data.access_token;
2881
+ this.httpClient.defaults.headers["Authorization"] = `Bearer ${data.access_token}`;
2882
+ delete this.httpClient.defaults.headers["X-API-Key"];
2883
+ }
2884
+ return data;
2885
+ }
2886
+ /**
2887
+ * Refresh JWT token
2888
+ */
2889
+ async refreshToken() {
2890
+ const { data } = await this.httpClient.post("/auth/refresh");
2891
+ if (data.access_token) {
2892
+ this.config.jwtToken = data.access_token;
2893
+ this.httpClient.defaults.headers["Authorization"] = `Bearer ${data.access_token}`;
2894
+ delete this.httpClient.defaults.headers["X-API-Key"];
2895
+ }
2896
+ return data;
2897
+ }
2898
+ /**
2899
+ * Set JWT token manually (useful after login)
2900
+ */
2901
+ setJWTToken(token) {
2902
+ this.config.jwtToken = token;
2903
+ this.httpClient.defaults.headers["Authorization"] = `Bearer ${token}`;
2904
+ delete this.httpClient.defaults.headers["X-API-Key"];
2905
+ }
2906
+ /**
2907
+ * Clear authentication (logout)
2908
+ */
2909
+ logout() {
2910
+ this.config.jwtToken = "";
2911
+ delete this.httpClient.defaults.headers["Authorization"];
2912
+ delete this.httpClient.defaults.headers["X-API-Key"];
2913
+ }
2914
+ // =================================================================
2915
+ // API KEY MANAGEMENT
2916
+ // =================================================================
2917
+ /**
2918
+ * Create a new API key
2919
+ */
2920
+ async createAPIKey(request) {
2921
+ const { data } = await this.httpClient.post("/api-keys", {
2922
+ name: request.name,
2923
+ permission: request.permission,
2924
+ expires_in_days: request.expires_in_days
2925
+ });
2926
+ return data;
2927
+ }
2928
+ /**
2929
+ * List all API keys
2930
+ */
2931
+ async listAPIKeys() {
2932
+ const { data } = await this.httpClient.get("/api-keys");
2933
+ return data;
2934
+ }
2935
+ /**
2936
+ * Get API key statistics
2937
+ */
2938
+ async getAPIKeyStats(keyId) {
2939
+ const { data } = await this.httpClient.get(`/api-keys/${keyId}/stats`);
2940
+ return data;
2941
+ }
2942
+ /**
2943
+ * Revoke (delete) an API key
2944
+ */
2945
+ async revokeAPIKey(keyId) {
2946
+ await this.httpClient.delete(`/api-keys/${keyId}`);
2947
+ }
2948
+ // =================================================================
2949
+ // MULTIMEDIA MANAGEMENT
2950
+ // =================================================================
2951
+ /**
2952
+ * Upload multimedia file to a document
2953
+ */
2954
+ async uploadMultimedia(collection, documentId, file, metadata) {
2955
+ let FormDataClass;
2956
+ try {
2957
+ FormDataClass = __require("form-data");
2958
+ } catch {
2959
+ FormDataClass = FormData;
2960
+ }
2961
+ const formData = new FormDataClass();
2962
+ if (Buffer.isBuffer(file)) {
2963
+ formData.append("file", file, { filename: "upload" });
2964
+ } else {
2965
+ formData.append("file", file);
2966
+ }
2967
+ if (metadata) {
2968
+ formData.append("metadata", JSON.stringify(metadata));
2969
+ }
2970
+ const headers = {};
2971
+ if (typeof formData.getHeaders === "function") {
2972
+ Object.assign(headers, formData.getHeaders());
2973
+ }
2974
+ const { data } = await this.httpClient.post(
2975
+ `/multimedia/${collection}/documents/${documentId}/multimedia`,
2976
+ formData,
2977
+ {
2978
+ headers
2979
+ }
2980
+ );
2981
+ return data;
2982
+ }
2983
+ /**
2984
+ * Get multimedia file URL (for viewing/downloading)
2985
+ */
2986
+ getMultimediaUrl(collection, documentId, multimediaId, download = false) {
2987
+ const protocol = this.config.useHttps ? "https" : "http";
2988
+ const baseUrl = `${protocol}://${this.config.host}:${this.config.port}/v1`;
2989
+ return `${baseUrl}/multimedia/${collection}/documents/${documentId}/multimedia/${multimediaId}${download ? "?download=true" : ""}`;
2990
+ }
2991
+ /**
2992
+ * Get multimedia thumbnail URL
2993
+ */
2994
+ getMultimediaThumbnailUrl(collection, documentId, multimediaId) {
2995
+ const protocol = this.config.useHttps ? "https" : "http";
2996
+ const baseUrl = `${protocol}://${this.config.host}:${this.config.port}/v1`;
2997
+ return `${baseUrl}/multimedia/${collection}/documents/${documentId}/multimedia/${multimediaId}/thumbnail`;
2998
+ }
2999
+ /**
3000
+ * List multimedia files in a document
3001
+ */
3002
+ async listMultimedia(collection, documentId, limit = 50, offset = 0) {
3003
+ const { data } = await this.httpClient.get(
3004
+ `/multimedia/${collection}/documents/${documentId}/multimedia?limit=${limit}&offset=${offset}`
3005
+ );
3006
+ return data;
3007
+ }
3008
+ /**
3009
+ * Get multimedia file information
3010
+ */
3011
+ async getMultimedia(collection, documentId, multimediaId) {
3012
+ const { data } = await this.httpClient.get(
3013
+ `/multimedia/${collection}/documents/${documentId}/multimedia/${multimediaId}`
3014
+ );
3015
+ return data;
3016
+ }
3017
+ /**
3018
+ * Delete multimedia file
3019
+ */
3020
+ async deleteMultimedia(collection, documentId, multimediaId) {
3021
+ await this.httpClient.delete(`/multimedia/${collection}/documents/${documentId}/multimedia/${multimediaId}`);
3022
+ }
3023
+ };
3024
+
3025
+ // src/index.ts
3026
+ import { z } from "zod";
3027
+ var VERSION = "0.1.0";
3028
+ export {
3029
+ AuthenticationError,
3030
+ AutoMLClient,
3031
+ AutoMLModel,
3032
+ BackupClient,
3033
+ BatchOperationError,
3034
+ Collection,
3035
+ ConnectionError,
3036
+ ImportExportClient,
3037
+ IntegrationClient,
3038
+ NLPClient,
3039
+ NotFoundError,
3040
+ RateLimitError,
3041
+ RecipeClient,
3042
+ SQLError,
3043
+ SchemaClient,
3044
+ ServerError,
3045
+ Subscription,
3046
+ SynapCores,
3047
+ SynapCoresError,
3048
+ TimeoutError,
3049
+ TransactionError,
3050
+ VERSION,
3051
+ ValidationError,
3052
+ VectorError,
3053
+ z
3054
+ };
3055
+ //# sourceMappingURL=index.mjs.map