@mastra/pinecone 0.1.6-alpha.1 → 0.1.6-alpha.4

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.
@@ -1,5 +1,5 @@
1
1
  import dotenv from 'dotenv';
2
- import { describe, it, expect, beforeAll, afterAll } from 'vitest';
2
+ import { describe, it, expect, beforeAll, afterAll, beforeEach, vi, afterEach } from 'vitest';
3
3
 
4
4
  import { PineconeVector } from './';
5
5
 
@@ -59,7 +59,7 @@ describe.skip('PineconeVector Integration Tests', () => {
59
59
  beforeAll(async () => {
60
60
  vectorDB = new PineconeVector(PINECONE_API_KEY);
61
61
  // Create test index
62
- await vectorDB.createIndex(testIndexName, dimension);
62
+ await vectorDB.createIndex({ indexName: testIndexName, dimension });
63
63
  await waitUntilReady(vectorDB, testIndexName);
64
64
  }, 500000);
65
65
 
@@ -92,7 +92,7 @@ describe.skip('PineconeVector Integration Tests', () => {
92
92
  let vectorIds: string[];
93
93
 
94
94
  it('should upsert vectors with metadata', async () => {
95
- vectorIds = await vectorDB.upsert(testIndexName, testVectors, testMetadata);
95
+ vectorIds = await vectorDB.upsert({ indexName: testIndexName, vectors: testVectors, metadata: testMetadata });
96
96
  expect(vectorIds).toHaveLength(3);
97
97
  // Wait for vectors to be indexed
98
98
  await waitUntilVectorsIndexed(vectorDB, testIndexName, 3);
@@ -100,7 +100,7 @@ describe.skip('PineconeVector Integration Tests', () => {
100
100
 
101
101
  it.skip('should query vectors and return nearest neighbors', async () => {
102
102
  const queryVector = [1.0, 0.1, 0.1];
103
- const results = await vectorDB.query(testIndexName, queryVector, 3);
103
+ const results = await vectorDB.query({ indexName: testIndexName, queryVector, topK: 3 });
104
104
 
105
105
  expect(results).toHaveLength(3);
106
106
  expect(results[0]!.score).toBeGreaterThan(0);
@@ -111,7 +111,7 @@ describe.skip('PineconeVector Integration Tests', () => {
111
111
  const queryVector = [0.0, 1.0, 0.0];
112
112
  const filter = { label: 'y-axis' };
113
113
 
114
- const results = await vectorDB.query(testIndexName, queryVector, 1, filter);
114
+ const results = await vectorDB.query({ indexName: testIndexName, queryVector, topK: 1, filter });
115
115
 
116
116
  expect(results).toHaveLength(1);
117
117
  expect(results?.[0]?.metadata?.label).toBe('y-axis');
@@ -119,7 +119,7 @@ describe.skip('PineconeVector Integration Tests', () => {
119
119
 
120
120
  it('should query vectors and return vectors in results', async () => {
121
121
  const queryVector = [0.0, 1.0, 0.0];
122
- const results = await vectorDB.query(testIndexName, queryVector, 1, undefined, true);
122
+ const results = await vectorDB.query({ indexName: testIndexName, queryVector, topK: 1, includeVector: true });
123
123
 
124
124
  expect(results).toHaveLength(1);
125
125
  expect(results?.[0]?.vector).toBeDefined();
@@ -130,12 +130,12 @@ describe.skip('PineconeVector Integration Tests', () => {
130
130
  describe('Error Handling', () => {
131
131
  it('should handle non-existent index query gracefully', async () => {
132
132
  const nonExistentIndex = 'non-existent-index';
133
- await expect(vectorDB.query(nonExistentIndex, [1, 0, 0])).rejects.toThrow();
133
+ await expect(vectorDB.query({ indexName: nonExistentIndex, queryVector: [1, 0, 0] })).rejects.toThrow();
134
134
  }, 500000);
135
135
 
136
136
  it('should handle incorrect dimension vectors', async () => {
137
137
  const wrongDimVector = [[1, 0]]; // 2D vector for 3D index
138
- await expect(vectorDB.upsert(testIndexName, wrongDimVector)).rejects.toThrow();
138
+ await expect(vectorDB.upsert({ indexName: testIndexName, vectors: wrongDimVector })).rejects.toThrow();
139
139
  }, 500000);
140
140
  });
141
141
 
@@ -152,7 +152,7 @@ describe.skip('PineconeVector Integration Tests', () => {
152
152
  const metadata = vectors.map((_, i) => ({ id: i }));
153
153
 
154
154
  const start = Date.now();
155
- const ids = await vectorDB.upsert(testIndexName, vectors, metadata);
155
+ const ids = await vectorDB.upsert({ indexName: testIndexName, vectors, metadata });
156
156
  const duration = Date.now() - start;
157
157
 
158
158
  expect(ids).toHaveLength(batchSize);
@@ -166,7 +166,7 @@ describe.skip('PineconeVector Integration Tests', () => {
166
166
  const start = Date.now();
167
167
  const promises = Array(numQueries)
168
168
  .fill(null)
169
- .map(() => vectorDB.query(testIndexName, queryVector));
169
+ .map(() => vectorDB.query({ indexName: testIndexName, queryVector }));
170
170
 
171
171
  const results = await Promise.all(promises);
172
172
  const duration = Date.now() - start;
@@ -179,14 +179,14 @@ describe.skip('PineconeVector Integration Tests', () => {
179
179
  describe('Filter Validation in Queries', () => {
180
180
  it('rejects queries with null values', async () => {
181
181
  await expect(
182
- vectorDB.query(testIndexName, [1, 0, 0], 10, {
183
- field: null,
184
- }),
182
+ vectorDB.query({ indexName: testIndexName, queryVector: [1, 0, 0], topK: 10, filter: { field: null } }),
185
183
  ).rejects.toThrow();
186
184
 
187
185
  await expect(
188
- vectorDB.query(testIndexName, [1, 0, 0], 10, {
189
- other: { $eq: null },
186
+ vectorDB.query({
187
+ indexName: testIndexName,
188
+ queryVector: [1, 0, 0],
189
+ filter: { other: { $eq: null } },
190
190
  }),
191
191
  ).rejects.toThrow('the $eq operator must be followed by a string, boolean or a number, got null instead');
192
192
  });
@@ -197,8 +197,10 @@ describe.skip('PineconeVector Integration Tests', () => {
197
197
  for (const op of ['$in', '$nin']) {
198
198
  for (const val of invalidValues) {
199
199
  await expect(
200
- vectorDB.query(testIndexName, [1, 0, 0], 10, {
201
- field: { [op]: val },
200
+ vectorDB.query({
201
+ indexName: testIndexName,
202
+ queryVector: [1, 0, 0],
203
+ filter: { field: { [op]: val } },
202
204
  }),
203
205
  ).rejects.toThrow(`the ${op} operator must be followed by a list of strings or a list of numbers`);
204
206
  }
@@ -211,8 +213,10 @@ describe.skip('PineconeVector Integration Tests', () => {
211
213
  for (const op of numOps) {
212
214
  for (const val of invalidNumericValues) {
213
215
  await expect(
214
- vectorDB.query(testIndexName, [1, 0, 0], 10, {
215
- field: { [op]: val },
216
+ vectorDB.query({
217
+ indexName: testIndexName,
218
+ queryVector: [1, 0, 0],
219
+ filter: { field: { [op]: val } },
216
220
  }),
217
221
  ).rejects.toThrow(`the ${op} operator must be followed by a number`);
218
222
  }
@@ -221,39 +225,49 @@ describe.skip('PineconeVector Integration Tests', () => {
221
225
 
222
226
  it('rejects multiple invalid values', async () => {
223
227
  await expect(
224
- vectorDB.query(testIndexName, [1, 0, 0], 10, {
225
- field1: { $in: 'not-array' },
226
- field2: { $exists: 'not-boolean' },
227
- field3: { $gt: 'not-number' },
228
+ vectorDB.query({
229
+ indexName: testIndexName,
230
+ queryVector: [1, 0, 0],
231
+ filter: { field1: { $in: 'not-array' }, field2: { $exists: 'not-boolean' }, field3: { $gt: 'not-number' } },
228
232
  }),
229
233
  ).rejects.toThrow();
230
234
  });
231
235
 
232
236
  it('rejects invalid array values', async () => {
233
237
  await expect(
234
- vectorDB.query(testIndexName, [1, 0, 0], 10, {
235
- field: { $in: [null] },
238
+ vectorDB.query({
239
+ indexName: testIndexName,
240
+ queryVector: [1, 0, 0],
241
+ filter: { field: { $in: [null] } },
236
242
  }),
237
243
  ).rejects.toThrow('the $in operator must be followed by a list of strings or a list of numbers');
238
244
 
239
245
  await expect(
240
- vectorDB.query(testIndexName, [1, 0, 0], 10, {
241
- field: { $in: [undefined] },
246
+ vectorDB.query({
247
+ indexName: testIndexName,
248
+ queryVector: [1, 0, 0],
249
+ filter: { field: { $in: [undefined] } },
242
250
  }),
243
251
  ).rejects.toThrow('the $in operator must be followed by a list of strings or a list of numbers');
244
252
 
245
253
  await expect(
246
- vectorDB.query(testIndexName, [1, 0, 0], 10, {
247
- field: { $all: 'not-an-array' },
254
+ vectorDB.query({
255
+ indexName: testIndexName,
256
+ queryVector: [1, 0, 0],
257
+ filter: { field: { $all: 'not-an-array' } },
248
258
  }),
249
259
  ).rejects.toThrow('A non-empty array is required for the $all operator');
250
260
  });
251
261
 
252
262
  it('handles empty object filters', async () => {
253
263
  // Test empty object at top level
254
- await expect(vectorDB.query(testIndexName, [1, 0, 0], 10, { field: { $eq: {} } })).rejects.toThrow(
255
- 'the $eq operator must be followed by a string, boolean or a number, got {} instead',
256
- );
264
+ await expect(
265
+ vectorDB.query({
266
+ indexName: testIndexName,
267
+ queryVector: [1, 0, 0],
268
+ filter: { field: { $eq: {} } },
269
+ }),
270
+ ).rejects.toThrow('the $eq operator must be followed by a string, boolean or a number, got {} instead');
257
271
  });
258
272
 
259
273
  it('handles empty/undefined filters by returning all results', async () => {
@@ -262,15 +276,23 @@ describe.skip('PineconeVector Integration Tests', () => {
262
276
  const noFilterCases = [{ field: {} }, { field: undefined }, { field: { $in: undefined } }];
263
277
 
264
278
  for (const filter of noFilterCases) {
265
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, filter);
279
+ const results = await vectorDB.query({
280
+ indexName: testIndexName,
281
+ queryVector: [1, 0, 0],
282
+ filter,
283
+ });
266
284
  expect(results.length).toBeGreaterThan(0);
267
285
  }
268
286
  });
269
287
  it('handles empty object filters', async () => {
270
288
  // Test empty object at top level
271
- await expect(vectorDB.query(testIndexName, [1, 0, 0], 10, {})).rejects.toThrow(
272
- 'You must enter a `filter` object with at least one key-value pair.',
273
- );
289
+ await expect(
290
+ vectorDB.query({
291
+ indexName: testIndexName,
292
+ queryVector: [1, 0, 0],
293
+ filter: {},
294
+ }),
295
+ ).rejects.toThrow('You must enter a `filter` object with at least one key-value pair.');
274
296
  });
275
297
  });
276
298
 
@@ -298,15 +320,17 @@ describe.skip('PineconeVector Integration Tests', () => {
298
320
  ];
299
321
 
300
322
  beforeAll(async () => {
301
- await vectorDB.upsert(testIndexName, testVectors, testMetadata);
323
+ await vectorDB.upsert({ indexName: testIndexName, vectors: testVectors, metadata: testMetadata });
302
324
  // Wait for vectors to be indexed
303
325
  await waitUntilVectorsIndexed(vectorDB, testIndexName, testVectors.length);
304
326
  }, 500000);
305
327
 
306
328
  describe('Comparison Operators', () => {
307
329
  it('should filter with implict $eq', async () => {
308
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
309
- category: 'electronics',
330
+ const results = await vectorDB.query({
331
+ indexName: testIndexName,
332
+ queryVector: [1, 0, 0],
333
+ filter: { category: 'electronics' },
310
334
  });
311
335
  expect(results.length).toBeGreaterThan(0);
312
336
  results.forEach(result => {
@@ -314,8 +338,10 @@ describe.skip('PineconeVector Integration Tests', () => {
314
338
  });
315
339
  });
316
340
  it('should filter with $eq operator', async () => {
317
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
318
- category: { $eq: 'electronics' },
341
+ const results = await vectorDB.query({
342
+ indexName: testIndexName,
343
+ queryVector: [1, 0, 0],
344
+ filter: { category: { $eq: 'electronics' } },
319
345
  });
320
346
  expect(results.length).toBeGreaterThan(0);
321
347
  results.forEach(result => {
@@ -324,8 +350,10 @@ describe.skip('PineconeVector Integration Tests', () => {
324
350
  });
325
351
 
326
352
  it('should filter with $gt operator', async () => {
327
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
328
- price: { $gt: 500 },
353
+ const results = await vectorDB.query({
354
+ indexName: testIndexName,
355
+ queryVector: [1, 0, 0],
356
+ filter: { price: { $gt: 500 } },
329
357
  });
330
358
  expect(results.length).toBeGreaterThan(0);
331
359
  results.forEach(result => {
@@ -334,8 +362,10 @@ describe.skip('PineconeVector Integration Tests', () => {
334
362
  });
335
363
 
336
364
  it('should filter with $gte operator', async () => {
337
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
338
- price: { $gte: 500 },
365
+ const results = await vectorDB.query({
366
+ indexName: testIndexName,
367
+ queryVector: [1, 0, 0],
368
+ filter: { price: { $gte: 500 } },
339
369
  });
340
370
  expect(results.length).toBeGreaterThan(0);
341
371
  results.forEach(result => {
@@ -344,8 +374,10 @@ describe.skip('PineconeVector Integration Tests', () => {
344
374
  });
345
375
 
346
376
  it('should filter with $lt operator', async () => {
347
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
348
- price: { $lt: 100 },
377
+ const results = await vectorDB.query({
378
+ indexName: testIndexName,
379
+ queryVector: [1, 0, 0],
380
+ filter: { price: { $lt: 100 } },
349
381
  });
350
382
  expect(results.length).toBeGreaterThan(0);
351
383
  results.forEach(result => {
@@ -354,8 +386,10 @@ describe.skip('PineconeVector Integration Tests', () => {
354
386
  });
355
387
 
356
388
  it('should filter with $lte operator', async () => {
357
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
358
- price: { $lte: 50 },
389
+ const results = await vectorDB.query({
390
+ indexName: testIndexName,
391
+ queryVector: [1, 0, 0],
392
+ filter: { price: { $lte: 50 } },
359
393
  });
360
394
  expect(results.length).toBeGreaterThan(0);
361
395
  results.forEach(result => {
@@ -364,8 +398,10 @@ describe.skip('PineconeVector Integration Tests', () => {
364
398
  });
365
399
 
366
400
  it('should filter with $ne operator', async () => {
367
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
368
- category: { $ne: 'electronics' },
401
+ const results = await vectorDB.query({
402
+ indexName: testIndexName,
403
+ queryVector: [1, 0, 0],
404
+ filter: { category: { $ne: 'electronics' } },
369
405
  });
370
406
  expect(results.length).toBeGreaterThan(0);
371
407
  results.forEach(result => {
@@ -374,8 +410,10 @@ describe.skip('PineconeVector Integration Tests', () => {
374
410
  });
375
411
 
376
412
  it('filters with $gte, $lt, $lte operators', async () => {
377
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
378
- price: { $gte: 25, $lte: 30 },
413
+ const results = await vectorDB.query({
414
+ indexName: testIndexName,
415
+ queryVector: [1, 0, 0],
416
+ filter: { price: { $gte: 25, $lte: 30 } },
379
417
  });
380
418
  expect(results.length).toBe(2);
381
419
  results.forEach(result => {
@@ -387,8 +425,10 @@ describe.skip('PineconeVector Integration Tests', () => {
387
425
 
388
426
  describe('Array Operators', () => {
389
427
  it('should filter with $in operator for strings', async () => {
390
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
391
- category: { $in: ['electronics', 'books'] },
428
+ const results = await vectorDB.query({
429
+ indexName: testIndexName,
430
+ queryVector: [1, 0, 0],
431
+ filter: { category: { $in: ['electronics', 'books'] } },
392
432
  });
393
433
  expect(results.length).toBeGreaterThan(0);
394
434
  results.forEach(result => {
@@ -397,8 +437,10 @@ describe.skip('PineconeVector Integration Tests', () => {
397
437
  });
398
438
 
399
439
  it('should filter with $in operator for numbers', async () => {
400
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
401
- price: { $in: [50, 75, 1000] },
440
+ const results = await vectorDB.query({
441
+ indexName: testIndexName,
442
+ queryVector: [1, 0, 0],
443
+ filter: { price: { $in: [50, 75, 1000] } },
402
444
  });
403
445
  expect(results.length).toBeGreaterThan(0);
404
446
  results.forEach(result => {
@@ -407,8 +449,10 @@ describe.skip('PineconeVector Integration Tests', () => {
407
449
  });
408
450
 
409
451
  it('should filter with $nin operator', async () => {
410
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
411
- category: { $nin: ['electronics', 'books'] },
452
+ const results = await vectorDB.query({
453
+ indexName: testIndexName,
454
+ queryVector: [1, 0, 0],
455
+ filter: { category: { $nin: ['electronics', 'books'] } },
412
456
  });
413
457
  expect(results.length).toBeGreaterThan(0);
414
458
  results.forEach(result => {
@@ -417,8 +461,10 @@ describe.skip('PineconeVector Integration Tests', () => {
417
461
  });
418
462
 
419
463
  it('should filter with $all operator', async () => {
420
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
421
- tags: { $all: ['premium', 'new'] },
464
+ const results = await vectorDB.query({
465
+ indexName: testIndexName,
466
+ queryVector: [1, 0, 0],
467
+ filter: { tags: { $all: ['premium', 'new'] } },
422
468
  });
423
469
  expect(results.length).toBeGreaterThan(0);
424
470
  results.forEach(result => {
@@ -430,10 +476,10 @@ describe.skip('PineconeVector Integration Tests', () => {
430
476
 
431
477
  describe('Logical Operators', () => {
432
478
  it('should filter with implict $and', async () => {
433
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
434
- category: 'electronics',
435
- price: { $gt: 700 },
436
- inStock: true,
479
+ const results = await vectorDB.query({
480
+ indexName: testIndexName,
481
+ queryVector: [1, 0, 0],
482
+ filter: { category: 'electronics', price: { $gt: 700 }, inStock: true },
437
483
  });
438
484
  expect(results.length).toBeGreaterThan(0);
439
485
  results.forEach(result => {
@@ -443,8 +489,10 @@ describe.skip('PineconeVector Integration Tests', () => {
443
489
  });
444
490
  });
445
491
  it('should filter with $and operator', async () => {
446
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
447
- $and: [{ category: 'electronics' }, { price: { $gt: 700 } }, { inStock: true }],
492
+ const results = await vectorDB.query({
493
+ indexName: testIndexName,
494
+ queryVector: [1, 0, 0],
495
+ filter: { $and: [{ category: 'electronics' }, { price: { $gt: 700 } }, { inStock: true }] },
448
496
  });
449
497
  expect(results.length).toBeGreaterThan(0);
450
498
  results.forEach(result => {
@@ -455,8 +503,10 @@ describe.skip('PineconeVector Integration Tests', () => {
455
503
  });
456
504
 
457
505
  it('should filter with $or operator', async () => {
458
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
459
- $or: [{ price: { $gt: 900 } }, { tags: { $all: ['bestseller'] } }],
506
+ const results = await vectorDB.query({
507
+ indexName: testIndexName,
508
+ queryVector: [1, 0, 0],
509
+ filter: { $or: [{ price: { $gt: 900 } }, { tags: { $all: ['bestseller'] } }] },
460
510
  });
461
511
  expect(results.length).toBeGreaterThan(0);
462
512
  results.forEach(result => {
@@ -467,14 +517,18 @@ describe.skip('PineconeVector Integration Tests', () => {
467
517
  });
468
518
 
469
519
  it('should handle nested logical operators', async () => {
470
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
471
- $and: [
472
- {
473
- $or: [{ category: 'electronics' }, { category: 'books' }],
474
- },
475
- { price: { $lt: 100 } },
476
- { inStock: true },
477
- ],
520
+ const results = await vectorDB.query({
521
+ indexName: testIndexName,
522
+ queryVector: [1, 0, 0],
523
+ filter: {
524
+ $and: [
525
+ {
526
+ $or: [{ category: 'electronics' }, { category: 'books' }],
527
+ },
528
+ { price: { $lt: 100 } },
529
+ { inStock: true },
530
+ ],
531
+ },
478
532
  });
479
533
  expect(results.length).toBeGreaterThan(0);
480
534
  results.forEach(result => {
@@ -487,8 +541,10 @@ describe.skip('PineconeVector Integration Tests', () => {
487
541
 
488
542
  describe('Complex Filter Combinations', () => {
489
543
  it('should combine comparison and array operators', async () => {
490
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
491
- $and: [{ price: { $gte: 500 } }, { tags: { $in: ['premium', 'refurbished'] } }],
544
+ const results = await vectorDB.query({
545
+ indexName: testIndexName,
546
+ queryVector: [1, 0, 0],
547
+ filter: { $and: [{ price: { $gte: 500 } }, { tags: { $in: ['premium', 'refurbished'] } }] },
492
548
  });
493
549
  expect(results.length).toBeGreaterThan(0);
494
550
  results.forEach(result => {
@@ -498,8 +554,10 @@ describe.skip('PineconeVector Integration Tests', () => {
498
554
  });
499
555
 
500
556
  it('should handle multiple conditions on same field', async () => {
501
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
502
- $and: [{ price: { $gte: 30 } }, { price: { $lte: 800 } }],
557
+ const results = await vectorDB.query({
558
+ indexName: testIndexName,
559
+ queryVector: [1, 0, 0],
560
+ filter: { $and: [{ price: { $gte: 30 } }, { price: { $lte: 800 } }] },
503
561
  });
504
562
  expect(results.length).toBeGreaterThan(0);
505
563
  results.forEach(result => {
@@ -510,15 +568,19 @@ describe.skip('PineconeVector Integration Tests', () => {
510
568
  });
511
569
 
512
570
  it('should handle complex nested conditions', async () => {
513
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
514
- $or: [
515
- {
516
- $and: [{ category: 'electronics' }, { price: { $gt: 700 } }, { tags: { $all: ['premium'] } }],
517
- },
518
- {
519
- $and: [{ category: 'books' }, { price: { $lt: 50 } }, { tags: { $in: ['paperback'] } }],
520
- },
521
- ],
571
+ const results = await vectorDB.query({
572
+ indexName: testIndexName,
573
+ queryVector: [1, 0, 0],
574
+ filter: {
575
+ $or: [
576
+ {
577
+ $and: [{ category: 'electronics' }, { price: { $gt: 700 } }, { tags: { $all: ['premium'] } }],
578
+ },
579
+ {
580
+ $and: [{ category: 'books' }, { price: { $lt: 50 } }, { tags: { $in: ['paperback'] } }],
581
+ },
582
+ ],
583
+ },
522
584
  });
523
585
  expect(results.length).toBeGreaterThan(0);
524
586
  results.forEach(result => {
@@ -537,8 +599,10 @@ describe.skip('PineconeVector Integration Tests', () => {
537
599
  });
538
600
 
539
601
  it('combines existence checks with other operators', async () => {
540
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
541
- $and: [{ category: 'clothing' }, { optionalField: { $exists: false } }],
602
+ const results = await vectorDB.query({
603
+ indexName: testIndexName,
604
+ queryVector: [1, 0, 0],
605
+ filter: { $and: [{ category: 'clothing' }, { optionalField: { $exists: false } }] },
542
606
  });
543
607
  expect(results.length).toBe(2);
544
608
  expect(results[0]!.metadata!.category).toBe('clothing');
@@ -548,8 +612,10 @@ describe.skip('PineconeVector Integration Tests', () => {
548
612
 
549
613
  describe('Edge Cases', () => {
550
614
  it('should handle numeric comparisons with decimals', async () => {
551
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
552
- rating: { $gt: 4.5 },
615
+ const results = await vectorDB.query({
616
+ indexName: testIndexName,
617
+ queryVector: [1, 0, 0],
618
+ filter: { rating: { $gt: 4.5 } },
553
619
  });
554
620
  expect(results.length).toBeGreaterThan(0);
555
621
  results.forEach(result => {
@@ -558,8 +624,10 @@ describe.skip('PineconeVector Integration Tests', () => {
558
624
  });
559
625
 
560
626
  it('should handle boolean values', async () => {
561
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
562
- inStock: { $eq: false },
627
+ const results = await vectorDB.query({
628
+ indexName: testIndexName,
629
+ queryVector: [1, 0, 0],
630
+ filter: { inStock: { $eq: false } },
563
631
  });
564
632
  expect(results.length).toBeGreaterThan(0);
565
633
  results.forEach(result => {
@@ -568,15 +636,19 @@ describe.skip('PineconeVector Integration Tests', () => {
568
636
  });
569
637
 
570
638
  it('should handle empty array in $in operator', async () => {
571
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
572
- category: { $in: [] },
639
+ const results = await vectorDB.query({
640
+ indexName: testIndexName,
641
+ queryVector: [1, 0, 0],
642
+ filter: { category: { $in: [] } },
573
643
  });
574
644
  expect(results).toHaveLength(0);
575
645
  });
576
646
 
577
647
  it('should handle single value in $all operator', async () => {
578
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
579
- tags: { $all: ['premium'] },
648
+ const results = await vectorDB.query({
649
+ indexName: testIndexName,
650
+ queryVector: [1, 0, 0],
651
+ filter: { tags: { $all: ['premium'] } },
580
652
  });
581
653
  expect(results.length).toBeGreaterThan(0);
582
654
  results.forEach(result => {
@@ -589,37 +661,57 @@ describe.skip('PineconeVector Integration Tests', () => {
589
661
  describe('Additional Validation Tests', () => {
590
662
  it('should reject non-numeric values in numeric comparisons', async () => {
591
663
  await expect(
592
- vectorDB.query(testIndexName, [1, 0, 0], 10, {
593
- price: { $gt: '500' }, // string instead of number
664
+ vectorDB.query({
665
+ indexName: testIndexName,
666
+ queryVector: [1, 0, 0],
667
+ filter: { price: { $gt: '500' } }, // string instead of number
594
668
  }),
595
669
  ).rejects.toThrow('the $gt operator must be followed by a number');
596
670
  });
597
671
 
598
672
  it('should reject invalid types in $in operator', async () => {
599
673
  await expect(
600
- vectorDB.query(testIndexName, [1, 0, 0], 10, {
601
- price: { $in: [true, false] }, // booleans instead of numbers
674
+ vectorDB.query({
675
+ indexName: testIndexName,
676
+ queryVector: [1, 0, 0],
677
+ filter: { price: { $in: [true, false] } }, // booleans instead of numbers
602
678
  }),
603
679
  ).rejects.toThrow('the $in operator must be followed by a list of strings or a list of numbers');
604
680
  });
605
681
 
606
682
  it('should reject mixed types in $in operator', async () => {
607
683
  await expect(
608
- vectorDB.query(testIndexName, [1, 0, 0], 10, {
609
- field: { $in: ['string', 123] }, // mixed string and number
684
+ vectorDB.query({
685
+ indexName: testIndexName,
686
+ queryVector: [1, 0, 0],
687
+ filter: { field: { $in: ['string', 123] } }, // mixed string and number
610
688
  }),
611
689
  ).rejects.toThrow();
612
690
  });
613
691
  it('should handle undefined filter', async () => {
614
- const results1 = await vectorDB.query(testIndexName, [1, 0, 0], 10, undefined);
615
- const results2 = await vectorDB.query(testIndexName, [1, 0, 0], 10);
692
+ const results1 = await vectorDB.query({
693
+ indexName: testIndexName,
694
+ queryVector: [1, 0, 0],
695
+ filter: undefined,
696
+ });
697
+ const results2 = await vectorDB.query({
698
+ indexName: testIndexName,
699
+ queryVector: [1, 0, 0],
700
+ });
616
701
  expect(results1).toEqual(results2);
617
702
  expect(results1.length).toBeGreaterThan(0);
618
703
  });
619
704
 
620
705
  it('should handle null filter', async () => {
621
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, null as any);
622
- const results2 = await vectorDB.query(testIndexName, [1, 0, 0], 10);
706
+ const results = await vectorDB.query({
707
+ indexName: testIndexName,
708
+ queryVector: [1, 0, 0],
709
+ filter: null,
710
+ });
711
+ const results2 = await vectorDB.query({
712
+ indexName: testIndexName,
713
+ queryVector: [1, 0, 0],
714
+ });
623
715
  expect(results).toEqual(results2);
624
716
  expect(results.length).toBeGreaterThan(0);
625
717
  });
@@ -628,11 +720,10 @@ describe.skip('PineconeVector Integration Tests', () => {
628
720
  describe('Additional Edge Cases', () => {
629
721
  it('should handle exact boundary conditions', async () => {
630
722
  // Test exact boundary values from our test data
631
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
632
- $and: [
633
- { price: { $gte: 25 } }, // lowest price in our data
634
- { price: { $lte: 1000 } }, // highest price in our data
635
- ],
723
+ const results = await vectorDB.query({
724
+ indexName: testIndexName,
725
+ queryVector: [1, 0, 0],
726
+ filter: { $and: [{ price: { $gte: 25 } }, { price: { $lte: 1000 } }] },
636
727
  });
637
728
  expect(results.length).toBeGreaterThan(0);
638
729
  // Should include both boundary values
@@ -641,8 +732,10 @@ describe.skip('PineconeVector Integration Tests', () => {
641
732
  });
642
733
 
643
734
  it('should handle multiple $all conditions on same array field', async () => {
644
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
645
- $and: [{ tags: { $all: ['premium'] } }, { tags: { $all: ['new'] } }],
735
+ const results = await vectorDB.query({
736
+ indexName: testIndexName,
737
+ queryVector: [1, 0, 0],
738
+ filter: { $and: [{ tags: { $all: ['premium'] } }, { tags: { $all: ['new'] } }] },
646
739
  });
647
740
  expect(results.length).toBeGreaterThan(0);
648
741
  results.forEach(result => {
@@ -652,8 +745,10 @@ describe.skip('PineconeVector Integration Tests', () => {
652
745
  });
653
746
 
654
747
  it('should handle multiple array operator combinations', async () => {
655
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
656
- $and: [{ tags: { $all: ['premium'] } }, { tags: { $in: ['new', 'refurbished'] } }],
748
+ const results = await vectorDB.query({
749
+ indexName: testIndexName,
750
+ queryVector: [1, 0, 0],
751
+ filter: { $and: [{ tags: { $all: ['premium'] } }, { tags: { $in: ['new', 'refurbished'] } }] },
657
752
  });
658
753
  expect(results.length).toBeGreaterThan(0);
659
754
  results.forEach(result => {
@@ -665,15 +760,19 @@ describe.skip('PineconeVector Integration Tests', () => {
665
760
 
666
761
  describe('Additional Complex Logical Combinations', () => {
667
762
  it('should handle deeply nested $or conditions', async () => {
668
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
669
- $or: [
670
- {
671
- $and: [{ category: 'electronics' }, { $or: [{ price: { $gt: 900 } }, { tags: { $all: ['premium'] } }] }],
672
- },
673
- {
674
- $and: [{ category: 'books' }, { $or: [{ price: { $lt: 30 } }, { tags: { $all: ['bestseller'] } }] }],
675
- },
676
- ],
763
+ const results = await vectorDB.query({
764
+ indexName: testIndexName,
765
+ queryVector: [1, 0, 0],
766
+ filter: {
767
+ $or: [
768
+ {
769
+ $and: [{ category: 'electronics' }, { $or: [{ price: { $gt: 900 } }, { tags: { $all: ['premium'] } }] }],
770
+ },
771
+ {
772
+ $and: [{ category: 'books' }, { $or: [{ price: { $lt: 30 } }, { tags: { $all: ['bestseller'] } }] }],
773
+ },
774
+ ],
775
+ },
677
776
  });
678
777
  expect(results.length).toBeGreaterThan(0);
679
778
  results.forEach(result => {
@@ -686,8 +785,10 @@ describe.skip('PineconeVector Integration Tests', () => {
686
785
  });
687
786
 
688
787
  it('should handle multiple field comparisons with same value', async () => {
689
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
690
- $or: [{ price: { $gt: 500 } }, { rating: { $gt: 4.5 } }],
788
+ const results = await vectorDB.query({
789
+ indexName: testIndexName,
790
+ queryVector: [1, 0, 0],
791
+ filter: { $or: [{ price: { $gt: 500 } }, { rating: { $gt: 4.5 } }] },
691
792
  });
692
793
  expect(results.length).toBeGreaterThan(0);
693
794
  results.forEach(result => {
@@ -696,11 +797,15 @@ describe.skip('PineconeVector Integration Tests', () => {
696
797
  });
697
798
 
698
799
  it('should handle combination of array and numeric comparisons', async () => {
699
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
700
- $and: [
701
- { tags: { $in: ['premium', 'bestseller'] } },
702
- { $or: [{ price: { $gt: 500 } }, { rating: { $gt: 4.5 } }] },
703
- ],
800
+ const results = await vectorDB.query({
801
+ indexName: testIndexName,
802
+ queryVector: [1, 0, 0],
803
+ filter: {
804
+ $and: [
805
+ { tags: { $in: ['premium', 'bestseller'] } },
806
+ { $or: [{ price: { $gt: 500 } }, { rating: { $gt: 4.5 } }] },
807
+ ],
808
+ },
704
809
  });
705
810
  expect(results.length).toBeGreaterThan(0);
706
811
  results.forEach(result => {
@@ -712,12 +817,16 @@ describe.skip('PineconeVector Integration Tests', () => {
712
817
 
713
818
  describe('Performance Edge Cases', () => {
714
819
  it('should handle filters with many conditions', async () => {
715
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
716
- $and: Array(10)
717
- .fill(null)
718
- .map(() => ({
719
- $or: [{ price: { $gt: 100 } }, { rating: { $gt: 4.0 } }],
720
- })),
820
+ const results = await vectorDB.query({
821
+ indexName: testIndexName,
822
+ queryVector: [1, 0, 0],
823
+ filter: {
824
+ $and: Array(10)
825
+ .fill(null)
826
+ .map(() => ({
827
+ $or: [{ price: { $gt: 100 } }, { rating: { $gt: 4.0 } }],
828
+ })),
829
+ },
721
830
  });
722
831
  expect(results.length).toBeGreaterThan(0);
723
832
  results.forEach(result => {
@@ -726,12 +835,16 @@ describe.skip('PineconeVector Integration Tests', () => {
726
835
  });
727
836
 
728
837
  it('should handle deeply nested conditions efficiently', async () => {
729
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
730
- $or: Array(5)
731
- .fill(null)
732
- .map(() => ({
733
- $and: [{ category: { $in: ['electronics', 'books'] } }, { price: { $gt: 50 } }, { rating: { $gt: 4.0 } }],
734
- })),
838
+ const results = await vectorDB.query({
839
+ indexName: testIndexName,
840
+ queryVector: [1, 0, 0],
841
+ filter: {
842
+ $or: Array(5)
843
+ .fill(null)
844
+ .map(() => ({
845
+ $and: [{ category: { $in: ['electronics', 'books'] } }, { price: { $gt: 50 } }, { rating: { $gt: 4.0 } }],
846
+ })),
847
+ },
735
848
  });
736
849
  expect(results.length).toBeGreaterThan(0);
737
850
  results.forEach(result => {
@@ -742,21 +855,164 @@ describe.skip('PineconeVector Integration Tests', () => {
742
855
  });
743
856
 
744
857
  it('should handle large number of $or conditions', async () => {
745
- const results = await vectorDB.query(testIndexName, [1, 0, 0], 10, {
746
- $or: [
747
- ...Array(5)
748
- .fill(null)
749
- .map((_, i) => ({
750
- price: { $gt: i * 100 },
751
- })),
752
- ...Array(5)
753
- .fill(null)
754
- .map((_, i) => ({
755
- rating: { $gt: 4.0 + i * 0.1 },
756
- })),
757
- ],
858
+ const results = await vectorDB.query({
859
+ indexName: testIndexName,
860
+ queryVector: [1, 0, 0],
861
+ filter: {
862
+ $or: [
863
+ ...Array(5)
864
+ .fill(null)
865
+ .map((_, i) => ({
866
+ price: { $gt: i * 100 },
867
+ })),
868
+ ...Array(5)
869
+ .fill(null)
870
+ .map((_, i) => ({
871
+ rating: { $gt: 4.0 + i * 0.1 },
872
+ })),
873
+ ],
874
+ },
758
875
  });
759
876
  expect(results.length).toBeGreaterThan(0);
760
877
  });
761
878
  });
879
+ describe('Deprecation Warnings', () => {
880
+ const indexName = 'testdeprecationwarnings';
881
+
882
+ const indexName2 = 'testdeprecationwarnings2';
883
+
884
+ const indexName3 = 'testdeprecationwarnings3';
885
+
886
+ const indexName4 = 'testdeprecationwarnings4';
887
+
888
+ let warnSpy;
889
+
890
+ beforeAll(async () => {
891
+ try {
892
+ await vectorDB.deleteIndex(indexName);
893
+ } catch {
894
+ // Ignore errors if index doesn't exist
895
+ }
896
+ try {
897
+ await vectorDB.deleteIndex(indexName2);
898
+ } catch {
899
+ // Ignore errors if index doesn't exist
900
+ }
901
+ try {
902
+ await vectorDB.deleteIndex(indexName3);
903
+ } catch {
904
+ // Ignore errors if index doesn't exist
905
+ }
906
+ try {
907
+ await vectorDB.deleteIndex(indexName4);
908
+ } catch {
909
+ // Ignore errors if index doesn't exist
910
+ }
911
+ await vectorDB.createIndex({ indexName: indexName, dimension: 3 });
912
+ await waitUntilReady(vectorDB, indexName);
913
+ });
914
+
915
+ afterAll(async () => {
916
+ try {
917
+ await vectorDB.deleteIndex(indexName);
918
+ } catch {
919
+ // Ignore errors if index doesn't exist
920
+ }
921
+ try {
922
+ await vectorDB.deleteIndex(indexName2);
923
+ } catch {
924
+ // Ignore errors if index doesn't exist
925
+ }
926
+ try {
927
+ await vectorDB.deleteIndex(indexName3);
928
+ } catch {
929
+ // Ignore errors if index doesn't exist
930
+ }
931
+ try {
932
+ await vectorDB.deleteIndex(indexName4);
933
+ } catch {
934
+ // Ignore errors if index doesn't exist
935
+ }
936
+ });
937
+
938
+ beforeEach(async () => {
939
+ warnSpy = vi.spyOn(vectorDB['logger'], 'warn');
940
+ });
941
+
942
+ afterEach(async () => {
943
+ warnSpy.mockRestore();
944
+ });
945
+
946
+ it('should show deprecation warning when using individual args for createIndex', async () => {
947
+ await vectorDB.createIndex(indexName2, 3, 'cosine');
948
+ await waitUntilReady(vectorDB, indexName2);
949
+ expect(warnSpy).toHaveBeenCalledWith(
950
+ expect.stringContaining('Deprecation Warning: Passing individual arguments to createIndex() is deprecated'),
951
+ );
952
+ });
953
+
954
+ it('should show deprecation warning when using individual args for upsert', async () => {
955
+ await vectorDB.upsert(indexName, [[1, 2, 3]], [{ test: 'data' }]);
956
+
957
+ expect(warnSpy).toHaveBeenCalledWith(
958
+ expect.stringContaining('Deprecation Warning: Passing individual arguments to upsert() is deprecated'),
959
+ );
960
+ });
961
+
962
+ it('should show deprecation warning when using individual args for query', async () => {
963
+ await vectorDB.query(indexName, [1, 2, 3], 5);
964
+
965
+ expect(warnSpy).toHaveBeenCalledWith(
966
+ expect.stringContaining('Deprecation Warning: Passing individual arguments to query() is deprecated'),
967
+ );
968
+ });
969
+
970
+ it('should not show deprecation warning when using object param for query', async () => {
971
+ await vectorDB.query({
972
+ indexName,
973
+ queryVector: [1, 2, 3],
974
+ topK: 5,
975
+ });
976
+
977
+ expect(warnSpy).not.toHaveBeenCalled();
978
+ });
979
+
980
+ it('should not show deprecation warning when using object param for createIndex', async () => {
981
+ await vectorDB.createIndex({
982
+ indexName: indexName3,
983
+ dimension: 3,
984
+ metric: 'cosine',
985
+ });
986
+
987
+ expect(warnSpy).not.toHaveBeenCalled();
988
+ });
989
+
990
+ it('should not show deprecation warning when using object param for upsert', async () => {
991
+ await vectorDB.upsert({
992
+ indexName,
993
+ vectors: [[1, 2, 3]],
994
+ metadata: [{ test: 'data' }],
995
+ });
996
+
997
+ expect(warnSpy).not.toHaveBeenCalled();
998
+ });
999
+
1000
+ it('should maintain backward compatibility with individual args', async () => {
1001
+ // Query
1002
+ const queryResults = await vectorDB.query(indexName, [1, 2, 3], 5);
1003
+ expect(Array.isArray(queryResults)).toBe(true);
1004
+
1005
+ // CreateIndex
1006
+ await expect(vectorDB.createIndex(indexName4, 3, 'cosine')).resolves.not.toThrow();
1007
+ await waitUntilReady(vectorDB, indexName4);
1008
+ // Upsert
1009
+ const upsertResults = await vectorDB.upsert({
1010
+ indexName,
1011
+ vectors: [[1, 2, 3]],
1012
+ metadata: [{ test: 'data' }],
1013
+ });
1014
+ expect(Array.isArray(upsertResults)).toBe(true);
1015
+ expect(upsertResults).toHaveLength(1);
1016
+ });
1017
+ });
762
1018
  });