UNPKG

@mastra/core

Version:

Mastra is a framework for building AI-powered applications and agents with a modern TypeScript stack.

1 lines • 21.1 kB
{"version":3,"sources":["../src/vector/filter/base.ts"],"names":[],"mappings":"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","file":"chunk-6XCINXZ7.cjs","sourcesContent":["type BasicOperator =\n | '$eq' // Matches values equal to specified value\n | '$ne'; // Matches values not equal\n\ntype NumericOperator =\n | '$gt' // Greater than\n | '$gte' // Greater than or equal\n | '$lt' // Less than\n | '$lte'; // Less than or equal\n\ntype LogicalOperator =\n | '$and' // Joins query clauses with logical AND\n | '$not' // Inverts the effect of a query expression\n | '$nor' // Joins query clauses with logical NOR\n | '$or'; // Joins query clauses with logical OR\n\ntype ArrayOperator =\n | '$all' // Matches arrays containing all elements\n | '$in' // Matches any value in array\n | '$nin' // Matches none of the values in array\n | '$elemMatch'; // Matches documents that contain an array field with at least one element that matches all the specified query criteria\n\ntype ElementOperator = '$exists'; // Matches documents that have the specified field\n\ntype RegexOperator = '$regex' | '$options'; // Matches documents that have the specified field\n\n// Union of all supported operators\ntype QueryOperator =\n | BasicOperator\n | NumericOperator\n | LogicalOperator\n | ArrayOperator\n | ElementOperator\n | RegexOperator;\n\ntype EmptyObject = Record<string, never>;\n\ntype FilterValue = string | number | boolean | Date | null | undefined | EmptyObject;\n\n// Logical operators are handled at the top level as objects, not as values here\n// $and, $or, $nor, $not are handled in LogicalCondition\ntype OperatorValueMap<Op extends string = string, ValueMap extends Record<string, any> = any> = {\n $eq: FilterValue;\n $ne: FilterValue;\n $gt: number | string | Date;\n $gte: number | string | Date;\n $lt: number | string | Date;\n $lte: number | string | Date;\n $all: FilterValue[];\n $in: FilterValue[];\n $nin: FilterValue[];\n $elemMatch: Record<string, unknown>;\n $exists: boolean;\n $regex: string | RegExp;\n $options: string;\n $not: OperatorCondition<Op, ValueMap> | RegExp;\n};\n\ntype LogicalOperatorValueMap = {\n $and: 'array';\n $or: 'array';\n $nor: 'array';\n $not: 'object';\n};\n\ntype BlacklistedRootOperators =\n | '$eq'\n | '$ne'\n | '$gt'\n | '$gte'\n | '$lt'\n | '$lte'\n | '$in'\n | '$nin'\n | '$all'\n | '$exists'\n | '$regex'\n | '$options'\n | '$elemMatch';\n\ntype VectorFieldValue = FilterValue | FilterValue[];\n\n// Vector filter parameterized by operator set\ntype VectorFilter<\n Op extends keyof ValueMap = keyof OperatorValueMap,\n ValueMap extends Record<string, any> = OperatorValueMap,\n LogicalValueMap extends Record<string, any> = LogicalOperatorValueMap,\n Blacklisted extends string = BlacklistedRootOperators,\n FieldValue = VectorFieldValue,\n> = FilterCondition<Op, ValueMap, LogicalValueMap, Blacklisted, FieldValue> | null | undefined;\n\ntype FilterCondition<\n Op extends keyof ValueMap = keyof OperatorValueMap,\n ValueMap extends Record<string, any> = OperatorValueMap,\n LogicalValueMap extends Record<string, any> = LogicalOperatorValueMap,\n Blacklisted extends string = BlacklistedRootOperators,\n FieldValue = VectorFieldValue,\n> = (FieldCondition<Op, ValueMap, FieldValue> | LogicalCondition<Op, ValueMap, LogicalValueMap>) &\n ForbiddenRootOperators<Blacklisted>;\n\n// Field condition can be a value or an operator condition\ntype FieldCondition<\n Op extends keyof ValueMap = keyof OperatorValueMap,\n ValueMap extends Record<string, any> = OperatorValueMap,\n FieldValue = VectorFieldValue,\n> = {\n [field: string]: OperatorCondition<Op, ValueMap> | FieldValue;\n};\n\ntype ForbiddenRootOperators<Blacklisted extends string> = {\n [K in Blacklisted]?: never;\n};\n\n// Logical conditions\ntype LogicalCondition<\n Op extends keyof ValueMap = keyof OperatorValueMap,\n ValueMap extends Record<string, any> = OperatorValueMap,\n LogicalValueMap extends Record<string, any> = LogicalOperatorValueMap,\n> = {\n [K in keyof LogicalValueMap]: LogicalValueMap[K] extends 'array'\n ? {\n [P in K]: Array<LogicalBranch<Op, ValueMap, LogicalValueMap>>;\n }\n : {\n [P in K]: LogicalBranch<Op, ValueMap, LogicalValueMap>;\n };\n}[keyof LogicalValueMap];\n\ntype LogicalBranch<\n Op extends keyof ValueMap = keyof OperatorValueMap,\n ValueMap extends Record<string, any> = OperatorValueMap,\n LogicalValueMap extends Record<string, any> = LogicalOperatorValueMap,\n> = FieldCondition<Op, ValueMap> | LogicalCondition<Op, ValueMap, LogicalValueMap>;\n\n// Base operator condition, parameterized by operator set\ntype OperatorCondition<\n Op extends keyof ValueMap = keyof OperatorValueMap,\n ValueMap extends Record<string, any> = OperatorValueMap,\n> = {\n [K in Exclude<Op, '$and' | '$or' | '$nor'>]?: ValueMap[K];\n};\n\ntype OperatorSupport = {\n logical?: LogicalOperator[];\n array?: ArrayOperator[];\n basic?: BasicOperator[];\n numeric?: NumericOperator[];\n element?: ElementOperator[];\n regex?: RegexOperator[];\n custom?: string[];\n};\n\n// Base abstract class for filter translators\nabstract class BaseFilterTranslator<Filter = VectorFilter, Result = Filter> {\n abstract translate(filter: Filter): Result;\n\n /**\n * Operator type checks\n */\n protected isOperator(key: string): key is QueryOperator {\n return key.startsWith('$');\n }\n\n protected static readonly BASIC_OPERATORS: BasicOperator[] = ['$eq', '$ne'];\n protected static readonly NUMERIC_OPERATORS: NumericOperator[] = ['$gt', '$gte', '$lt', '$lte'];\n protected static readonly ARRAY_OPERATORS: ArrayOperator[] = ['$in', '$nin', '$all', '$elemMatch'];\n protected static readonly LOGICAL_OPERATORS: LogicalOperator[] = ['$and', '$or', '$not', '$nor'];\n protected static readonly ELEMENT_OPERATORS: ElementOperator[] = ['$exists'];\n protected static readonly REGEX_OPERATORS: RegexOperator[] = ['$regex', '$options'];\n\n public static readonly DEFAULT_OPERATORS = {\n logical: BaseFilterTranslator.LOGICAL_OPERATORS,\n basic: BaseFilterTranslator.BASIC_OPERATORS,\n numeric: BaseFilterTranslator.NUMERIC_OPERATORS,\n array: BaseFilterTranslator.ARRAY_OPERATORS,\n element: BaseFilterTranslator.ELEMENT_OPERATORS,\n regex: BaseFilterTranslator.REGEX_OPERATORS,\n };\n\n protected isLogicalOperator(key: string): key is LogicalOperator {\n return BaseFilterTranslator.DEFAULT_OPERATORS.logical.includes(key as LogicalOperator);\n }\n\n protected isBasicOperator(key: string): key is BasicOperator {\n return BaseFilterTranslator.DEFAULT_OPERATORS.basic.includes(key as BasicOperator);\n }\n\n protected isNumericOperator(key: string): key is NumericOperator {\n return BaseFilterTranslator.DEFAULT_OPERATORS.numeric.includes(key as NumericOperator);\n }\n\n protected isArrayOperator(key: string): key is ArrayOperator {\n return BaseFilterTranslator.DEFAULT_OPERATORS.array.includes(key as ArrayOperator);\n }\n\n protected isElementOperator(key: string): key is ElementOperator {\n return BaseFilterTranslator.DEFAULT_OPERATORS.element.includes(key as ElementOperator);\n }\n\n protected isRegexOperator(key: string): key is RegexOperator {\n return BaseFilterTranslator.DEFAULT_OPERATORS.regex.includes(key as RegexOperator);\n }\n\n protected isFieldOperator(key: string): key is QueryOperator {\n return this.isOperator(key) && !this.isLogicalOperator(key);\n }\n\n protected isCustomOperator(key: string): boolean {\n const support = this.getSupportedOperators();\n return support.custom?.includes(key) ?? false;\n }\n\n protected getSupportedOperators(): OperatorSupport {\n return BaseFilterTranslator.DEFAULT_OPERATORS;\n }\n\n protected isValidOperator(key: string): boolean {\n const support = this.getSupportedOperators();\n const allSupported = Object.values(support).flat();\n return allSupported.includes(key as QueryOperator);\n }\n\n /**\n * Value normalization for comparison operators\n */\n protected normalizeComparisonValue(value: any): any {\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n // Handle -0 case\n if (typeof value === 'number' && Object.is(value, -0)) {\n return 0;\n }\n return value;\n }\n\n /**\n * Helper method to simulate $all operator using $and + $eq when needed.\n * Some vector stores don't support $all natively.\n */\n protected simulateAllOperator(field: string, values: any[]): VectorFilter<keyof OperatorValueMap, OperatorValueMap> {\n return {\n $and: values.map(value => ({\n [field]: { $in: [this.normalizeComparisonValue(value)] },\n })),\n };\n }\n\n /**\n * Utility functions for type checking\n */\n protected isPrimitive(value: any): boolean {\n return (\n value === null ||\n value === undefined ||\n typeof value === 'string' ||\n typeof value === 'number' ||\n typeof value === 'boolean'\n );\n }\n\n protected isRegex(value: any): boolean {\n return value instanceof RegExp;\n }\n\n protected isEmpty(obj: any): boolean {\n return obj === null || obj === undefined || (typeof obj === 'object' && Object.keys(obj).length === 0);\n }\n\n protected static readonly ErrorMessages = {\n UNSUPPORTED_OPERATOR: (op: string) => `Unsupported operator: ${op}`,\n INVALID_LOGICAL_OPERATOR_LOCATION: (op: string, path: string) =>\n `Logical operator ${op} cannot be used at field level: ${path}`,\n NOT_REQUIRES_OBJECT: `$not operator requires an object`,\n NOT_CANNOT_BE_EMPTY: `$not operator cannot be empty`,\n INVALID_LOGICAL_OPERATOR_CONTENT: (path: string) =>\n `Logical operators must contain field conditions, not direct operators: ${path}`,\n INVALID_TOP_LEVEL_OPERATOR: (op: string) => `Invalid top-level operator: ${op}`,\n ELEM_MATCH_REQUIRES_OBJECT: `$elemMatch requires an object with conditions`,\n } as const;\n\n /**\n * Helper to handle array value normalization consistently\n */\n protected normalizeArrayValues(values: any[]): any[] {\n return values.map(value => this.normalizeComparisonValue(value));\n }\n\n protected validateFilter(filter: Filter): void {\n const validation = this.validateFilterSupport(filter);\n if (!validation.supported) {\n throw new Error(validation.messages.join(', '));\n }\n }\n\n /**\n * Validates if a filter structure is supported by the specific vector DB\n * and returns detailed validation information.\n */\n private validateFilterSupport(\n node: Filter,\n path: string = '',\n ): {\n supported: boolean;\n messages: string[];\n } {\n const messages: string[] = [];\n\n // Handle primitives and empty values\n if (this.isPrimitive(node) || this.isEmpty(node)) {\n return { supported: true, messages: [] };\n }\n\n // Handle arrays\n if (Array.isArray(node)) {\n const arrayResults = node.map(item => this.validateFilterSupport(item, path));\n const arrayMessages = arrayResults.flatMap(r => r.messages);\n return {\n supported: arrayResults.every(r => r.supported),\n messages: arrayMessages,\n };\n }\n\n // Process object entries\n const nodeObj = node as Record<string, any>;\n let isSupported = true;\n\n for (const [key, value] of Object.entries(nodeObj)) {\n const newPath = path ? `${path}.${key}` : key;\n // Check if the key is an operator\n if (this.isOperator(key)) {\n if (!this.isValidOperator(key)) {\n isSupported = false;\n messages.push(BaseFilterTranslator.ErrorMessages.UNSUPPORTED_OPERATOR(key));\n continue;\n }\n\n // Add check for non-logical operators at top level\n if (!path && !this.isLogicalOperator(key)) {\n isSupported = false;\n messages.push(BaseFilterTranslator.ErrorMessages.INVALID_TOP_LEVEL_OPERATOR(key));\n continue;\n }\n\n // In the translate method or wherever operators are handled\n if (key === '$elemMatch' && (typeof value !== 'object' || Array.isArray(value))) {\n isSupported = false;\n messages.push(BaseFilterTranslator.ErrorMessages.ELEM_MATCH_REQUIRES_OBJECT);\n continue;\n }\n\n // Special validation for logical operators\n if (this.isLogicalOperator(key)) {\n if (key === '$not') {\n if (Array.isArray(value) || typeof value !== 'object') {\n isSupported = false;\n messages.push(BaseFilterTranslator.ErrorMessages.NOT_REQUIRES_OBJECT);\n continue;\n }\n if (this.isEmpty(value)) {\n isSupported = false;\n messages.push(BaseFilterTranslator.ErrorMessages.NOT_CANNOT_BE_EMPTY);\n continue;\n }\n // $not can be used at field level or top level\n continue;\n }\n // Other logical operators can only be at top level or nested in logical operators\n if (path && !this.isLogicalOperator(path.split('.').pop()!)) {\n isSupported = false;\n messages.push(BaseFilterTranslator.ErrorMessages.INVALID_LOGICAL_OPERATOR_LOCATION(key, newPath));\n continue;\n }\n\n if (Array.isArray(value)) {\n const hasDirectOperators = value.some(\n item =>\n typeof item === 'object' &&\n Object.keys(item).length === 1 &&\n this.isFieldOperator(Object.keys(item)[0]!),\n );\n\n if (hasDirectOperators) {\n isSupported = false;\n messages.push(BaseFilterTranslator.ErrorMessages.INVALID_LOGICAL_OPERATOR_CONTENT(newPath));\n continue;\n }\n }\n }\n }\n\n // Recursively validate nested value\n const nestedValidation = this.validateFilterSupport(value, newPath);\n if (!nestedValidation.supported) {\n isSupported = false;\n messages.push(...nestedValidation.messages);\n }\n }\n\n return { supported: isSupported, messages };\n }\n}\n\n// Export types and base class\nexport {\n type QueryOperator,\n type BasicOperator,\n type NumericOperator,\n type LogicalOperator,\n type ArrayOperator,\n type RegexOperator,\n type ElementOperator,\n type VectorFilter,\n type FilterValue,\n type VectorFieldValue,\n type FieldCondition,\n type OperatorCondition,\n type OperatorSupport,\n type OperatorValueMap,\n type LogicalOperatorValueMap,\n type BlacklistedRootOperators,\n BaseFilterTranslator,\n};\n"]}