@synapcores/sdk 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -1
- package/dist/index.d.mts +1024 -188
- package/dist/index.d.ts +1024 -188
- package/dist/index.js +1779 -893
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1770 -893
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs
CHANGED
|
@@ -30,13 +30,14 @@ var Subscription = class extends EventEmitter {
|
|
|
30
30
|
}
|
|
31
31
|
async createConnection() {
|
|
32
32
|
const client = this.collection.client;
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
33
|
+
const { token } = await client.createWsTicket();
|
|
34
|
+
const wsBase = client._getWsBaseUrl ? client._getWsBaseUrl() : (() => {
|
|
35
|
+
const cfg = client.config ?? client._getConfig();
|
|
36
|
+
const protocol = cfg.useHttps ? "wss" : "ws";
|
|
37
|
+
return `${protocol}://${cfg.host}:${cfg.port}`;
|
|
38
|
+
})();
|
|
39
|
+
const url = `${wsBase}/ws?token=${encodeURIComponent(token)}`;
|
|
40
|
+
this.ws = new WebSocket(url);
|
|
40
41
|
this.ws.on("open", () => {
|
|
41
42
|
this.reconnectAttempts = 0;
|
|
42
43
|
this.subscribe();
|
|
@@ -347,19 +348,14 @@ var AutoMLModel = class {
|
|
|
347
348
|
const isSingle = !Array.isArray(data);
|
|
348
349
|
const inputs = isSingle ? [data] : data;
|
|
349
350
|
const response = await this.client.synapCores._getHttpClient().post(
|
|
350
|
-
|
|
351
|
-
{
|
|
352
|
-
model_id: this.id,
|
|
353
|
-
inputs
|
|
354
|
-
}
|
|
351
|
+
`/automl/models/${this.id}/predict`,
|
|
352
|
+
{ inputs }
|
|
355
353
|
);
|
|
356
|
-
const predictions = response.data.predictions;
|
|
354
|
+
const predictions = response.data.predictions ?? response.data;
|
|
357
355
|
return isSingle ? predictions[0] : predictions;
|
|
358
356
|
}
|
|
359
357
|
async evaluate(testData, target) {
|
|
360
|
-
const payload = {
|
|
361
|
-
model_id: this.id
|
|
362
|
-
};
|
|
358
|
+
const payload = {};
|
|
363
359
|
if (typeof testData === "string") {
|
|
364
360
|
payload.collection = testData;
|
|
365
361
|
} else {
|
|
@@ -369,14 +365,14 @@ var AutoMLModel = class {
|
|
|
369
365
|
}
|
|
370
366
|
}
|
|
371
367
|
const { data } = await this.client.synapCores._getHttpClient().post(
|
|
372
|
-
|
|
368
|
+
`/automl/models/${this.id}/evaluate`,
|
|
373
369
|
payload
|
|
374
370
|
);
|
|
375
371
|
return data;
|
|
376
372
|
}
|
|
377
373
|
async delete() {
|
|
378
374
|
await this.client.synapCores._getHttpClient().delete(
|
|
379
|
-
`/
|
|
375
|
+
`/automl/models/${this.id}`
|
|
380
376
|
);
|
|
381
377
|
}
|
|
382
378
|
};
|
|
@@ -385,7 +381,7 @@ var AutoMLClient = class {
|
|
|
385
381
|
this.synapCores = synapCores;
|
|
386
382
|
}
|
|
387
383
|
async train(options) {
|
|
388
|
-
const { data } = await this.synapCores._getHttpClient().post("/
|
|
384
|
+
const { data } = await this.synapCores._getHttpClient().post("/automl/train", {
|
|
389
385
|
collection: options.collection,
|
|
390
386
|
target: options.target,
|
|
391
387
|
features: options.features,
|
|
@@ -402,15 +398,15 @@ var AutoMLClient = class {
|
|
|
402
398
|
task: data.task,
|
|
403
399
|
status: data.status,
|
|
404
400
|
accuracy: data.accuracy,
|
|
405
|
-
createdAt: new Date(data.created_at),
|
|
401
|
+
createdAt: new Date(data.created_at ?? Date.now()),
|
|
406
402
|
updatedAt: data.updated_at ? new Date(data.updated_at) : void 0,
|
|
407
|
-
config: data.config
|
|
403
|
+
config: data.config ?? {}
|
|
408
404
|
};
|
|
409
405
|
return new AutoMLModel(this, modelInfo);
|
|
410
406
|
}
|
|
411
407
|
async getModel(modelId) {
|
|
412
408
|
const { data } = await this.synapCores._getHttpClient().get(
|
|
413
|
-
`/
|
|
409
|
+
`/automl/models/${modelId}`
|
|
414
410
|
);
|
|
415
411
|
const modelInfo = {
|
|
416
412
|
id: data.id,
|
|
@@ -418,32 +414,35 @@ var AutoMLClient = class {
|
|
|
418
414
|
task: data.task,
|
|
419
415
|
status: data.status,
|
|
420
416
|
accuracy: data.accuracy,
|
|
421
|
-
createdAt: new Date(data.created_at),
|
|
417
|
+
createdAt: new Date(data.created_at ?? Date.now()),
|
|
422
418
|
updatedAt: data.updated_at ? new Date(data.updated_at) : void 0,
|
|
423
|
-
config: data.config
|
|
419
|
+
config: data.config ?? {}
|
|
424
420
|
};
|
|
425
421
|
return new AutoMLModel(this, modelInfo);
|
|
426
422
|
}
|
|
427
423
|
async listModels(filters) {
|
|
428
|
-
const { data } = await this.synapCores._getHttpClient().get("/
|
|
424
|
+
const { data } = await this.synapCores._getHttpClient().get("/automl/models", {
|
|
429
425
|
params: filters
|
|
430
426
|
});
|
|
431
|
-
return data.models.map((model) => ({
|
|
427
|
+
return (data.models ?? data ?? []).map((model) => ({
|
|
432
428
|
id: model.id,
|
|
433
429
|
name: model.name,
|
|
434
430
|
task: model.task,
|
|
435
431
|
status: model.status,
|
|
436
432
|
accuracy: model.accuracy,
|
|
437
|
-
createdAt: new Date(model.created_at),
|
|
433
|
+
createdAt: new Date(model.created_at ?? Date.now()),
|
|
438
434
|
updatedAt: model.updated_at ? new Date(model.updated_at) : void 0,
|
|
439
|
-
config: model.config
|
|
435
|
+
config: model.config ?? {}
|
|
440
436
|
}));
|
|
441
437
|
}
|
|
442
438
|
/**
|
|
443
|
-
* Start async training job
|
|
439
|
+
* Start async training job.
|
|
440
|
+
*
|
|
441
|
+
* In v1.5.0-ce there is no separate /train/async endpoint — /automl/train
|
|
442
|
+
* itself returns a job descriptor when the training is long-running.
|
|
444
443
|
*/
|
|
445
444
|
async trainAsync(options) {
|
|
446
|
-
const { data } = await this.synapCores._getHttpClient().post("/
|
|
445
|
+
const { data } = await this.synapCores._getHttpClient().post("/automl/train", {
|
|
447
446
|
collection: options.collection,
|
|
448
447
|
target: options.target,
|
|
449
448
|
features: options.features,
|
|
@@ -453,49 +452,20 @@ var AutoMLClient = class {
|
|
|
453
452
|
validation_split: options.validationSplit || 0.2,
|
|
454
453
|
max_trials: options.maxTrials || 10,
|
|
455
454
|
timeout_minutes: options.timeoutMinutes || 60,
|
|
455
|
+
async: true,
|
|
456
456
|
callback_url: options.callback_url,
|
|
457
457
|
webhook_url: options.webhook_url
|
|
458
458
|
});
|
|
459
|
-
return
|
|
460
|
-
id: data.id || data.job_id,
|
|
461
|
-
name: data.name,
|
|
462
|
-
status: data.status,
|
|
463
|
-
progress: data.progress || 0,
|
|
464
|
-
phase: data.phase,
|
|
465
|
-
task: data.task,
|
|
466
|
-
current_trial: data.current_trial,
|
|
467
|
-
total_trials: data.total_trials || options.maxTrials || 10,
|
|
468
|
-
best_accuracy: data.best_accuracy,
|
|
469
|
-
eta_ms: data.eta_ms || data.estimated_time_remaining_ms,
|
|
470
|
-
error: data.error,
|
|
471
|
-
started_at: new Date(data.started_at || Date.now()),
|
|
472
|
-
completed_at: data.completed_at ? new Date(data.completed_at) : void 0,
|
|
473
|
-
model_id: data.model_id
|
|
474
|
-
};
|
|
459
|
+
return this.mapTrainingJob(data, options.maxTrials || 10);
|
|
475
460
|
}
|
|
476
461
|
/**
|
|
477
462
|
* Get training job status
|
|
478
463
|
*/
|
|
479
464
|
async getTrainingJob(jobId) {
|
|
480
465
|
const { data } = await this.synapCores._getHttpClient().get(
|
|
481
|
-
`/
|
|
466
|
+
`/automl/jobs/${jobId}`
|
|
482
467
|
);
|
|
483
|
-
return
|
|
484
|
-
id: data.id || jobId,
|
|
485
|
-
name: data.name,
|
|
486
|
-
status: data.status,
|
|
487
|
-
progress: data.progress || 0,
|
|
488
|
-
phase: data.phase,
|
|
489
|
-
task: data.task,
|
|
490
|
-
current_trial: data.current_trial,
|
|
491
|
-
total_trials: data.total_trials,
|
|
492
|
-
best_accuracy: data.best_accuracy,
|
|
493
|
-
eta_ms: data.eta_ms || data.estimated_time_remaining_ms,
|
|
494
|
-
error: data.error,
|
|
495
|
-
started_at: new Date(data.started_at),
|
|
496
|
-
completed_at: data.completed_at ? new Date(data.completed_at) : void 0,
|
|
497
|
-
model_id: data.model_id
|
|
498
|
-
};
|
|
468
|
+
return this.mapTrainingJob(data);
|
|
499
469
|
}
|
|
500
470
|
/**
|
|
501
471
|
* List training jobs
|
|
@@ -505,45 +475,36 @@ var AutoMLClient = class {
|
|
|
505
475
|
if (options.status) params.append("status", options.status);
|
|
506
476
|
if (options.page) params.append("page", options.page.toString());
|
|
507
477
|
if (options.page_size) params.append("page_size", options.page_size.toString());
|
|
478
|
+
const qs = params.toString();
|
|
508
479
|
const { data } = await this.synapCores._getHttpClient().get(
|
|
509
|
-
`/
|
|
480
|
+
`/automl/jobs${qs ? `?${qs}` : ""}`
|
|
510
481
|
);
|
|
511
|
-
return (data.jobs
|
|
512
|
-
id: job.id,
|
|
513
|
-
name: job.name,
|
|
514
|
-
status: job.status,
|
|
515
|
-
progress: job.progress || 0,
|
|
516
|
-
phase: job.phase,
|
|
517
|
-
task: job.task,
|
|
518
|
-
current_trial: job.current_trial,
|
|
519
|
-
total_trials: job.total_trials,
|
|
520
|
-
best_accuracy: job.best_accuracy,
|
|
521
|
-
eta_ms: job.eta_ms || job.estimated_time_remaining_ms,
|
|
522
|
-
error: job.error,
|
|
523
|
-
started_at: new Date(job.started_at),
|
|
524
|
-
completed_at: job.completed_at ? new Date(job.completed_at) : void 0,
|
|
525
|
-
model_id: job.model_id
|
|
526
|
-
}));
|
|
482
|
+
return (data.jobs ?? data ?? []).map((job) => this.mapTrainingJob(job));
|
|
527
483
|
}
|
|
528
484
|
/**
|
|
529
|
-
* Cancel a training job
|
|
485
|
+
* Cancel/stop a training job
|
|
530
486
|
*/
|
|
531
487
|
async cancelTrainingJob(jobId) {
|
|
532
|
-
await this.synapCores._getHttpClient().post(`/
|
|
488
|
+
await this.synapCores._getHttpClient().post(`/automl/jobs/${jobId}/stop`);
|
|
533
489
|
}
|
|
534
490
|
/**
|
|
535
|
-
* Get training metrics for a job
|
|
491
|
+
* Get training metrics for a job.
|
|
492
|
+
*
|
|
493
|
+
* v1.5.0-ce: gateway no longer has a dedicated /metrics route — metrics
|
|
494
|
+
* (when available) ship inside the /automl/jobs/:id payload as
|
|
495
|
+
* `metrics` or `trial_metrics`. We just unwrap that field here.
|
|
536
496
|
*/
|
|
537
497
|
async getTrainingMetrics(jobId) {
|
|
538
498
|
const { data } = await this.synapCores._getHttpClient().get(
|
|
539
|
-
`/
|
|
499
|
+
`/automl/jobs/${jobId}`
|
|
540
500
|
);
|
|
541
|
-
|
|
501
|
+
const metrics = data.metrics ?? data.trial_metrics ?? [];
|
|
502
|
+
return metrics.map((metric) => ({
|
|
542
503
|
trial: metric.trial,
|
|
543
504
|
accuracy: metric.accuracy,
|
|
544
505
|
loss: metric.loss,
|
|
545
506
|
metrics: metric.metrics,
|
|
546
|
-
timestamp: new Date(metric.timestamp)
|
|
507
|
+
timestamp: new Date(metric.timestamp ?? Date.now())
|
|
547
508
|
}));
|
|
548
509
|
}
|
|
549
510
|
/**
|
|
@@ -576,6 +537,24 @@ var AutoMLClient = class {
|
|
|
576
537
|
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
577
538
|
}
|
|
578
539
|
}
|
|
540
|
+
mapTrainingJob(data, fallbackMaxTrials) {
|
|
541
|
+
return {
|
|
542
|
+
id: data.id ?? data.job_id,
|
|
543
|
+
name: data.name,
|
|
544
|
+
status: data.status,
|
|
545
|
+
progress: data.progress ?? 0,
|
|
546
|
+
phase: data.phase,
|
|
547
|
+
task: data.task,
|
|
548
|
+
current_trial: data.current_trial,
|
|
549
|
+
total_trials: data.total_trials ?? fallbackMaxTrials,
|
|
550
|
+
best_accuracy: data.best_accuracy,
|
|
551
|
+
eta_ms: data.eta_ms ?? data.estimated_time_remaining_ms,
|
|
552
|
+
error: data.error,
|
|
553
|
+
started_at: new Date(data.started_at ?? Date.now()),
|
|
554
|
+
completed_at: data.completed_at ? new Date(data.completed_at) : void 0,
|
|
555
|
+
model_id: data.model_id
|
|
556
|
+
};
|
|
557
|
+
}
|
|
579
558
|
};
|
|
580
559
|
|
|
581
560
|
// src/nlp.ts
|
|
@@ -583,32 +562,67 @@ var NLPClient = class {
|
|
|
583
562
|
constructor(synapCores) {
|
|
584
563
|
this.synapCores = synapCores;
|
|
585
564
|
}
|
|
565
|
+
/**
|
|
566
|
+
* Run multiple NLP tasks in parallel and stitch them into a single
|
|
567
|
+
* NLPAnalysis (or array of them, matching the input shape).
|
|
568
|
+
*/
|
|
586
569
|
async analyze(options) {
|
|
587
570
|
const isBatch = Array.isArray(options.text);
|
|
588
571
|
const texts = isBatch ? options.text : [options.text];
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
const
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
572
|
+
const tasks = options.tasks || ["sentiment", "entities", "summarize"];
|
|
573
|
+
const http = this.synapCores._getHttpClient();
|
|
574
|
+
const wantSentiment = tasks.includes("sentiment");
|
|
575
|
+
const wantEntities = tasks.includes("entities");
|
|
576
|
+
const wantSummarize = tasks.includes("summarize") || tasks.includes("summary");
|
|
577
|
+
const wantKeywords = tasks.includes("keywords");
|
|
578
|
+
const results = await Promise.all(
|
|
579
|
+
texts.map(async (text) => {
|
|
580
|
+
const out = {};
|
|
581
|
+
const calls = [];
|
|
582
|
+
if (wantSentiment) {
|
|
583
|
+
calls.push(
|
|
584
|
+
http.post("/ai/sentiment", { texts: [text], language: options.language }).then(({ data }) => {
|
|
585
|
+
const s = (data.sentiments ?? [])[0] ?? data.sentiment ?? data;
|
|
586
|
+
if (s) {
|
|
587
|
+
out.sentiment = {
|
|
588
|
+
label: s.label,
|
|
589
|
+
score: s.score,
|
|
590
|
+
confidence: s.confidence
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
}).catch(() => void 0)
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
if (wantEntities) {
|
|
597
|
+
calls.push(
|
|
598
|
+
http.post("/ai/entities", { text, language: options.language }).then(({ data }) => {
|
|
599
|
+
const arr = data.entities ?? [];
|
|
600
|
+
out.entities = arr.map((e) => ({
|
|
601
|
+
text: e.text,
|
|
602
|
+
type: e.type,
|
|
603
|
+
start: e.start,
|
|
604
|
+
end: e.end,
|
|
605
|
+
score: e.score
|
|
606
|
+
}));
|
|
607
|
+
}).catch(() => void 0)
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
if (wantSummarize) {
|
|
611
|
+
calls.push(
|
|
612
|
+
http.post("/ai/summarize", { text }).then(({ data }) => {
|
|
613
|
+
out.summary = data.summary;
|
|
614
|
+
}).catch(() => void 0)
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
if (wantKeywords) {
|
|
618
|
+
out.keywords = void 0;
|
|
619
|
+
}
|
|
620
|
+
await Promise.all(calls);
|
|
621
|
+
return out;
|
|
622
|
+
})
|
|
623
|
+
);
|
|
624
|
+
if (isBatch) return results;
|
|
625
|
+
return results[0] ?? {};
|
|
612
626
|
}
|
|
613
627
|
async summarize(options) {
|
|
614
628
|
const { data } = await this.synapCores._getHttpClient().post("/ai/summarize", {
|
|
@@ -623,7 +637,7 @@ var NLPClient = class {
|
|
|
623
637
|
text,
|
|
624
638
|
entity_types: entityTypes
|
|
625
639
|
});
|
|
626
|
-
return data.entities.map((e) => ({
|
|
640
|
+
return (data.entities ?? []).map((e) => ({
|
|
627
641
|
text: e.text,
|
|
628
642
|
type: e.type,
|
|
629
643
|
start: e.start,
|
|
@@ -637,7 +651,7 @@ var NLPClient = class {
|
|
|
637
651
|
const { data } = await this.synapCores._getHttpClient().post("/ai/sentiment", {
|
|
638
652
|
texts
|
|
639
653
|
});
|
|
640
|
-
const results = data.sentiments.map((s) => ({
|
|
654
|
+
const results = (data.sentiments ?? []).map((s) => ({
|
|
641
655
|
label: s.label,
|
|
642
656
|
score: s.score,
|
|
643
657
|
confidence: s.confidence
|
|
@@ -654,6 +668,22 @@ var NLPClient = class {
|
|
|
654
668
|
});
|
|
655
669
|
return isBatch ? data.classifications : data.classifications[0];
|
|
656
670
|
}
|
|
671
|
+
/**
|
|
672
|
+
* Question-answering against an optional context window.
|
|
673
|
+
*/
|
|
674
|
+
async qa(question, context, opts = {}) {
|
|
675
|
+
const { data } = await this.synapCores._getHttpClient().post("/ai/qa", {
|
|
676
|
+
question,
|
|
677
|
+
context,
|
|
678
|
+
max_answer_tokens: opts.maxAnswerTokens
|
|
679
|
+
});
|
|
680
|
+
return {
|
|
681
|
+
answer: data.answer ?? data.text ?? "",
|
|
682
|
+
score: data.score ?? data.confidence,
|
|
683
|
+
start: data.start,
|
|
684
|
+
end: data.end
|
|
685
|
+
};
|
|
686
|
+
}
|
|
657
687
|
};
|
|
658
688
|
|
|
659
689
|
// src/recipes.ts
|
|
@@ -797,11 +827,142 @@ var RecipeClient = class {
|
|
|
797
827
|
};
|
|
798
828
|
}
|
|
799
829
|
/**
|
|
800
|
-
* List available recipe categories
|
|
830
|
+
* List available recipe categories with counts.
|
|
831
|
+
*
|
|
832
|
+
* v0.2.0: gateway path is /recipes/categories/counts.
|
|
833
|
+
* Returns the array of category names; for the {category, count}
|
|
834
|
+
* payload use `listCategoriesWithCounts`.
|
|
801
835
|
*/
|
|
802
836
|
async listCategories() {
|
|
803
|
-
const
|
|
804
|
-
return data.
|
|
837
|
+
const data = await this.listCategoriesWithCounts();
|
|
838
|
+
return data.map((c) => c.category);
|
|
839
|
+
}
|
|
840
|
+
async listCategoriesWithCounts() {
|
|
841
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
842
|
+
"/recipes/categories/counts"
|
|
843
|
+
);
|
|
844
|
+
const arr = data.categories ?? data ?? [];
|
|
845
|
+
return arr.map((c) => ({
|
|
846
|
+
category: c.category ?? c.name ?? c,
|
|
847
|
+
count: c.count ?? c.recipe_count ?? 0
|
|
848
|
+
}));
|
|
849
|
+
}
|
|
850
|
+
/**
|
|
851
|
+
* Validate a recipe payload before saving/executing.
|
|
852
|
+
*/
|
|
853
|
+
async validate(body) {
|
|
854
|
+
const { data } = await this.synapCores._getHttpClient().post("/recipes/validate", body);
|
|
855
|
+
return {
|
|
856
|
+
is_valid: data.is_valid ?? data.valid ?? false,
|
|
857
|
+
errors: data.errors ?? [],
|
|
858
|
+
warnings: data.warnings ?? []
|
|
859
|
+
};
|
|
860
|
+
}
|
|
861
|
+
/**
|
|
862
|
+
* Get execution history for a specific recipe.
|
|
863
|
+
*/
|
|
864
|
+
async getHistory(id) {
|
|
865
|
+
const { data } = await this.synapCores._getHttpClient().get(`/recipes/${id}/history`);
|
|
866
|
+
const arr = data.history ?? data.executions ?? data ?? [];
|
|
867
|
+
return arr.map((row) => ({
|
|
868
|
+
id: row.id ?? row.execution_id ?? "",
|
|
869
|
+
success: row.success ?? row.status === "completed",
|
|
870
|
+
results: row.results,
|
|
871
|
+
error: row.error,
|
|
872
|
+
execution_time_ms: row.execution_time_ms ?? row.took_ms ?? 0,
|
|
873
|
+
statements_executed: row.statements_executed ?? 0
|
|
874
|
+
}));
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* List built-in / shared recipe templates.
|
|
878
|
+
*/
|
|
879
|
+
async listTemplates() {
|
|
880
|
+
const { data } = await this.synapCores._getHttpClient().get("/recipes/templates");
|
|
881
|
+
return (data.templates ?? data ?? []).map((t) => ({
|
|
882
|
+
id: t.id,
|
|
883
|
+
name: t.name,
|
|
884
|
+
description: t.description ?? "",
|
|
885
|
+
category: t.category ?? "template",
|
|
886
|
+
tags: t.tags ?? [],
|
|
887
|
+
created_at: new Date(t.created_at ?? Date.now()),
|
|
888
|
+
updated_at: new Date(t.updated_at ?? t.created_at ?? Date.now()),
|
|
889
|
+
author: t.author,
|
|
890
|
+
execution_count: t.execution_count
|
|
891
|
+
}));
|
|
892
|
+
}
|
|
893
|
+
/**
|
|
894
|
+
* Get a specific recipe template.
|
|
895
|
+
*/
|
|
896
|
+
async getTemplate(id) {
|
|
897
|
+
const { data } = await this.synapCores._getHttpClient().get(`/recipes/templates/${id}`);
|
|
898
|
+
return {
|
|
899
|
+
id: data.id,
|
|
900
|
+
name: data.name,
|
|
901
|
+
description: data.description ?? "",
|
|
902
|
+
category: data.category ?? "template",
|
|
903
|
+
content: data.content ?? "",
|
|
904
|
+
tags: data.tags ?? [],
|
|
905
|
+
parameters: data.parameters ?? [],
|
|
906
|
+
created_at: new Date(data.created_at ?? Date.now()),
|
|
907
|
+
updated_at: new Date(data.updated_at ?? data.created_at ?? Date.now()),
|
|
908
|
+
author: data.author,
|
|
909
|
+
execution_count: data.execution_count,
|
|
910
|
+
version: data.version
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
/**
|
|
914
|
+
* Execute a recipe template with a parameter set.
|
|
915
|
+
*/
|
|
916
|
+
async executeTemplate(id, params = {}) {
|
|
917
|
+
const { data } = await this.synapCores._getHttpClient().post(
|
|
918
|
+
`/recipes/templates/${id}/execute`,
|
|
919
|
+
{ parameters: params }
|
|
920
|
+
);
|
|
921
|
+
return {
|
|
922
|
+
id: data.id ?? data.execution_id ?? "",
|
|
923
|
+
success: data.success ?? false,
|
|
924
|
+
results: data.results,
|
|
925
|
+
error: data.error,
|
|
926
|
+
execution_time_ms: data.execution_time_ms ?? data.took_ms ?? 0,
|
|
927
|
+
statements_executed: data.statements_executed ?? 0
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
/**
|
|
931
|
+
* List all recipe executions across recipes.
|
|
932
|
+
*/
|
|
933
|
+
async listExecutions(options = {}) {
|
|
934
|
+
const params = new URLSearchParams();
|
|
935
|
+
if (options.limit) params.append("limit", options.limit.toString());
|
|
936
|
+
if (options.status) params.append("status", options.status);
|
|
937
|
+
const qs = params.toString();
|
|
938
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
939
|
+
`/recipes/executions${qs ? `?${qs}` : ""}`
|
|
940
|
+
);
|
|
941
|
+
const arr = data.executions ?? data ?? [];
|
|
942
|
+
return arr.map((row) => ({
|
|
943
|
+
id: row.id ?? row.execution_id ?? "",
|
|
944
|
+
success: row.success ?? row.status === "completed",
|
|
945
|
+
results: row.results,
|
|
946
|
+
error: row.error,
|
|
947
|
+
execution_time_ms: row.execution_time_ms ?? row.took_ms ?? 0,
|
|
948
|
+
statements_executed: row.statements_executed ?? 0
|
|
949
|
+
}));
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* Get a single execution by ID.
|
|
953
|
+
*/
|
|
954
|
+
async getExecution(id) {
|
|
955
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
956
|
+
`/recipes/executions/${id}`
|
|
957
|
+
);
|
|
958
|
+
return {
|
|
959
|
+
id: data.id ?? id,
|
|
960
|
+
success: data.success ?? data.status === "completed",
|
|
961
|
+
results: data.results,
|
|
962
|
+
error: data.error,
|
|
963
|
+
execution_time_ms: data.execution_time_ms ?? data.took_ms ?? 0,
|
|
964
|
+
statements_executed: data.statements_executed ?? 0
|
|
965
|
+
};
|
|
805
966
|
}
|
|
806
967
|
};
|
|
807
968
|
|
|
@@ -811,17 +972,30 @@ var SchemaClient = class {
|
|
|
811
972
|
this.synapCores = synapCores;
|
|
812
973
|
}
|
|
813
974
|
/**
|
|
814
|
-
* List all
|
|
975
|
+
* List all databases visible to the current authentication context.
|
|
976
|
+
*/
|
|
977
|
+
async listDatabases() {
|
|
978
|
+
const { data } = await this.synapCores._getHttpClient().get("/schema/databases");
|
|
979
|
+
return (data.databases ?? data ?? []).map((db) => ({
|
|
980
|
+
name: db.name,
|
|
981
|
+
table_count: db.table_count,
|
|
982
|
+
size_bytes: db.size_bytes,
|
|
983
|
+
is_default: db.is_default
|
|
984
|
+
}));
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* List all tables in the current database.
|
|
815
988
|
*/
|
|
816
989
|
async listTables(options = {}) {
|
|
817
990
|
const params = new URLSearchParams();
|
|
818
991
|
if (options.includeSystem) {
|
|
819
992
|
params.append("include_system", "true");
|
|
820
993
|
}
|
|
994
|
+
const qs = params.toString();
|
|
821
995
|
const { data } = await this.synapCores._getHttpClient().get(
|
|
822
|
-
`/schema/tables
|
|
996
|
+
`/schema/tables${qs ? `?${qs}` : ""}`
|
|
823
997
|
);
|
|
824
|
-
return (data.tables || data).map((table) => ({
|
|
998
|
+
return (data.tables || data || []).map((table) => ({
|
|
825
999
|
name: table.name,
|
|
826
1000
|
type: table.type || "table",
|
|
827
1001
|
column_count: table.column_count || 0,
|
|
@@ -833,24 +1007,33 @@ var SchemaClient = class {
|
|
|
833
1007
|
}));
|
|
834
1008
|
}
|
|
835
1009
|
/**
|
|
836
|
-
* Get complete schema for a specific table
|
|
1010
|
+
* Get complete schema for a specific table.
|
|
1011
|
+
*
|
|
1012
|
+
* Combines /schema/tables/:t with /schema/tables/:t/columns and
|
|
1013
|
+
* /schema/tables/:t/indexes side-channels because the table-only payload
|
|
1014
|
+
* does not always include columns and indexes inline.
|
|
837
1015
|
*/
|
|
838
1016
|
async getTable(tableName) {
|
|
839
|
-
const
|
|
840
|
-
`/schema/tables/${tableName}`
|
|
841
|
-
|
|
1017
|
+
const [tableRes, colsRes, idxRes] = await Promise.all([
|
|
1018
|
+
this.synapCores._getHttpClient().get(`/schema/tables/${tableName}`),
|
|
1019
|
+
this.synapCores._getHttpClient().get(`/schema/tables/${tableName}/columns`),
|
|
1020
|
+
this.synapCores._getHttpClient().get(`/schema/tables/${tableName}/indexes`)
|
|
1021
|
+
]);
|
|
1022
|
+
const table = tableRes.data ?? {};
|
|
1023
|
+
const columns = colsRes.data?.columns ?? colsRes.data ?? [];
|
|
1024
|
+
const indexes = idxRes.data?.indexes ?? idxRes.data ?? [];
|
|
842
1025
|
return {
|
|
843
1026
|
table: {
|
|
844
|
-
name:
|
|
845
|
-
type:
|
|
846
|
-
column_count:
|
|
847
|
-
row_count:
|
|
848
|
-
size_bytes:
|
|
849
|
-
created_at:
|
|
850
|
-
updated_at:
|
|
851
|
-
comment:
|
|
1027
|
+
name: table.name ?? tableName,
|
|
1028
|
+
type: table.type || "table",
|
|
1029
|
+
column_count: columns.length,
|
|
1030
|
+
row_count: table.row_count,
|
|
1031
|
+
size_bytes: table.size_bytes,
|
|
1032
|
+
created_at: table.created_at ? new Date(table.created_at) : void 0,
|
|
1033
|
+
updated_at: table.updated_at ? new Date(table.updated_at) : void 0,
|
|
1034
|
+
comment: table.comment
|
|
852
1035
|
},
|
|
853
|
-
columns:
|
|
1036
|
+
columns: columns.map((col) => ({
|
|
854
1037
|
name: col.name,
|
|
855
1038
|
data_type: col.data_type || col.type,
|
|
856
1039
|
nullable: col.nullable !== false,
|
|
@@ -862,7 +1045,7 @@ var SchemaClient = class {
|
|
|
862
1045
|
comment: col.comment,
|
|
863
1046
|
ordinal_position: col.ordinal_position || col.position
|
|
864
1047
|
})),
|
|
865
|
-
indexes:
|
|
1048
|
+
indexes: indexes.map((idx) => ({
|
|
866
1049
|
name: idx.name,
|
|
867
1050
|
table: idx.table || tableName,
|
|
868
1051
|
type: idx.type || "btree",
|
|
@@ -872,8 +1055,8 @@ var SchemaClient = class {
|
|
|
872
1055
|
size_bytes: idx.size_bytes,
|
|
873
1056
|
created_at: idx.created_at ? new Date(idx.created_at) : void 0
|
|
874
1057
|
})),
|
|
875
|
-
constraints:
|
|
876
|
-
relationships: (
|
|
1058
|
+
constraints: table.constraints || [],
|
|
1059
|
+
relationships: (table.relationships || []).map((rel) => ({
|
|
877
1060
|
type: rel.type,
|
|
878
1061
|
from_table: rel.from_table || rel.source_table,
|
|
879
1062
|
from_column: rel.from_column || rel.source_column,
|
|
@@ -884,106 +1067,186 @@ var SchemaClient = class {
|
|
|
884
1067
|
};
|
|
885
1068
|
}
|
|
886
1069
|
/**
|
|
887
|
-
* Get columns for a specific table
|
|
1070
|
+
* Get columns for a specific table.
|
|
888
1071
|
*/
|
|
889
1072
|
async getColumns(tableName) {
|
|
890
|
-
const
|
|
891
|
-
|
|
1073
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
1074
|
+
`/schema/tables/${tableName}/columns`
|
|
1075
|
+
);
|
|
1076
|
+
const cols = data.columns ?? data ?? [];
|
|
1077
|
+
return cols.map((col) => ({
|
|
1078
|
+
name: col.name,
|
|
1079
|
+
data_type: col.data_type || col.type,
|
|
1080
|
+
nullable: col.nullable !== false,
|
|
1081
|
+
default_value: col.default_value || col.default,
|
|
1082
|
+
is_primary_key: col.is_primary_key || col.primary_key,
|
|
1083
|
+
is_unique: col.is_unique || col.unique,
|
|
1084
|
+
is_indexed: col.is_indexed || col.indexed,
|
|
1085
|
+
foreign_key: col.foreign_key,
|
|
1086
|
+
comment: col.comment,
|
|
1087
|
+
ordinal_position: col.ordinal_position || col.position
|
|
1088
|
+
}));
|
|
892
1089
|
}
|
|
893
1090
|
/**
|
|
894
|
-
* Get indexes for a specific table
|
|
1091
|
+
* Get indexes for a specific table.
|
|
895
1092
|
*/
|
|
896
1093
|
async getIndexes(tableName) {
|
|
897
|
-
const
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
to_column: rel.to_column || rel.target_column,
|
|
911
|
-
name: rel.name
|
|
1094
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
1095
|
+
`/schema/tables/${tableName}/indexes`
|
|
1096
|
+
);
|
|
1097
|
+
const idxs = data.indexes ?? data ?? [];
|
|
1098
|
+
return idxs.map((idx) => ({
|
|
1099
|
+
name: idx.name,
|
|
1100
|
+
table: idx.table || tableName,
|
|
1101
|
+
type: idx.type || "btree",
|
|
1102
|
+
columns: idx.columns || [],
|
|
1103
|
+
is_unique: idx.is_unique || idx.unique || false,
|
|
1104
|
+
is_primary: idx.is_primary || idx.primary || false,
|
|
1105
|
+
size_bytes: idx.size_bytes,
|
|
1106
|
+
created_at: idx.created_at ? new Date(idx.created_at) : void 0
|
|
912
1107
|
}));
|
|
913
1108
|
}
|
|
914
1109
|
/**
|
|
915
|
-
*
|
|
1110
|
+
* Preview rows from a table without writing SQL.
|
|
1111
|
+
*
|
|
1112
|
+
* GET /schema/tables/:t/data?limit=&offset=
|
|
916
1113
|
*/
|
|
917
|
-
async
|
|
918
|
-
const
|
|
1114
|
+
async previewTable(tableName, opts = {}) {
|
|
1115
|
+
const params = new URLSearchParams();
|
|
1116
|
+
if (opts.limit !== void 0) params.append("limit", String(opts.limit));
|
|
1117
|
+
if (opts.offset !== void 0) params.append("offset", String(opts.offset));
|
|
1118
|
+
const qs = params.toString();
|
|
1119
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
1120
|
+
`/schema/tables/${tableName}/data${qs ? `?${qs}` : ""}`
|
|
1121
|
+
);
|
|
919
1122
|
return {
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
relationship_count: data.relationship_count || 0,
|
|
924
|
-
total_size_bytes: data.total_size_bytes || 0,
|
|
925
|
-
total_rows: data.total_rows || 0,
|
|
926
|
-
version: data.version,
|
|
927
|
-
analyzed_at: data.analyzed_at ? new Date(data.analyzed_at) : void 0
|
|
1123
|
+
columns: data.columns ?? [],
|
|
1124
|
+
rows: data.rows ?? data.data ?? [],
|
|
1125
|
+
total_rows: data.total_rows ?? data.total
|
|
928
1126
|
};
|
|
929
1127
|
}
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
}
|
|
1128
|
+
};
|
|
1129
|
+
|
|
1130
|
+
// src/errors.ts
|
|
1131
|
+
var SynapCoresError = class _SynapCoresError extends Error {
|
|
1132
|
+
constructor(message, code, details) {
|
|
1133
|
+
super(message);
|
|
1134
|
+
this.name = "SynapCoresError";
|
|
1135
|
+
this.code = code;
|
|
1136
|
+
this.details = details;
|
|
1137
|
+
if (Error.captureStackTrace) {
|
|
1138
|
+
Error.captureStackTrace(this, _SynapCoresError);
|
|
1139
|
+
}
|
|
942
1140
|
}
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
schema1,
|
|
949
|
-
schema2
|
|
950
|
-
});
|
|
951
|
-
return {
|
|
952
|
-
differences: data.differences || [],
|
|
953
|
-
added: data.added || [],
|
|
954
|
-
removed: data.removed || [],
|
|
955
|
-
modified: data.modified || []
|
|
956
|
-
};
|
|
1141
|
+
};
|
|
1142
|
+
var ConnectionError = class extends SynapCoresError {
|
|
1143
|
+
constructor(message, details) {
|
|
1144
|
+
super(message, "CONNECTION_ERROR", details);
|
|
1145
|
+
this.name = "ConnectionError";
|
|
957
1146
|
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
`/schema/tables/${tableName}/ddl`
|
|
964
|
-
);
|
|
965
|
-
return data.ddl || data.sql;
|
|
1147
|
+
};
|
|
1148
|
+
var AuthenticationError = class extends SynapCoresError {
|
|
1149
|
+
constructor(message, details) {
|
|
1150
|
+
super(message, "AUTH_ERROR", details);
|
|
1151
|
+
this.name = "AuthenticationError";
|
|
966
1152
|
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
1153
|
+
};
|
|
1154
|
+
var ValidationError = class extends SynapCoresError {
|
|
1155
|
+
constructor(message, details) {
|
|
1156
|
+
super(message, "VALIDATION_ERROR", details);
|
|
1157
|
+
this.name = "ValidationError";
|
|
1158
|
+
}
|
|
1159
|
+
};
|
|
1160
|
+
var NotFoundError = class extends SynapCoresError {
|
|
1161
|
+
constructor(message, details) {
|
|
1162
|
+
super(message, "NOT_FOUND", details);
|
|
1163
|
+
this.name = "NotFoundError";
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
var ServerError = class extends SynapCoresError {
|
|
1167
|
+
constructor(message, details) {
|
|
1168
|
+
super(message, "SERVER_ERROR", details);
|
|
1169
|
+
this.name = "ServerError";
|
|
1170
|
+
}
|
|
1171
|
+
};
|
|
1172
|
+
var TimeoutError = class extends SynapCoresError {
|
|
1173
|
+
constructor(message, details) {
|
|
1174
|
+
super(message, "TIMEOUT_ERROR", details);
|
|
1175
|
+
this.name = "TimeoutError";
|
|
1176
|
+
}
|
|
1177
|
+
};
|
|
1178
|
+
var RateLimitError = class extends SynapCoresError {
|
|
1179
|
+
constructor(message, retryAfter, details) {
|
|
1180
|
+
super(message, "RATE_LIMIT_ERROR", details);
|
|
1181
|
+
this.name = "RateLimitError";
|
|
1182
|
+
this.retryAfter = retryAfter;
|
|
1183
|
+
}
|
|
1184
|
+
};
|
|
1185
|
+
var SQLError = class extends SynapCoresError {
|
|
1186
|
+
constructor(message, code, severity = "ERROR", position, hint, detail, details) {
|
|
1187
|
+
super(message, code, details);
|
|
1188
|
+
this.name = "SQLError";
|
|
1189
|
+
this.severity = severity;
|
|
1190
|
+
this.position = position;
|
|
1191
|
+
this.hint = hint;
|
|
1192
|
+
this.detail = detail;
|
|
1193
|
+
}
|
|
1194
|
+
};
|
|
1195
|
+
var VectorError = class extends SynapCoresError {
|
|
1196
|
+
constructor(message, code, vectorDimensions, expectedDimensions, operation, details) {
|
|
1197
|
+
super(message, code, details);
|
|
1198
|
+
this.name = "VectorError";
|
|
1199
|
+
this.vectorDimensions = vectorDimensions;
|
|
1200
|
+
this.expectedDimensions = expectedDimensions;
|
|
1201
|
+
this.operation = operation;
|
|
1202
|
+
}
|
|
1203
|
+
};
|
|
1204
|
+
var TransactionError = class extends SynapCoresError {
|
|
1205
|
+
constructor(message, code, transactionId, transactionState, details) {
|
|
1206
|
+
super(message, code, details);
|
|
1207
|
+
this.name = "TransactionError";
|
|
1208
|
+
this.transactionId = transactionId;
|
|
1209
|
+
this.transactionState = transactionState;
|
|
1210
|
+
}
|
|
1211
|
+
};
|
|
1212
|
+
var BatchOperationError = class extends SynapCoresError {
|
|
1213
|
+
constructor(message, code, failedItems, totalProcessed, successfulCount, details) {
|
|
1214
|
+
super(message, code, details);
|
|
1215
|
+
this.name = "BatchOperationError";
|
|
1216
|
+
this.failedItems = failedItems;
|
|
1217
|
+
this.totalProcessed = totalProcessed;
|
|
1218
|
+
this.successfulCount = successfulCount;
|
|
972
1219
|
}
|
|
973
1220
|
};
|
|
974
1221
|
|
|
975
1222
|
// src/import.ts
|
|
1223
|
+
var NOT_SUPPORTED_MSG = "not supported in v1.5.0-ce \u2014 use SynapCores.executeQuery with COPY ... or process locally";
|
|
976
1224
|
var ImportExportClient = class {
|
|
977
1225
|
constructor(synapCores) {
|
|
978
1226
|
this.synapCores = synapCores;
|
|
979
1227
|
}
|
|
980
1228
|
/**
|
|
981
|
-
* Import data into a table
|
|
1229
|
+
* Import data into a table.
|
|
1230
|
+
*
|
|
1231
|
+
* Routes to /v1/data/import/csv or /v1/data/import/json based on
|
|
1232
|
+
* `options.format`. NDJSON falls under the JSON endpoint.
|
|
982
1233
|
*/
|
|
983
1234
|
async import(options) {
|
|
984
|
-
const
|
|
1235
|
+
const fmt = options.format;
|
|
1236
|
+
if (fmt !== "csv" && fmt !== "json" && fmt !== "ndjson") {
|
|
1237
|
+
throw new ValidationError(
|
|
1238
|
+
`Unsupported import format '${fmt}' \u2014 gateway v1.5.0-ce only accepts csv or json`
|
|
1239
|
+
);
|
|
1240
|
+
}
|
|
1241
|
+
const path = fmt === "csv" ? "/data/import/csv" : "/data/import/json";
|
|
1242
|
+
let FormDataClass;
|
|
1243
|
+
try {
|
|
1244
|
+
FormDataClass = __require("form-data");
|
|
1245
|
+
} catch {
|
|
1246
|
+
FormDataClass = globalThis.FormData;
|
|
1247
|
+
}
|
|
1248
|
+
const formData = new FormDataClass();
|
|
985
1249
|
formData.append("table", options.table);
|
|
986
|
-
formData.append("format", options.format);
|
|
987
1250
|
if (options.mode) formData.append("mode", options.mode);
|
|
988
1251
|
if (options.column_mapping) {
|
|
989
1252
|
formData.append("column_mapping", JSON.stringify(options.column_mapping));
|
|
@@ -992,7 +1255,9 @@ var ImportExportClient = class {
|
|
|
992
1255
|
formData.append("skip_header", options.skip_header.toString());
|
|
993
1256
|
}
|
|
994
1257
|
if (options.delimiter) formData.append("delimiter", options.delimiter);
|
|
995
|
-
if (options.batch_size)
|
|
1258
|
+
if (options.batch_size) {
|
|
1259
|
+
formData.append("batch_size", options.batch_size.toString());
|
|
1260
|
+
}
|
|
996
1261
|
if (options.continue_on_error !== void 0) {
|
|
997
1262
|
formData.append("continue_on_error", options.continue_on_error.toString());
|
|
998
1263
|
}
|
|
@@ -1000,228 +1265,88 @@ var ImportExportClient = class {
|
|
|
1000
1265
|
formData.append("primary_keys", JSON.stringify(options.primary_keys));
|
|
1001
1266
|
}
|
|
1002
1267
|
if (Buffer.isBuffer(options.data)) {
|
|
1003
|
-
formData.append("file",
|
|
1268
|
+
formData.append("file", options.data, { filename: `data.${fmt}` });
|
|
1004
1269
|
} else {
|
|
1005
|
-
formData.append("
|
|
1270
|
+
formData.append("file", Buffer.from(String(options.data)), {
|
|
1271
|
+
filename: `data.${fmt}`
|
|
1272
|
+
});
|
|
1006
1273
|
}
|
|
1007
|
-
const
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1274
|
+
const headers = {};
|
|
1275
|
+
if (typeof formData.getHeaders === "function") {
|
|
1276
|
+
Object.assign(headers, formData.getHeaders());
|
|
1277
|
+
} else {
|
|
1278
|
+
headers["Content-Type"] = "multipart/form-data";
|
|
1279
|
+
}
|
|
1280
|
+
const { data } = await this.synapCores._getHttpClient().post(path, formData, {
|
|
1281
|
+
headers,
|
|
1282
|
+
maxBodyLength: Infinity,
|
|
1283
|
+
maxContentLength: Infinity
|
|
1011
1284
|
});
|
|
1012
1285
|
return {
|
|
1013
|
-
id: data.id
|
|
1014
|
-
success: data.success,
|
|
1015
|
-
rows_processed: data.rows_processed
|
|
1016
|
-
rows_imported: data.rows_imported
|
|
1017
|
-
rows_failed: data.rows_failed
|
|
1018
|
-
duration_ms: data.duration_ms
|
|
1019
|
-
errors: data.errors
|
|
1020
|
-
warnings: data.warnings
|
|
1286
|
+
id: data.id ?? data.job_id ?? "",
|
|
1287
|
+
success: data.success ?? true,
|
|
1288
|
+
rows_processed: data.rows_processed ?? 0,
|
|
1289
|
+
rows_imported: data.rows_imported ?? data.rows_processed ?? 0,
|
|
1290
|
+
rows_failed: data.rows_failed ?? 0,
|
|
1291
|
+
duration_ms: data.duration_ms ?? data.took_ms ?? 0,
|
|
1292
|
+
errors: data.errors ?? [],
|
|
1293
|
+
warnings: data.warnings ?? []
|
|
1021
1294
|
};
|
|
1022
1295
|
}
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
columns: options.columns,
|
|
1032
|
-
filter: options.filter,
|
|
1033
|
-
order_by: options.order_by,
|
|
1034
|
-
limit: options.limit,
|
|
1035
|
-
include_header: options.include_header,
|
|
1036
|
-
delimiter: options.delimiter,
|
|
1037
|
-
compress: options.compress
|
|
1038
|
-
});
|
|
1039
|
-
return {
|
|
1040
|
-
id: data.id || data.job_id,
|
|
1041
|
-
success: data.success,
|
|
1042
|
-
rows_exported: data.rows_exported || 0,
|
|
1043
|
-
duration_ms: data.duration_ms || data.took_ms || 0,
|
|
1044
|
-
file_path: data.file_path,
|
|
1045
|
-
data: data.data,
|
|
1046
|
-
size_bytes: data.size_bytes,
|
|
1047
|
-
download_url: data.download_url,
|
|
1048
|
-
expires_at: data.expires_at ? new Date(data.expires_at) : void 0
|
|
1049
|
-
};
|
|
1296
|
+
// ---------------------------------------------------------------------
|
|
1297
|
+
// Removed methods: every export route, every job-tracking route, bulk
|
|
1298
|
+
// import, validate, template — none of those endpoints exist in the
|
|
1299
|
+
// v1.5.0-ce gateway. We keep the shape so old callers get a clear error
|
|
1300
|
+
// instead of a silent 404.
|
|
1301
|
+
// ---------------------------------------------------------------------
|
|
1302
|
+
async export(_options) {
|
|
1303
|
+
throw new ValidationError(`export() ${NOT_SUPPORTED_MSG}`);
|
|
1050
1304
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
*/
|
|
1054
|
-
async getImportStatus(jobId) {
|
|
1055
|
-
const { data } = await this.synapCores._getHttpClient().get(`/import/${jobId}/status`);
|
|
1056
|
-
return {
|
|
1057
|
-
id: data.id || jobId,
|
|
1058
|
-
status: data.status,
|
|
1059
|
-
progress: data.progress || 0,
|
|
1060
|
-
phase: data.phase,
|
|
1061
|
-
rows_processed: data.rows_processed,
|
|
1062
|
-
eta_ms: data.eta_ms || data.estimated_time_remaining_ms,
|
|
1063
|
-
error: data.error,
|
|
1064
|
-
started_at: data.started_at ? new Date(data.started_at) : void 0,
|
|
1065
|
-
completed_at: data.completed_at ? new Date(data.completed_at) : void 0
|
|
1066
|
-
};
|
|
1305
|
+
async getImportStatus(_jobId) {
|
|
1306
|
+
throw new ValidationError(`getImportStatus() ${NOT_SUPPORTED_MSG}`);
|
|
1067
1307
|
}
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
*/
|
|
1071
|
-
async getExportStatus(jobId) {
|
|
1072
|
-
const { data } = await this.synapCores._getHttpClient().get(`/export/${jobId}/status`);
|
|
1073
|
-
return {
|
|
1074
|
-
id: data.id || jobId,
|
|
1075
|
-
status: data.status,
|
|
1076
|
-
progress: data.progress || 0,
|
|
1077
|
-
phase: data.phase,
|
|
1078
|
-
rows_exported: data.rows_exported,
|
|
1079
|
-
eta_ms: data.eta_ms || data.estimated_time_remaining_ms,
|
|
1080
|
-
error: data.error,
|
|
1081
|
-
started_at: data.started_at ? new Date(data.started_at) : void 0,
|
|
1082
|
-
completed_at: data.completed_at ? new Date(data.completed_at) : void 0
|
|
1083
|
-
};
|
|
1308
|
+
async getExportStatus(_jobId) {
|
|
1309
|
+
throw new ValidationError(`getExportStatus() ${NOT_SUPPORTED_MSG}`);
|
|
1084
1310
|
}
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
*/
|
|
1088
|
-
async cancelImport(jobId) {
|
|
1089
|
-
await this.synapCores._getHttpClient().post(`/import/${jobId}/cancel`);
|
|
1311
|
+
async cancelImport(_jobId) {
|
|
1312
|
+
throw new ValidationError(`cancelImport() ${NOT_SUPPORTED_MSG}`);
|
|
1090
1313
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
*/
|
|
1094
|
-
async cancelExport(jobId) {
|
|
1095
|
-
await this.synapCores._getHttpClient().post(`/export/${jobId}/cancel`);
|
|
1314
|
+
async cancelExport(_jobId) {
|
|
1315
|
+
throw new ValidationError(`cancelExport() ${NOT_SUPPORTED_MSG}`);
|
|
1096
1316
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
*/
|
|
1100
|
-
async bulkImport(options) {
|
|
1101
|
-
const { data } = await this.synapCores._getHttpClient().post("/import/bulk", {
|
|
1102
|
-
jobs: options.jobs,
|
|
1103
|
-
parallel: options.parallel || false,
|
|
1104
|
-
stop_on_error: options.stop_on_error || false
|
|
1105
|
-
});
|
|
1106
|
-
return {
|
|
1107
|
-
id: data.id || data.bulk_id,
|
|
1108
|
-
success: data.success,
|
|
1109
|
-
results: data.results || [],
|
|
1110
|
-
total_rows_imported: data.total_rows_imported || 0,
|
|
1111
|
-
total_duration_ms: data.total_duration_ms || data.took_ms || 0
|
|
1112
|
-
};
|
|
1317
|
+
async bulkImport(_options) {
|
|
1318
|
+
throw new ValidationError(`bulkImport() ${NOT_SUPPORTED_MSG}`);
|
|
1113
1319
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
*/
|
|
1117
|
-
async validateData(options) {
|
|
1118
|
-
const { data } = await this.synapCores._getHttpClient().post("/import/validate", {
|
|
1119
|
-
table: options.table,
|
|
1120
|
-
data: options.data,
|
|
1121
|
-
mode: options.mode || "strict",
|
|
1122
|
-
check_foreign_keys: options.check_foreign_keys,
|
|
1123
|
-
check_unique: options.check_unique
|
|
1124
|
-
});
|
|
1125
|
-
return {
|
|
1126
|
-
is_valid: data.is_valid || data.valid,
|
|
1127
|
-
errors: data.errors || [],
|
|
1128
|
-
warnings: data.warnings || [],
|
|
1129
|
-
rows_validated: data.rows_validated || options.data.length
|
|
1130
|
-
};
|
|
1320
|
+
async validateData(_options) {
|
|
1321
|
+
throw new ValidationError(`validateData() ${NOT_SUPPORTED_MSG}`);
|
|
1131
1322
|
}
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
*/
|
|
1135
|
-
async getImportTemplate(tableName, format = "csv") {
|
|
1136
|
-
const { data } = await this.synapCores._getHttpClient().get(
|
|
1137
|
-
`/import/template/${tableName}?format=${format}`
|
|
1138
|
-
);
|
|
1139
|
-
return data.template || data.content || data;
|
|
1323
|
+
async getImportTemplate(_tableName, _format = "csv") {
|
|
1324
|
+
throw new ValidationError(`getImportTemplate() ${NOT_SUPPORTED_MSG}`);
|
|
1140
1325
|
}
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
*/
|
|
1144
|
-
async listJobs(options = {}) {
|
|
1145
|
-
const params = new URLSearchParams();
|
|
1146
|
-
if (options.type) params.append("type", options.type);
|
|
1147
|
-
if (options.status) params.append("status", options.status);
|
|
1148
|
-
if (options.limit) params.append("limit", options.limit.toString());
|
|
1149
|
-
const { data } = await this.synapCores._getHttpClient().get(
|
|
1150
|
-
`/import/jobs?${params.toString()}`
|
|
1151
|
-
);
|
|
1152
|
-
return (data.jobs || data).map((job) => ({
|
|
1153
|
-
id: job.id,
|
|
1154
|
-
status: job.status,
|
|
1155
|
-
progress: job.progress || 0,
|
|
1156
|
-
phase: job.phase,
|
|
1157
|
-
rows_processed: job.rows_processed,
|
|
1158
|
-
rows_exported: job.rows_exported,
|
|
1159
|
-
eta_ms: job.eta_ms,
|
|
1160
|
-
error: job.error,
|
|
1161
|
-
started_at: job.started_at ? new Date(job.started_at) : void 0,
|
|
1162
|
-
completed_at: job.completed_at ? new Date(job.completed_at) : void 0
|
|
1163
|
-
}));
|
|
1326
|
+
async listJobs(_options = {}) {
|
|
1327
|
+
throw new ValidationError(`listJobs() ${NOT_SUPPORTED_MSG}`);
|
|
1164
1328
|
}
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
*/
|
|
1168
|
-
async downloadExport(jobId) {
|
|
1169
|
-
const { data } = await this.synapCores._getHttpClient().get(`/export/${jobId}/download`, {
|
|
1170
|
-
responseType: "arraybuffer"
|
|
1171
|
-
});
|
|
1172
|
-
return Buffer.from(data);
|
|
1329
|
+
async downloadExport(_jobId) {
|
|
1330
|
+
throw new ValidationError(`downloadExport() ${NOT_SUPPORTED_MSG}`);
|
|
1173
1331
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
*/
|
|
1177
|
-
async streamImport(options, onProgress) {
|
|
1178
|
-
const result = await this.import(options);
|
|
1179
|
-
const jobId = result.id;
|
|
1180
|
-
if (onProgress) {
|
|
1181
|
-
const pollInterval = setInterval(async () => {
|
|
1182
|
-
try {
|
|
1183
|
-
const status = await this.getImportStatus(jobId);
|
|
1184
|
-
onProgress(status);
|
|
1185
|
-
if (status.status === "completed" || status.status === "failed" || status.status === "cancelled") {
|
|
1186
|
-
clearInterval(pollInterval);
|
|
1187
|
-
}
|
|
1188
|
-
} catch (error) {
|
|
1189
|
-
clearInterval(pollInterval);
|
|
1190
|
-
}
|
|
1191
|
-
}, 1e3);
|
|
1192
|
-
}
|
|
1193
|
-
return result;
|
|
1332
|
+
async streamImport(options, _onProgress) {
|
|
1333
|
+
return this.import(options);
|
|
1194
1334
|
}
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
*/
|
|
1198
|
-
async streamExport(options, onProgress) {
|
|
1199
|
-
const result = await this.export(options);
|
|
1200
|
-
const jobId = result.id;
|
|
1201
|
-
if (onProgress) {
|
|
1202
|
-
const pollInterval = setInterval(async () => {
|
|
1203
|
-
try {
|
|
1204
|
-
const status = await this.getExportStatus(jobId);
|
|
1205
|
-
onProgress(status);
|
|
1206
|
-
if (status.status === "completed" || status.status === "failed" || status.status === "cancelled") {
|
|
1207
|
-
clearInterval(pollInterval);
|
|
1208
|
-
}
|
|
1209
|
-
} catch (error) {
|
|
1210
|
-
clearInterval(pollInterval);
|
|
1211
|
-
}
|
|
1212
|
-
}, 1e3);
|
|
1213
|
-
}
|
|
1214
|
-
return result;
|
|
1335
|
+
async streamExport(_options, _onProgress) {
|
|
1336
|
+
throw new ValidationError(`streamExport() ${NOT_SUPPORTED_MSG}`);
|
|
1215
1337
|
}
|
|
1216
1338
|
};
|
|
1217
1339
|
|
|
1218
1340
|
// src/integrations.ts
|
|
1341
|
+
var NOT_SUPPORTED = "not supported in v1.5.0-ce \u2014 see SynapCores integrations API";
|
|
1219
1342
|
var IntegrationClient = class {
|
|
1220
1343
|
constructor(synapCores) {
|
|
1221
1344
|
this.synapCores = synapCores;
|
|
1222
1345
|
}
|
|
1223
1346
|
/**
|
|
1224
|
-
* Create a new integration
|
|
1347
|
+
* Create a new integration. Gateway v1.5.0-ce keys integrations by
|
|
1348
|
+
* `type` (slug). The body still carries the type so old call sites
|
|
1349
|
+
* remain backwards compatible.
|
|
1225
1350
|
*/
|
|
1226
1351
|
async create(options) {
|
|
1227
1352
|
const { data } = await this.synapCores._getHttpClient().post("/integrations", {
|
|
@@ -1235,7 +1360,7 @@ var IntegrationClient = class {
|
|
|
1235
1360
|
return this.mapIntegration(data);
|
|
1236
1361
|
}
|
|
1237
1362
|
/**
|
|
1238
|
-
* List integrations
|
|
1363
|
+
* List integrations (optional filters).
|
|
1239
1364
|
*/
|
|
1240
1365
|
async list(options = {}) {
|
|
1241
1366
|
const params = new URLSearchParams();
|
|
@@ -1247,79 +1372,41 @@ var IntegrationClient = class {
|
|
|
1247
1372
|
if (options.tags && options.tags.length > 0) {
|
|
1248
1373
|
params.append("tags", options.tags.join(","));
|
|
1249
1374
|
}
|
|
1375
|
+
const qs = params.toString();
|
|
1250
1376
|
const { data } = await this.synapCores._getHttpClient().get(
|
|
1251
|
-
`/integrations
|
|
1377
|
+
`/integrations${qs ? `?${qs}` : ""}`
|
|
1252
1378
|
);
|
|
1253
|
-
return (data.integrations || data).map(
|
|
1379
|
+
return (data.integrations || data || []).map(
|
|
1254
1380
|
(integration) => this.mapIntegration(integration)
|
|
1255
1381
|
);
|
|
1256
1382
|
}
|
|
1257
1383
|
/**
|
|
1258
|
-
* Get a specific integration by
|
|
1384
|
+
* Get a specific integration by type-slug.
|
|
1259
1385
|
*/
|
|
1260
|
-
async get(
|
|
1261
|
-
const { data } = await this.synapCores._getHttpClient().get(
|
|
1386
|
+
async get(type) {
|
|
1387
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
1388
|
+
`/integrations/${type}`
|
|
1389
|
+
);
|
|
1262
1390
|
return this.mapIntegration(data);
|
|
1263
1391
|
}
|
|
1264
1392
|
/**
|
|
1265
|
-
* Update an existing integration
|
|
1393
|
+
* Update an existing integration by type-slug.
|
|
1266
1394
|
*/
|
|
1267
|
-
async update(
|
|
1395
|
+
async update(type, updates) {
|
|
1268
1396
|
const { data } = await this.synapCores._getHttpClient().put(
|
|
1269
|
-
`/integrations/${
|
|
1397
|
+
`/integrations/${type}`,
|
|
1270
1398
|
updates
|
|
1271
1399
|
);
|
|
1272
1400
|
return this.mapIntegration(data);
|
|
1273
1401
|
}
|
|
1274
1402
|
/**
|
|
1275
|
-
* Delete an integration
|
|
1276
|
-
*/
|
|
1277
|
-
async delete(id) {
|
|
1278
|
-
await this.synapCores._getHttpClient().delete(`/integrations/${id}`);
|
|
1279
|
-
}
|
|
1280
|
-
/**
|
|
1281
|
-
* Activate an integration
|
|
1282
|
-
*/
|
|
1283
|
-
async activate(id) {
|
|
1284
|
-
const { data } = await this.synapCores._getHttpClient().post(
|
|
1285
|
-
`/integrations/${id}/activate`
|
|
1286
|
-
);
|
|
1287
|
-
return this.mapIntegration(data);
|
|
1288
|
-
}
|
|
1289
|
-
/**
|
|
1290
|
-
* Deactivate an integration
|
|
1291
|
-
*/
|
|
1292
|
-
async deactivate(id) {
|
|
1293
|
-
const { data } = await this.synapCores._getHttpClient().post(
|
|
1294
|
-
`/integrations/${id}/deactivate`
|
|
1295
|
-
);
|
|
1296
|
-
return this.mapIntegration(data);
|
|
1297
|
-
}
|
|
1298
|
-
/**
|
|
1299
|
-
* Execute an integration
|
|
1403
|
+
* Delete an integration by type-slug.
|
|
1300
1404
|
*/
|
|
1301
|
-
async
|
|
1302
|
-
|
|
1303
|
-
`/integrations/${options.integration}/execute`,
|
|
1304
|
-
{
|
|
1305
|
-
payload: options.payload,
|
|
1306
|
-
config_override: options.config_override,
|
|
1307
|
-
sync: options.sync !== false
|
|
1308
|
-
}
|
|
1309
|
-
);
|
|
1310
|
-
return {
|
|
1311
|
-
id: data.id || data.execution_id,
|
|
1312
|
-
success: data.success,
|
|
1313
|
-
response: data.response,
|
|
1314
|
-
status_code: data.status_code,
|
|
1315
|
-
error: data.error,
|
|
1316
|
-
execution_time_ms: data.execution_time_ms || data.took_ms || 0,
|
|
1317
|
-
retry_count: data.retry_count || 0,
|
|
1318
|
-
executed_at: data.executed_at ? new Date(data.executed_at) : /* @__PURE__ */ new Date()
|
|
1319
|
-
};
|
|
1405
|
+
async delete(type) {
|
|
1406
|
+
await this.synapCores._getHttpClient().delete(`/integrations/${type}`);
|
|
1320
1407
|
}
|
|
1321
1408
|
/**
|
|
1322
|
-
* Test an integration
|
|
1409
|
+
* Test an integration connection.
|
|
1323
1410
|
*/
|
|
1324
1411
|
async test(options) {
|
|
1325
1412
|
const { data } = await this.synapCores._getHttpClient().post(
|
|
@@ -1338,160 +1425,88 @@ var IntegrationClient = class {
|
|
|
1338
1425
|
};
|
|
1339
1426
|
}
|
|
1340
1427
|
/**
|
|
1341
|
-
*
|
|
1428
|
+
* List supported integration types and their config schemas.
|
|
1342
1429
|
*/
|
|
1343
|
-
async
|
|
1344
|
-
const
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
return (data.executions || data).map((exec) => ({
|
|
1351
|
-
id: exec.id || exec.execution_id,
|
|
1352
|
-
success: exec.success,
|
|
1353
|
-
response: exec.response,
|
|
1354
|
-
status_code: exec.status_code,
|
|
1355
|
-
error: exec.error,
|
|
1356
|
-
execution_time_ms: exec.execution_time_ms || exec.took_ms || 0,
|
|
1357
|
-
retry_count: exec.retry_count || 0,
|
|
1358
|
-
executed_at: exec.executed_at ? new Date(exec.executed_at) : /* @__PURE__ */ new Date()
|
|
1430
|
+
async listTypes() {
|
|
1431
|
+
const { data } = await this.synapCores._getHttpClient().get("/integrations/types");
|
|
1432
|
+
return (data.types ?? data ?? []).map((t) => ({
|
|
1433
|
+
type: t.type ?? t.name,
|
|
1434
|
+
display_name: t.display_name ?? t.label,
|
|
1435
|
+
description: t.description,
|
|
1436
|
+
config_schema: t.config_schema ?? t.schema
|
|
1359
1437
|
}));
|
|
1360
1438
|
}
|
|
1361
1439
|
/**
|
|
1362
|
-
* Get
|
|
1440
|
+
* Get the integrations audit trail.
|
|
1363
1441
|
*/
|
|
1364
|
-
async
|
|
1442
|
+
async audit(options = {}) {
|
|
1443
|
+
const params = new URLSearchParams();
|
|
1444
|
+
if (options.limit) params.append("limit", options.limit.toString());
|
|
1445
|
+
if (options.type) params.append("type", options.type);
|
|
1446
|
+
const qs = params.toString();
|
|
1365
1447
|
const { data } = await this.synapCores._getHttpClient().get(
|
|
1366
|
-
`/integrations
|
|
1448
|
+
`/integrations/audit${qs ? `?${qs}` : ""}`
|
|
1367
1449
|
);
|
|
1368
|
-
return {
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
last_success_at: data.last_success_at ? new Date(data.last_success_at) : void 0,
|
|
1377
|
-
last_error_at: data.last_error_at ? new Date(data.last_error_at) : void 0
|
|
1378
|
-
};
|
|
1450
|
+
return (data.entries ?? data.audit ?? data ?? []).map((row) => ({
|
|
1451
|
+
id: row.id,
|
|
1452
|
+
type: row.type ?? row.integration_type,
|
|
1453
|
+
action: row.action ?? row.event,
|
|
1454
|
+
user: row.user ?? row.actor,
|
|
1455
|
+
timestamp: new Date(row.timestamp ?? row.created_at ?? Date.now()),
|
|
1456
|
+
details: row.details ?? row.data
|
|
1457
|
+
}));
|
|
1379
1458
|
}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
event: options.event,
|
|
1387
|
-
url: options.url,
|
|
1388
|
-
secret: options.secret,
|
|
1389
|
-
activate: options.activate !== false
|
|
1390
|
-
});
|
|
1391
|
-
return {
|
|
1392
|
-
id: data.id,
|
|
1393
|
-
integration_id: data.integration_id,
|
|
1394
|
-
event: data.event,
|
|
1395
|
-
url: data.url,
|
|
1396
|
-
active: data.active,
|
|
1397
|
-
secret: data.secret,
|
|
1398
|
-
created_at: new Date(data.created_at)
|
|
1399
|
-
};
|
|
1459
|
+
// -------------------------------------------------------------------
|
|
1460
|
+
// Methods removed from v1.5.0-ce (gateway has no matching route).
|
|
1461
|
+
// We keep the names for backwards-compat but throw a clear error.
|
|
1462
|
+
// -------------------------------------------------------------------
|
|
1463
|
+
async activate(_type) {
|
|
1464
|
+
throw new ValidationError(`integrations.activate() ${NOT_SUPPORTED} \u2014 use update() with {activate:true}`);
|
|
1400
1465
|
}
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
*/
|
|
1404
|
-
async listWebhooks(integrationId) {
|
|
1405
|
-
const { data } = await this.synapCores._getHttpClient().get(
|
|
1406
|
-
`/integrations/${integrationId}/webhooks`
|
|
1407
|
-
);
|
|
1408
|
-
return (data.webhooks || data).map((webhook) => ({
|
|
1409
|
-
id: webhook.id,
|
|
1410
|
-
integration_id: webhook.integration_id,
|
|
1411
|
-
event: webhook.event,
|
|
1412
|
-
url: webhook.url,
|
|
1413
|
-
active: webhook.active,
|
|
1414
|
-
secret: webhook.secret,
|
|
1415
|
-
created_at: new Date(webhook.created_at)
|
|
1416
|
-
}));
|
|
1466
|
+
async deactivate(_type) {
|
|
1467
|
+
throw new ValidationError(`integrations.deactivate() ${NOT_SUPPORTED} \u2014 use update() with {activate:false}`);
|
|
1417
1468
|
}
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
*/
|
|
1421
|
-
async deleteWebhook(webhookId) {
|
|
1422
|
-
await this.synapCores._getHttpClient().delete(`/integrations/webhooks/${webhookId}`);
|
|
1469
|
+
async execute(_options) {
|
|
1470
|
+
throw new ValidationError(`integrations.execute() ${NOT_SUPPORTED}`);
|
|
1423
1471
|
}
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
*/
|
|
1427
|
-
async getEvents(integrationId, options = {}) {
|
|
1428
|
-
const params = new URLSearchParams();
|
|
1429
|
-
if (options.limit) params.append("limit", options.limit.toString());
|
|
1430
|
-
if (options.status) params.append("status", options.status);
|
|
1431
|
-
const { data } = await this.synapCores._getHttpClient().get(
|
|
1432
|
-
`/integrations/${integrationId}/events?${params.toString()}`
|
|
1433
|
-
);
|
|
1434
|
-
return (data.events || data).map((event) => ({
|
|
1435
|
-
id: event.id,
|
|
1436
|
-
integration_id: event.integration_id,
|
|
1437
|
-
event: event.event,
|
|
1438
|
-
data: event.data,
|
|
1439
|
-
timestamp: new Date(event.timestamp),
|
|
1440
|
-
status: event.status,
|
|
1441
|
-
error: event.error
|
|
1442
|
-
}));
|
|
1472
|
+
async getExecutionHistory(_type, _options = {}) {
|
|
1473
|
+
throw new ValidationError(`integrations.getExecutionHistory() ${NOT_SUPPORTED}`);
|
|
1443
1474
|
}
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
*/
|
|
1447
|
-
async getLogs(integrationId, options = {}) {
|
|
1448
|
-
const params = new URLSearchParams();
|
|
1449
|
-
if (options.limit) params.append("limit", options.limit.toString());
|
|
1450
|
-
if (options.level) params.append("level", options.level);
|
|
1451
|
-
const { data } = await this.synapCores._getHttpClient().get(
|
|
1452
|
-
`/integrations/${integrationId}/logs?${params.toString()}`
|
|
1453
|
-
);
|
|
1454
|
-
return (data.logs || data).map((log) => ({
|
|
1455
|
-
id: log.id,
|
|
1456
|
-
integration_id: log.integration_id,
|
|
1457
|
-
level: log.level,
|
|
1458
|
-
message: log.message,
|
|
1459
|
-
data: log.data,
|
|
1460
|
-
timestamp: new Date(log.timestamp)
|
|
1461
|
-
}));
|
|
1475
|
+
async getStats(_type) {
|
|
1476
|
+
throw new ValidationError(`integrations.getStats() ${NOT_SUPPORTED}`);
|
|
1462
1477
|
}
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
async
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
};
|
|
1478
|
+
async createWebhook(_options) {
|
|
1479
|
+
throw new ValidationError(`integrations.createWebhook() ${NOT_SUPPORTED}`);
|
|
1480
|
+
}
|
|
1481
|
+
async listWebhooks(_type) {
|
|
1482
|
+
throw new ValidationError(`integrations.listWebhooks() ${NOT_SUPPORTED}`);
|
|
1483
|
+
}
|
|
1484
|
+
async deleteWebhook(_webhookId) {
|
|
1485
|
+
throw new ValidationError(`integrations.deleteWebhook() ${NOT_SUPPORTED}`);
|
|
1486
|
+
}
|
|
1487
|
+
async getEvents(_type, _options = {}) {
|
|
1488
|
+
throw new ValidationError(`integrations.getEvents() ${NOT_SUPPORTED}`);
|
|
1489
|
+
}
|
|
1490
|
+
async getLogs(_type, _options = {}) {
|
|
1491
|
+
throw new ValidationError(`integrations.getLogs() ${NOT_SUPPORTED}`);
|
|
1492
|
+
}
|
|
1493
|
+
async retryExecution(_executionId) {
|
|
1494
|
+
throw new ValidationError(`integrations.retryExecution() ${NOT_SUPPORTED}`);
|
|
1480
1495
|
}
|
|
1481
1496
|
/**
|
|
1482
|
-
* Map raw integration data to Integration type
|
|
1497
|
+
* Map raw integration data to Integration type.
|
|
1483
1498
|
*/
|
|
1484
1499
|
mapIntegration(data) {
|
|
1485
1500
|
return {
|
|
1486
|
-
id: data.id,
|
|
1487
|
-
name: data.name,
|
|
1501
|
+
id: data.id ?? data.type,
|
|
1502
|
+
name: data.name ?? data.type,
|
|
1488
1503
|
type: data.type,
|
|
1489
|
-
status: data.status,
|
|
1490
|
-
config: data.config,
|
|
1504
|
+
status: data.status ?? (data.active ? "active" : "inactive"),
|
|
1505
|
+
config: data.config ?? {},
|
|
1491
1506
|
description: data.description,
|
|
1492
1507
|
tags: data.tags || [],
|
|
1493
|
-
created_at: new Date(data.created_at),
|
|
1494
|
-
updated_at: new Date(data.updated_at),
|
|
1508
|
+
created_at: new Date(data.created_at ?? Date.now()),
|
|
1509
|
+
updated_at: new Date(data.updated_at ?? data.created_at ?? Date.now()),
|
|
1495
1510
|
last_success_at: data.last_success_at ? new Date(data.last_success_at) : void 0,
|
|
1496
1511
|
last_error: data.last_error,
|
|
1497
1512
|
execution_count: data.execution_count
|
|
@@ -1624,18 +1639,9 @@ var BackupClient = class {
|
|
|
1624
1639
|
completed_at: data.completed_at ? new Date(data.completed_at) : void 0
|
|
1625
1640
|
};
|
|
1626
1641
|
}
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
async cancelBackup(backupId) {
|
|
1631
|
-
await this.synapCores._getHttpClient().post(`/backups/${backupId}/cancel`);
|
|
1632
|
-
}
|
|
1633
|
-
/**
|
|
1634
|
-
* Cancel a restore in progress
|
|
1635
|
-
*/
|
|
1636
|
-
async cancelRestore(restoreId) {
|
|
1637
|
-
await this.synapCores._getHttpClient().post(`/backups/restore/${restoreId}/cancel`);
|
|
1638
|
-
}
|
|
1642
|
+
// cancelBackup() / cancelRestore() removed — gateway v1.5.0-ce has no
|
|
1643
|
+
// /backups/:id/cancel or /backups/restore/:id/cancel routes. Use
|
|
1644
|
+
// delete() to clean up an aborted backup record.
|
|
1639
1645
|
/**
|
|
1640
1646
|
* Download a backup file
|
|
1641
1647
|
*/
|
|
@@ -1770,155 +1776,972 @@ var BackupClient = class {
|
|
|
1770
1776
|
};
|
|
1771
1777
|
}
|
|
1772
1778
|
/**
|
|
1773
|
-
* Deactivate a schedule
|
|
1779
|
+
* Deactivate a schedule
|
|
1780
|
+
*/
|
|
1781
|
+
async deactivateSchedule(scheduleId) {
|
|
1782
|
+
const { data } = await this.synapCores._getHttpClient().post(
|
|
1783
|
+
`/backups/schedules/${scheduleId}/deactivate`
|
|
1784
|
+
);
|
|
1785
|
+
return {
|
|
1786
|
+
id: data.id,
|
|
1787
|
+
name: data.name,
|
|
1788
|
+
cron: data.cron,
|
|
1789
|
+
backup_options: data.backup_options,
|
|
1790
|
+
active: data.active,
|
|
1791
|
+
last_run_at: data.last_run_at ? new Date(data.last_run_at) : void 0,
|
|
1792
|
+
next_run_at: data.next_run_at ? new Date(data.next_run_at) : void 0,
|
|
1793
|
+
created_at: new Date(data.created_at),
|
|
1794
|
+
tags: data.tags || []
|
|
1795
|
+
};
|
|
1796
|
+
}
|
|
1797
|
+
// getMetrics() removed — gateway v1.5.0-ce has no /backups/metrics route.
|
|
1798
|
+
// Aggregate metrics can be derived client-side from list().
|
|
1799
|
+
/**
|
|
1800
|
+
* Map raw backup data to Backup type
|
|
1801
|
+
*/
|
|
1802
|
+
mapBackup(data) {
|
|
1803
|
+
return {
|
|
1804
|
+
id: data.id,
|
|
1805
|
+
name: data.name,
|
|
1806
|
+
description: data.description,
|
|
1807
|
+
type: data.type,
|
|
1808
|
+
status: data.status,
|
|
1809
|
+
size_bytes: data.size_bytes,
|
|
1810
|
+
compressed_size_bytes: data.compressed_size_bytes,
|
|
1811
|
+
table_count: data.table_count,
|
|
1812
|
+
created_at: new Date(data.created_at),
|
|
1813
|
+
completed_at: data.completed_at ? new Date(data.completed_at) : void 0,
|
|
1814
|
+
duration_ms: data.duration_ms || data.took_ms,
|
|
1815
|
+
storage: data.storage,
|
|
1816
|
+
storage_path: data.storage_path,
|
|
1817
|
+
encrypted: data.encrypted || false,
|
|
1818
|
+
tags: data.tags || [],
|
|
1819
|
+
parent_backup_id: data.parent_backup_id,
|
|
1820
|
+
error: data.error
|
|
1821
|
+
};
|
|
1822
|
+
}
|
|
1823
|
+
};
|
|
1824
|
+
|
|
1825
|
+
// src/graph.ts
|
|
1826
|
+
var GraphNodeApi = class {
|
|
1827
|
+
constructor(synapCores) {
|
|
1828
|
+
this.synapCores = synapCores;
|
|
1829
|
+
}
|
|
1830
|
+
async create(label, props = {}) {
|
|
1831
|
+
const { data } = await this.synapCores._getHttpClient().post("/graph/nodes", {
|
|
1832
|
+
label,
|
|
1833
|
+
properties: props
|
|
1834
|
+
});
|
|
1835
|
+
return this.normalize(data);
|
|
1836
|
+
}
|
|
1837
|
+
async get(id) {
|
|
1838
|
+
const { data } = await this.synapCores._getHttpClient().get(`/graph/nodes/${id}`);
|
|
1839
|
+
return this.normalize(data);
|
|
1840
|
+
}
|
|
1841
|
+
async update(id, patch) {
|
|
1842
|
+
const { data } = await this.synapCores._getHttpClient().patch(
|
|
1843
|
+
`/graph/nodes/${id}`,
|
|
1844
|
+
{ properties: patch }
|
|
1845
|
+
);
|
|
1846
|
+
return this.normalize(data);
|
|
1847
|
+
}
|
|
1848
|
+
async delete(id) {
|
|
1849
|
+
await this.synapCores._getHttpClient().delete(`/graph/nodes/${id}`);
|
|
1850
|
+
}
|
|
1851
|
+
async neighbors(id, opts = {}) {
|
|
1852
|
+
const params = new URLSearchParams();
|
|
1853
|
+
if (opts.direction) params.append("direction", opts.direction);
|
|
1854
|
+
if (opts.limit !== void 0) params.append("limit", String(opts.limit));
|
|
1855
|
+
if (opts.type) params.append("type", opts.type);
|
|
1856
|
+
const qs = params.toString();
|
|
1857
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
1858
|
+
`/graph/nodes/${id}/neighbors${qs ? `?${qs}` : ""}`
|
|
1859
|
+
);
|
|
1860
|
+
return {
|
|
1861
|
+
nodes: (data.nodes ?? []).map((n) => this.normalize(n)),
|
|
1862
|
+
edges: (data.edges ?? []).map((e) => this.normalizeEdge(e))
|
|
1863
|
+
};
|
|
1864
|
+
}
|
|
1865
|
+
normalize(data) {
|
|
1866
|
+
return {
|
|
1867
|
+
id: String(data.id ?? data.node_id ?? ""),
|
|
1868
|
+
label: data.label,
|
|
1869
|
+
labels: data.labels,
|
|
1870
|
+
properties: data.properties ?? data.props ?? {}
|
|
1871
|
+
};
|
|
1872
|
+
}
|
|
1873
|
+
normalizeEdge(data) {
|
|
1874
|
+
return {
|
|
1875
|
+
id: data.id !== void 0 ? String(data.id) : void 0,
|
|
1876
|
+
from: String(data.from ?? data.source ?? ""),
|
|
1877
|
+
to: String(data.to ?? data.target ?? ""),
|
|
1878
|
+
type: data.type ?? data.label ?? "",
|
|
1879
|
+
properties: data.properties ?? data.props ?? {}
|
|
1880
|
+
};
|
|
1881
|
+
}
|
|
1882
|
+
};
|
|
1883
|
+
var GraphEdgeApi = class {
|
|
1884
|
+
constructor(synapCores) {
|
|
1885
|
+
this.synapCores = synapCores;
|
|
1886
|
+
}
|
|
1887
|
+
async create(from, to, type, props = {}) {
|
|
1888
|
+
const { data } = await this.synapCores._getHttpClient().post("/graph/edges", {
|
|
1889
|
+
from,
|
|
1890
|
+
to,
|
|
1891
|
+
type,
|
|
1892
|
+
properties: props
|
|
1893
|
+
});
|
|
1894
|
+
return {
|
|
1895
|
+
id: data.id !== void 0 ? String(data.id) : void 0,
|
|
1896
|
+
from: String(data.from ?? from),
|
|
1897
|
+
to: String(data.to ?? to),
|
|
1898
|
+
type: data.type ?? type,
|
|
1899
|
+
properties: data.properties ?? props
|
|
1900
|
+
};
|
|
1901
|
+
}
|
|
1902
|
+
};
|
|
1903
|
+
var GraphIndexesApi = class {
|
|
1904
|
+
constructor(synapCores) {
|
|
1905
|
+
this.synapCores = synapCores;
|
|
1906
|
+
}
|
|
1907
|
+
/**
|
|
1908
|
+
* Create a graph index (label/property index, fulltext, or vector
|
|
1909
|
+
* depending on the gateway's accepted DDL strings).
|
|
1910
|
+
*/
|
|
1911
|
+
async create(stmt) {
|
|
1912
|
+
const { data } = await this.synapCores._getHttpClient().post("/graph/indexes", {
|
|
1913
|
+
statement: stmt
|
|
1914
|
+
});
|
|
1915
|
+
return { name: data.name ?? data.index_name, raw: data };
|
|
1916
|
+
}
|
|
1917
|
+
};
|
|
1918
|
+
var GraphAlgorithmsApi = class {
|
|
1919
|
+
constructor(synapCores) {
|
|
1920
|
+
this.synapCores = synapCores;
|
|
1921
|
+
}
|
|
1922
|
+
async run(name, opts = {}) {
|
|
1923
|
+
const { data } = await this.synapCores._getHttpClient().post("/graph/algorithms", {
|
|
1924
|
+
algorithm: name,
|
|
1925
|
+
...opts
|
|
1926
|
+
});
|
|
1927
|
+
return {
|
|
1928
|
+
algorithm: name,
|
|
1929
|
+
results: data.results ?? data.result ?? data,
|
|
1930
|
+
stats: data.stats,
|
|
1931
|
+
execution_time_ms: data.execution_time_ms ?? data.took_ms
|
|
1932
|
+
};
|
|
1933
|
+
}
|
|
1934
|
+
};
|
|
1935
|
+
var GraphsApi = class {
|
|
1936
|
+
constructor(synapCores) {
|
|
1937
|
+
this.synapCores = synapCores;
|
|
1938
|
+
}
|
|
1939
|
+
async list() {
|
|
1940
|
+
const { data } = await this.synapCores._getHttpClient().get("/graphs");
|
|
1941
|
+
return (data.graphs ?? data ?? []).map((g) => this.normalize(g));
|
|
1942
|
+
}
|
|
1943
|
+
async create(name, opts = {}) {
|
|
1944
|
+
const { data } = await this.synapCores._getHttpClient().post("/graphs", {
|
|
1945
|
+
name,
|
|
1946
|
+
description: opts.description
|
|
1947
|
+
});
|
|
1948
|
+
return this.normalize(data);
|
|
1949
|
+
}
|
|
1950
|
+
async get(name) {
|
|
1951
|
+
const { data } = await this.synapCores._getHttpClient().get(`/graphs/${name}`);
|
|
1952
|
+
return this.normalize(data);
|
|
1953
|
+
}
|
|
1954
|
+
async delete(name) {
|
|
1955
|
+
await this.synapCores._getHttpClient().delete(`/graphs/${name}`);
|
|
1956
|
+
}
|
|
1957
|
+
normalize(data) {
|
|
1958
|
+
return {
|
|
1959
|
+
name: data.name,
|
|
1960
|
+
node_count: data.node_count ?? data.nodes,
|
|
1961
|
+
edge_count: data.edge_count ?? data.edges,
|
|
1962
|
+
created_at: data.created_at ? new Date(data.created_at) : void 0,
|
|
1963
|
+
description: data.description
|
|
1964
|
+
};
|
|
1965
|
+
}
|
|
1966
|
+
};
|
|
1967
|
+
var GraphClient = class {
|
|
1968
|
+
constructor(synapCores) {
|
|
1969
|
+
this.synapCores = synapCores;
|
|
1970
|
+
this.nodes = new GraphNodeApi(synapCores);
|
|
1971
|
+
this.edges = new GraphEdgeApi(synapCores);
|
|
1972
|
+
this.indexes = new GraphIndexesApi(synapCores);
|
|
1973
|
+
this.algorithms = new GraphAlgorithmsApi(synapCores);
|
|
1974
|
+
this.graphs = new GraphsApi(synapCores);
|
|
1975
|
+
}
|
|
1976
|
+
/**
|
|
1977
|
+
* Run a Cypher / MATCH query.
|
|
1978
|
+
*
|
|
1979
|
+
* The gateway's MatchRequest expects `sql: String` (see
|
|
1980
|
+
* crates/aidb-gateway/src/routes/graph.rs MatchRequest); we keep the
|
|
1981
|
+
* SDK-facing parameter named `query` because every caller writes
|
|
1982
|
+
* Cypher, not SQL — the gateway's field name is a historical artifact.
|
|
1983
|
+
*/
|
|
1984
|
+
async cypher(query, params = {}, graph) {
|
|
1985
|
+
const { data } = await this.synapCores._getHttpClient().post("/graph/match", {
|
|
1986
|
+
sql: query,
|
|
1987
|
+
params,
|
|
1988
|
+
graph
|
|
1989
|
+
});
|
|
1990
|
+
return this.normalizeCypher(data);
|
|
1991
|
+
}
|
|
1992
|
+
/**
|
|
1993
|
+
* Profile a Cypher / MATCH query (returns plan/profile metadata).
|
|
1994
|
+
*/
|
|
1995
|
+
async cypherProfile(query, params = {}, graph) {
|
|
1996
|
+
const { data } = await this.synapCores._getHttpClient().post("/graph/match/profile", {
|
|
1997
|
+
sql: query,
|
|
1998
|
+
params,
|
|
1999
|
+
graph
|
|
2000
|
+
});
|
|
2001
|
+
return {
|
|
2002
|
+
...this.normalizeCypher(data),
|
|
2003
|
+
plan: data.plan,
|
|
2004
|
+
profile: data.profile ?? data.profile_data
|
|
2005
|
+
};
|
|
2006
|
+
}
|
|
2007
|
+
/**
|
|
2008
|
+
* Run LLM-based extraction over text into the given graph.
|
|
2009
|
+
*/
|
|
2010
|
+
async extract(req, graphName) {
|
|
2011
|
+
const body = typeof req === "string" ? { text: req, graph: graphName } : req;
|
|
2012
|
+
const { data } = await this.synapCores._getHttpClient().post("/graph/extract", body);
|
|
2013
|
+
return {
|
|
2014
|
+
nodes: (data.nodes ?? []).map((n) => ({
|
|
2015
|
+
id: String(n.id ?? ""),
|
|
2016
|
+
label: n.label,
|
|
2017
|
+
labels: n.labels,
|
|
2018
|
+
properties: n.properties ?? n.props ?? {}
|
|
2019
|
+
})),
|
|
2020
|
+
edges: (data.edges ?? []).map((e) => ({
|
|
2021
|
+
id: e.id !== void 0 ? String(e.id) : void 0,
|
|
2022
|
+
from: String(e.from ?? e.source ?? ""),
|
|
2023
|
+
to: String(e.to ?? e.target ?? ""),
|
|
2024
|
+
type: e.type ?? e.label ?? "",
|
|
2025
|
+
properties: e.properties ?? e.props ?? {}
|
|
2026
|
+
})),
|
|
2027
|
+
spans: data.spans
|
|
2028
|
+
};
|
|
2029
|
+
}
|
|
2030
|
+
normalizeCypher(data) {
|
|
2031
|
+
return {
|
|
2032
|
+
columns: data.columns ?? data.fields,
|
|
2033
|
+
rows: data.rows ?? data.values ?? [],
|
|
2034
|
+
records: data.records ?? data.results,
|
|
2035
|
+
stats: data.stats,
|
|
2036
|
+
execution_time_ms: data.execution_time_ms ?? data.took_ms
|
|
2037
|
+
};
|
|
2038
|
+
}
|
|
2039
|
+
};
|
|
2040
|
+
|
|
2041
|
+
// src/nl2sql.ts
|
|
2042
|
+
var NL2SqlClient = class {
|
|
2043
|
+
constructor(synapCores) {
|
|
2044
|
+
this.synapCores = synapCores;
|
|
2045
|
+
}
|
|
2046
|
+
/**
|
|
2047
|
+
* Ask a question in natural language. The gateway returns the
|
|
2048
|
+
* generated SQL and optionally the executed result set when
|
|
2049
|
+
* `execute=true`.
|
|
2050
|
+
*/
|
|
2051
|
+
async ask(question, opts = {}) {
|
|
2052
|
+
const { data } = await this.synapCores._getHttpClient().post("/nl2sql/query", {
|
|
2053
|
+
question,
|
|
2054
|
+
...opts
|
|
2055
|
+
});
|
|
2056
|
+
return {
|
|
2057
|
+
sql: data.sql ?? data.generated_sql ?? "",
|
|
2058
|
+
confidence: data.confidence,
|
|
2059
|
+
rows: data.rows ?? data.data,
|
|
2060
|
+
columns: data.columns,
|
|
2061
|
+
execution_time_ms: data.execution_time_ms ?? data.took_ms,
|
|
2062
|
+
trace: data.trace ?? data.plan,
|
|
2063
|
+
question
|
|
2064
|
+
};
|
|
2065
|
+
}
|
|
2066
|
+
/**
|
|
2067
|
+
* Push schema context the model should use for subsequent ask() calls.
|
|
2068
|
+
*/
|
|
2069
|
+
async updateSchemaContext(payload) {
|
|
2070
|
+
const { data } = await this.synapCores._getHttpClient().post(
|
|
2071
|
+
"/nl2sql/schema/context",
|
|
2072
|
+
payload
|
|
2073
|
+
);
|
|
2074
|
+
return { accepted: data.accepted ?? data.success ?? true, raw: data };
|
|
2075
|
+
}
|
|
2076
|
+
/**
|
|
2077
|
+
* Retrieve recent NL2SQL history for the current authenticated user.
|
|
2078
|
+
*/
|
|
2079
|
+
async history(opts = {}) {
|
|
2080
|
+
const params = new URLSearchParams();
|
|
2081
|
+
if (opts.limit) params.append("limit", String(opts.limit));
|
|
2082
|
+
if (opts.session_id) params.append("session_id", opts.session_id);
|
|
2083
|
+
const qs = params.toString();
|
|
2084
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
2085
|
+
`/nl2sql/history${qs ? `?${qs}` : ""}`
|
|
2086
|
+
);
|
|
2087
|
+
return (data.history ?? data.entries ?? data ?? []).map((row) => ({
|
|
2088
|
+
id: String(row.id ?? row.entry_id ?? ""),
|
|
2089
|
+
question: row.question ?? row.prompt ?? "",
|
|
2090
|
+
sql: row.sql ?? row.generated_sql ?? "",
|
|
2091
|
+
created_at: new Date(row.created_at ?? row.timestamp ?? Date.now()),
|
|
2092
|
+
executed: row.executed,
|
|
2093
|
+
success: row.success
|
|
2094
|
+
}));
|
|
2095
|
+
}
|
|
2096
|
+
/**
|
|
2097
|
+
* Validate a SQL string against the current schema and policies.
|
|
2098
|
+
*/
|
|
2099
|
+
async validate(sql) {
|
|
2100
|
+
const { data } = await this.synapCores._getHttpClient().post("/nl2sql/validate", {
|
|
2101
|
+
sql
|
|
2102
|
+
});
|
|
2103
|
+
return {
|
|
2104
|
+
is_valid: data.is_valid ?? data.valid ?? false,
|
|
2105
|
+
errors: data.errors ?? [],
|
|
2106
|
+
warnings: data.warnings ?? [],
|
|
2107
|
+
rewritten_sql: data.rewritten_sql ?? data.sql
|
|
2108
|
+
};
|
|
2109
|
+
}
|
|
2110
|
+
};
|
|
2111
|
+
|
|
2112
|
+
// src/filesystem.ts
|
|
2113
|
+
import WebSocket2 from "ws";
|
|
2114
|
+
var FsCollectionsApi = class {
|
|
2115
|
+
constructor(synapCores) {
|
|
2116
|
+
this.synapCores = synapCores;
|
|
2117
|
+
}
|
|
2118
|
+
async create(opts) {
|
|
2119
|
+
const { data } = await this.synapCores._getHttpClient().post(
|
|
2120
|
+
"/filesystem-collections",
|
|
2121
|
+
opts
|
|
2122
|
+
);
|
|
2123
|
+
return this.normalize(data);
|
|
2124
|
+
}
|
|
2125
|
+
async list() {
|
|
2126
|
+
const { data } = await this.synapCores._getHttpClient().get("/filesystem-collections");
|
|
2127
|
+
return (data.collections ?? data ?? []).map((c) => this.normalize(c));
|
|
2128
|
+
}
|
|
2129
|
+
async get(id) {
|
|
2130
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
2131
|
+
`/filesystem-collections/${id}`
|
|
2132
|
+
);
|
|
2133
|
+
return this.normalize(data);
|
|
2134
|
+
}
|
|
2135
|
+
async patch(id, p) {
|
|
2136
|
+
const { data } = await this.synapCores._getHttpClient().patch(
|
|
2137
|
+
`/filesystem-collections/${id}`,
|
|
2138
|
+
p
|
|
2139
|
+
);
|
|
2140
|
+
return this.normalize(data);
|
|
2141
|
+
}
|
|
2142
|
+
async delete(id) {
|
|
2143
|
+
await this.synapCores._getHttpClient().delete(`/filesystem-collections/${id}`);
|
|
2144
|
+
}
|
|
2145
|
+
async documents(id, opts = {}) {
|
|
2146
|
+
const params = new URLSearchParams();
|
|
2147
|
+
if (opts.page) params.append("page", String(opts.page));
|
|
2148
|
+
if (opts.page_size) params.append("page_size", String(opts.page_size));
|
|
2149
|
+
const qs = params.toString();
|
|
2150
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
2151
|
+
`/filesystem-collections/${id}/documents${qs ? `?${qs}` : ""}`
|
|
2152
|
+
);
|
|
2153
|
+
return (data.documents ?? data ?? []).map((d) => ({
|
|
2154
|
+
id: String(d.id ?? d.document_id ?? ""),
|
|
2155
|
+
collection_id: d.collection_id !== void 0 ? String(d.collection_id) : id,
|
|
2156
|
+
filename: d.filename ?? d.name,
|
|
2157
|
+
path: d.path,
|
|
2158
|
+
status: d.status,
|
|
2159
|
+
size_bytes: d.size_bytes,
|
|
2160
|
+
created_at: d.created_at ? new Date(d.created_at) : void 0,
|
|
2161
|
+
updated_at: d.updated_at ? new Date(d.updated_at) : void 0
|
|
2162
|
+
}));
|
|
2163
|
+
}
|
|
2164
|
+
async reprocess(id, fileId) {
|
|
2165
|
+
const body = fileId ? { document_id: fileId } : {};
|
|
2166
|
+
const { data } = await this.synapCores._getHttpClient().post(
|
|
2167
|
+
`/filesystem-collections/${id}/reprocess`,
|
|
2168
|
+
body
|
|
2169
|
+
);
|
|
2170
|
+
return { accepted: data.accepted ?? data.success ?? true, raw: data };
|
|
2171
|
+
}
|
|
2172
|
+
/**
|
|
2173
|
+
* Stream progress events for an in-flight ingestion. Each tick maps to
|
|
2174
|
+
* a JSON payload broadcast by the gateway over the WS channel. The
|
|
2175
|
+
* iterator ends when the server closes the socket or the consumer
|
|
2176
|
+
* breaks out of the for-await loop.
|
|
2177
|
+
*/
|
|
2178
|
+
async *subscribeProgress(id, opts = {}) {
|
|
2179
|
+
const { token } = await this.synapCores.createWsTicket();
|
|
2180
|
+
const wsBase = this.synapCores._getWsBaseUrl();
|
|
2181
|
+
const url = `${wsBase}/ws/filesystem-collections/${id}/progress?token=${encodeURIComponent(token)}`;
|
|
2182
|
+
const ws = new WebSocket2(url);
|
|
2183
|
+
const queue = [];
|
|
2184
|
+
let resolver = null;
|
|
2185
|
+
const push = (p) => {
|
|
2186
|
+
if (resolver) {
|
|
2187
|
+
const r = resolver;
|
|
2188
|
+
resolver = null;
|
|
2189
|
+
r(p);
|
|
2190
|
+
} else {
|
|
2191
|
+
queue.push(p);
|
|
2192
|
+
}
|
|
2193
|
+
};
|
|
2194
|
+
ws.on("message", (raw) => {
|
|
2195
|
+
try {
|
|
2196
|
+
const obj = JSON.parse(raw.toString());
|
|
2197
|
+
push({
|
|
2198
|
+
kind: "value",
|
|
2199
|
+
value: {
|
|
2200
|
+
type: obj.type ?? obj.event ?? "progress",
|
|
2201
|
+
collection_id: obj.collection_id !== void 0 ? String(obj.collection_id) : id,
|
|
2202
|
+
document_id: obj.document_id !== void 0 ? String(obj.document_id) : void 0,
|
|
2203
|
+
filename: obj.filename ?? obj.path,
|
|
2204
|
+
status: obj.status,
|
|
2205
|
+
progress: obj.progress,
|
|
2206
|
+
message: obj.message,
|
|
2207
|
+
error: obj.error,
|
|
2208
|
+
timestamp: obj.timestamp ? new Date(obj.timestamp) : void 0,
|
|
2209
|
+
raw: obj
|
|
2210
|
+
}
|
|
2211
|
+
});
|
|
2212
|
+
} catch (e) {
|
|
2213
|
+
push({ kind: "error", error: e });
|
|
2214
|
+
}
|
|
2215
|
+
});
|
|
2216
|
+
ws.on("error", (err) => push({ kind: "error", error: err }));
|
|
2217
|
+
ws.on("close", () => push({ kind: "done" }));
|
|
2218
|
+
const onAbort = () => {
|
|
2219
|
+
try {
|
|
2220
|
+
ws.close();
|
|
2221
|
+
} catch {
|
|
2222
|
+
}
|
|
2223
|
+
};
|
|
2224
|
+
if (opts.signal) {
|
|
2225
|
+
if (opts.signal.aborted) onAbort();
|
|
2226
|
+
else opts.signal.addEventListener("abort", onAbort);
|
|
2227
|
+
}
|
|
2228
|
+
try {
|
|
2229
|
+
while (true) {
|
|
2230
|
+
const next = await new Promise((resolve) => {
|
|
2231
|
+
if (queue.length > 0) {
|
|
2232
|
+
resolve(queue.shift());
|
|
2233
|
+
} else {
|
|
2234
|
+
resolver = resolve;
|
|
2235
|
+
}
|
|
2236
|
+
});
|
|
2237
|
+
if (next.kind === "value") yield next.value;
|
|
2238
|
+
else if (next.kind === "error") throw next.error;
|
|
2239
|
+
else return;
|
|
2240
|
+
}
|
|
2241
|
+
} finally {
|
|
2242
|
+
try {
|
|
2243
|
+
ws.close();
|
|
2244
|
+
} catch {
|
|
2245
|
+
}
|
|
2246
|
+
if (opts.signal) opts.signal.removeEventListener("abort", onAbort);
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
normalize(data) {
|
|
2250
|
+
return {
|
|
2251
|
+
id: String(data.id ?? data.collection_id ?? ""),
|
|
2252
|
+
name: data.name,
|
|
2253
|
+
description: data.description,
|
|
2254
|
+
path: data.path,
|
|
2255
|
+
status: data.status,
|
|
2256
|
+
document_count: data.document_count ?? data.documents,
|
|
2257
|
+
created_at: data.created_at ? new Date(data.created_at) : void 0,
|
|
2258
|
+
updated_at: data.updated_at ? new Date(data.updated_at) : void 0,
|
|
2259
|
+
config: data.config
|
|
2260
|
+
};
|
|
2261
|
+
}
|
|
2262
|
+
};
|
|
2263
|
+
var FilesystemCollectionsClient = class {
|
|
2264
|
+
constructor(synapCores) {
|
|
2265
|
+
this.collections = new FsCollectionsApi(synapCores);
|
|
2266
|
+
}
|
|
2267
|
+
};
|
|
2268
|
+
|
|
2269
|
+
// src/chat.ts
|
|
2270
|
+
var ChatSessionsApi = class {
|
|
2271
|
+
constructor(synapCores) {
|
|
2272
|
+
this.synapCores = synapCores;
|
|
2273
|
+
}
|
|
2274
|
+
async create(opts = {}) {
|
|
2275
|
+
const { data } = await this.synapCores._getHttpClient().post("/ai/sessions", opts);
|
|
2276
|
+
return this.normalize(data);
|
|
2277
|
+
}
|
|
2278
|
+
async list(opts = {}) {
|
|
2279
|
+
const params = new URLSearchParams();
|
|
2280
|
+
if (opts.limit) params.append("limit", String(opts.limit));
|
|
2281
|
+
if (opts.offset) params.append("offset", String(opts.offset));
|
|
2282
|
+
const qs = params.toString();
|
|
2283
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
2284
|
+
`/ai/sessions${qs ? `?${qs}` : ""}`
|
|
2285
|
+
);
|
|
2286
|
+
return (data.sessions ?? data ?? []).map((s) => this.normalize(s));
|
|
2287
|
+
}
|
|
2288
|
+
async get(id) {
|
|
2289
|
+
const { data } = await this.synapCores._getHttpClient().get(`/ai/sessions/${id}`);
|
|
2290
|
+
return this.normalize(data);
|
|
2291
|
+
}
|
|
2292
|
+
async delete(id) {
|
|
2293
|
+
await this.synapCores._getHttpClient().delete(`/ai/sessions/${id}`);
|
|
2294
|
+
}
|
|
2295
|
+
async messages(id, opts = {}) {
|
|
2296
|
+
const params = new URLSearchParams();
|
|
2297
|
+
if (opts.limit) params.append("limit", String(opts.limit));
|
|
2298
|
+
if (opts.offset) params.append("offset", String(opts.offset));
|
|
2299
|
+
const qs = params.toString();
|
|
2300
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
2301
|
+
`/ai/sessions/${id}/messages${qs ? `?${qs}` : ""}`
|
|
2302
|
+
);
|
|
2303
|
+
return (data.messages ?? data ?? []).map((m) => this.normalizeMessage(m, id));
|
|
2304
|
+
}
|
|
2305
|
+
normalize(data) {
|
|
2306
|
+
return {
|
|
2307
|
+
id: String(data.id ?? data.session_id ?? ""),
|
|
2308
|
+
title: data.title,
|
|
2309
|
+
model: data.model,
|
|
2310
|
+
system_prompt: data.system_prompt,
|
|
2311
|
+
created_at: new Date(data.created_at ?? Date.now()),
|
|
2312
|
+
updated_at: data.updated_at ? new Date(data.updated_at) : void 0,
|
|
2313
|
+
message_count: data.message_count ?? data.messages,
|
|
2314
|
+
metadata: data.metadata
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
2317
|
+
normalizeMessage(m, sessionId) {
|
|
2318
|
+
return {
|
|
2319
|
+
id: String(m.id ?? m.message_id ?? ""),
|
|
2320
|
+
session_id: m.session_id !== void 0 ? String(m.session_id) : sessionId,
|
|
2321
|
+
role: m.role,
|
|
2322
|
+
content: m.content ?? m.text ?? "",
|
|
2323
|
+
created_at: new Date(m.created_at ?? Date.now()),
|
|
2324
|
+
metadata: m.metadata
|
|
2325
|
+
};
|
|
2326
|
+
}
|
|
2327
|
+
};
|
|
2328
|
+
var ChatToolsApi = class {
|
|
2329
|
+
constructor(synapCores) {
|
|
2330
|
+
this.synapCores = synapCores;
|
|
2331
|
+
}
|
|
2332
|
+
async list() {
|
|
2333
|
+
const { data } = await this.synapCores._getHttpClient().get("/ai/tools");
|
|
2334
|
+
return (data.tools ?? data ?? []).map((t) => ({
|
|
2335
|
+
name: t.name,
|
|
2336
|
+
description: t.description,
|
|
2337
|
+
parameters: t.parameters ?? t.schema
|
|
2338
|
+
}));
|
|
2339
|
+
}
|
|
2340
|
+
async execute(name, args = {}) {
|
|
2341
|
+
const { data } = await this.synapCores._getHttpClient().post("/ai/tools/execute", {
|
|
2342
|
+
tool: name,
|
|
2343
|
+
arguments: args
|
|
2344
|
+
});
|
|
2345
|
+
return data;
|
|
2346
|
+
}
|
|
2347
|
+
async sql(sql, params = []) {
|
|
2348
|
+
const { data } = await this.synapCores._getHttpClient().post("/ai/tools/sql", {
|
|
2349
|
+
sql,
|
|
2350
|
+
parameters: params
|
|
2351
|
+
});
|
|
2352
|
+
return data;
|
|
2353
|
+
}
|
|
2354
|
+
};
|
|
2355
|
+
var ChatCacheApi = class {
|
|
2356
|
+
constructor(synapCores) {
|
|
2357
|
+
this.synapCores = synapCores;
|
|
2358
|
+
}
|
|
2359
|
+
async stats() {
|
|
2360
|
+
const { data } = await this.synapCores._getHttpClient().get("/ai/cache/stats");
|
|
2361
|
+
return {
|
|
2362
|
+
size_bytes: data.size_bytes ?? data.bytes,
|
|
2363
|
+
hit_count: data.hit_count ?? data.hits,
|
|
2364
|
+
miss_count: data.miss_count ?? data.misses,
|
|
2365
|
+
entries: data.entries ?? data.count,
|
|
2366
|
+
raw: data
|
|
2367
|
+
};
|
|
2368
|
+
}
|
|
2369
|
+
async clear() {
|
|
2370
|
+
await this.synapCores._getHttpClient().post("/ai/cache/clear", {});
|
|
2371
|
+
}
|
|
2372
|
+
};
|
|
2373
|
+
var ChatClient = class {
|
|
2374
|
+
constructor(synapCores) {
|
|
2375
|
+
this.synapCores = synapCores;
|
|
2376
|
+
this.sessions = new ChatSessionsApi(synapCores);
|
|
2377
|
+
this.tools = new ChatToolsApi(synapCores);
|
|
2378
|
+
this.cache = new ChatCacheApi(synapCores);
|
|
2379
|
+
}
|
|
2380
|
+
/**
|
|
2381
|
+
* Send a one-shot chat message. The gateway accepts both /ai/chat and
|
|
2382
|
+
* the alias /ai/ — we use /ai/chat for clarity.
|
|
2383
|
+
*/
|
|
2384
|
+
async send(sessionId, content, opts = {}) {
|
|
2385
|
+
const { data } = await this.synapCores._getHttpClient().post("/ai/chat", {
|
|
2386
|
+
session_id: sessionId,
|
|
2387
|
+
content,
|
|
2388
|
+
...opts
|
|
2389
|
+
});
|
|
2390
|
+
const messageData = data.message ?? data;
|
|
2391
|
+
return {
|
|
2392
|
+
message: {
|
|
2393
|
+
id: String(messageData.id ?? messageData.message_id ?? ""),
|
|
2394
|
+
session_id: sessionId,
|
|
2395
|
+
role: messageData.role ?? "assistant",
|
|
2396
|
+
content: messageData.content ?? messageData.text ?? "",
|
|
2397
|
+
created_at: new Date(messageData.created_at ?? Date.now()),
|
|
2398
|
+
metadata: messageData.metadata
|
|
2399
|
+
},
|
|
2400
|
+
tool_calls: data.tool_calls,
|
|
2401
|
+
usage: data.usage
|
|
2402
|
+
};
|
|
2403
|
+
}
|
|
2404
|
+
/**
|
|
2405
|
+
* Stream a chat completion. Returns an async iterator over SSE chunks.
|
|
2406
|
+
*/
|
|
2407
|
+
async *stream(sessionId, content, opts = {}) {
|
|
2408
|
+
const http = this.synapCores._getHttpClient();
|
|
2409
|
+
const response = await http.post(
|
|
2410
|
+
"/ai/chat/stream",
|
|
2411
|
+
{
|
|
2412
|
+
session_id: sessionId,
|
|
2413
|
+
content,
|
|
2414
|
+
...opts
|
|
2415
|
+
},
|
|
2416
|
+
{ responseType: "stream" }
|
|
2417
|
+
);
|
|
2418
|
+
const stream = response.data;
|
|
2419
|
+
let buffer = "";
|
|
2420
|
+
for await (const chunk of stream) {
|
|
2421
|
+
buffer += chunk.toString();
|
|
2422
|
+
const frames = buffer.split(/\n\n/);
|
|
2423
|
+
buffer = frames.pop() ?? "";
|
|
2424
|
+
for (const frame of frames) {
|
|
2425
|
+
const trimmed = frame.trim();
|
|
2426
|
+
if (!trimmed) continue;
|
|
2427
|
+
const line = trimmed.startsWith("data:") ? trimmed.slice(5).trim() : trimmed;
|
|
2428
|
+
if (line === "[DONE]") {
|
|
2429
|
+
yield { done: true };
|
|
2430
|
+
return;
|
|
2431
|
+
}
|
|
2432
|
+
try {
|
|
2433
|
+
const obj = JSON.parse(line);
|
|
2434
|
+
yield {
|
|
2435
|
+
delta: obj.delta ?? obj.choices?.[0]?.delta?.content ?? obj.text ?? void 0,
|
|
2436
|
+
content: obj.content ?? obj.message?.content,
|
|
2437
|
+
type: obj.type ?? obj.event,
|
|
2438
|
+
done: obj.done ?? obj.finished,
|
|
2439
|
+
raw: obj
|
|
2440
|
+
};
|
|
2441
|
+
} catch {
|
|
2442
|
+
yield { delta: line, raw: line };
|
|
2443
|
+
}
|
|
2444
|
+
}
|
|
2445
|
+
}
|
|
2446
|
+
if (buffer.trim()) {
|
|
2447
|
+
try {
|
|
2448
|
+
yield { raw: JSON.parse(buffer) };
|
|
2449
|
+
} catch {
|
|
2450
|
+
yield { delta: buffer };
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
/**
|
|
2455
|
+
* Get prompt suggestions, e.g. for an empty session UI.
|
|
2456
|
+
*/
|
|
2457
|
+
async suggestions(opts = {}) {
|
|
2458
|
+
const { data } = await this.synapCores._getHttpClient().post("/ai/suggestions", opts);
|
|
2459
|
+
return (data.suggestions ?? data ?? []).map((s) => ({
|
|
2460
|
+
prompt: s.prompt ?? s.text ?? "",
|
|
2461
|
+
category: s.category,
|
|
2462
|
+
meta: s.meta ?? s.metadata
|
|
2463
|
+
}));
|
|
2464
|
+
}
|
|
2465
|
+
/**
|
|
2466
|
+
* List configured chat models.
|
|
1774
2467
|
*/
|
|
1775
|
-
async
|
|
1776
|
-
const { data } = await this.synapCores._getHttpClient().
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
active: data.active,
|
|
1785
|
-
last_run_at: data.last_run_at ? new Date(data.last_run_at) : void 0,
|
|
1786
|
-
next_run_at: data.next_run_at ? new Date(data.next_run_at) : void 0,
|
|
1787
|
-
created_at: new Date(data.created_at),
|
|
1788
|
-
tags: data.tags || []
|
|
1789
|
-
};
|
|
2468
|
+
async models() {
|
|
2469
|
+
const { data } = await this.synapCores._getHttpClient().get("/ai/models");
|
|
2470
|
+
return (data.models ?? data ?? []).map((m) => ({
|
|
2471
|
+
id: m.id ?? m.name,
|
|
2472
|
+
name: m.name,
|
|
2473
|
+
provider: m.provider,
|
|
2474
|
+
context_window: m.context_window ?? m.max_context,
|
|
2475
|
+
capabilities: m.capabilities
|
|
2476
|
+
}));
|
|
1790
2477
|
}
|
|
1791
2478
|
/**
|
|
1792
|
-
*
|
|
2479
|
+
* List the available system prompts library.
|
|
1793
2480
|
*/
|
|
1794
|
-
async
|
|
1795
|
-
const { data } = await this.synapCores._getHttpClient().get("/
|
|
2481
|
+
async systemPrompts() {
|
|
2482
|
+
const { data } = await this.synapCores._getHttpClient().get("/ai/system-prompts");
|
|
2483
|
+
return (data.prompts ?? data.system_prompts ?? data ?? []).map((p) => ({
|
|
2484
|
+
id: String(p.id ?? p.name ?? ""),
|
|
2485
|
+
name: p.name,
|
|
2486
|
+
content: p.content ?? p.text ?? "",
|
|
2487
|
+
description: p.description,
|
|
2488
|
+
category: p.category
|
|
2489
|
+
}));
|
|
2490
|
+
}
|
|
2491
|
+
};
|
|
2492
|
+
|
|
2493
|
+
// src/multimodal.ts
|
|
2494
|
+
var MultimodalClient = class {
|
|
2495
|
+
constructor(synapCores) {
|
|
2496
|
+
this.synapCores = synapCores;
|
|
2497
|
+
}
|
|
2498
|
+
async similarity(a, b, opts = {}) {
|
|
2499
|
+
const { data } = await this.synapCores._getHttpClient().post("/multimodal/similarity", {
|
|
2500
|
+
a: typeof a === "string" ? { type: "text", text: a } : a,
|
|
2501
|
+
b: typeof b === "string" ? { type: "text", text: b } : b,
|
|
2502
|
+
...opts
|
|
2503
|
+
});
|
|
1796
2504
|
return {
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
failed_backups: data.failed_backups || 0,
|
|
1801
|
-
avg_backup_size_bytes: data.avg_backup_size_bytes || 0,
|
|
1802
|
-
avg_duration_ms: data.avg_duration_ms || 0,
|
|
1803
|
-
last_backup_at: data.last_backup_at ? new Date(data.last_backup_at) : void 0,
|
|
1804
|
-
next_scheduled_at: data.next_scheduled_at ? new Date(data.next_scheduled_at) : void 0
|
|
2505
|
+
similarity: data.similarity ?? data.score ?? 0,
|
|
2506
|
+
metric: data.metric ?? opts.metric,
|
|
2507
|
+
raw: data
|
|
1805
2508
|
};
|
|
1806
2509
|
}
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
2510
|
+
async search(query, opts = {}) {
|
|
2511
|
+
const { data } = await this.synapCores._getHttpClient().post("/multimodal/search", {
|
|
2512
|
+
query: typeof query === "string" ? { type: "text", text: query } : query,
|
|
2513
|
+
...opts
|
|
2514
|
+
});
|
|
2515
|
+
return (data.results ?? data.hits ?? data ?? []).map((r) => ({
|
|
2516
|
+
id: String(r.id ?? r.document_id ?? ""),
|
|
2517
|
+
score: r.score ?? r.similarity ?? 0,
|
|
2518
|
+
modality: r.modality,
|
|
2519
|
+
metadata: r.metadata
|
|
2520
|
+
}));
|
|
2521
|
+
}
|
|
2522
|
+
async join(left, right, opts = {}) {
|
|
2523
|
+
const normalize = (side) => Array.isArray(side) ? side.map((s) => typeof s === "string" ? { type: "text", text: s } : s) : side;
|
|
2524
|
+
const { data } = await this.synapCores._getHttpClient().post("/multimodal/join", {
|
|
2525
|
+
left: normalize(left),
|
|
2526
|
+
right: normalize(right),
|
|
2527
|
+
...opts
|
|
2528
|
+
});
|
|
1811
2529
|
return {
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
2530
|
+
pairs: (data.pairs ?? data.results ?? []).map((p) => ({
|
|
2531
|
+
left: p.left,
|
|
2532
|
+
right: p.right,
|
|
2533
|
+
score: p.score ?? p.similarity ?? 0
|
|
2534
|
+
}))
|
|
2535
|
+
};
|
|
2536
|
+
}
|
|
2537
|
+
async embed(input, model) {
|
|
2538
|
+
const { data } = await this.synapCores._getHttpClient().post("/multimodal/embed", {
|
|
2539
|
+
input: typeof input === "string" ? { type: "text", text: input } : input,
|
|
2540
|
+
model
|
|
2541
|
+
});
|
|
2542
|
+
const embedding = data.embedding ?? data.vector ?? [];
|
|
2543
|
+
return {
|
|
2544
|
+
embedding,
|
|
2545
|
+
modality: data.modality,
|
|
2546
|
+
model: data.model ?? model,
|
|
2547
|
+
dimensions: data.dimensions ?? embedding.length
|
|
1829
2548
|
};
|
|
1830
2549
|
}
|
|
1831
2550
|
};
|
|
1832
2551
|
|
|
1833
|
-
// src/
|
|
1834
|
-
var
|
|
1835
|
-
constructor(
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
2552
|
+
// src/system.ts
|
|
2553
|
+
var VisionApi = class {
|
|
2554
|
+
constructor(synapCores) {
|
|
2555
|
+
this.synapCores = synapCores;
|
|
2556
|
+
}
|
|
2557
|
+
async get() {
|
|
2558
|
+
try {
|
|
2559
|
+
const { data } = await this.synapCores._getHttpClient().get("/system/vision");
|
|
2560
|
+
if (!data || Object.keys(data).length === 0) return null;
|
|
2561
|
+
return data;
|
|
2562
|
+
} catch (e) {
|
|
2563
|
+
if (e?.statusCode === 404 || e?.code === "NOT_FOUND") return null;
|
|
2564
|
+
throw e;
|
|
1842
2565
|
}
|
|
1843
2566
|
}
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
super(message, "CONNECTION_ERROR", details);
|
|
1848
|
-
this.name = "ConnectionError";
|
|
2567
|
+
async set(cfg) {
|
|
2568
|
+
const { data } = await this.synapCores._getHttpClient().put("/system/vision", cfg);
|
|
2569
|
+
return data;
|
|
1849
2570
|
}
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
constructor(message, details) {
|
|
1853
|
-
super(message, "AUTH_ERROR", details);
|
|
1854
|
-
this.name = "AuthenticationError";
|
|
2571
|
+
async delete() {
|
|
2572
|
+
await this.synapCores._getHttpClient().delete("/system/vision");
|
|
1855
2573
|
}
|
|
1856
|
-
}
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
2574
|
+
async test(payload = {}) {
|
|
2575
|
+
const { data } = await this.synapCores._getHttpClient().post("/system/vision/test", payload);
|
|
2576
|
+
return {
|
|
2577
|
+
success: data.success ?? false,
|
|
2578
|
+
latency_ms: data.latency_ms,
|
|
2579
|
+
response: data.response,
|
|
2580
|
+
error: data.error
|
|
2581
|
+
};
|
|
1861
2582
|
}
|
|
1862
2583
|
};
|
|
1863
|
-
var
|
|
1864
|
-
constructor(
|
|
1865
|
-
|
|
1866
|
-
this.name = "NotFoundError";
|
|
2584
|
+
var SystemClient = class {
|
|
2585
|
+
constructor(synapCores) {
|
|
2586
|
+
this.vision = new VisionApi(synapCores);
|
|
1867
2587
|
}
|
|
1868
2588
|
};
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
2589
|
+
|
|
2590
|
+
// src/transactions.ts
|
|
2591
|
+
var Tx = class {
|
|
2592
|
+
constructor(http, id, options) {
|
|
2593
|
+
this.http = http;
|
|
2594
|
+
this.id = id;
|
|
2595
|
+
this.options = options;
|
|
2596
|
+
this.active = true;
|
|
1873
2597
|
}
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
constructor(message, details) {
|
|
1877
|
-
super(message, "TIMEOUT_ERROR", details);
|
|
1878
|
-
this.name = "TimeoutError";
|
|
2598
|
+
isActive() {
|
|
2599
|
+
return this.active;
|
|
1879
2600
|
}
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
2601
|
+
async execute(sql, params = []) {
|
|
2602
|
+
this.assertActive();
|
|
2603
|
+
const { data } = await this.http.post(`/transactions/${this.id}/execute`, {
|
|
2604
|
+
sql,
|
|
2605
|
+
parameters: params
|
|
2606
|
+
});
|
|
2607
|
+
return {
|
|
2608
|
+
columns: data.columns ?? [],
|
|
2609
|
+
rows: data.rows ?? [],
|
|
2610
|
+
rows_affected: data.rows_affected,
|
|
2611
|
+
execution_time_ms: data.execution_time_ms ?? data.took_ms
|
|
2612
|
+
};
|
|
1886
2613
|
}
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
this.
|
|
1894
|
-
this.
|
|
1895
|
-
this.
|
|
2614
|
+
async commit() {
|
|
2615
|
+
this.assertActive();
|
|
2616
|
+
await this.http.post(`/transactions/${this.id}/commit`, {});
|
|
2617
|
+
this.active = false;
|
|
2618
|
+
}
|
|
2619
|
+
async rollback() {
|
|
2620
|
+
this.assertActive();
|
|
2621
|
+
await this.http.post(`/transactions/${this.id}/rollback`, {});
|
|
2622
|
+
this.active = false;
|
|
2623
|
+
}
|
|
2624
|
+
async savepoint(name) {
|
|
2625
|
+
this.assertActive();
|
|
2626
|
+
await this.http.post(`/transactions/${this.id}/savepoint`, { name });
|
|
2627
|
+
}
|
|
2628
|
+
async rollbackTo(name) {
|
|
2629
|
+
this.assertActive();
|
|
2630
|
+
await this.http.post(`/transactions/${this.id}/savepoint/${name}/rollback`, {});
|
|
2631
|
+
}
|
|
2632
|
+
assertActive() {
|
|
2633
|
+
if (!this.active) {
|
|
2634
|
+
throw new Error(`Transaction ${this.id} has already been committed/rolled back`);
|
|
2635
|
+
}
|
|
1896
2636
|
}
|
|
1897
2637
|
};
|
|
1898
|
-
var
|
|
1899
|
-
constructor(
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
2638
|
+
var TxHistoryApi = class {
|
|
2639
|
+
constructor(synapCores) {
|
|
2640
|
+
this.synapCores = synapCores;
|
|
2641
|
+
}
|
|
2642
|
+
async list(opts = {}) {
|
|
2643
|
+
const params = new URLSearchParams();
|
|
2644
|
+
if (opts.limit) params.append("limit", String(opts.limit));
|
|
2645
|
+
if (opts.status) params.append("status", opts.status);
|
|
2646
|
+
const qs = params.toString();
|
|
2647
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
2648
|
+
`/transactions/history${qs ? `?${qs}` : ""}`
|
|
2649
|
+
);
|
|
2650
|
+
return (data.transactions ?? data.history ?? data ?? []).map((row) => ({
|
|
2651
|
+
id: String(row.id ?? row.transaction_id ?? ""),
|
|
2652
|
+
status: row.status ?? "unknown",
|
|
2653
|
+
started_at: new Date(row.started_at ?? row.created_at ?? Date.now()),
|
|
2654
|
+
completed_at: row.completed_at ? new Date(row.completed_at) : void 0,
|
|
2655
|
+
isolation_level: row.isolation_level,
|
|
2656
|
+
read_only: row.read_only,
|
|
2657
|
+
statement_count: row.statement_count ?? row.statements,
|
|
2658
|
+
metrics: row.metrics
|
|
2659
|
+
}));
|
|
2660
|
+
}
|
|
2661
|
+
async get(id) {
|
|
2662
|
+
const { data } = await this.synapCores._getHttpClient().get(
|
|
2663
|
+
`/transactions/history/${id}`
|
|
2664
|
+
);
|
|
2665
|
+
return {
|
|
2666
|
+
id: String(data.id ?? id),
|
|
2667
|
+
status: data.status ?? "unknown",
|
|
2668
|
+
started_at: new Date(data.started_at ?? data.created_at ?? Date.now()),
|
|
2669
|
+
completed_at: data.completed_at ? new Date(data.completed_at) : void 0,
|
|
2670
|
+
isolation_level: data.isolation_level,
|
|
2671
|
+
read_only: data.read_only,
|
|
2672
|
+
statement_count: data.statement_count ?? data.statements,
|
|
2673
|
+
metrics: data.metrics
|
|
2674
|
+
};
|
|
1905
2675
|
}
|
|
1906
2676
|
};
|
|
1907
|
-
var
|
|
1908
|
-
constructor(
|
|
1909
|
-
|
|
1910
|
-
this.
|
|
1911
|
-
|
|
1912
|
-
|
|
2677
|
+
var TransactionsClient = class {
|
|
2678
|
+
constructor(synapCores) {
|
|
2679
|
+
this.synapCores = synapCores;
|
|
2680
|
+
this.history = new TxHistoryApi(synapCores);
|
|
2681
|
+
}
|
|
2682
|
+
/**
|
|
2683
|
+
* Begin a new server-side transaction.
|
|
2684
|
+
*/
|
|
2685
|
+
async begin(opts = {}) {
|
|
2686
|
+
const { data } = await this.synapCores._getHttpClient().post("/transactions", opts);
|
|
2687
|
+
const id = String(data.id ?? data.transaction_id ?? "");
|
|
2688
|
+
if (!id) {
|
|
2689
|
+
throw new Error("begin(): server did not return a transaction id");
|
|
2690
|
+
}
|
|
2691
|
+
return new Tx(this.synapCores._getHttpClient(), id, opts);
|
|
1913
2692
|
}
|
|
1914
2693
|
};
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
2694
|
+
|
|
2695
|
+
// src/mcp.ts
|
|
2696
|
+
var mcpRequestCounter = 0;
|
|
2697
|
+
function withId(req) {
|
|
2698
|
+
if (req.id !== void 0 && req.id !== null) return req;
|
|
2699
|
+
mcpRequestCounter += 1;
|
|
2700
|
+
return { ...req, id: `mcp-${Date.now()}-${mcpRequestCounter}` };
|
|
2701
|
+
}
|
|
2702
|
+
var McpClient = class {
|
|
2703
|
+
constructor(synapCores) {
|
|
2704
|
+
this.synapCores = synapCores;
|
|
2705
|
+
}
|
|
2706
|
+
/**
|
|
2707
|
+
* Invoke a single MCP method.
|
|
2708
|
+
*/
|
|
2709
|
+
async invoke(req) {
|
|
2710
|
+
const body = withId(req);
|
|
2711
|
+
const { data } = await this.synapCores._getHttpClient().post("/mcp", body);
|
|
2712
|
+
return {
|
|
2713
|
+
id: data.id ?? body.id,
|
|
2714
|
+
result: data.result,
|
|
2715
|
+
error: data.error,
|
|
2716
|
+
raw: data
|
|
2717
|
+
};
|
|
2718
|
+
}
|
|
2719
|
+
/**
|
|
2720
|
+
* Send an array of MCP invocations and resolve to the matching array
|
|
2721
|
+
* of responses (in the order returned by the gateway).
|
|
2722
|
+
*/
|
|
2723
|
+
async batch(reqs) {
|
|
2724
|
+
const body = reqs.map(withId);
|
|
2725
|
+
const { data } = await this.synapCores._getHttpClient().post("/mcp/batch", body);
|
|
2726
|
+
const arr = Array.isArray(data) ? data : data.responses ?? data.results ?? [];
|
|
2727
|
+
return arr.map((r) => ({
|
|
2728
|
+
id: r.id,
|
|
2729
|
+
result: r.result,
|
|
2730
|
+
error: r.error,
|
|
2731
|
+
raw: r
|
|
2732
|
+
}));
|
|
2733
|
+
}
|
|
2734
|
+
/**
|
|
2735
|
+
* Discover the server's MCP capabilities and tools.
|
|
2736
|
+
*/
|
|
2737
|
+
async info() {
|
|
2738
|
+
const { data } = await this.synapCores._getHttpClient().get("/mcp/info");
|
|
2739
|
+
return {
|
|
2740
|
+
version: data.version ?? data.mcp_version ?? "0",
|
|
2741
|
+
capabilities: data.capabilities,
|
|
2742
|
+
tools: data.tools,
|
|
2743
|
+
meta: data.meta ?? data.metadata
|
|
2744
|
+
};
|
|
1922
2745
|
}
|
|
1923
2746
|
};
|
|
1924
2747
|
|
|
@@ -1957,7 +2780,7 @@ var SynapCores = class {
|
|
|
1957
2780
|
timeout: this.config.timeout,
|
|
1958
2781
|
headers: {
|
|
1959
2782
|
"Content-Type": "application/json",
|
|
1960
|
-
"User-Agent": "synapcores-nodejs/0.
|
|
2783
|
+
"User-Agent": "synapcores-nodejs/0.2.0",
|
|
1961
2784
|
...authHeader
|
|
1962
2785
|
},
|
|
1963
2786
|
...httpsAgent && { httpsAgent }
|
|
@@ -1973,6 +2796,44 @@ var SynapCores = class {
|
|
|
1973
2796
|
this.import = new ImportExportClient(this);
|
|
1974
2797
|
this.integrations = new IntegrationClient(this);
|
|
1975
2798
|
this.backup = new BackupClient(this);
|
|
2799
|
+
this.graph = new GraphClient(this);
|
|
2800
|
+
this.nl2sql = new NL2SqlClient(this);
|
|
2801
|
+
this.filesystem = new FilesystemCollectionsClient(this);
|
|
2802
|
+
this.chat = new ChatClient(this);
|
|
2803
|
+
this.multimodal = new MultimodalClient(this);
|
|
2804
|
+
this.system = new SystemClient(this);
|
|
2805
|
+
this.transactions = new TransactionsClient(this);
|
|
2806
|
+
this.mcp = new McpClient(this);
|
|
2807
|
+
}
|
|
2808
|
+
/**
|
|
2809
|
+
* Build the WebSocket base URL (ws:// or wss://).
|
|
2810
|
+
*/
|
|
2811
|
+
_getWsBaseUrl() {
|
|
2812
|
+
const protocol = this.config.useHttps ? "wss" : "ws";
|
|
2813
|
+
return `${protocol}://${this.config.host}:${this.config.port}`;
|
|
2814
|
+
}
|
|
2815
|
+
/**
|
|
2816
|
+
* Read-only access to the configured host/port for WS-clients.
|
|
2817
|
+
*/
|
|
2818
|
+
_getConfig() {
|
|
2819
|
+
return this.config;
|
|
2820
|
+
}
|
|
2821
|
+
/**
|
|
2822
|
+
* Exchange the current credentials (JWT or API key) for a short-lived
|
|
2823
|
+
* WebSocket ticket. Use the returned token as the `?token=` query
|
|
2824
|
+
* param when opening any /ws endpoint.
|
|
2825
|
+
*/
|
|
2826
|
+
async createWsTicket() {
|
|
2827
|
+
const { data } = await this.httpClient.post("/ws/ticket", {});
|
|
2828
|
+
const token = data.token ?? data.ticket;
|
|
2829
|
+
const expiresAt = typeof data.expiresAt === "number" ? data.expiresAt : data.expires_at ? Date.parse(data.expires_at) : Date.now() + 6e4;
|
|
2830
|
+
return { token, expiresAt };
|
|
2831
|
+
}
|
|
2832
|
+
/**
|
|
2833
|
+
* Revoke a previously-issued ticket (best-effort).
|
|
2834
|
+
*/
|
|
2835
|
+
async revokeWsTicket(token) {
|
|
2836
|
+
await this.httpClient.post("/ws/ticket/revoke", { token });
|
|
1976
2837
|
}
|
|
1977
2838
|
handleError(error) {
|
|
1978
2839
|
if (!error.response) {
|
|
@@ -2161,11 +3022,11 @@ var SynapCores = class {
|
|
|
2161
3022
|
async embed(text, options = {}) {
|
|
2162
3023
|
const isBatch = Array.isArray(text);
|
|
2163
3024
|
const texts = isBatch ? text : [text];
|
|
2164
|
-
const
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
return
|
|
3025
|
+
const path = isBatch ? "/ai/embeddings/batch" : "/ai/embeddings";
|
|
3026
|
+
const body = isBatch ? { texts, model: options.model } : { text: texts[0], model: options.model };
|
|
3027
|
+
const { data } = await this.httpClient.post(path, body);
|
|
3028
|
+
if (isBatch) return data.embeddings ?? data;
|
|
3029
|
+
return data.embedding ?? data.embeddings?.[0] ?? data;
|
|
2169
3030
|
}
|
|
2170
3031
|
// Internal method for HTTP client access
|
|
2171
3032
|
_getHttpClient() {
|
|
@@ -2292,8 +3153,16 @@ var SynapCores = class {
|
|
|
2292
3153
|
* @returns Promise resolving to table information
|
|
2293
3154
|
*/
|
|
2294
3155
|
async describeTable(tableName) {
|
|
2295
|
-
const
|
|
2296
|
-
|
|
3156
|
+
const [tableRes, colsRes, idxRes] = await Promise.all([
|
|
3157
|
+
this.httpClient.get(`/schema/tables/${tableName}`),
|
|
3158
|
+
this.httpClient.get(`/schema/tables/${tableName}/columns`),
|
|
3159
|
+
this.httpClient.get(`/schema/tables/${tableName}/indexes`)
|
|
3160
|
+
]);
|
|
3161
|
+
return {
|
|
3162
|
+
...tableRes.data,
|
|
3163
|
+
columns: colsRes.data?.columns ?? colsRes.data ?? [],
|
|
3164
|
+
indexes: idxRes.data?.indexes ?? idxRes.data ?? []
|
|
3165
|
+
};
|
|
2297
3166
|
}
|
|
2298
3167
|
/**
|
|
2299
3168
|
* Lists all tables in the current database
|
|
@@ -2426,19 +3295,26 @@ var SynapCores = class {
|
|
|
2426
3295
|
* @returns Promise resolving to batch operation result
|
|
2427
3296
|
*/
|
|
2428
3297
|
async batchInsert(options) {
|
|
2429
|
-
const
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
3298
|
+
const cols = options.columns ?? [];
|
|
3299
|
+
const queries = options.rows.map((row) => {
|
|
3300
|
+
const values = Array.isArray(row) ? row : cols.map((c) => row[c]);
|
|
3301
|
+
return {
|
|
3302
|
+
sql: `INSERT INTO ${options.tableName} (${cols.join(", ")}) VALUES (${values.map((_, i) => "$" + (i + 1)).join(", ")})`,
|
|
3303
|
+
parameters: values
|
|
3304
|
+
};
|
|
3305
|
+
});
|
|
3306
|
+
const { data } = await this.httpClient.post("/query/execute/batch", {
|
|
3307
|
+
queries,
|
|
3308
|
+
transactional: false
|
|
3309
|
+
});
|
|
3310
|
+
const results = data.results ?? [];
|
|
3311
|
+
const successful = results.filter((r) => !r.error).length;
|
|
3312
|
+
return {
|
|
3313
|
+
totalProcessed: results.length,
|
|
3314
|
+
successful,
|
|
3315
|
+
failed: results.length - successful,
|
|
3316
|
+
errors: results.filter((r) => r.error).map((r) => r.error),
|
|
3317
|
+
tookMs: data.total_execution_time_ms ?? 0
|
|
2442
3318
|
};
|
|
2443
3319
|
}
|
|
2444
3320
|
/**
|
|
@@ -2447,17 +3323,27 @@ var SynapCores = class {
|
|
|
2447
3323
|
* @returns Promise resolving to batch operation result
|
|
2448
3324
|
*/
|
|
2449
3325
|
async batchUpdate(options) {
|
|
2450
|
-
const
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
3326
|
+
const queries = options.updates.map((u) => {
|
|
3327
|
+
const setClause = Object.keys(u.set ?? {}).map((k, i) => `${k} = $${i + 1}`).join(", ");
|
|
3328
|
+
const setVals = Object.values(u.set ?? {});
|
|
3329
|
+
const whereStr = u.where ?? "1=1";
|
|
3330
|
+
return {
|
|
3331
|
+
sql: `UPDATE ${options.tableName} SET ${setClause} WHERE ${whereStr}`,
|
|
3332
|
+
parameters: setVals
|
|
3333
|
+
};
|
|
2454
3334
|
});
|
|
3335
|
+
const { data } = await this.httpClient.post("/query/execute/batch", {
|
|
3336
|
+
queries,
|
|
3337
|
+
transactional: false
|
|
3338
|
+
});
|
|
3339
|
+
const results = data.results ?? [];
|
|
3340
|
+
const successful = results.filter((r) => !r.error).length;
|
|
2455
3341
|
return {
|
|
2456
|
-
totalProcessed:
|
|
2457
|
-
successful
|
|
2458
|
-
failed:
|
|
2459
|
-
errors:
|
|
2460
|
-
tookMs: data.
|
|
3342
|
+
totalProcessed: results.length,
|
|
3343
|
+
successful,
|
|
3344
|
+
failed: results.length - successful,
|
|
3345
|
+
errors: results.filter((r) => r.error).map((r) => r.error),
|
|
3346
|
+
tookMs: data.total_execution_time_ms ?? 0
|
|
2461
3347
|
};
|
|
2462
3348
|
}
|
|
2463
3349
|
/**
|
|
@@ -2466,17 +3352,22 @@ var SynapCores = class {
|
|
|
2466
3352
|
* @returns Promise resolving to batch operation result
|
|
2467
3353
|
*/
|
|
2468
3354
|
async batchDelete(options) {
|
|
2469
|
-
const
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
3355
|
+
const queries = (options.whereConditions ?? []).map((cond) => ({
|
|
3356
|
+
sql: `DELETE FROM ${options.tableName} WHERE ${typeof cond === "string" ? cond : JSON.stringify(cond)}`,
|
|
3357
|
+
parameters: []
|
|
3358
|
+
}));
|
|
3359
|
+
const { data } = await this.httpClient.post("/query/execute/batch", {
|
|
3360
|
+
queries,
|
|
3361
|
+
transactional: false
|
|
2473
3362
|
});
|
|
3363
|
+
const results = data.results ?? [];
|
|
3364
|
+
const successful = results.filter((r) => !r.error).length;
|
|
2474
3365
|
return {
|
|
2475
|
-
totalProcessed:
|
|
2476
|
-
successful
|
|
2477
|
-
failed:
|
|
2478
|
-
errors:
|
|
2479
|
-
tookMs: data.
|
|
3366
|
+
totalProcessed: results.length,
|
|
3367
|
+
successful,
|
|
3368
|
+
failed: results.length - successful,
|
|
3369
|
+
errors: results.filter((r) => r.error).map((r) => r.error),
|
|
3370
|
+
tookMs: data.total_execution_time_ms ?? 0
|
|
2480
3371
|
};
|
|
2481
3372
|
}
|
|
2482
3373
|
// =================================================================
|
|
@@ -2489,15 +3380,15 @@ var SynapCores = class {
|
|
|
2489
3380
|
* @returns Promise resolving to prepared statement
|
|
2490
3381
|
*/
|
|
2491
3382
|
async prepareStatement(sql, options = {}) {
|
|
2492
|
-
const { data } = await this.httpClient.post("/prepare", {
|
|
3383
|
+
const { data } = await this.httpClient.post("/query/prepare", {
|
|
2493
3384
|
sql,
|
|
2494
3385
|
name: options.name,
|
|
2495
3386
|
parameter_types: options.parameterTypes
|
|
2496
3387
|
});
|
|
2497
3388
|
const prepared = {
|
|
2498
|
-
id: data.statement_id,
|
|
3389
|
+
id: data.statement_id ?? data.id,
|
|
2499
3390
|
sql,
|
|
2500
|
-
parameterCount: data.parameter_count
|
|
3391
|
+
parameterCount: data.parameter_count ?? data.parameters_count ?? 0
|
|
2501
3392
|
};
|
|
2502
3393
|
if (options.name) {
|
|
2503
3394
|
this.preparedStatements.set(options.name, prepared);
|
|
@@ -2514,7 +3405,7 @@ var SynapCores = class {
|
|
|
2514
3405
|
if (this.preparedStatements.has(statementId)) {
|
|
2515
3406
|
statementId = this.preparedStatements.get(statementId).id;
|
|
2516
3407
|
}
|
|
2517
|
-
const { data } = await this.httpClient.post("/
|
|
3408
|
+
const { data } = await this.httpClient.post("/query/exec", {
|
|
2518
3409
|
statement_id: statementId,
|
|
2519
3410
|
parameters: params
|
|
2520
3411
|
});
|
|
@@ -2534,10 +3425,10 @@ var SynapCores = class {
|
|
|
2534
3425
|
async deallocatePrepared(statementId) {
|
|
2535
3426
|
if (this.preparedStatements.has(statementId)) {
|
|
2536
3427
|
const prepared = this.preparedStatements.get(statementId);
|
|
2537
|
-
await this.httpClient.
|
|
3428
|
+
await this.httpClient.post("/query/close", { statement_id: prepared.id });
|
|
2538
3429
|
this.preparedStatements.delete(statementId);
|
|
2539
3430
|
} else {
|
|
2540
|
-
await this.httpClient.
|
|
3431
|
+
await this.httpClient.post("/query/close", { statement_id: statementId });
|
|
2541
3432
|
}
|
|
2542
3433
|
}
|
|
2543
3434
|
/**
|
|
@@ -2628,231 +3519,198 @@ var SynapCores = class {
|
|
|
2628
3519
|
if (vector1.length !== vector2.length) {
|
|
2629
3520
|
throw new VectorError("Vector dimensions must match", "DIMENSION_MISMATCH");
|
|
2630
3521
|
}
|
|
2631
|
-
const { data } = await this.httpClient.post("/
|
|
2632
|
-
|
|
2633
|
-
|
|
3522
|
+
const { data } = await this.httpClient.post("/vector-algebra/operation", {
|
|
3523
|
+
op: "add",
|
|
3524
|
+
a: vector1,
|
|
3525
|
+
b: vector2
|
|
2634
3526
|
});
|
|
3527
|
+
const result = data.result ?? data.vector ?? [];
|
|
2635
3528
|
return {
|
|
2636
|
-
result: { values:
|
|
3529
|
+
result: { values: result, dimensions: result.length },
|
|
2637
3530
|
operation: "addition",
|
|
2638
3531
|
tookMs: data.took_ms
|
|
2639
3532
|
};
|
|
2640
3533
|
}
|
|
2641
3534
|
/**
|
|
2642
3535
|
* Performs vector subtraction
|
|
2643
|
-
* @param vector1 - First vector (minuend)
|
|
2644
|
-
* @param vector2 - Second vector (subtrahend)
|
|
2645
|
-
* @returns Promise resolving to vector subtraction result
|
|
2646
3536
|
*/
|
|
2647
3537
|
async vectorSubtract(vector1, vector2) {
|
|
2648
3538
|
if (vector1.length !== vector2.length) {
|
|
2649
3539
|
throw new VectorError("Vector dimensions must match", "DIMENSION_MISMATCH");
|
|
2650
3540
|
}
|
|
2651
|
-
const { data } = await this.httpClient.post("/
|
|
2652
|
-
|
|
2653
|
-
|
|
3541
|
+
const { data } = await this.httpClient.post("/vector-algebra/operation", {
|
|
3542
|
+
op: "subtract",
|
|
3543
|
+
a: vector1,
|
|
3544
|
+
b: vector2
|
|
2654
3545
|
});
|
|
3546
|
+
const result = data.result ?? data.vector ?? [];
|
|
2655
3547
|
return {
|
|
2656
|
-
result: { values:
|
|
3548
|
+
result: { values: result, dimensions: result.length },
|
|
2657
3549
|
operation: "subtraction",
|
|
2658
3550
|
tookMs: data.took_ms
|
|
2659
3551
|
};
|
|
2660
3552
|
}
|
|
2661
3553
|
/**
|
|
2662
3554
|
* Performs scalar multiplication on a vector
|
|
2663
|
-
* @param vector - Input vector
|
|
2664
|
-
* @param scalar - Scalar value to multiply by
|
|
2665
|
-
* @returns Promise resolving to scalar multiplication result
|
|
2666
3555
|
*/
|
|
2667
3556
|
async vectorScalarMultiply(vector, scalar) {
|
|
2668
|
-
const { data } = await this.httpClient.post("/
|
|
2669
|
-
|
|
3557
|
+
const { data } = await this.httpClient.post("/vector-algebra/operation", {
|
|
3558
|
+
op: "scalar_multiply",
|
|
3559
|
+
a: vector,
|
|
2670
3560
|
scalar
|
|
2671
3561
|
});
|
|
3562
|
+
const result = data.result ?? data.vector ?? [];
|
|
2672
3563
|
return {
|
|
2673
|
-
result: { values:
|
|
3564
|
+
result: { values: result, dimensions: result.length },
|
|
2674
3565
|
operation: "scalar_multiplication",
|
|
2675
3566
|
tookMs: data.took_ms
|
|
2676
3567
|
};
|
|
2677
3568
|
}
|
|
2678
3569
|
/**
|
|
2679
3570
|
* Calculates the dot product of two vectors
|
|
2680
|
-
* @param vector1 - First vector
|
|
2681
|
-
* @param vector2 - Second vector
|
|
2682
|
-
* @returns Promise resolving to dot product result
|
|
2683
3571
|
*/
|
|
2684
3572
|
async vectorDotProduct(vector1, vector2) {
|
|
2685
3573
|
if (vector1.length !== vector2.length) {
|
|
2686
3574
|
throw new VectorError("Vector dimensions must match", "DIMENSION_MISMATCH");
|
|
2687
3575
|
}
|
|
2688
|
-
const { data } = await this.httpClient.post("/
|
|
2689
|
-
|
|
2690
|
-
|
|
3576
|
+
const { data } = await this.httpClient.post("/vector-algebra/operation", {
|
|
3577
|
+
op: "dot_product",
|
|
3578
|
+
a: vector1,
|
|
3579
|
+
b: vector2
|
|
2691
3580
|
});
|
|
2692
|
-
return {
|
|
2693
|
-
dotProduct: data.dot_product,
|
|
2694
|
-
tookMs: data.took_ms
|
|
2695
|
-
};
|
|
3581
|
+
return { dotProduct: data.scalar ?? data.dot_product ?? 0, tookMs: data.took_ms };
|
|
2696
3582
|
}
|
|
2697
3583
|
/**
|
|
2698
3584
|
* Calculates cosine similarity between two vectors
|
|
2699
|
-
* @param vector1 - First vector
|
|
2700
|
-
* @param vector2 - Second vector
|
|
2701
|
-
* @returns Promise resolving to cosine similarity result
|
|
2702
3585
|
*/
|
|
2703
3586
|
async cosineSimilarity(vector1, vector2) {
|
|
2704
3587
|
if (vector1.length !== vector2.length) {
|
|
2705
3588
|
throw new VectorError("Vector dimensions must match", "DIMENSION_MISMATCH");
|
|
2706
3589
|
}
|
|
2707
|
-
const { data } = await this.httpClient.post("/
|
|
2708
|
-
|
|
2709
|
-
|
|
3590
|
+
const { data } = await this.httpClient.post("/vector-algebra/operation", {
|
|
3591
|
+
op: "cosine_similarity",
|
|
3592
|
+
a: vector1,
|
|
3593
|
+
b: vector2
|
|
2710
3594
|
});
|
|
2711
|
-
return {
|
|
2712
|
-
similarity: data.similarity,
|
|
2713
|
-
function: "cosine",
|
|
2714
|
-
tookMs: data.took_ms
|
|
2715
|
-
};
|
|
3595
|
+
return { similarity: data.scalar ?? data.similarity ?? 0, function: "cosine", tookMs: data.took_ms };
|
|
2716
3596
|
}
|
|
2717
3597
|
/**
|
|
2718
3598
|
* Calculates L2 (Euclidean) distance between two vectors
|
|
2719
|
-
* @param vector1 - First vector
|
|
2720
|
-
* @param vector2 - Second vector
|
|
2721
|
-
* @returns Promise resolving to L2 distance result
|
|
2722
3599
|
*/
|
|
2723
3600
|
async l2Distance(vector1, vector2) {
|
|
2724
3601
|
if (vector1.length !== vector2.length) {
|
|
2725
3602
|
throw new VectorError("Vector dimensions must match", "DIMENSION_MISMATCH");
|
|
2726
3603
|
}
|
|
2727
|
-
const { data } = await this.httpClient.post("/
|
|
2728
|
-
|
|
2729
|
-
|
|
3604
|
+
const { data } = await this.httpClient.post("/vector-algebra/operation", {
|
|
3605
|
+
op: "l2_distance",
|
|
3606
|
+
a: vector1,
|
|
3607
|
+
b: vector2
|
|
2730
3608
|
});
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
similarity: data.distance,
|
|
2734
|
-
// Include similarity for compatibility
|
|
2735
|
-
function: "l2",
|
|
2736
|
-
tookMs: data.took_ms
|
|
2737
|
-
};
|
|
3609
|
+
const distance = data.scalar ?? data.distance ?? 0;
|
|
3610
|
+
return { distance, similarity: distance, function: "l2", tookMs: data.took_ms };
|
|
2738
3611
|
}
|
|
2739
3612
|
/**
|
|
2740
3613
|
* Calculates inner product between two vectors
|
|
2741
|
-
* @param vector1 - First vector
|
|
2742
|
-
* @param vector2 - Second vector
|
|
2743
|
-
* @returns Promise resolving to inner product result
|
|
2744
3614
|
*/
|
|
2745
3615
|
async innerProduct(vector1, vector2) {
|
|
2746
3616
|
if (vector1.length !== vector2.length) {
|
|
2747
3617
|
throw new VectorError("Vector dimensions must match", "DIMENSION_MISMATCH");
|
|
2748
3618
|
}
|
|
2749
|
-
const { data } = await this.httpClient.post("/
|
|
2750
|
-
|
|
2751
|
-
|
|
3619
|
+
const { data } = await this.httpClient.post("/vector-algebra/operation", {
|
|
3620
|
+
op: "inner_product",
|
|
3621
|
+
a: vector1,
|
|
3622
|
+
b: vector2
|
|
2752
3623
|
});
|
|
2753
|
-
return {
|
|
2754
|
-
similarity: data.inner_product,
|
|
2755
|
-
function: "inner_product",
|
|
2756
|
-
tookMs: data.took_ms
|
|
2757
|
-
};
|
|
3624
|
+
return { similarity: data.scalar ?? data.inner_product ?? 0, function: "inner_product", tookMs: data.took_ms };
|
|
2758
3625
|
}
|
|
2759
3626
|
/**
|
|
2760
|
-
* Performs K-nearest neighbors vector search
|
|
2761
|
-
*
|
|
2762
|
-
* @returns Promise resolving to KNN search results
|
|
3627
|
+
* Performs K-nearest neighbors vector search.
|
|
3628
|
+
* v0.2.0: routes through /vectors/collections/:c/search with mode discriminator.
|
|
2763
3629
|
*/
|
|
2764
3630
|
async knnSearch(options) {
|
|
2765
|
-
const
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
metadata_columns: options.metadataColumns,
|
|
3631
|
+
const collection = options.collectionName ?? options.tableName;
|
|
3632
|
+
const { data } = await this.httpClient.post(`/vectors/collections/${collection}/search`, {
|
|
3633
|
+
mode: "knn",
|
|
3634
|
+
vector: options.queryVector,
|
|
3635
|
+
limit: options.k,
|
|
2771
3636
|
filter: options.filter
|
|
2772
3637
|
});
|
|
2773
|
-
return data.results.map((
|
|
2774
|
-
id:
|
|
2775
|
-
vector:
|
|
2776
|
-
similarity:
|
|
2777
|
-
distance:
|
|
2778
|
-
metadata:
|
|
3638
|
+
return (data.matches ?? data.results ?? []).map((r) => ({
|
|
3639
|
+
id: r.id,
|
|
3640
|
+
vector: r.vector,
|
|
3641
|
+
similarity: r.similarity,
|
|
3642
|
+
distance: r.distance,
|
|
3643
|
+
metadata: r.metadata
|
|
2779
3644
|
}));
|
|
2780
3645
|
}
|
|
2781
3646
|
/**
|
|
2782
|
-
* Performs range-based vector similarity search
|
|
2783
|
-
* @param options - Range search options
|
|
2784
|
-
* @returns Promise resolving to range search results
|
|
3647
|
+
* Performs range-based vector similarity search.
|
|
2785
3648
|
*/
|
|
2786
3649
|
async rangeSearch(options) {
|
|
2787
|
-
const
|
|
2788
|
-
|
|
3650
|
+
const collection = options.collectionName ?? options.tableName;
|
|
3651
|
+
const { data } = await this.httpClient.post(`/vectors/collections/${collection}/search`, {
|
|
3652
|
+
mode: "range",
|
|
3653
|
+
vector: options.queryVector,
|
|
2789
3654
|
threshold: options.threshold,
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
similarity: result.similarity,
|
|
2800
|
-
distance: result.distance,
|
|
2801
|
-
metadata: result.metadata
|
|
3655
|
+
max_results: options.maxResults,
|
|
3656
|
+
filter: options.filter
|
|
3657
|
+
});
|
|
3658
|
+
return (data.matches ?? data.results ?? []).map((r) => ({
|
|
3659
|
+
id: r.id,
|
|
3660
|
+
vector: r.vector,
|
|
3661
|
+
similarity: r.similarity,
|
|
3662
|
+
distance: r.distance,
|
|
3663
|
+
metadata: r.metadata
|
|
2802
3664
|
}));
|
|
2803
3665
|
}
|
|
2804
3666
|
/**
|
|
2805
|
-
* Performs hybrid search combining vector similarity and SQL filtering
|
|
2806
|
-
* @param options - Hybrid search options
|
|
2807
|
-
* @returns Promise resolving to hybrid search results
|
|
3667
|
+
* Performs hybrid search combining vector similarity and SQL filtering.
|
|
2808
3668
|
*/
|
|
2809
3669
|
async hybridSearch(options) {
|
|
2810
|
-
const
|
|
3670
|
+
const collection = options.collectionName ?? options.tableName;
|
|
3671
|
+
const { data } = await this.httpClient.post(`/vectors/collections/${collection}/search`, {
|
|
3672
|
+
mode: "hybrid",
|
|
2811
3673
|
vector: options.vector,
|
|
2812
3674
|
text_query: options.textQuery,
|
|
2813
3675
|
sql_filter: options.sqlFilter,
|
|
2814
|
-
|
|
3676
|
+
limit: options.k,
|
|
2815
3677
|
threshold: options.threshold,
|
|
2816
3678
|
metric: options.metric,
|
|
2817
3679
|
filter: options.filter,
|
|
2818
3680
|
weights: options.weights
|
|
2819
3681
|
});
|
|
2820
|
-
return data.results.map((
|
|
2821
|
-
id:
|
|
2822
|
-
vector:
|
|
2823
|
-
similarity:
|
|
2824
|
-
distance:
|
|
2825
|
-
metadata:
|
|
3682
|
+
return (data.matches ?? data.results ?? []).map((r) => ({
|
|
3683
|
+
id: r.id,
|
|
3684
|
+
vector: r.vector,
|
|
3685
|
+
similarity: r.similarity,
|
|
3686
|
+
distance: r.distance,
|
|
3687
|
+
metadata: r.metadata
|
|
2826
3688
|
}));
|
|
2827
3689
|
}
|
|
2828
3690
|
/**
|
|
2829
3691
|
* Normalizes a vector to unit length
|
|
2830
|
-
* @param vector - Input vector to normalize
|
|
2831
|
-
* @returns Promise resolving to normalized vector
|
|
2832
3692
|
*/
|
|
2833
3693
|
async normalizeVector(vector) {
|
|
2834
|
-
const { data } = await this.httpClient.post("/
|
|
2835
|
-
|
|
3694
|
+
const { data } = await this.httpClient.post("/vector-algebra/operation", {
|
|
3695
|
+
op: "normalize",
|
|
3696
|
+
a: vector
|
|
2836
3697
|
});
|
|
3698
|
+
const result = data.result ?? data.vector ?? [];
|
|
2837
3699
|
return {
|
|
2838
|
-
result: { values:
|
|
3700
|
+
result: { values: result, dimensions: result.length },
|
|
2839
3701
|
operation: "normalization",
|
|
2840
3702
|
tookMs: data.took_ms
|
|
2841
3703
|
};
|
|
2842
3704
|
}
|
|
2843
3705
|
/**
|
|
2844
3706
|
* Calculates the magnitude (length) of a vector
|
|
2845
|
-
* @param vector - Input vector
|
|
2846
|
-
* @returns Promise resolving to vector magnitude
|
|
2847
3707
|
*/
|
|
2848
3708
|
async vectorMagnitude(vector) {
|
|
2849
|
-
const { data } = await this.httpClient.post("/
|
|
2850
|
-
|
|
3709
|
+
const { data } = await this.httpClient.post("/vector-algebra/operation", {
|
|
3710
|
+
op: "magnitude",
|
|
3711
|
+
a: vector
|
|
2851
3712
|
});
|
|
2852
|
-
return {
|
|
2853
|
-
magnitude: data.magnitude,
|
|
2854
|
-
tookMs: data.took_ms
|
|
2855
|
-
};
|
|
3713
|
+
return { magnitude: data.scalar ?? data.magnitude ?? 0, tookMs: data.took_ms };
|
|
2856
3714
|
}
|
|
2857
3715
|
// =================================================================
|
|
2858
3716
|
// AUTHENTICATION & USER MANAGEMENT
|
|
@@ -2884,16 +3742,26 @@ var SynapCores = class {
|
|
|
2884
3742
|
return data;
|
|
2885
3743
|
}
|
|
2886
3744
|
/**
|
|
2887
|
-
* Refresh JWT token
|
|
3745
|
+
* Refresh JWT token.
|
|
3746
|
+
*
|
|
3747
|
+
* v0.2.0: the gateway does not currently expose a refresh endpoint —
|
|
3748
|
+
* this method now re-runs login() with the same credentials. Pass
|
|
3749
|
+
* the credentials in the call site (or supply them at SDK construction
|
|
3750
|
+
* time and we'll re-use the cached pair).
|
|
2888
3751
|
*/
|
|
2889
|
-
async refreshToken() {
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
3752
|
+
async refreshToken(credentials) {
|
|
3753
|
+
if (credentials?.username && credentials?.password) {
|
|
3754
|
+
const login = await this.login({ username: credentials.username, password: credentials.password });
|
|
3755
|
+
return {
|
|
3756
|
+
access_token: login.access_token,
|
|
3757
|
+
refresh_token: "",
|
|
3758
|
+
token_type: "Bearer",
|
|
3759
|
+
expires_in: login.expires_in
|
|
3760
|
+
};
|
|
2895
3761
|
}
|
|
2896
|
-
|
|
3762
|
+
throw new ValidationError(
|
|
3763
|
+
"refreshToken now requires credentials \u2014 the gateway has no /auth/refresh endpoint in v1.5.0-ce. Pass {username, password} or call login() again."
|
|
3764
|
+
);
|
|
2897
3765
|
}
|
|
2898
3766
|
/**
|
|
2899
3767
|
* Set JWT token manually (useful after login)
|
|
@@ -3024,17 +3892,23 @@ var SynapCores = class {
|
|
|
3024
3892
|
|
|
3025
3893
|
// src/index.ts
|
|
3026
3894
|
import { z } from "zod";
|
|
3027
|
-
var VERSION = "0.
|
|
3895
|
+
var VERSION = "0.2.0";
|
|
3028
3896
|
export {
|
|
3029
3897
|
AuthenticationError,
|
|
3030
3898
|
AutoMLClient,
|
|
3031
3899
|
AutoMLModel,
|
|
3032
3900
|
BackupClient,
|
|
3033
3901
|
BatchOperationError,
|
|
3902
|
+
ChatClient,
|
|
3034
3903
|
Collection,
|
|
3035
3904
|
ConnectionError,
|
|
3905
|
+
FilesystemCollectionsClient,
|
|
3906
|
+
GraphClient,
|
|
3036
3907
|
ImportExportClient,
|
|
3037
3908
|
IntegrationClient,
|
|
3909
|
+
McpClient,
|
|
3910
|
+
MultimodalClient,
|
|
3911
|
+
NL2SqlClient,
|
|
3038
3912
|
NLPClient,
|
|
3039
3913
|
NotFoundError,
|
|
3040
3914
|
RateLimitError,
|
|
@@ -3045,8 +3919,11 @@ export {
|
|
|
3045
3919
|
Subscription,
|
|
3046
3920
|
SynapCores,
|
|
3047
3921
|
SynapCoresError,
|
|
3922
|
+
SystemClient,
|
|
3048
3923
|
TimeoutError,
|
|
3049
3924
|
TransactionError,
|
|
3925
|
+
TransactionsClient,
|
|
3926
|
+
Tx,
|
|
3050
3927
|
VERSION,
|
|
3051
3928
|
ValidationError,
|
|
3052
3929
|
VectorError,
|