@mastra/astra 0.10.2 → 0.10.3-alpha.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/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { DataAPIClient, UUID } from '@datastax/astra-db-ts';
2
+ import { MastraError, ErrorCategory, ErrorDomain } from '@mastra/core/error';
2
3
  import { MastraVector } from '@mastra/core/vector';
3
4
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
4
5
 
@@ -68,15 +69,32 @@ var AstraVector = class extends MastraVector {
68
69
  */
69
70
  async createIndex({ indexName, dimension, metric = "cosine" }) {
70
71
  if (!Number.isInteger(dimension) || dimension <= 0) {
71
- throw new Error("Dimension must be a positive integer");
72
+ throw new MastraError({
73
+ id: "ASTRA_VECTOR_CREATE_INDEX_INVALID_DIMENSION",
74
+ text: "Dimension must be a positive integer",
75
+ domain: ErrorDomain.MASTRA_VECTOR,
76
+ category: ErrorCategory.USER
77
+ });
78
+ }
79
+ try {
80
+ await this.#db.createCollection(indexName, {
81
+ vector: {
82
+ dimension,
83
+ metric: metricMap[metric]
84
+ },
85
+ checkExists: false
86
+ });
87
+ } catch (error) {
88
+ new MastraError(
89
+ {
90
+ id: "ASTRA_VECTOR_CREATE_INDEX_DB_ERROR",
91
+ domain: ErrorDomain.MASTRA_VECTOR,
92
+ category: ErrorCategory.THIRD_PARTY,
93
+ details: { indexName }
94
+ },
95
+ error
96
+ );
72
97
  }
73
- await this.#db.createCollection(indexName, {
74
- vector: {
75
- dimension,
76
- metric: metricMap[metric]
77
- },
78
- checkExists: false
79
- });
80
98
  }
81
99
  /**
82
100
  * Inserts or updates vectors in the specified collection.
@@ -95,7 +113,19 @@ var AstraVector = class extends MastraVector {
95
113
  $vector: vector,
96
114
  metadata: metadata?.[i] || {}
97
115
  }));
98
- await collection.insertMany(records);
116
+ try {
117
+ await collection.insertMany(records);
118
+ } catch (error) {
119
+ throw new MastraError(
120
+ {
121
+ id: "ASTRA_VECTOR_UPSERT_DB_ERROR",
122
+ domain: ErrorDomain.MASTRA_VECTOR,
123
+ category: ErrorCategory.THIRD_PARTY,
124
+ details: { indexName }
125
+ },
126
+ error
127
+ );
128
+ }
99
129
  return vectorIds;
100
130
  }
101
131
  transformFilter(filter) {
@@ -121,29 +151,52 @@ var AstraVector = class extends MastraVector {
121
151
  }) {
122
152
  const collection = this.#db.collection(indexName);
123
153
  const translatedFilter = this.transformFilter(filter);
124
- const cursor = collection.find(translatedFilter ?? {}, {
125
- sort: { $vector: queryVector },
126
- limit: topK,
127
- includeSimilarity: true,
128
- projection: {
129
- $vector: includeVector ? true : false
130
- }
131
- });
132
- const results = await cursor.toArray();
133
- return results.map((result) => ({
134
- id: result.id,
135
- score: result.$similarity,
136
- metadata: result.metadata,
137
- ...includeVector && { vector: result.$vector }
138
- }));
154
+ try {
155
+ const cursor = collection.find(translatedFilter ?? {}, {
156
+ sort: { $vector: queryVector },
157
+ limit: topK,
158
+ includeSimilarity: true,
159
+ projection: {
160
+ $vector: includeVector ? true : false
161
+ }
162
+ });
163
+ const results = await cursor.toArray();
164
+ return results.map((result) => ({
165
+ id: result.id,
166
+ score: result.$similarity,
167
+ metadata: result.metadata,
168
+ ...includeVector && { vector: result.$vector }
169
+ }));
170
+ } catch (error) {
171
+ throw new MastraError(
172
+ {
173
+ id: "ASTRA_VECTOR_QUERY_DB_ERROR",
174
+ domain: ErrorDomain.MASTRA_VECTOR,
175
+ category: ErrorCategory.THIRD_PARTY,
176
+ details: { indexName }
177
+ },
178
+ error
179
+ );
180
+ }
139
181
  }
140
182
  /**
141
183
  * Lists all collections in the database.
142
184
  *
143
185
  * @returns {Promise<string[]>} A promise that resolves to an array of collection names.
144
186
  */
