@mastra/libsql 0.13.0-alpha.1 → 0.13.1-alpha.0
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +34 -0
- package/dist/index.cjs +46 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +46 -33
- package/dist/index.js.map +1 -1
- package/dist/vector/index.d.ts.map +1 -1
- package/dist/vector/sql-builder.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/vector/index.test.ts +22 -1
- package/src/vector/index.ts +1 -1
- package/src/vector/sql-builder.ts +51 -33
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vector/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAInD,UAAU,uBAAwB,SAAQ,iBAAiB,CAAC,kBAAkB,CAAC;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,YAAa,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IAChE,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE9B,EACV,aAAa,EACb,SAAS,EACT,OAAO,EACP,YAAY,EACZ,UAAc,EACd,gBAAsB,GACvB,EAAE,kBAAkB;YAwBP,8BAA8B;IAgC5C,eAAe,CAAC,MAAM,CAAC,EAAE,kBAAkB;IAKrC,KAAK,CAAC,EACV,SAAS,EACT,WAAW,EACX,IAAS,EACT,MAAM,EACN,aAAqB,EACrB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/vector/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAInD,UAAU,uBAAwB,SAAQ,iBAAiB,CAAC,kBAAkB,CAAC;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,YAAa,SAAQ,YAAY,CAAC,kBAAkB,CAAC;IAChE,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE9B,EACV,aAAa,EACb,SAAS,EACT,OAAO,EACP,YAAY,EACZ,UAAc,EACd,gBAAsB,GACvB,EAAE,kBAAkB;YAwBP,8BAA8B;IAgC5C,eAAe,CAAC,MAAM,CAAC,EAAE,kBAAkB;IAKrC,KAAK,CAAC,EACV,SAAS,EACT,WAAW,EACX,IAAS,EACT,MAAM,EACN,aAAqB,EACrB,QAAa,GACd,EAAE,uBAAuB,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAoE5C,MAAM,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;YAe5C,QAAQ;IA2Cf,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;YAgB5C,aAAa;IAyBpB,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;YAgB5C,aAAa;IAQrB,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAwBtC;;;;;OAKG;IACG,aAAa,CAAC,EAAE,SAAS,EAAE,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC;IAqD5E;;;;;;;;;;OAUG;IACI,YAAY,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;YAI9C,cAAc;IAiD5B;;;;;;OAMG;IACI,YAAY,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;YAgB9C,cAAc;IAQrB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;YAgB9C,gBAAgB;CAM/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-builder.d.ts","sourceRoot":"","sources":["../../src/vector/sql-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAS9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"sql-builder.d.ts","sourceRoot":"","sources":["../../src/vector/sql-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAS9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AA8VnD,UAAU,YAAY;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB;AA6BD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CAkBzE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mastra/libsql",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.1-alpha.0",
|
|
4
4
|
"description": "Libsql provider for Mastra - includes both vector and db storage capabilities",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,10 +29,10 @@
|
|
|
29
29
|
"tsup": "^8.5.0",
|
|
30
30
|
"typescript": "^5.8.3",
|
|
31
31
|
"vitest": "^3.2.4",
|
|
32
|
-
"@internal/lint": "0.0.
|
|
33
|
-
"@internal/storage-test-utils": "0.0.
|
|
34
|
-
"@mastra/core": "0.13.
|
|
35
|
-
"@internal/types-builder": "0.0.
|
|
32
|
+
"@internal/lint": "0.0.27",
|
|
33
|
+
"@internal/storage-test-utils": "0.0.23",
|
|
34
|
+
"@mastra/core": "0.13.1-alpha.0",
|
|
35
|
+
"@internal/types-builder": "0.0.2"
|
|
36
36
|
},
|
|
37
37
|
"peerDependencies": {
|
|
38
38
|
"@mastra/core": ">=0.13.0-0 <0.14.0-0"
|
package/src/vector/index.test.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createVectorTestSuite } from '@internal/storage-test-utils';
|
|
1
2
|
import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';
|
|
2
3
|
|
|
3
4
|
import { LibSQLVector } from './index.js';
|
|
@@ -254,7 +255,7 @@ describe('LibSQLVector', () => {
|
|
|
254
255
|
const metadata = [
|
|
255
256
|
{ type: 'a', value: 1 },
|
|
256
257
|
{ type: 'b', value: 2 },
|
|
257
|
-
{ type: '
|
|
258
|
+
{ type: 'c', value: 3 },
|
|
258
259
|
];
|
|
259
260
|
await vectorDB.upsert({ indexName, vectors, metadata });
|
|
260
261
|
});
|
|
@@ -1670,3 +1671,23 @@ describe('LibSQLVector', () => {
|
|
|
1670
1671
|
});
|
|
1671
1672
|
});
|
|
1672
1673
|
});
|
|
1674
|
+
|
|
1675
|
+
// Use the shared test suite with factory pattern
|
|
1676
|
+
const libSQLVectorDB = new LibSQLVector({
|
|
1677
|
+
connectionUrl: 'file::memory:?cache=shared',
|
|
1678
|
+
});
|
|
1679
|
+
|
|
1680
|
+
createVectorTestSuite({
|
|
1681
|
+
vector: libSQLVectorDB,
|
|
1682
|
+
createIndex: async (indexName: string) => {
|
|
1683
|
+
await libSQLVectorDB.createIndex({ indexName, dimension: 4, metric: 'cosine' });
|
|
1684
|
+
},
|
|
1685
|
+
deleteIndex: async (indexName: string) => {
|
|
1686
|
+
try {
|
|
1687
|
+
await libSQLVectorDB.deleteIndex({ indexName });
|
|
1688
|
+
} catch (error) {
|
|
1689
|
+
console.error(`Error deleting index ${indexName}:`, error);
|
|
1690
|
+
}
|
|
1691
|
+
},
|
|
1692
|
+
waitForIndexing: () => new Promise(resolve => setTimeout(resolve, 100)),
|
|
1693
|
+
});
|
package/src/vector/index.ts
CHANGED
|
@@ -120,7 +120,7 @@ export class LibSQLVector extends MastraVector<LibSQLVectorFilter> {
|
|
|
120
120
|
topK = 10,
|
|
121
121
|
filter,
|
|
122
122
|
includeVector = false,
|
|
123
|
-
minScore =
|
|
123
|
+
minScore = -1, // Default to -1 to include all results (cosine similarity ranges from -1 to 1)
|
|
124
124
|
}: LibSQLQueryVectorParams): Promise<QueryResult[]> {
|
|
125
125
|
try {
|
|
126
126
|
if (!Number.isInteger(topK) || topK <= 0) {
|
|
@@ -29,11 +29,11 @@ type OperatorFn = (key: string, value?: any) => FilterOperator;
|
|
|
29
29
|
// Helper functions to create operators
|
|
30
30
|
const createBasicOperator = (symbol: string) => {
|
|
31
31
|
return (key: string, value: any): FilterOperator => {
|
|
32
|
-
const
|
|
32
|
+
const jsonPath = getJsonPath(key);
|
|
33
33
|
return {
|
|
34
34
|
sql: `CASE
|
|
35
|
-
WHEN ? IS NULL THEN json_extract(metadata,
|
|
36
|
-
ELSE json_extract(metadata,
|
|
35
|
+
WHEN ? IS NULL THEN json_extract(metadata, ${jsonPath}) IS ${symbol === '=' ? '' : 'NOT'} NULL
|
|
36
|
+
ELSE json_extract(metadata, ${jsonPath}) ${symbol} ?
|
|
37
37
|
END`,
|
|
38
38
|
needsValue: true,
|
|
39
39
|
transformValue: () => {
|
|
@@ -45,19 +45,21 @@ const createBasicOperator = (symbol: string) => {
|
|
|
45
45
|
};
|
|
46
46
|
const createNumericOperator = (symbol: string) => {
|
|
47
47
|
return (key: string): FilterOperator => {
|
|
48
|
-
const
|
|
48
|
+
const jsonPath = getJsonPath(key);
|
|
49
49
|
return {
|
|
50
|
-
sql: `CAST(json_extract(metadata,
|
|
50
|
+
sql: `CAST(json_extract(metadata, ${jsonPath}) AS NUMERIC) ${symbol} ?`,
|
|
51
51
|
needsValue: true,
|
|
52
52
|
};
|
|
53
53
|
};
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
const validateJsonArray = (key: string) =>
|
|
57
|
-
|
|
58
|
-
|
|
56
|
+
const validateJsonArray = (key: string) => {
|
|
57
|
+
const jsonPath = getJsonPath(key);
|
|
58
|
+
return `json_valid(json_extract(metadata, ${jsonPath}))
|
|
59
|
+
AND json_type(json_extract(metadata, ${jsonPath})) = 'array'`;
|
|
60
|
+
};
|
|
59
61
|
|
|
60
|
-
const pattern = /json_extract\(metadata, '\$\."[^"]*"(
|
|
62
|
+
const pattern = /json_extract\(metadata, '\$\.(?:"[^"]*"(?:\."[^"]*")*|[^']+)'\)/g;
|
|
61
63
|
|
|
62
64
|
function buildElemMatchConditions(value: any) {
|
|
63
65
|
const conditions = Object.entries(value).map(([field, fieldValue]) => {
|
|
@@ -71,13 +73,14 @@ function buildElemMatchConditions(value: any) {
|
|
|
71
73
|
// Nested field with operators (count: { $gt: 20 })
|
|
72
74
|
const { sql, values } = buildCondition(field, fieldValue, '');
|
|
73
75
|
// Replace the field path with elem.value path
|
|
74
|
-
const
|
|
76
|
+
const jsonPath = parseJsonPathKey(field);
|
|
77
|
+
const elemSql = sql.replace(pattern, `json_extract(elem.value, '$.${jsonPath}')`);
|
|
75
78
|
return { sql: elemSql, values };
|
|
76
79
|
} else {
|
|
77
|
-
const
|
|
80
|
+
const jsonPath = parseJsonPathKey(field);
|
|
78
81
|
// Simple field equality (warehouse: 'A')
|
|
79
82
|
return {
|
|
80
|
-
sql: `json_extract(elem.value, '
|
|
83
|
+
sql: `json_extract(elem.value, '$.${jsonPath}') = ?`,
|
|
81
84
|
values: [fieldValue],
|
|
82
85
|
};
|
|
83
86
|
}
|
|
@@ -97,7 +100,7 @@ const FILTER_OPERATORS: Record<OperatorType, OperatorFn> = {
|
|
|
97
100
|
|
|
98
101
|
// Array Operators
|
|
99
102
|
$in: (key: string, value: any) => {
|
|
100
|
-
const
|
|
103
|
+
const jsonPath = getJsonPath(key);
|
|
101
104
|
const arr = Array.isArray(value) ? value : [value];
|
|
102
105
|
if (arr.length === 0) {
|
|
103
106
|
return { sql: '1 = 0', needsValue: true, transformValue: () => [] };
|
|
@@ -106,12 +109,12 @@ const FILTER_OPERATORS: Record<OperatorType, OperatorFn> = {
|
|
|
106
109
|
return {
|
|
107
110
|
sql: `(
|
|
108
111
|
CASE
|
|
109
|
-
WHEN ${validateJsonArray(
|
|
112
|
+
WHEN ${validateJsonArray(key)} THEN
|
|
110
113
|
EXISTS (
|
|
111
|
-
SELECT 1 FROM json_each(json_extract(metadata,
|
|
114
|
+
SELECT 1 FROM json_each(json_extract(metadata, ${jsonPath})) as elem
|
|
112
115
|
WHERE elem.value IN (SELECT value FROM json_each(?))
|
|
113
116
|
)
|
|
114
|
-
ELSE json_extract(metadata,
|
|
117
|
+
ELSE json_extract(metadata, ${jsonPath}) IN (${paramPlaceholders})
|
|
115
118
|
END
|
|
116
119
|
)`,
|
|
117
120
|
needsValue: true,
|
|
@@ -120,7 +123,7 @@ const FILTER_OPERATORS: Record<OperatorType, OperatorFn> = {
|
|
|
120
123
|
},
|
|
121
124
|
|
|
122
125
|
$nin: (key: string, value: any) => {
|
|
123
|
-
const
|
|
126
|
+
const jsonPath = getJsonPath(key);
|
|
124
127
|
const arr = Array.isArray(value) ? value : [value];
|
|
125
128
|
if (arr.length === 0) {
|
|
126
129
|
return { sql: '1 = 1', needsValue: true, transformValue: () => [] };
|
|
@@ -129,12 +132,12 @@ const FILTER_OPERATORS: Record<OperatorType, OperatorFn> = {
|
|
|
129
132
|
return {
|
|
130
133
|
sql: `(
|
|
131
134
|
CASE
|
|
132
|
-
WHEN ${validateJsonArray(
|
|
135
|
+
WHEN ${validateJsonArray(key)} THEN
|
|
133
136
|
NOT EXISTS (
|
|
134
|
-
SELECT 1 FROM json_each(json_extract(metadata,
|
|
137
|
+
SELECT 1 FROM json_each(json_extract(metadata, ${jsonPath})) as elem
|
|
135
138
|
WHERE elem.value IN (SELECT value FROM json_each(?))
|
|
136
139
|
)
|
|
137
|
-
ELSE json_extract(metadata,
|
|
140
|
+
ELSE json_extract(metadata, ${jsonPath}) NOT IN (${paramPlaceholders})
|
|
138
141
|
END
|
|
139
142
|
)`,
|
|
140
143
|
needsValue: true,
|
|
@@ -142,7 +145,7 @@ const FILTER_OPERATORS: Record<OperatorType, OperatorFn> = {
|
|
|
142
145
|
};
|
|
143
146
|
},
|
|
144
147
|
$all: (key: string, value: any) => {
|
|
145
|
-
const
|
|
148
|
+
const jsonPath = getJsonPath(key);
|
|
146
149
|
let sql: string;
|
|
147
150
|
const arrayValue = Array.isArray(value) ? value : [value];
|
|
148
151
|
|
|
@@ -152,13 +155,13 @@ const FILTER_OPERATORS: Record<OperatorType, OperatorFn> = {
|
|
|
152
155
|
} else {
|
|
153
156
|
sql = `(
|
|
154
157
|
CASE
|
|
155
|
-
WHEN ${validateJsonArray(
|
|
158
|
+
WHEN ${validateJsonArray(key)} THEN
|
|
156
159
|
NOT EXISTS (
|
|
157
160
|
SELECT value
|
|
158
161
|
FROM json_each(?)
|
|
159
162
|
WHERE value NOT IN (
|
|
160
163
|
SELECT value
|
|
161
|
-
FROM json_each(json_extract(metadata,
|
|
164
|
+
FROM json_each(json_extract(metadata, ${jsonPath}))
|
|
162
165
|
)
|
|
163
166
|
)
|
|
164
167
|
ELSE FALSE
|
|
@@ -178,7 +181,7 @@ const FILTER_OPERATORS: Record<OperatorType, OperatorFn> = {
|
|
|
178
181
|
};
|
|
179
182
|
},
|
|
180
183
|
$elemMatch: (key: string, value: any) => {
|
|
181
|
-
const
|
|
184
|
+
const jsonPath = getJsonPath(key);
|
|
182
185
|
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
183
186
|
throw new Error('$elemMatch requires an object with conditions');
|
|
184
187
|
}
|
|
@@ -189,10 +192,10 @@ const FILTER_OPERATORS: Record<OperatorType, OperatorFn> = {
|
|
|
189
192
|
return {
|
|
190
193
|
sql: `(
|
|
191
194
|
CASE
|
|
192
|
-
WHEN ${validateJsonArray(
|
|
195
|
+
WHEN ${validateJsonArray(key)} THEN
|
|
193
196
|
EXISTS (
|
|
194
197
|
SELECT 1
|
|
195
|
-
FROM json_each(json_extract(metadata,
|
|
198
|
+
FROM json_each(json_extract(metadata, ${jsonPath})) as elem
|
|
196
199
|
WHERE ${conditions.map(c => c.sql).join(' AND ')}
|
|
197
200
|
)
|
|
198
201
|
ELSE FALSE
|
|
@@ -205,9 +208,9 @@ const FILTER_OPERATORS: Record<OperatorType, OperatorFn> = {
|
|
|
205
208
|
|
|
206
209
|
// Element Operators
|
|
207
210
|
$exists: (key: string) => {
|
|
208
|
-
const
|
|
211
|
+
const jsonPath = getJsonPath(key);
|
|
209
212
|
return {
|
|
210
|
-
sql: `json_extract(metadata,
|
|
213
|
+
sql: `json_extract(metadata, ${jsonPath}) IS NOT NULL`,
|
|
211
214
|
needsValue: false,
|
|
212
215
|
};
|
|
213
216
|
},
|
|
@@ -227,12 +230,12 @@ const FILTER_OPERATORS: Record<OperatorType, OperatorFn> = {
|
|
|
227
230
|
needsValue: false,
|
|
228
231
|
}),
|
|
229
232
|
$size: (key: string, paramIndex: number) => {
|
|
230
|
-
const
|
|
233
|
+
const jsonPath = getJsonPath(key);
|
|
231
234
|
return {
|
|
232
235
|
sql: `(
|
|
233
236
|
CASE
|
|
234
|
-
WHEN json_type(json_extract(metadata,
|
|
235
|
-
json_array_length(json_extract(metadata,
|
|
237
|
+
WHEN json_type(json_extract(metadata, ${jsonPath})) = 'array' THEN
|
|
238
|
+
json_array_length(json_extract(metadata, ${jsonPath})) = $${paramIndex}
|
|
236
239
|
ELSE FALSE
|
|
237
240
|
END
|
|
238
241
|
)`,
|
|
@@ -365,7 +368,21 @@ function isFilterResult(obj: any): obj is FilterResult {
|
|
|
365
368
|
|
|
366
369
|
const parseJsonPathKey = (key: string) => {
|
|
367
370
|
const parsedKey = parseFieldKey(key);
|
|
368
|
-
|
|
371
|
+
// Only add quotes around path segments if they contain dots
|
|
372
|
+
if (parsedKey.includes('.')) {
|
|
373
|
+
return parsedKey
|
|
374
|
+
.split('.')
|
|
375
|
+
.map(segment => `"${segment}"`)
|
|
376
|
+
.join('.');
|
|
377
|
+
}
|
|
378
|
+
return parsedKey;
|
|
379
|
+
};
|
|
380
|
+
|
|
381
|
+
// Helper to generate the correct JSON path format for LibSQL
|
|
382
|
+
const getJsonPath = (key: string) => {
|
|
383
|
+
const jsonPathKey = parseJsonPathKey(key);
|
|
384
|
+
// Always use quotes for consistency
|
|
385
|
+
return `'$.${jsonPathKey}'`;
|
|
369
386
|
};
|
|
370
387
|
|
|
371
388
|
function escapeLikePattern(str: string): string {
|
|
@@ -400,8 +417,9 @@ function buildCondition(key: string, value: any, parentPath: string): FilterResu
|
|
|
400
417
|
|
|
401
418
|
// If condition is not a FilterCondition object, assume it's an equality check
|
|
402
419
|
if (!value || typeof value !== 'object') {
|
|
420
|
+
const jsonPath = getJsonPath(key);
|
|
403
421
|
return {
|
|
404
|
-
sql: `json_extract(metadata,
|
|
422
|
+
sql: `json_extract(metadata, ${jsonPath}) = ?`,
|
|
405
423
|
values: [value],
|
|
406
424
|
};
|
|
407
425
|
}
|