@mastra/couchbase 0.0.0-trigger-playground-ui-package-20250506151043 → 0.0.0-update-stores-peerDeps-20250723031338

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/couchbase",
3
- "version": "0.0.0-trigger-playground-ui-package-20250506151043",
3
+ "version": "0.0.0-update-stores-peerDeps-20250723031338",
4
4
  "description": "Couchbase vector store provider for Mastra",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -19,20 +19,23 @@
19
19
  "./package.json": "./package.json"
20
20
  },
21
21
  "dependencies": {
22
- "couchbase": "^4.4.5",
23
- "@mastra/core": "0.0.0-trigger-playground-ui-package-20250506151043"
22
+ "couchbase": "^4.5.0"
24
23
  },
25
24
  "devDependencies": {
26
- "@microsoft/api-extractor": "^7.52.1",
27
- "@types/node": "^20.17.27",
28
- "@vitest/coverage-v8": "3.0.9",
29
- "@vitest/ui": "3.0.9",
30
- "axios": "^1.8.4",
31
- "eslint": "^9.23.0",
32
- "tsup": "^8.4.0",
33
- "typescript": "^5.8.2",
34
- "vitest": "^3.0.9",
35
- "@internal/lint": "0.0.0-trigger-playground-ui-package-20250506151043"
25
+ "@microsoft/api-extractor": "^7.52.8",
26
+ "@types/node": "^20.19.0",
27
+ "@vitest/coverage-v8": "3.2.3",
28
+ "@vitest/ui": "3.2.3",
29
+ "axios": "^1.10.0",
30
+ "eslint": "^9.30.1",
31
+ "tsup": "^8.5.0",
32
+ "typescript": "^5.8.3",
33
+ "vitest": "^3.2.4",
34
+ "@internal/lint": "0.0.0-update-stores-peerDeps-20250723031338",
35
+ "@mastra/core": "0.11.0"
36
+ },
37
+ "peerDependencies": {
38
+ "@mastra/core": "0.11.0"
36
39
  },