145
- listIndexes() {
146
- return this.#db.listCollections({ nameOnly: true });
187
+ async listIndexes() {
188
+ try {
189
+ return await this.#db.listCollections({ nameOnly: true });
190
+ } catch (error) {
191
+ throw new MastraError(
192
+ {
193
+ id: "ASTRA_VECTOR_LIST_INDEXES_DB_ERROR",
194
+ domain: ErrorDomain.MASTRA_VECTOR,
195
+ category: ErrorCategory.THIRD_PARTY
196
+ },
197
+ error
198
+ );
199
+ }
147
200
  }
148
201
  /**
149
202
  * Retrieves statistics about a vector index.
@@ -153,16 +206,29 @@ var AstraVector = class extends MastraVector {
153
206
  */
154
207
  async describeIndex({ indexName }) {
155
208
  const collection = this.#db.collection(indexName);
156
- const optionsPromise = collection.options();
157
- const countPromise = collection.countDocuments({}, 100);
158
- const [options, count] = await Promise.all([optionsPromise, countPromise]);
159
- const keys = Object.keys(metricMap);
160
- const metric = keys.find((key) => metricMap[key] === options.vector?.metric);
161
- return {
162
- dimension: options.vector?.dimension,
163
- metric,
164
- count
165
- };
209
+ try {
210
+ const optionsPromise = collection.options();
211
+ const countPromise = collection.countDocuments({}, 100);
212
+ const [options, count] = await Promise.all([optionsPromise, countPromise]);
213
+ const keys = Object.keys(metricMap);
214
+ const metric = keys.find((key) => metricMap[key] === options.vector?.metric);
215
+ return {
216
+ dimension: options.vector?.dimension,
217
+ metric,
218
+ count
219
+ };
220
+ } catch (error) {
221
+ if (error instanceof MastraError) throw error;
222
+ throw new MastraError(
223
+ {
224
+ id: "ASTRA_VECTOR_DESCRIBE_INDEX_DB_ERROR",
225
+ domain: ErrorDomain.MASTRA_VECTOR,
226
+ category: ErrorCategory.THIRD_PARTY,
227
+ details: { indexName }
228
+ },
229
+ error
230
+ );
231
+ }
166
232
  }
167
233
  /**
168
234
  * Deletes the specified collection.
@@ -172,7 +238,19 @@ var AstraVector = class extends MastraVector {
172
238
  */
173
239
  async deleteIndex({ indexName }) {
174
240
  const collection = this.#db.collection(indexName);
175
- await collection.drop();
241
+ try {
242
+ await collection.drop();
243
+ } catch (error) {
244
+ throw new MastraError(
245
+ {
246
+ id: "ASTRA_VECTOR_DELETE_INDEX_DB_ERROR",
247
+ domain: ErrorDomain.MASTRA_VECTOR,
248
+ category: ErrorCategory.THIRD_PARTY,
249
+ details: { indexName }
250
+ },
251
+ error
252
+ );
253
+ }
176
254
  }
177
255
  /**
178
256
  * Updates a vector by its ID with the provided vector and/or metadata.
@@ -185,10 +263,16 @@ var AstraVector = class extends MastraVector {
185
263
  * @throws Will throw an error if no updates are provided or if the update operation fails.
186
264
  */
187
265
  async updateVector({ indexName, id, update }) {
266
+ if (!update.vector && !update.metadata) {
267
+ throw new MastraError({
268
+ id: "ASTRA_VECTOR_UPDATE_NO_PAYLOAD",
269
+ text: "No updates provided for vector",
270
+ domain: ErrorDomain.MASTRA_VECTOR,
271
+ category: ErrorCategory.USER,
272
+ details: { indexName, id }
273
+ });
274
+ }
188
275
  try {
189
- if (!update.vector && !update.metadata) {
190
- throw new Error("No updates provided");
191
- }
192
276
  const collection = this.#db.collection(indexName);
193
277
  const updateDoc = {};
194
278
  if (update.vector) {
@@ -199,7 +283,16 @@ var AstraVector = class extends MastraVector {
199
283
  }
200
284
  await collection.findOneAndUpdate({ id }, { $set: updateDoc });
201
285
  } catch (error) {
202
- throw new Error(`Failed to update vector by id: ${id} for index name: ${indexName}: ${error.message}`);
286
+ if (error instanceof MastraError) throw error;
287
+ throw new MastraError(
288
+ {
289
+ id: "ASTRA_VECTOR_UPDATE_FAILED_UNHANDLED",
290
+ domain: ErrorDomain.MASTRA_VECTOR,
291
+ category: ErrorCategory.THIRD_PARTY,
292
+ details: { indexName, id }
293
+ },
294
+ error
295
+ );
203
296
  }
204
297
  }
205
298
  /**
@@ -214,7 +307,16 @@ var AstraVector = class extends MastraVector {
214
307
  const collection = this.#db.collection(indexName);
215
308
  await collection.deleteOne({ id });
216
309
  } catch (error) {
217
- throw new Error(`Failed to delete vector by id: ${id} for index name: ${indexName}: ${error.message}`);
310
+ if (error instanceof MastraError) throw error;
311
+ throw new MastraError(
312
+ {
313
+ id: "ASTRA_VECTOR_DELETE_FAILED",
314
+ domain: ErrorDomain.MASTRA_VECTOR,
315
+ category: ErrorCategory.THIRD_PARTY,
316
+ details: { indexName, id }
317
+ },
318
+ error
319
+ );
218
320
  }
219
321
  }
220
322
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/astra",
3
- "version": "0.10.2",
3
+ "version": "0.10.3-alpha.1",
4
4
  "description": "Astra DB provider for Mastra - includes vector store capabilities",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -24,13 +24,13 @@
24
24
  },
25
25
  "devDependencies": {
26
26
  "@microsoft/api-extractor": "^7.52.8",
27
- "@types/node": "^20.17.57",
28
- "eslint": "^9.28.0",
27
+ "@types/node": "^20.19.0",
28
+ "eslint": "^9.29.0",
29
29
  "tsup": "^8.5.0",
30
- "typescript": "^5.8.2",
31
- "vitest": "^3.2.2",
32
- "@internal/lint": "0.0.11",
33
- "@mastra/core": "0.10.4"
30
+ "typescript": "^5.8.3",
31
+ "vitest": "^3.2.3",
32
+ "@mastra/core": "0.10.7-alpha.2",
33
+ "@internal/lint": "0.0.13"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@mastra/core": ">=0.10.4-0 <0.11.0"
@@ -1,5 +1,6 @@
1
1
  import { describe, it, expect, beforeEach } from 'vitest';
2
2
 
3
+ import type { AstraVectorFilter } from './filter';
3
4
  import { AstraFilterTranslator } from './filter';
4
5
 
5
6
  describe('AstraFilterTranslator', () => {
@@ -12,12 +13,12 @@ describe('AstraFilterTranslator', () => {
12
13
  // Basic Filter Operations
13
14
  describe('basic operations', () => {
14
15
  it('handles simple equality', () => {
15
- const filter = { field: 'value' };
16
+ const filter: AstraVectorFilter = { field: 'value' };
16
17
  expect(translator.translate(filter)).toEqual(filter);
17
18
  });
18
19
 
19
20
  it('handles comparison operators', () => {
20
- const filter = {
21
+ const filter: AstraVectorFilter = {
21
22
  age: { $gt: 25 },
22
23
  score: { $lte: 100 },
23
24
  };
@@ -25,7 +26,7 @@ describe('AstraFilterTranslator', () => {
25
26
  });
26
27
 
27
28
  it('handles valid multiple operators on same field', () => {
28
- const filter = {
29
+ const filter: AstraVectorFilter = {
29
30
  price: { $gt: 100, $lt: 200 },
30
31
  quantity: { $gte: 10, $lte: 20 },
31
32
  };
@@ -33,7 +34,7 @@ describe('AstraFilterTranslator', () => {
33
34
  });
34
35
 
35
36
  it('handles null values correctly', () => {
36
- const filter = {
37
+ const filter: AstraVectorFilter = {
37
38
  field: null,
38
39
  other: { $eq: null },
39
40
  };
@@ -41,7 +42,7 @@ describe('AstraFilterTranslator', () => {
41
42
  });
42
43
 
43
44
  it('throws on unsupported combinations', () => {
44
- const filter = {
45
+ const filter: AstraVectorFilter = {
45
46
  field: { $gt: 100, $lt: 200 },
46
47
  };
47
48
  expect(translator.translate(filter)).toEqual(filter);
@@ -51,14 +52,14 @@ describe('AstraFilterTranslator', () => {
51
52
  // Array Operations
52
53
  describe('array operations', () => {
53
54
  it('handles array operators', () => {
54
- const filter = {
55
+ const filter: AstraVectorFilter = {
55
56
  tags: { $all: ['tag1', 'tag2'] },
56
57
  categories: { $in: ['A', 'B'] },
57
58
  };
58
59
  expect(translator.translate(filter)).toEqual(filter);
59
60
  });
60
61
  it('handles empty array values', () => {
61
- const filter = {
62
+ const filter: AstraVectorFilter = {
62
63
  tags: { $in: [] },
63
64
  categories: { $all: [] },
64
65
  };
@@ -66,7 +67,7 @@ describe('AstraFilterTranslator', () => {
66
67
  });
67
68
 
68
69
  it('handles nested array operators', () => {
69
- const filter = {
70
+ const filter: AstraVectorFilter = {
70
71
  $and: [{ tags: { $all: ['tag1', 'tag2'] } }, { 'nested.array': { $in: [1, 2, 3] } }],
71
72
  };
72
73
  expect(translator.translate(filter)).toEqual(filter);
@@ -76,14 +77,14 @@ describe('AstraFilterTranslator', () => {
76
77
  // Logical Operators
77
78
  describe('logical operators', () => {
78
79
  it('handles logical operators', () => {
79
- const filter = {
80
+ const filter: AstraVectorFilter = {
80
81
  $or: [{ status: 'active' }, { age: { $gt: 25 } }],
81
82
  };
82
83
  expect(translator.translate(filter)).toEqual(filter);
83
84
  });
84
85
 
85
86
  it('handles nested logical operators', () => {
86
- const filter = {
87
+ const filter: AstraVectorFilter = {
87
88
  $and: [
88
89
  { status: 'active' },
89
90
  { $or: [{ category: { $in: ['A', 'B'] } }, { $and: [{ price: { $gt: 100 } }, { stock: { $lt: 50 } }] }] },
@@ -93,7 +94,7 @@ describe('AstraFilterTranslator', () => {
93
94
  });
94
95
 
95
96
  it('handles empty conditions in logical operators', () => {
96
- const filter = {
97
+ const filter: AstraVectorFilter = {
97
98
  $and: [],
98
99
  $or: [{}],
99
100
  field: 'value',
@@ -147,7 +148,7 @@ describe('AstraFilterTranslator', () => {
147
148
 
148
149
  expect(() =>
149
150
  translator.translate({
150
- $or: [{ $in: ['value1', 'value2'] }],
151
+ $or: [{ $in: ['value1', 'value2'] as any }],
151
152
  }),
152
153
  ).toThrow(/Logical operators must contain field conditions/);
153
154
  });
@@ -158,7 +159,7 @@ describe('AstraFilterTranslator', () => {
158
159
  field: {
159
160
  $gt: {
160
161
  $or: [{ subfield: 'value1' }, { subfield: 'value2' }],
161
- },
162
+ } as any,
162
163
  },
163
164
  }),
164
165
  ).toThrow();
@@ -169,7 +170,7 @@ describe('AstraFilterTranslator', () => {
169
170
  $in: [
170
171
  {
171
172
  $and: [{ subfield: 'value1' }, { subfield: 'value2' }],
172
- },
173
+ } as any,
173
174
  ],
174
175
  },
175
176
  }),
@@ -182,7 +183,7 @@ describe('AstraFilterTranslator', () => {
182
183
  field: {
183
184
  $gt: {
184
185
  $or: [{ subfield: 'value1' }, { subfield: 'value2' }],
185
- },
186
+ } as any,
186
187
  },
187
188
  }),
188
189
  ).toThrow();
@@ -200,7 +201,7 @@ describe('AstraFilterTranslator', () => {
200
201
 
201
202
  it('throws error for $not if not an object', () => {
202
203
  expect(() => translator.translate({ $not: 'value' })).toThrow();
203
- expect(() => translator.translate({ $not: [{ field: 'value' }] })).toThrow();
204
+ expect(() => translator.translate({ $not: [{ field: 'value' }] } as any)).toThrow();
204
205
  });
205
206
 
206
207
  it('throws error for $not if empty', () => {
@@ -211,7 +212,7 @@ describe('AstraFilterTranslator', () => {
211
212
  // Nested Objects and Fields
212
213
  describe('nested objects and fields', () => {
213
214
  it('handles nested objects', () => {
214
- const filter = {
215
+ const filter: AstraVectorFilter = {
215
216
  'user.profile.age': { $gt: 25 },
216
217
  'user.status': 'active',
217
218
  };
@@ -219,7 +220,7 @@ describe('AstraFilterTranslator', () => {
219
220
  });
220
221
 
221
222
  it('handles deeply nested field paths', () => {
222
- const filter = {
223
+ const filter: AstraVectorFilter = {
223
224
  'user.profile.address.city': { $eq: 'New York' },
224
225
  'deep.nested.field': { $gt: 100 },
225
226
  };
@@ -227,38 +228,28 @@ describe('AstraFilterTranslator', () => {
227
228
  });
228
229
 
229
230
  it('preserves nested empty objects', () => {
230
- const filter = {
231
+ const filter: AstraVectorFilter = {
231
232
  status: 'active',
232
233
  metadata: {},
233
- user: {
234
- profile: {},
235
- settings: { theme: null },
236
- },
234
+ 'user.profile': {},
235
+ 'usersettings.theme': null,
237
236
  };
238
237
  expect(translator.translate(filter)).toEqual(filter);
239
238
  });
240
239
 
241
240
  it('handles mix of operators and empty objects', () => {
242
- const filter = {
241
+ const filter: AstraVectorFilter = {
243
242
  tags: { $in: ['a', 'b'] },
244
243
  metadata: {},
245
- nested: {
246
- field: { $eq: 'value' },
247
- empty: {},
248
- },
244
+ 'nested.field': { $eq: 'value' },
245
+ 'nested.empty': {},
249
246
  };
250
247
  expect(translator.translate(filter)).toEqual(filter);
251
248
  });
252
249
 
253
250
  it('handles deeply nested operators', () => {
254
- const filter = {
255
- user: {
256
- profile: {
257
- preferences: {
258
- theme: { $in: ['dark', 'light'] },
259
- },
260
- },
261
- },
251
+ const filter: AstraVectorFilter = {
252
+ 'user.profile.preferences.theme': { $in: ['dark', 'light'] },
262
253
  };
263
254
  expect(translator.translate(filter)).toEqual(filter);
264
255
  });
@@ -268,13 +259,13 @@ describe('AstraFilterTranslator', () => {
268
259
  describe('special cases', () => {
269
260
  it('handles empty filters', () => {
270
261
  expect(translator.translate({})).toEqual({});
271
- expect(translator.translate(null as any)).toEqual(null);
272
- expect(translator.translate(undefined as any)).toEqual(undefined);
262
+ expect(translator.translate(null)).toEqual(null);
263
+ expect(translator.translate(undefined)).toEqual(undefined);
273
264
  });
274
265
 
275
266
  it('normalizes dates', () => {
276
267
  const date = new Date('2024-01-01');
277
- const filter = { timestamp: { $gt: date } };
268
+ const filter: AstraVectorFilter = { timestamp: { $gt: date } };
278
269
  expect(translator.translate(filter)).toEqual({
279
270
  timestamp: { $gt: date.toISOString() },
280
271
  });
@@ -293,7 +284,7 @@ describe('AstraFilterTranslator', () => {
293
284
 
294
285
  describe('operator validation', () => {
295
286
  it('ensure all operator filters are supported', () => {
296
- const supportedFilters = [
287
+ const supportedFilters: AstraVectorFilter[] = [
297
288
  // Basic comparison operators
298
289
  { field: { $eq: 'value' } },
299
290
  { field: { $ne: 'value' } },
@@ -313,11 +304,9 @@ describe('AstraFilterTranslator', () => {
313
304
  { $and: [{ field1: 'value1' }, { field2: 'value2' }] },
314
305
  { $or: [{ field1: 'value1' }, { field2: 'value2' }] },
315
306
 
316
- { $and: { field: 'value' } },
317
- { $or: { field: 'value' } },
318
307
  { $not: { field: 'value' } },
319
308
 
320
- { $or: [{ $and: { field1: 'value1' } }, { $not: { field2: 'value2' } }] },
309
+ { $or: [{ $and: [{ field1: 'value1' }] }, { $not: { field2: 'value2' } }] },
321
310
 
322
311
  { field: { $not: { $eq: 'value' } } },
323
312
  { field: { $not: { $in: ['value1', 'value2'] } } },
@@ -333,16 +322,16 @@ describe('AstraFilterTranslator', () => {
333
322
  });
334
323
 
335
324
  it('throws on unsupported operators', () => {
336
- expect(() => translator.translate({ field: { $regex: 'value' } })).toThrow('Unsupported operator: $regex');
337
- const filter = { field: /pattern/i };
325
+ expect(() => translator.translate({ field: { $regex: 'value' } as any })).toThrow('Unsupported operator: $regex');
326
+ const filter: any = { field: /pattern/i };
338
327
  expect(() => translator.translate(filter)).toThrow();
339
- expect(() => translator.translate({ $nor: [{ field: 'value' }] })).toThrow('Unsupported operator: $nor');
340
- expect(() => translator.translate({ field: { $elemMatch: { $gt: 5 } } })).toThrow(
328
+ expect(() => translator.translate({ $nor: [{ field: 'value' }] } as any)).toThrow('Unsupported operator: $nor');
329
+ expect(() => translator.translate({ field: { $elemMatch: { $gt: 5 } } } as any)).toThrow(
341
330
  'Unsupported operator: $elemMatch',
342
331
  );
343
332
  });
344
333
  it('throws error for non-logical operators at top level', () => {
345
- const invalidFilters = [{ $gt: 100 }, { $in: ['value1', 'value2'] }, { $exists: true }];
334
+ const invalidFilters: any = [{ $gt: 100 }, { $in: ['value1', 'value2'] }, { $exists: true }];
346
335
 
347
336
  invalidFilters.forEach(filter => {
348
337
  expect(() => translator.translate(filter)).toThrow(/Invalid top-level operator/);
@@ -350,7 +339,7 @@ describe('AstraFilterTranslator', () => {
350
339
  });
351
340
 
352
341
  it('allows logical operators at top level', () => {
353
- const validFilters = [
342
+ const validFilters: AstraVectorFilter[] = [
354
343
  { $and: [{ field: 'value' }] },
355
344
  { $or: [{ field: 'value' }] },
356
345
  { $not: { field: 'value' } },
@@ -1,12 +1,34 @@
1
1
  import { BaseFilterTranslator } from '@mastra/core/vector/filter';
2
- import type { FieldCondition, VectorFilter, OperatorSupport, QueryOperator } from '@mastra/core/vector/filter';
2
+ import type {
3
+ VectorFilter,
4
+ OperatorSupport,
5
+ QueryOperator,
6
+ OperatorValueMap,
7
+ LogicalOperatorValueMap,
8
+ BlacklistedRootOperators,
9
+ } from '@mastra/core/vector/filter';
10
+
11
+ type AstraOperatorValueMap = Omit<OperatorValueMap, '$elemMatch' | '$regex' | '$options'> & {
12
+ $size: number; // Astra-specific
13
+ };
14
+
15
+ type AstraLogicalOperatorValueMap = Omit<LogicalOperatorValueMap, '$nor'>;
16
+
17
+ type AstraBlacklisted = BlacklistedRootOperators | '$nor' | '$size';
18
+
19
+ export type AstraVectorFilter = VectorFilter<
20
+ keyof AstraOperatorValueMap,
21
+ AstraOperatorValueMap,
22
+ AstraLogicalOperatorValueMap,
23
+ AstraBlacklisted
24
+ >;
3
25
 
4
26
  /**
5
27
  * Translator for Astra DB filter queries.
6
28
  * Maintains MongoDB-compatible syntax while ensuring proper validation
7
29
  * and normalization of values.
8
30
  */
9
- export class AstraFilterTranslator extends BaseFilterTranslator {
31
+ export class AstraFilterTranslator extends BaseFilterTranslator<AstraVectorFilter> {
10
32
  protected override getSupportedOperators(): OperatorSupport {
11
33
  return {
12
34
  ...BaseFilterTranslator.DEFAULT_OPERATORS,
@@ -17,14 +39,14 @@ export class AstraFilterTranslator extends BaseFilterTranslator {
17
39
  };
18
40
  }
19
41
 
20
- translate(filter?: VectorFilter): VectorFilter {
42
+ translate(filter?: AstraVectorFilter): AstraVectorFilter {
21
43
  if (this.isEmpty(filter)) return filter;
22
44
  this.validateFilter(filter);
23
45
 
24
46
  return this.translateNode(filter);
25
47
  }
26
48
 
27
- private translateNode(node: VectorFilter | FieldCondition): any {
49
+ private translateNode(node: AstraVectorFilter): any {
28
50
  // Handle primitive values and arrays
29
51
  if (this.isRegex(node)) {
30
52
  throw new Error('Regex is not supported in Astra DB');
@@ -297,7 +297,7 @@ describe.skip('AstraVector Integration Tests', () => {
297
297
  vectorDB.query({
298
298
  indexName: testIndexName2,
299
299
  queryVector: [1, 0, 0, 0],
300
- filter: { tags: { $all: 'not-an-array' } },
300
+ filter: { tags: { $all: 'not-an-array' as any } },
301
301
  }),
302
302
  ).rejects.toThrow();
303
303
  });
@@ -307,15 +307,7 @@ describe.skip('AstraVector Integration Tests', () => {
307
307
  vectorDB.query({
308
308
  indexName: testIndexName2,
309
309
  queryVector: [1, 0, 0, 0],
310
- filter: { tags: { $in: null } },
311
- }),
312
- ).rejects.toThrow();
313
-
314
- await expect(
315
- vectorDB.query({
316
- indexName: testIndexName2,
317
- queryVector: [1, 0, 0, 0],
318
- filter: { tags: { $all: 'not-an-array' } },
310
+ filter: { tags: { $in: null as any } },
319
311
  }),
320
312
  ).rejects.toThrow();
321
313
  });
@@ -327,7 +319,7 @@ describe.skip('AstraVector Integration Tests', () => {
327
319
  vectorDB.query({
328
320
  indexName: testIndexName2,
329
321
  queryVector: [1, 0, 0, 0],
330
- filter: { field: { $in: val } },
322
+ filter: { field: { $in: val as any } },
331
323
  }),
332
324
  ).rejects.toThrow();
333
325
  }
@@ -340,7 +332,7 @@ describe.skip('AstraVector Integration Tests', () => {
340
332
  vectorDB.query({
341
333
  indexName: testIndexName2,
342
334
  queryVector: [1, 0, 0, 0],
343
- filter: { field: { $nin: val } },
335
+ filter: { field: { $nin: val as any } },
344
336
  }),
345
337
  ).rejects.toThrow();
346
338
  }
@@ -353,7 +345,7 @@ describe.skip('AstraVector Integration Tests', () => {
353
345
  vectorDB.query({
354
346
  indexName: testIndexName2,
355
347
  queryVector: [1, 0, 0, 0],
356
- filter: { field: { $all: val } },
348
+ filter: { field: { $all: val as any } },
357
349
  }),
358
350
  ).rejects.toThrow();
359
351
  }
@@ -366,7 +358,7 @@ describe.skip('AstraVector Integration Tests', () => {
366
358
  vectorDB.query({
367
359
  indexName: testIndexName2,
368
360
  queryVector: [1, 0, 0, 0],
369
- filter: { field: { $exists: val } },
361
+ filter: { field: { $exists: val as any } },
370
362
  }),
371
363
  ).rejects.toThrow();
372
364
  }
@@ -395,9 +387,9 @@ describe.skip('AstraVector Integration Tests', () => {
395
387
  indexName: testIndexName2,
396
388
  queryVector: [1, 0, 0, 0],
397
389
  filter: {
398
- field1: { $in: 'not-array' },
399
- field2: { $exists: 'not-boolean' },
400
- field3: { $gt: 'not-number' },
390
+ field1: { $in: 'not-array' as any },
391
+ field2: { $exists: 'not-boolean' as any },
392
+ field3: { $gt: 'not-number' as any },
401
393
  },
402
394
  }),
403
395
  ).rejects.toThrow();