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