37
40
  "scripts": {
38
41
  "build": "tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting",
@@ -3,10 +3,11 @@
3
3
  // The tests will automatically start and configure the required Couchbase container.
4
4
 
5
5
  import { execSync } from 'child_process';
6
+ import { randomUUID } from 'crypto';
6
7
  import axios from 'axios';
7
8
  import type { Cluster, Bucket, Scope, Collection } from 'couchbase';
8
9
  import { connect } from 'couchbase';
9
- import { describe, it, expect, beforeAll, afterAll } from 'vitest';
10
+ import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest';
10
11
  import { CouchbaseVector, DISTANCE_MAPPING } from './index';
11
12
 
12
13
  const containerName = 'mastra_couchbase_testing';
@@ -172,14 +173,14 @@ describe('Integration Testing CouchbaseVector', async () => {
172
173
 
173
174
  describe('Connection', () => {
174
175
  it('should connect to couchbase', async () => {
175
- couchbase_client = new CouchbaseVector(
176
+ couchbase_client = new CouchbaseVector({
176
177
  connectionString,
177
178
  username,
178
179
  password,
179
- test_bucketName,
180
- test_scopeName,
181
- test_collectionName,
182
- );
180
+ bucketName: test_bucketName,
181
+ scopeName: test_scopeName,
182
+ collectionName: test_collectionName,
183
+ });
183
184
  expect(couchbase_client).toBeDefined();
184
185
  const collection = await couchbase_client.getCollection();
185
186
  expect(collection).toBeDefined();
@@ -210,14 +211,14 @@ describe('Integration Testing CouchbaseVector', async () => {
210
211
  }, 50000);
211
212
 
212
213
  it('should describe index', async () => {
213
- const stats = await couchbase_client.describeIndex(test_indexName);
214
+ const stats = await couchbase_client.describeIndex({ indexName: test_indexName });
214
215
  expect(stats.dimension).toBe(dimension);
215
216
  expect(stats.metric).toBe('euclidean'); // similiarity(=="l2_norm") is mapped to euclidean in couchbase
216
217
  expect(typeof stats.count).toBe('number');
217
218
  }, 50000);
218
219
 
219
220
  it('should delete index', async () => {
220
- await couchbase_client.deleteIndex(test_indexName);
221
+ await couchbase_client.deleteIndex({ indexName: test_indexName });
221
222
  await new Promise(resolve => setTimeout(resolve, 5000));
222
223
  await expect(scope.searchIndexes().getIndex(test_indexName)).rejects.toThrowError();
223
224
  }, 50000);
@@ -245,7 +246,7 @@ describe('Integration Testing CouchbaseVector', async () => {
245
246
  }, 50000);
246
247
 
247
248
  afterAll(async () => {
248
- await couchbase_client.deleteIndex(test_indexName);
249
+ await couchbase_client.deleteIndex({ indexName: test_indexName });
249
250
  await new Promise(resolve => setTimeout(resolve, 5000));
250
251
  }, 50000);
251
252
 
@@ -379,6 +380,120 @@ describe('Integration Testing CouchbaseVector', async () => {
379
380
  }),
380
381
  ).rejects.toThrow('Including vectors in search results is not yet supported by the Couchbase vector store');
381
382
  }, 50000);
383
+
384
+ it('should upsert vectors with generated ids', async () => {
385
+ const ids = await couchbase_client.upsert({ indexName: test_indexName, vectors: testVectors });
386
+ expect(ids).toHaveLength(testVectors.length);
387
+ ids.forEach(id => expect(typeof id).toBe('string'));
388
+
389
+ // Count is not supported by Couchbase
390
+ const stats = await couchbase_client.describeIndex({ indexName: test_indexName });
391
+ expect(stats.count).toBe(-1);
392
+ });
393
+
394
+ it('should update existing vectors', async () => {
395
+ // Initial upsert
396
+ await couchbase_client.upsert({
397
+ indexName: test_indexName,
398
+ vectors: testVectors,
399
+ metadata: testMetadata,
400
+ ids: testVectorIds,
401
+ });
402
+
403
+ // Update first vector
404
+ const updatedVector = [[0.5, 0.5, 0.0]];
405
+ const updatedMetadata = [{ label: 'updated-x-axis' }];
406
+ await couchbase_client.upsert({
407
+ indexName: test_indexName,
408
+ vectors: updatedVector,
409
+ metadata: updatedMetadata,
410
+ ids: [testVectorIds?.[0]!],
411
+ });
412
+
413
+ // Verify update
414
+ const result = await collection.get(testVectorIds?.[0]!);
415
+ expect(result.content.embedding).toEqual(updatedVector[0]);
416
+ expect(result.content.metadata).toEqual(updatedMetadata[0]);
417
+ });
418
+
419
+ it('should update the vector by id', async () => {
420
+ const ids = await couchbase_client.upsert({ indexName: test_indexName, vectors: testVectors });
421
+ expect(ids).toHaveLength(3);
422
+
423
+ const idToBeUpdated = ids[0];
424
+ const newVector = [1, 2, 3];
425
+ const newMetaData = {
426
+ test: 'updates',
427
+ };
428
+
429
+ const update = {
430
+ vector: newVector,
431
+ metadata: newMetaData,
432
+ };
433
+
434
+ await couchbase_client.updateVector({ indexName: test_indexName, id: idToBeUpdated, update });
435
+
436
+ const result = await collection.get(idToBeUpdated);
437
+ expect(result.content.embedding).toEqual(newVector);
438
+ expect(result.content.metadata).toEqual(newMetaData);
439
+ });
440
+
441
+ it('should only update the metadata by id', async () => {
442
+ const ids = await couchbase_client.upsert({ indexName: test_indexName, vectors: testVectors });
443
+ expect(ids).toHaveLength(3);
444
+
445
+ const idToBeUpdated = ids[0];
446
+ const newMetaData = {
447
+ test: 'updates',
448
+ };
449
+
450
+ const update = {
451
+ metadata: newMetaData,
452
+ };
453
+
454
+ await couchbase_client.updateVector({ indexName: test_indexName, id: idToBeUpdated, update });
455
+
456
+ const result = await collection.get(idToBeUpdated);
457
+ expect(result.content.embedding).toEqual(testVectors[0]);
458
+ expect(result.content.metadata).toEqual(newMetaData);
459
+ });
460
+
461
+ it('should only update vector embeddings by id', async () => {
462
+ const ids = await couchbase_client.upsert({ indexName: test_indexName, vectors: testVectors });
463
+ expect(ids).toHaveLength(3);
464
+
465
+ const idToBeUpdated = ids[0];
466
+ const newVector = [1, 2, 3];
467
+
468
+ const update = {
469
+ vector: newVector,
470
+ };
471
+
472
+ await couchbase_client.updateVector({ indexName: test_indexName, id: idToBeUpdated, update });
473
+
474
+ const result = await collection.get(idToBeUpdated);
475
+ expect(result.content.embedding).toEqual(newVector);
476
+ });
477
+
478
+ it('should throw exception when no updates are given', async () => {
479
+ await expect(couchbase_client.updateVector({ indexName: test_indexName, id: 'id', update: {} })).rejects.toThrow(
480
+ 'No updates provided',
481
+ );
482
+ });
483
+
484
+ it('should delete the vector by id', async () => {
485
+ const ids = await couchbase_client.upsert({ indexName: test_indexName, vectors: testVectors });
486
+ expect(ids).toHaveLength(3);
487
+ const idToBeDeleted = ids[0];
488
+
489
+ await couchbase_client.deleteVector({ indexName: test_indexName, id: idToBeDeleted });
490
+
491
+ try {
492
+ await collection.get(idToBeDeleted);
493
+ } catch (error) {
494
+ expect(error).toBeInstanceOf(Error);
495
+ }
496
+ });
382
497
  });
383
498
 
384
499
  describe('Error Cases and Edge Cases', () => {
@@ -408,7 +523,7 @@ describe('Integration Testing CouchbaseVector', async () => {
408
523
  expect(allIndexes.find(idx => idx.name === nonExistentIndex)).toBeUndefined();
409
524
 
410
525
  // Now test the couchbase_client method
411
- await expect(couchbase_client.describeIndex(nonExistentIndex)).rejects.toThrow();
526
+ await expect(couchbase_client.describeIndex({ indexName: nonExistentIndex })).rejects.toThrow();
412
527
  }, 50000);
413
528
 
414
529
  it('should throw error when deleting a non-existent index', async () => {
@@ -419,7 +534,7 @@ describe('Integration Testing CouchbaseVector', async () => {
419
534
  expect(allIndexes.find(idx => idx.name === nonExistentIndex)).toBeUndefined();
420
535
 
421
536
  // Now test the couchbase_client method
422
- await expect(couchbase_client.deleteIndex(nonExistentIndex)).rejects.toThrow();
537
+ await expect(couchbase_client.deleteIndex({ indexName: nonExistentIndex })).rejects.toThrow();
423
538
  }, 50000);
424
539
 
425
540
  it('should throw error for empty vectors array in upsert', async () => {
@@ -431,6 +546,66 @@ describe('Integration Testing CouchbaseVector', async () => {
431
546
  }),
432
547
  ).rejects.toThrow('No vectors provided');
433
548
  }, 50000);
549
+
550
+ it('should handle non-existent index queries', async () => {
551
+ await expect(
552
+ couchbase_client.query({ indexName: 'non-existent-index', queryVector: [1, 2, 3] }),
553
+ ).rejects.toThrow();
554
+ }, 50000);
555
+
556
+ it('should handle duplicate index creation gracefully', async () => {
557
+ const duplicateIndexName = `duplicate-test-${randomUUID()}`;
558
+ const dimension = 768;
559
+ const infoSpy = vi.spyOn(couchbase_client['logger'], 'info');
560
+ const warnSpy = vi.spyOn(couchbase_client['logger'], 'warn');
561
+
562
+ try {
563
+ // Create index first time
564
+ await couchbase_client.createIndex({
565
+ indexName: duplicateIndexName,
566
+ dimension,
567
+ metric: 'cosine',
568
+ });
569
+
570
+ // Try to create with same dimensions - should not throw
571
+ await expect(
572
+ couchbase_client.createIndex({
573
+ indexName: duplicateIndexName,
574
+ dimension,
575
+ metric: 'cosine',
576
+ }),
577
+ ).resolves.not.toThrow();
578
+
579
+ expect(infoSpy).toHaveBeenCalledWith(expect.stringContaining('already exists with'));
580
+
581
+ // Try to create with same dimensions and different metric - should not throw
582
+ await expect(
583
+ couchbase_client.createIndex({
584
+ indexName: duplicateIndexName,
585
+ dimension,
586
+ metric: 'euclidean',
587
+ }),
588
+ ).resolves.not.toThrow();
589
+
590
+ expect(warnSpy).toHaveBeenCalledWith(expect.stringContaining('Attempted to create index with metric'));
591
+
592
+ // Try to create with different dimensions - should throw
593
+ await expect(
594
+ couchbase_client.createIndex({
595
+ indexName: duplicateIndexName,
596
+ dimension: dimension + 1,
597
+ metric: 'cosine',
598
+ }),
599
+ ).rejects.toThrow(
600
+ `Index "${duplicateIndexName}" already exists with ${dimension} dimensions, but ${dimension + 1} dimensions were requested`,
601
+ );
602
+ } finally {
603
+ infoSpy.mockRestore();
604
+ warnSpy.mockRestore();
605
+ // Cleanup
606
+ await couchbase_client.deleteIndex({ indexName: duplicateIndexName });
607
+ }
608
+ }, 50000);
434
609
  });
435
610
 
436
611
  describe('Vector Dimension Tracking', () => {
@@ -438,7 +613,7 @@ describe('Integration Testing CouchbaseVector', async () => {
438
613
  const indexes = await couchbase_client.listIndexes();
439
614
  if (indexes.length > 0) {
440
615
  for (const index of indexes) {
441
- await couchbase_client.deleteIndex(index);
616
+ await couchbase_client.deleteIndex({ indexName: index });
442
617
  await new Promise(resolve => setTimeout(resolve, 5000));
443
618
  }
444
619
  }
@@ -501,7 +676,7 @@ describe('Integration Testing CouchbaseVector', async () => {
501
676
  expect((couchbase_client as any).vector_dimension).toBe(testDimension);
502
677
 
503
678
  // Delete the index
504
- await couchbase_client.deleteIndex(testIndexName);
679
+ await couchbase_client.deleteIndex({ indexName: testIndexName });
505
680
  await new Promise(resolve => setTimeout(resolve, 5000));
506
681
 
507
682
  // Verify dimension is reset
@@ -517,7 +692,7 @@ describe('Integration Testing CouchbaseVector', async () => {
517
692
  const indexes = await couchbase_client.listIndexes();
518
693
  if (indexes.length > 0) {
519
694
  for (const index of indexes) {
520
- await couchbase_client.deleteIndex(index);
695
+ await couchbase_client.deleteIndex({ indexName: index });
521
696
  await new Promise(resolve => setTimeout(resolve, 5000));
522
697
  }
523
698
  }
@@ -546,11 +721,11 @@ describe('Integration Testing CouchbaseVector', async () => {
546
721
  expect(similarityParam).toBe(couchbaseMetric);
547
722
 
548
723
  // Verify through our API
549
- const stats = await couchbase_client.describeIndex(testIndexName);
724
+ const stats = await couchbase_client.describeIndex({ indexName: testIndexName });
550
725
  expect(stats.metric).toBe(mastraMetric);
551
726
 
552
727
  // Clean up
553
- await couchbase_client.deleteIndex(testIndexName);
728
+ await couchbase_client.deleteIndex({ indexName: testIndexName });
554
729
  await new Promise(resolve => setTimeout(resolve, 5000));
555
730
  }
556
731
  }, 50000);