@truto/sqlite-builder 1.0.2 → 1.0.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.
- package/README.md +159 -4
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/filter.d.ts.map +1 -1
- package/dist/index.js +46 -15
- package/dist/index.js.map +6 -5
- package/dist/sql.d.ts.map +1 -1
- package/dist/types.d.ts +3 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
- 🎯 **TypeScript-first**: Full type safety with excellent IDE support
|
|
19
19
|
- 🔧 **Helper functions**: Built-in utilities for identifiers, IN clauses, and more
|
|
20
20
|
- 🔍 **JSON Filter Language**: MongoDB-style JSON filters for WHERE clauses
|
|
21
|
+
- 🔗 **Qualified Filters**: Table/alias scoping for complex JOINs using `$alias` blocks
|
|
21
22
|
- ⚡ **Lightweight**: Minimal bundle size with tree-shaking support
|
|
22
23
|
|
|
23
24
|
## 📦 Installation
|
|
@@ -65,6 +66,29 @@ const query = sql`
|
|
|
65
66
|
`
|
|
66
67
|
|
|
67
68
|
const results = db.prepare(query.text).all(...query.values)
|
|
69
|
+
|
|
70
|
+
// Qualified filters for JOINs with alias blocks
|
|
71
|
+
const joinFilter = {
|
|
72
|
+
status: 'ACTIVE', // Main table
|
|
73
|
+
$profiles: {
|
|
74
|
+
// Profile table alias
|
|
75
|
+
verified: true,
|
|
76
|
+
'settings.theme': 'dark', // JSON path in profile
|
|
77
|
+
},
|
|
78
|
+
$orders: {
|
|
79
|
+
// Orders table alias
|
|
80
|
+
total: { gt: 100 },
|
|
81
|
+
},
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const joinWhere = compileFilter(joinFilter)
|
|
85
|
+
const joinQuery = sql`
|
|
86
|
+
SELECT u.name, p.verified, o.total
|
|
87
|
+
FROM users u
|
|
88
|
+
JOIN profiles p ON u.id = p.user_id
|
|
89
|
+
JOIN orders o ON u.id = o.user_id
|
|
90
|
+
WHERE ${sql.raw(joinWhere.text)}
|
|
91
|
+
`
|
|
68
92
|
```
|
|
69
93
|
|
|
70
94
|
## 📖 API Reference
|
|
@@ -95,7 +119,7 @@ const query = sql`SELECT * FROM ${sql.ident(table)}`
|
|
|
95
119
|
|
|
96
120
|
// Qualified identifiers (table.column)
|
|
97
121
|
const qualifiedQuery = sql`SELECT ${sql.ident('u.name')}, ${sql.ident('u.email')} FROM users u`
|
|
98
|
-
// Returns: { text: 'SELECT "u.name", "u.email" FROM users u', values: [] }
|
|
122
|
+
// Returns: { text: 'SELECT "u"."name", "u"."email" FROM users u', values: [] }
|
|
99
123
|
|
|
100
124
|
// Array of identifiers (useful for column lists)
|
|
101
125
|
const columns = ['name', 'email', 'created_at']
|
|
@@ -105,7 +129,7 @@ const selectQuery = sql`SELECT ${sql.ident(columns)} FROM users`
|
|
|
105
129
|
// Mixed arrays with qualified and simple identifiers
|
|
106
130
|
const mixedColumns = ['u.id', 'name', 'u.email', 'p.title']
|
|
107
131
|
const joinQuery = sql`SELECT ${sql.ident(mixedColumns)} FROM users u JOIN posts p ON u.id = p.user_id`
|
|
108
|
-
// Returns: { text: 'SELECT "u.id", "name", "u.email", "p.title" FROM users u JOIN posts p ON u.id = p.user_id', values: [] }
|
|
132
|
+
// Returns: { text: 'SELECT "u"."id", "name", "u"."email", "p"."title" FROM users u JOIN posts p ON u.id = p.user_id', values: [] }
|
|
109
133
|
|
|
110
134
|
// Mixed arrays with identifiers and SQL fragments
|
|
111
135
|
const mixedColumns = ['id', 'name', sql.raw('UPPER(email) as email_upper')]
|
|
@@ -216,6 +240,7 @@ const query = sql`
|
|
|
216
240
|
| **Logical AND** | `"and": [filter1, filter2]` | `(filter1 AND filter2)` | All conditions must match |
|
|
217
241
|
| **Logical OR** | `"or": [filter1, filter2]` | `(filter1 OR filter2)` | Any condition must match |
|
|
218
242
|
| **JSON Path** | `"profile.email": "test@example.com"` | `json_extract("profile", '$.email') = ?` | Query JSON column fields |
|
|
243
|
+
| **Alias Blocks** | `"$alias": { "field": value }` | `alias."field" = ?` | Table/alias qualified fields |
|
|
219
244
|
|
|
220
245
|
### Filter Examples
|
|
221
246
|
|
|
@@ -319,6 +344,136 @@ const filter10 = {
|
|
|
319
344
|
}
|
|
320
345
|
```
|
|
321
346
|
|
|
347
|
+
#### Qualified Filters for JOINs
|
|
348
|
+
|
|
349
|
+
For complex queries involving multiple tables or aliases, use **alias blocks** with keys starting with `$`:
|
|
350
|
+
|
|
351
|
+
```typescript
|
|
352
|
+
// Basic alias usage
|
|
353
|
+
const joinFilter = {
|
|
354
|
+
// Main table fields (no prefix)
|
|
355
|
+
status: 'ACTIVE',
|
|
356
|
+
age: { gte: 18, lt: 65 },
|
|
357
|
+
|
|
358
|
+
// Table alias 't2'
|
|
359
|
+
$t2: {
|
|
360
|
+
column_in_table_2: { gte: 100 },
|
|
361
|
+
'stats.avg': { lt: 10 }, // JSON path in aliased table
|
|
362
|
+
},
|
|
363
|
+
|
|
364
|
+
// Table alias 'orders'
|
|
365
|
+
$orders: {
|
|
366
|
+
amount: { gt: 500 },
|
|
367
|
+
status: { in: ['completed', 'shipped'] },
|
|
368
|
+
},
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
const result = compileFilter(joinFilter)
|
|
372
|
+
// SQL: ((("status" = ?) AND ("age" >= ? AND "age" < ?) AND
|
|
373
|
+
// ((t2."column_in_table_2" >= ?) AND (json_extract(t2."stats", '$.avg') < ?)) AND
|
|
374
|
+
// ((orders."amount" > ?) AND (orders."status" IN (?,?)))))
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
**Alias Block Rules:**
|
|
378
|
+
|
|
379
|
+
- **Alias names**: Must be valid SQL identifiers (`[A-Za-z_][A-Za-z0-9_]*`)
|
|
380
|
+
- **Prefixing**: All fields in alias blocks get prefixed with `alias.`
|
|
381
|
+
- **JSON paths**: Work seamlessly with aliases: `json_extract(alias."column", '$.path')`
|
|
382
|
+
- **Combination**: Alias blocks are AND-combined with root fields and each other
|
|
383
|
+
- **Order**: Regular fields processed first, then alias blocks
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
// Complex alias example with logical operators
|
|
387
|
+
const complexJoinFilter = {
|
|
388
|
+
// Primary table conditions
|
|
389
|
+
user_status: 'ACTIVE',
|
|
390
|
+
|
|
391
|
+
// User profile table
|
|
392
|
+
$profile: {
|
|
393
|
+
verified: true,
|
|
394
|
+
'preferences.notifications': { ne: false },
|
|
395
|
+
or: [{ subscription_type: 'premium' }, { credits: { gte: 100 } }],
|
|
396
|
+
},
|
|
397
|
+
|
|
398
|
+
// Orders table with complex conditions
|
|
399
|
+
$orders: {
|
|
400
|
+
and: [
|
|
401
|
+
{ created_at: { gte: '2024-01-01' } },
|
|
402
|
+
{ or: [{ total_amount: { gt: 1000 } }, { item_count: { gte: 5 } }] },
|
|
403
|
+
],
|
|
404
|
+
},
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Use in JOIN queries
|
|
408
|
+
const whereClause = compileFilter(complexJoinFilter)
|
|
409
|
+
const query = sql`
|
|
410
|
+
SELECT u.id, u.name, p.subscription_type, o.total_amount
|
|
411
|
+
FROM users u
|
|
412
|
+
JOIN profiles p ON u.id = p.user_id
|
|
413
|
+
JOIN orders o ON u.id = o.user_id
|
|
414
|
+
WHERE ${sql.raw(whereClause.text)}
|
|
415
|
+
`
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
**Security & Validation:**
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
// ✅ Valid alias identifiers
|
|
422
|
+
$users: { name: 'John' } // Simple identifier
|
|
423
|
+
$user_profiles: { age: 25 } // Underscore allowed
|
|
424
|
+
$_temp: { status: 'active' } // Starting underscore allowed
|
|
425
|
+
|
|
426
|
+
// ❌ Invalid alias identifiers (will throw SyntaxError)
|
|
427
|
+
$123invalid: { ... } // Cannot start with number
|
|
428
|
+
$'invalid-alias': { ... } // Hyphens not allowed
|
|
429
|
+
$'table.alias': { ... } // Dots not allowed in alias name
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Integration with Complex Queries:**
|
|
433
|
+
|
|
434
|
+
```typescript
|
|
435
|
+
// Real-world JOIN example
|
|
436
|
+
const userOrderFilter = {
|
|
437
|
+
// Users table
|
|
438
|
+
active: true,
|
|
439
|
+
email: { exists: true },
|
|
440
|
+
|
|
441
|
+
// User profiles
|
|
442
|
+
$profiles: {
|
|
443
|
+
'settings.email_notifications': true,
|
|
444
|
+
verified_at: { exists: true },
|
|
445
|
+
},
|
|
446
|
+
|
|
447
|
+
// Recent orders
|
|
448
|
+
$recent_orders: {
|
|
449
|
+
created_at: { gte: '2024-01-01' },
|
|
450
|
+
status: { in: ['completed', 'shipped'] },
|
|
451
|
+
total: { gt: 50 },
|
|
452
|
+
},
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
const whereClause = compileFilter(userOrderFilter)
|
|
456
|
+
|
|
457
|
+
const complexQuery = sql`
|
|
458
|
+
SELECT
|
|
459
|
+
u.id,
|
|
460
|
+
u.name,
|
|
461
|
+
u.email,
|
|
462
|
+
p.verified_at,
|
|
463
|
+
COUNT(ro.id) as recent_order_count,
|
|
464
|
+
SUM(ro.total) as recent_order_total
|
|
465
|
+
FROM users u
|
|
466
|
+
JOIN profiles p ON u.id = p.user_id
|
|
467
|
+
JOIN orders ro ON u.id = ro.user_id
|
|
468
|
+
WHERE ${sql.raw(whereClause.text)}
|
|
469
|
+
GROUP BY u.id, u.name, u.email, p.verified_at
|
|
470
|
+
HAVING recent_order_count > 0
|
|
471
|
+
ORDER BY recent_order_total DESC
|
|
472
|
+
`
|
|
473
|
+
|
|
474
|
+
const results = db.prepare(complexQuery.text).all(...complexQuery.values)
|
|
475
|
+
```
|
|
476
|
+
|
|
322
477
|
#### Kitchen Sink Examples
|
|
323
478
|
|
|
324
479
|
Real-world complex filters:
|
|
@@ -567,7 +722,7 @@ const simpleQuery = sql`SELECT ${sql.ident(column)} FROM ${sql.ident(table)}`
|
|
|
567
722
|
|
|
568
723
|
// ✅ Qualified identifiers (table.column)
|
|
569
724
|
const qualifiedQuery = sql`SELECT ${sql.ident('u.name')}, ${sql.ident('p.title')} FROM users u JOIN posts p ON u.id = p.user_id`
|
|
570
|
-
// Result: SELECT "u.name", "p.title" FROM users u JOIN posts p ON u.id = p.user_id
|
|
725
|
+
// Result: SELECT "u"."name", "p"."title" FROM users u JOIN posts p ON u.id = p.user_id
|
|
571
726
|
|
|
572
727
|
// ✅ Pure identifier arrays (clean and concise)
|
|
573
728
|
const columns = ['id', 'name', 'email', 'created_at']
|
|
@@ -577,7 +732,7 @@ const arrayQuery = sql`SELECT ${sql.ident(columns)} FROM users`
|
|
|
577
732
|
// ✅ Mixed qualified and simple identifiers in arrays
|
|
578
733
|
const mixedColumns = ['u.id', 'name', 'u.email', 'p.title', 'created_at']
|
|
579
734
|
const mixedQuery = sql`SELECT ${sql.ident(mixedColumns)} FROM users u LEFT JOIN posts p ON u.id = p.user_id`
|
|
580
|
-
// Result: SELECT "u.id", "name", "u.email", "p.title", "created_at" FROM users u LEFT JOIN posts p ON u.id = p.user_id
|
|
735
|
+
// Result: SELECT "u"."id", "name", "u"."email", "p"."title", "created_at" FROM users u LEFT JOIN posts p ON u.id = p.user_id
|
|
581
736
|
|
|
582
737
|
// ✅ NEW: Mixed arrays with identifiers and SQL fragments
|
|
583
738
|
const mixedColumns = [
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Common regex patterns used across the codebase
|
|
3
|
+
*/
|
|
4
|
+
export declare const MAX_QUERY_LENGTH = 102400;
|
|
5
|
+
export declare const STACKED_QUERY_REGEX: RegExp;
|
|
6
|
+
export declare const QUALIFIED_IDENTIFIER_REGEX: RegExp;
|
|
7
|
+
export declare const SIMPLE_IDENTIFIER_REGEX: RegExp;
|
|
8
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,eAAO,MAAM,gBAAgB,SAAS,CAAA;AAGtC,eAAO,MAAM,mBAAmB,QAAe,CAAA;AAG/C,eAAO,MAAM,0BAA0B,QACgB,CAAA;AAGvD,eAAO,MAAM,uBAAuB,QAA6B,CAAA"}
|
package/dist/filter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"filter.d.ts","sourceRoot":"","sources":["../src/filter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAGV,YAAY,EACZ,UAAU,EACX,MAAM,SAAS,CAAA;AA8XhB;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAa9D"}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/constants.ts
|
|
2
2
|
var MAX_QUERY_LENGTH = 102400;
|
|
3
3
|
var STACKED_QUERY_REGEX = /;[\s\S]*\S/;
|
|
4
4
|
var QUALIFIED_IDENTIFIER_REGEX = /^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$/;
|
|
5
|
+
var SIMPLE_IDENTIFIER_REGEX = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
6
|
+
|
|
7
|
+
// src/sql.ts
|
|
5
8
|
function formatDate(date) {
|
|
6
9
|
const year = date.getFullYear();
|
|
7
10
|
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
@@ -29,6 +32,19 @@ function sqlValue(value) {
|
|
|
29
32
|
}
|
|
30
33
|
throw new TypeError(`Unsupported value type: ${typeof value}`);
|
|
31
34
|
}
|
|
35
|
+
function quoteSingleIdentifier(identifier) {
|
|
36
|
+
if (!SIMPLE_IDENTIFIER_REGEX.test(identifier)) {
|
|
37
|
+
throw new TypeError(`Invalid identifier part: ${identifier}. Must be a valid ANSI identifier.`);
|
|
38
|
+
}
|
|
39
|
+
return `"${identifier}"`;
|
|
40
|
+
}
|
|
41
|
+
function quoteQualifiedIdentifier(identifier) {
|
|
42
|
+
if (!QUALIFIED_IDENTIFIER_REGEX.test(identifier)) {
|
|
43
|
+
throw new TypeError(`Invalid identifier: ${identifier}. Must be a valid identifier or qualified identifier (e.g., table.column)`);
|
|
44
|
+
}
|
|
45
|
+
const parts = identifier.split(".");
|
|
46
|
+
return parts.map(quoteSingleIdentifier).join(".");
|
|
47
|
+
}
|
|
32
48
|
function sqlIdent(identifier) {
|
|
33
49
|
if (Array.isArray(identifier)) {
|
|
34
50
|
if (identifier.length === 0) {
|
|
@@ -46,7 +62,7 @@ function sqlIdent(identifier) {
|
|
|
46
62
|
throw new TypeError(`Invalid identifier: ${item}. Must be a valid identifier or qualified identifier (e.g., table.column)`);
|
|
47
63
|
}
|
|
48
64
|
fragments.push({
|
|
49
|
-
text:
|
|
65
|
+
text: quoteQualifiedIdentifier(item),
|
|
50
66
|
values: []
|
|
51
67
|
});
|
|
52
68
|
} else {
|
|
@@ -67,7 +83,7 @@ function sqlIdent(identifier) {
|
|
|
67
83
|
throw new TypeError(`Invalid identifier: ${identifier}. Must be a valid identifier or qualified identifier (e.g., table.column)`);
|
|
68
84
|
}
|
|
69
85
|
return {
|
|
70
|
-
text:
|
|
86
|
+
text: quoteQualifiedIdentifier(identifier),
|
|
71
87
|
values: []
|
|
72
88
|
};
|
|
73
89
|
}
|
|
@@ -183,7 +199,10 @@ function compileJsonPath(field) {
|
|
|
183
199
|
jsonPath: "$." + jsonPath.join(".")
|
|
184
200
|
};
|
|
185
201
|
}
|
|
186
|
-
function
|
|
202
|
+
function isValidSqlIdentifier(identifier) {
|
|
203
|
+
return SIMPLE_IDENTIFIER_REGEX.test(identifier);
|
|
204
|
+
}
|
|
205
|
+
function compileFieldCondition(field, condition, context, alias) {
|
|
187
206
|
if (condition === null || condition === undefined || typeof condition === "string" || typeof condition === "number" || typeof condition === "boolean" || condition instanceof Date) {
|
|
188
207
|
context.operatorCount++;
|
|
189
208
|
if (context.operatorCount > MAX_OPERATORS) {
|
|
@@ -192,20 +211,22 @@ function compileFieldCondition(field, condition, context) {
|
|
|
192
211
|
if (isJsonPath(field)) {
|
|
193
212
|
const { columnName, jsonPath } = compileJsonPath(field);
|
|
194
213
|
const identFragment2 = sql.ident(columnName);
|
|
214
|
+
const fullFieldExpr = alias ? `${alias}.${identFragment2.text}` : identFragment2.text;
|
|
195
215
|
if (condition === null || condition === undefined) {
|
|
196
216
|
context.values.push(jsonPath);
|
|
197
|
-
return `(json_extract(${
|
|
217
|
+
return `(json_extract(${fullFieldExpr}, ?) IS NULL)`;
|
|
198
218
|
} else {
|
|
199
219
|
context.values.push(jsonPath, sql.value(condition));
|
|
200
|
-
return `(json_extract(${
|
|
220
|
+
return `(json_extract(${fullFieldExpr}, ?) = ?)`;
|
|
201
221
|
}
|
|
202
222
|
} else {
|
|
203
223
|
const identFragment2 = sql.ident(field);
|
|
224
|
+
const fullFieldExpr = alias ? `${alias}.${identFragment2.text}` : identFragment2.text;
|
|
204
225
|
if (condition === null || condition === undefined) {
|
|
205
|
-
return `(${
|
|
226
|
+
return `(${fullFieldExpr} IS NULL)`;
|
|
206
227
|
} else {
|
|
207
228
|
context.values.push(sql.value(condition));
|
|
208
|
-
return `(${
|
|
229
|
+
return `(${fullFieldExpr} = ?)`;
|
|
209
230
|
}
|
|
210
231
|
}
|
|
211
232
|
}
|
|
@@ -220,7 +241,8 @@ function compileFieldCondition(field, condition, context) {
|
|
|
220
241
|
}
|
|
221
242
|
}
|
|
222
243
|
const identFragment = sql.ident(isJsonPath(field) ? compileJsonPath(field).columnName : field);
|
|
223
|
-
const
|
|
244
|
+
const baseFieldExpr = alias ? `${alias}.${identFragment.text}` : identFragment.text;
|
|
245
|
+
const fieldExpr = isJsonPath(field) ? `json_extract(${baseFieldExpr}, ?)` : baseFieldExpr;
|
|
224
246
|
if (isJsonPath(field)) {
|
|
225
247
|
context.values.push(compileJsonPath(field).jsonPath);
|
|
226
248
|
}
|
|
@@ -319,7 +341,7 @@ function compileFieldCondition(field, condition, context) {
|
|
|
319
341
|
}
|
|
320
342
|
return clauses.length === 1 ? `(${clauses[0]})` : `(${clauses.join(" AND ")})`;
|
|
321
343
|
}
|
|
322
|
-
function compileFilterRecursive(filter, context) {
|
|
344
|
+
function compileFilterRecursive(filter, context, alias) {
|
|
323
345
|
if (context.depth >= MAX_NESTING_DEPTH) {
|
|
324
346
|
throw new RangeError(`Nesting depth too deep (max: ${MAX_NESTING_DEPTH})`);
|
|
325
347
|
}
|
|
@@ -339,7 +361,7 @@ function compileFilterRecursive(filter, context) {
|
|
|
339
361
|
if (filter.and.length === 0) {
|
|
340
362
|
throw new TypeError("AND operator cannot be used with empty arrays");
|
|
341
363
|
}
|
|
342
|
-
const andClauses = filter.and.map((subFilter) => compileFilterRecursive(subFilter, context));
|
|
364
|
+
const andClauses = filter.and.map((subFilter) => compileFilterRecursive(subFilter, context, alias));
|
|
343
365
|
clauses.push(`(${andClauses.join(" AND ")})`);
|
|
344
366
|
}
|
|
345
367
|
if ("or" in filter && filter.or) {
|
|
@@ -353,15 +375,24 @@ function compileFilterRecursive(filter, context) {
|
|
|
353
375
|
if (filter.or.length === 0) {
|
|
354
376
|
throw new TypeError("OR operator cannot be used with empty arrays");
|
|
355
377
|
}
|
|
356
|
-
const orClauses = filter.or.map((subFilter) => compileFilterRecursive(subFilter, context));
|
|
378
|
+
const orClauses = filter.or.map((subFilter) => compileFilterRecursive(subFilter, context, alias));
|
|
357
379
|
clauses.push(`(${orClauses.join(" OR ")})`);
|
|
358
380
|
}
|
|
359
|
-
const fieldEntries = Object.entries(filter).filter(([field, condition]) => field !== "and" && field !== "or" && condition !== undefined);
|
|
381
|
+
const fieldEntries = Object.entries(filter).filter(([field, condition]) => field !== "and" && field !== "or" && !field.startsWith("$") && condition !== undefined);
|
|
360
382
|
for (const [field, condition] of fieldEntries) {
|
|
361
383
|
if (Array.isArray(condition)) {
|
|
362
384
|
throw new SyntaxError(`Field '${field}' cannot have array value. Use logical operators 'and'/'or' instead.`);
|
|
363
385
|
}
|
|
364
|
-
clauses.push(compileFieldCondition(field, condition, context));
|
|
386
|
+
clauses.push(compileFieldCondition(field, condition, context, alias));
|
|
387
|
+
}
|
|
388
|
+
const aliasEntries = Object.entries(filter).filter(([key, value]) => key.startsWith("$") && value !== undefined && typeof value === "object" && value !== null);
|
|
389
|
+
for (const [aliasKey, aliasFilter] of aliasEntries) {
|
|
390
|
+
const aliasName = aliasKey.slice(1);
|
|
391
|
+
if (!isValidSqlIdentifier(aliasName)) {
|
|
392
|
+
throw new SyntaxError(`Invalid alias identifier: ${aliasName}`);
|
|
393
|
+
}
|
|
394
|
+
const aliasClause = compileFilterRecursive(aliasFilter, context, aliasName);
|
|
395
|
+
clauses.push(aliasClause);
|
|
365
396
|
}
|
|
366
397
|
context.depth--;
|
|
367
398
|
if (clauses.length === 0) {
|
|
@@ -390,5 +421,5 @@ export {
|
|
|
390
421
|
compileFilter
|
|
391
422
|
};
|
|
392
423
|
|
|
393
|
-
//# debugId=
|
|
424
|
+
//# debugId=2601C616902F043764756E2164756E21
|
|
394
425
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/sql.ts", "../src/filter.ts"],
|
|
3
|
+
"sources": ["../src/constants.ts", "../src/sql.ts", "../src/filter.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"
|
|
6
|
-
"import { sql } from './sql'\nimport type {\n ComparisonOperators,\n FieldCondition,\n FilterResult,\n JsonFilter,\n} from './types'\n\n// Limits to prevent DoS attacks\nconst MAX_NESTING_DEPTH = 10\nconst MAX_OPERATORS = 100\n\n// Valid operators for validation\nconst VALID_OPERATORS = new Set([\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n 'ne',\n 'in',\n 'nin',\n 'like',\n 'ilike',\n 'regex',\n 'exists',\n 'and',\n 'or',\n])\n\n/**\n * Context for tracking compilation state\n */\ninterface CompileContext {\n depth: number\n operatorCount: number\n values: unknown[]\n}\n\n/**\n * Check if a field name represents a JSON path (contains dots)\n */\nfunction isJsonPath(field: string): boolean {\n return field.includes('.')\n}\n\n/**\n * Convert a JSON path field to json_extract expression\n */\nfunction compileJsonPath(field: string): {\n columnName: string\n jsonPath: string\n} {\n const parts = field.split('.')\n const columnName = parts[0]\n const jsonPath = parts.slice(1)\n\n if (!columnName || jsonPath.length === 0 || jsonPath.some((part) => !part)) {\n throw new SyntaxError(`Invalid JSON path: ${field}`)\n }\n\n return {\n columnName,\n jsonPath: '$.' + jsonPath.join('.'),\n }\n}\n\n/**\n * Compile a single field condition to SQL\n */\nfunction compileFieldCondition(\n field: string,\n condition: FieldCondition,\n context: CompileContext,\n): string {\n // Handle direct value (equality)\n if (\n condition === null ||\n condition === undefined ||\n typeof condition === 'string' ||\n typeof condition === 'number' ||\n typeof condition === 'boolean' ||\n condition instanceof Date\n ) {\n context.operatorCount++\n if (context.operatorCount > MAX_OPERATORS) {\n throw new RangeError(`Too many operators (max: ${MAX_OPERATORS})`)\n }\n\n if (isJsonPath(field)) {\n const { columnName, jsonPath } = compileJsonPath(field)\n const identFragment = sql.ident(columnName)\n\n if (condition === null || condition === undefined) {\n context.values.push(jsonPath)\n return `(json_extract(${identFragment.text}, ?) IS NULL)`\n } else {\n context.values.push(jsonPath, sql.value(condition))\n return `(json_extract(${identFragment.text}, ?) = ?)`\n }\n } else {\n const identFragment = sql.ident(field)\n\n if (condition === null || condition === undefined) {\n return `(${identFragment.text} IS NULL)`\n } else {\n context.values.push(sql.value(condition))\n return `(${identFragment.text} = ?)`\n }\n }\n }\n\n // Handle operator object\n if (typeof condition !== 'object' || condition === null) {\n throw new TypeError('Condition must be a value or operator object')\n }\n\n const operators = condition as ComparisonOperators\n const clauses: string[] = []\n\n // Validate all operators are known\n for (const op of Object.keys(operators)) {\n if (!VALID_OPERATORS.has(op)) {\n throw new SyntaxError(`Unknown operator: ${op}`)\n }\n }\n\n const identFragment = sql.ident(\n isJsonPath(field) ? compileJsonPath(field).columnName : field,\n )\n const fieldExpr = isJsonPath(field)\n ? `json_extract(${identFragment.text}, ?)`\n : identFragment.text\n\n // Add JSON path to values if needed\n if (isJsonPath(field)) {\n context.values.push(compileJsonPath(field).jsonPath)\n }\n\n // Handle exists operator first (it overrides other operators)\n if ('exists' in operators) {\n context.operatorCount++\n if (context.operatorCount > MAX_OPERATORS) {\n throw new RangeError(`Too many operators (max: ${MAX_OPERATORS})`)\n }\n\n return operators.exists\n ? `(${fieldExpr} IS NOT NULL)`\n : `(${fieldExpr} IS NULL)`\n }\n\n // Handle comparison operators\n for (const [op, value] of Object.entries(operators)) {\n context.operatorCount++\n if (context.operatorCount > MAX_OPERATORS) {\n throw new RangeError(`Too many operators (max: ${MAX_OPERATORS})`)\n }\n\n switch (op) {\n case 'gt':\n context.values.push(sql.value(value))\n clauses.push(`${fieldExpr} > ?`)\n break\n case 'gte':\n context.values.push(sql.value(value))\n clauses.push(`${fieldExpr} >= ?`)\n break\n case 'lt':\n context.values.push(sql.value(value))\n clauses.push(`${fieldExpr} < ?`)\n break\n case 'lte':\n context.values.push(sql.value(value))\n clauses.push(`${fieldExpr} <= ?`)\n break\n case 'ne':\n if (value === null || value === undefined) {\n clauses.push(`${fieldExpr} IS NOT NULL`)\n } else {\n context.values.push(sql.value(value))\n clauses.push(`${fieldExpr} <> ?`)\n }\n break\n case 'in': {\n if (!Array.isArray(value)) {\n throw new TypeError('IN operator requires an array')\n }\n if (value.length === 0) {\n throw new TypeError('IN operator cannot be used with empty arrays')\n }\n if (value.length > 999) {\n throw new RangeError(\n 'IN operator cannot be used with arrays larger than 999 items',\n )\n }\n\n const inFragment = sql.in(value)\n context.values.push(...inFragment.values)\n clauses.push(`${fieldExpr} IN ${inFragment.text}`)\n break\n }\n case 'nin': {\n if (!Array.isArray(value)) {\n throw new TypeError('NIN operator requires an array')\n }\n if (value.length === 0) {\n throw new TypeError('NIN operator cannot be used with empty arrays')\n }\n if (value.length > 999) {\n throw new RangeError(\n 'NIN operator cannot be used with arrays larger than 999 items',\n )\n }\n\n const ninFragment = sql.in(value)\n context.values.push(...ninFragment.values)\n clauses.push(`${fieldExpr} NOT IN ${ninFragment.text}`)\n break\n }\n case 'like':\n if (typeof value !== 'string') {\n throw new TypeError('LIKE operator requires a string pattern')\n }\n context.values.push(value)\n clauses.push(`${fieldExpr} LIKE ?`)\n break\n case 'ilike':\n if (typeof value !== 'string') {\n throw new TypeError('ILIKE operator requires a string pattern')\n }\n context.values.push(value)\n clauses.push(`${fieldExpr} LIKE ? COLLATE NOCASE`)\n break\n case 'regex':\n if (typeof value !== 'string') {\n throw new TypeError('REGEX operator requires a string pattern')\n }\n context.values.push(value)\n clauses.push(`${fieldExpr} REGEXP ?`)\n break\n }\n }\n\n if (clauses.length === 0) {\n throw new SyntaxError(\n 'Operator object must contain at least one valid operator',\n )\n }\n\n return clauses.length === 1 ? `(${clauses[0]})` : `(${clauses.join(' AND ')})`\n}\n\n/**\n * Compile a JSON filter to SQL recursively\n */\nfunction compileFilterRecursive(\n filter: JsonFilter,\n context: CompileContext,\n): string {\n if (context.depth >= MAX_NESTING_DEPTH) {\n throw new RangeError(`Nesting depth too deep (max: ${MAX_NESTING_DEPTH})`)\n }\n\n if (typeof filter !== 'object' || filter === null) {\n throw new TypeError('Filter must be an object')\n }\n\n context.depth++\n const clauses: string[] = []\n\n // Handle logical operators first\n if ('and' in filter && filter.and) {\n context.operatorCount++\n if (context.operatorCount > MAX_OPERATORS) {\n throw new RangeError(`Too many operators (max: ${MAX_OPERATORS})`)\n }\n\n if (!Array.isArray(filter.and)) {\n throw new TypeError('AND operator must be an array')\n }\n if (filter.and.length === 0) {\n throw new TypeError('AND operator cannot be used with empty arrays')\n }\n\n const andClauses = filter.and.map((subFilter) =>\n compileFilterRecursive(subFilter, context),\n )\n clauses.push(`(${andClauses.join(' AND ')})`)\n }\n\n if ('or' in filter && filter.or) {\n context.operatorCount++\n if (context.operatorCount > MAX_OPERATORS) {\n throw new RangeError(`Too many operators (max: ${MAX_OPERATORS})`)\n }\n\n if (!Array.isArray(filter.or)) {\n throw new TypeError('OR operator must be an array')\n }\n if (filter.or.length === 0) {\n throw new TypeError('OR operator cannot be used with empty arrays')\n }\n\n const orClauses = filter.or.map((subFilter) =>\n compileFilterRecursive(subFilter, context),\n )\n clauses.push(`(${orClauses.join(' OR ')})`)\n }\n\n // Handle field conditions (implicit AND) - preserve original order\n const fieldEntries = Object.entries(filter).filter(\n ([field, condition]) =>\n field !== 'and' && field !== 'or' && condition !== undefined,\n )\n\n for (const [field, condition] of fieldEntries) {\n // Handle array conditions (for 'and'/'or' at field level)\n if (Array.isArray(condition)) {\n throw new SyntaxError(\n `Field '${field}' cannot have array value. Use logical operators 'and'/'or' instead.`,\n )\n }\n\n clauses.push(\n compileFieldCondition(field, condition as FieldCondition, context),\n )\n }\n\n context.depth--\n\n if (clauses.length === 0) {\n throw new SyntaxError('Filter must contain at least one condition')\n }\n\n // Fix: ensure we have at least one clause before accessing clauses[0]\n if (clauses.length === 1) {\n return clauses[0]!\n } else {\n return `(${clauses.join(' AND ')})`\n }\n}\n\n/**\n * Compile a JSON filter to a SQL WHERE clause\n */\nexport function compileFilter(filter: JsonFilter): FilterResult {\n const context: CompileContext = {\n depth: 0,\n operatorCount: 0,\n values: [],\n }\n\n const text = compileFilterRecursive(filter, context)\n\n return Object.freeze({\n text: `(${text})`,\n values: Object.freeze([...context.values]),\n })\n}\n"
|
|
5
|
+
"/**\n * Common regex patterns used across the codebase\n */\n\n// Maximum query length (100KB)\nexport const MAX_QUERY_LENGTH = 102400\n\n// Regex to detect stacked queries (semicolon followed by non-whitespace)\nexport const STACKED_QUERY_REGEX = /;[\\s\\S]*\\S/\n\n// ANSI identifier validation - supports qualified identifiers (e.g., table.column)\nexport const QUALIFIED_IDENTIFIER_REGEX =\n /^[A-Za-z_][A-Za-z0-9_]*(\\.[A-Za-z_][A-Za-z0-9_]*)*$/\n\n// Simple identifier validation (for individual parts)\nexport const SIMPLE_IDENTIFIER_REGEX = /^[A-Za-z_][A-Za-z0-9_]*$/\n",
|
|
6
|
+
"import {\n MAX_QUERY_LENGTH,\n QUALIFIED_IDENTIFIER_REGEX,\n SIMPLE_IDENTIFIER_REGEX,\n STACKED_QUERY_REGEX,\n} from './constants'\nimport type { SqlFragment, SqlQuery, SqlValue } from './types'\n\n/**\n * Format a date for SQLite (YYYY-MM-DD HH:MM:SS)\n */\nfunction formatDate(date: Date): string {\n const year = date.getFullYear()\n const month = String(date.getMonth() + 1).padStart(2, '0')\n const day = String(date.getDate()).padStart(2, '0')\n const hours = String(date.getHours()).padStart(2, '0')\n const minutes = String(date.getMinutes()).padStart(2, '0')\n const seconds = String(date.getSeconds()).padStart(2, '0')\n\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`\n}\n\n/**\n * Convert a value to its SQLite representation\n */\nfunction sqlValue(value: SqlValue): unknown {\n if (value === null || value === undefined) {\n return null\n }\n\n if (typeof value === 'string') {\n return value\n }\n\n if (typeof value === 'number' || typeof value === 'boolean') {\n return value\n }\n\n if (value instanceof Date) {\n return formatDate(value)\n }\n\n if (value instanceof Buffer || value instanceof Uint8Array) {\n throw new TypeError(\n 'Buffer/Uint8Array values must be used with sql.blob() for safe BLOB handling',\n )\n }\n\n throw new TypeError(`Unsupported value type: ${typeof value}`)\n}\n\n/**\n * Quote a single identifier part\n */\nfunction quoteSingleIdentifier(identifier: string): string {\n if (!SIMPLE_IDENTIFIER_REGEX.test(identifier)) {\n throw new TypeError(\n `Invalid identifier part: ${identifier}. Must be a valid ANSI identifier.`,\n )\n }\n return `\"${identifier}\"`\n}\n\n/**\n * Quote a qualified identifier by splitting on dots and quoting each part\n */\nfunction quoteQualifiedIdentifier(identifier: string): string {\n if (!QUALIFIED_IDENTIFIER_REGEX.test(identifier)) {\n throw new TypeError(\n `Invalid identifier: ${identifier}. Must be a valid identifier or qualified identifier (e.g., table.column)`,\n )\n }\n\n const parts = identifier.split('.')\n return parts.map(quoteSingleIdentifier).join('.')\n}\n\n/**\n * Validate and quote a SQL identifier or array of identifiers/fragments\n */\nfunction sqlIdent(\n identifier: string | readonly (string | SqlFragment)[],\n): SqlFragment {\n // Handle array of identifiers and fragments\n if (Array.isArray(identifier)) {\n if (identifier.length === 0) {\n throw new TypeError('Identifier array cannot be empty')\n }\n\n const fragments: SqlFragment[] = []\n\n for (const item of identifier) {\n // Handle SqlFragment objects (like sql.raw())\n if (\n item &&\n typeof item === 'object' &&\n 'text' in item &&\n 'values' in item &&\n typeof (item as Record<string, unknown>).text === 'string' &&\n Array.isArray((item as Record<string, unknown>).values)\n ) {\n fragments.push(item as SqlFragment)\n } else if (typeof item === 'string') {\n // Handle string identifiers\n if (!item) {\n throw new TypeError('All identifiers must be non-empty strings')\n }\n\n if (!QUALIFIED_IDENTIFIER_REGEX.test(item)) {\n throw new TypeError(\n `Invalid identifier: ${item}. Must be a valid identifier or qualified identifier (e.g., table.column)`,\n )\n }\n\n fragments.push({\n text: quoteQualifiedIdentifier(item),\n values: [],\n })\n } else {\n throw new TypeError('Array items must be strings or SQL fragments')\n }\n }\n\n // Join all fragments\n const text = fragments.map((f) => f.text).join(', ')\n const values = fragments.flatMap((f) => [...f.values])\n\n return {\n text,\n values,\n }\n }\n\n // Handle single identifier (existing behavior)\n if (!identifier || typeof identifier !== 'string') {\n throw new TypeError('Identifier must be a non-empty string')\n }\n\n if (!QUALIFIED_IDENTIFIER_REGEX.test(identifier)) {\n throw new TypeError(\n `Invalid identifier: ${identifier}. Must be a valid identifier or qualified identifier (e.g., table.column)`,\n )\n }\n\n return {\n text: quoteQualifiedIdentifier(identifier),\n values: [],\n }\n}\n\n/**\n * Create SQL IN clause from array\n */\nfunction sqlIn(array: readonly unknown[]): SqlFragment {\n if (!Array.isArray(array)) {\n throw new TypeError('sql.in() requires an array')\n }\n\n if (array.length === 0) {\n throw new TypeError('sql.in() cannot be used with empty arrays')\n }\n\n // Soft warning for large arrays\n if (array.length > 1000) {\n console.warn(\n `sql.in(): Large array with ${array.length} items. Consider using temporary tables for better performance.`,\n )\n }\n\n const placeholders = array.map(() => '?').join(',')\n const values = array.map(sqlValue)\n\n return {\n text: `(${placeholders})`,\n values,\n }\n}\n\n/**\n * Create raw SQL fragment (DANGEROUS - must not contain user input)\n */\nfunction sqlRaw(rawSql: string): SqlFragment {\n if (typeof rawSql !== 'string') {\n throw new TypeError('sql.raw() requires a string')\n }\n\n return {\n text: rawSql,\n values: [],\n }\n}\n\n/**\n * Create SQL fragment for BLOB data (for validated binary data)\n */\nfunction sqlBlob(data: Buffer | Uint8Array): SqlFragment {\n if (!(data instanceof Buffer) && !(data instanceof Uint8Array)) {\n throw new TypeError('sql.blob() requires a Buffer or Uint8Array')\n }\n\n return {\n text: '?',\n values: [data],\n }\n}\n\n/**\n * Join SQL fragments with a separator\n */\nfunction sqlJoin(\n fragments: readonly SqlFragment[],\n separator = ', ',\n): SqlFragment {\n if (!Array.isArray(fragments)) {\n throw new TypeError('sql.join() requires an array of fragments')\n }\n\n if (fragments.length === 0) {\n return { text: '', values: [] }\n }\n\n const text = fragments.map((f: SqlFragment) => f.text).join(separator)\n const values = fragments.flatMap((f: SqlFragment) => [...f.values])\n\n return { text, values }\n}\n\n/**\n * Main SQL tagged template function\n */\nfunction sql(strings: TemplateStringsArray, ...values: unknown[]): SqlQuery {\n // Build the query text and collect values\n let text = strings[0] || ''\n const queryValues: unknown[] = []\n\n for (let i = 0; i < values.length; i++) {\n const value = values[i]\n\n // Handle SqlFragment objects (from helper functions)\n if (\n value &&\n typeof value === 'object' &&\n 'text' in value &&\n 'values' in value &&\n typeof (value as Record<string, unknown>).text === 'string' &&\n Array.isArray((value as Record<string, unknown>).values)\n ) {\n const fragment = value as SqlFragment\n text += fragment.text\n queryValues.push(...fragment.values)\n } else {\n // Regular value - add placeholder and collect value\n text += '?'\n queryValues.push(sqlValue(value as SqlValue))\n }\n\n text += strings[i + 1] || ''\n }\n\n // Security checks\n if (text.length > MAX_QUERY_LENGTH) {\n throw new Error(\n `Query too long: ${text.length} bytes (max: ${MAX_QUERY_LENGTH})`,\n )\n }\n\n if (STACKED_QUERY_REGEX.test(text)) {\n throw new Error('Stacked queries are not allowed')\n }\n\n // Return frozen result\n return Object.freeze({\n text,\n values: Object.freeze([...queryValues]),\n })\n}\n\n// Attach helper functions to sql\nsql.value = sqlValue\nsql.ident = sqlIdent\nsql.in = sqlIn\nsql.raw = sqlRaw\nsql.blob = sqlBlob\nsql.join = sqlJoin\n\nexport { sql }\n",
|
|
7
|
+
"import { SIMPLE_IDENTIFIER_REGEX } from './constants'\nimport { sql } from './sql'\nimport type {\n ComparisonOperators,\n FieldCondition,\n FilterResult,\n JsonFilter,\n} from './types'\n\n// Limits to prevent DoS attacks\nconst MAX_NESTING_DEPTH = 10\nconst MAX_OPERATORS = 100\n\n// Valid operators for validation\nconst VALID_OPERATORS = new Set([\n 'gt',\n 'gte',\n 'lt',\n 'lte',\n 'ne',\n 'in',\n 'nin',\n 'like',\n 'ilike',\n 'regex',\n 'exists',\n 'and',\n 'or',\n])\n\n/**\n * Context for tracking compilation state\n */\ninterface CompileContext {\n depth: number\n operatorCount: number\n values: unknown[]\n}\n\n/**\n * Check if a field name represents a JSON path (contains dots)\n */\nfunction isJsonPath(field: string): boolean {\n return field.includes('.')\n}\n\n/**\n * Convert a JSON path field to json_extract expression\n */\nfunction compileJsonPath(field: string): {\n columnName: string\n jsonPath: string\n} {\n const parts = field.split('.')\n const columnName = parts[0]\n const jsonPath = parts.slice(1)\n\n if (!columnName || jsonPath.length === 0 || jsonPath.some((part) => !part)) {\n throw new SyntaxError(`Invalid JSON path: ${field}`)\n }\n\n return {\n columnName,\n jsonPath: '$.' + jsonPath.join('.'),\n }\n}\n\n/**\n * Validate if a string is a valid SQL identifier\n */\nfunction isValidSqlIdentifier(identifier: string): boolean {\n return SIMPLE_IDENTIFIER_REGEX.test(identifier)\n}\n\n/**\n * Compile a single field condition to SQL\n */\nfunction compileFieldCondition(\n field: string,\n condition: FieldCondition,\n context: CompileContext,\n alias?: string,\n): string {\n // Handle direct value (equality)\n if (\n condition === null ||\n condition === undefined ||\n typeof condition === 'string' ||\n typeof condition === 'number' ||\n typeof condition === 'boolean' ||\n condition instanceof Date\n ) {\n context.operatorCount++\n if (context.operatorCount > MAX_OPERATORS) {\n throw new RangeError(`Too many operators (max: ${MAX_OPERATORS})`)\n }\n\n if (isJsonPath(field)) {\n const { columnName, jsonPath } = compileJsonPath(field)\n const identFragment = sql.ident(columnName)\n const fullFieldExpr = alias\n ? `${alias}.${identFragment.text}`\n : identFragment.text\n\n if (condition === null || condition === undefined) {\n context.values.push(jsonPath)\n return `(json_extract(${fullFieldExpr}, ?) IS NULL)`\n } else {\n context.values.push(jsonPath, sql.value(condition))\n return `(json_extract(${fullFieldExpr}, ?) = ?)`\n }\n } else {\n const identFragment = sql.ident(field)\n const fullFieldExpr = alias\n ? `${alias}.${identFragment.text}`\n : identFragment.text\n\n if (condition === null || condition === undefined) {\n return `(${fullFieldExpr} IS NULL)`\n } else {\n context.values.push(sql.value(condition))\n return `(${fullFieldExpr} = ?)`\n }\n }\n }\n\n // Handle operator object\n if (typeof condition !== 'object' || condition === null) {\n throw new TypeError('Condition must be a value or operator object')\n }\n\n const operators = condition as ComparisonOperators\n const clauses: string[] = []\n\n // Validate all operators are known\n for (const op of Object.keys(operators)) {\n if (!VALID_OPERATORS.has(op)) {\n throw new SyntaxError(`Unknown operator: ${op}`)\n }\n }\n\n const identFragment = sql.ident(\n isJsonPath(field) ? compileJsonPath(field).columnName : field,\n )\n const baseFieldExpr = alias\n ? `${alias}.${identFragment.text}`\n : identFragment.text\n const fieldExpr = isJsonPath(field)\n ? `json_extract(${baseFieldExpr}, ?)`\n : baseFieldExpr\n\n // Add JSON path to values if needed\n if (isJsonPath(field)) {\n context.values.push(compileJsonPath(field).jsonPath)\n }\n\n // Handle exists operator first (it overrides other operators)\n if ('exists' in operators) {\n context.operatorCount++\n if (context.operatorCount > MAX_OPERATORS) {\n throw new RangeError(`Too many operators (max: ${MAX_OPERATORS})`)\n }\n\n return operators.exists\n ? `(${fieldExpr} IS NOT NULL)`\n : `(${fieldExpr} IS NULL)`\n }\n\n // Handle comparison operators\n for (const [op, value] of Object.entries(operators)) {\n context.operatorCount++\n if (context.operatorCount > MAX_OPERATORS) {\n throw new RangeError(`Too many operators (max: ${MAX_OPERATORS})`)\n }\n\n switch (op) {\n case 'gt':\n context.values.push(sql.value(value))\n clauses.push(`${fieldExpr} > ?`)\n break\n case 'gte':\n context.values.push(sql.value(value))\n clauses.push(`${fieldExpr} >= ?`)\n break\n case 'lt':\n context.values.push(sql.value(value))\n clauses.push(`${fieldExpr} < ?`)\n break\n case 'lte':\n context.values.push(sql.value(value))\n clauses.push(`${fieldExpr} <= ?`)\n break\n case 'ne':\n if (value === null || value === undefined) {\n clauses.push(`${fieldExpr} IS NOT NULL`)\n } else {\n context.values.push(sql.value(value))\n clauses.push(`${fieldExpr} <> ?`)\n }\n break\n case 'in': {\n if (!Array.isArray(value)) {\n throw new TypeError('IN operator requires an array')\n }\n if (value.length === 0) {\n throw new TypeError('IN operator cannot be used with empty arrays')\n }\n if (value.length > 999) {\n throw new RangeError(\n 'IN operator cannot be used with arrays larger than 999 items',\n )\n }\n\n const inFragment = sql.in(value)\n context.values.push(...inFragment.values)\n clauses.push(`${fieldExpr} IN ${inFragment.text}`)\n break\n }\n case 'nin': {\n if (!Array.isArray(value)) {\n throw new TypeError('NIN operator requires an array')\n }\n if (value.length === 0) {\n throw new TypeError('NIN operator cannot be used with empty arrays')\n }\n if (value.length > 999) {\n throw new RangeError(\n 'NIN operator cannot be used with arrays larger than 999 items',\n )\n }\n\n const ninFragment = sql.in(value)\n context.values.push(...ninFragment.values)\n clauses.push(`${fieldExpr} NOT IN ${ninFragment.text}`)\n break\n }\n case 'like':\n if (typeof value !== 'string') {\n throw new TypeError('LIKE operator requires a string pattern')\n }\n context.values.push(value)\n clauses.push(`${fieldExpr} LIKE ?`)\n break\n case 'ilike':\n if (typeof value !== 'string') {\n throw new TypeError('ILIKE operator requires a string pattern')\n }\n context.values.push(value)\n clauses.push(`${fieldExpr} LIKE ? COLLATE NOCASE`)\n break\n case 'regex':\n if (typeof value !== 'string') {\n throw new TypeError('REGEX operator requires a string pattern')\n }\n context.values.push(value)\n clauses.push(`${fieldExpr} REGEXP ?`)\n break\n }\n }\n\n if (clauses.length === 0) {\n throw new SyntaxError(\n 'Operator object must contain at least one valid operator',\n )\n }\n\n return clauses.length === 1 ? `(${clauses[0]})` : `(${clauses.join(' AND ')})`\n}\n\n/**\n * Compile a JSON filter to SQL recursively\n */\nfunction compileFilterRecursive(\n filter: JsonFilter,\n context: CompileContext,\n alias?: string,\n): string {\n if (context.depth >= MAX_NESTING_DEPTH) {\n throw new RangeError(`Nesting depth too deep (max: ${MAX_NESTING_DEPTH})`)\n }\n\n if (typeof filter !== 'object' || filter === null) {\n throw new TypeError('Filter must be an object')\n }\n\n context.depth++\n const clauses: string[] = []\n\n // Handle logical operators first\n if ('and' in filter && filter.and) {\n context.operatorCount++\n if (context.operatorCount > MAX_OPERATORS) {\n throw new RangeError(`Too many operators (max: ${MAX_OPERATORS})`)\n }\n\n if (!Array.isArray(filter.and)) {\n throw new TypeError('AND operator must be an array')\n }\n if (filter.and.length === 0) {\n throw new TypeError('AND operator cannot be used with empty arrays')\n }\n\n const andClauses = filter.and.map((subFilter) =>\n compileFilterRecursive(subFilter, context, alias),\n )\n clauses.push(`(${andClauses.join(' AND ')})`)\n }\n\n if ('or' in filter && filter.or) {\n context.operatorCount++\n if (context.operatorCount > MAX_OPERATORS) {\n throw new RangeError(`Too many operators (max: ${MAX_OPERATORS})`)\n }\n\n if (!Array.isArray(filter.or)) {\n throw new TypeError('OR operator must be an array')\n }\n if (filter.or.length === 0) {\n throw new TypeError('OR operator cannot be used with empty arrays')\n }\n\n const orClauses = filter.or.map((subFilter) =>\n compileFilterRecursive(subFilter, context, alias),\n )\n clauses.push(`(${orClauses.join(' OR ')})`)\n }\n\n // Handle field conditions (implicit AND) first - preserve original order\n const fieldEntries = Object.entries(filter).filter(\n ([field, condition]) =>\n field !== 'and' &&\n field !== 'or' &&\n !field.startsWith('$') &&\n condition !== undefined,\n )\n\n for (const [field, condition] of fieldEntries) {\n // Handle array conditions (for 'and'/'or' at field level)\n if (Array.isArray(condition)) {\n throw new SyntaxError(\n `Field '${field}' cannot have array value. Use logical operators 'and'/'or' instead.`,\n )\n }\n\n clauses.push(\n compileFieldCondition(field, condition as FieldCondition, context, alias),\n )\n }\n\n // Handle alias blocks (keys starting with $) after regular fields\n const aliasEntries = Object.entries(filter).filter(\n ([key, value]) =>\n key.startsWith('$') &&\n value !== undefined &&\n typeof value === 'object' &&\n value !== null,\n )\n\n for (const [aliasKey, aliasFilter] of aliasEntries) {\n const aliasName = aliasKey.slice(1) // Remove the $ prefix\n\n // Validate alias name\n if (!isValidSqlIdentifier(aliasName)) {\n throw new SyntaxError(`Invalid alias identifier: ${aliasName}`)\n }\n\n // Recursively compile the alias block with the alias context\n const aliasClause = compileFilterRecursive(\n aliasFilter as JsonFilter,\n context,\n aliasName,\n )\n clauses.push(aliasClause)\n }\n\n context.depth--\n\n if (clauses.length === 0) {\n throw new SyntaxError('Filter must contain at least one condition')\n }\n\n // Fix: ensure we have at least one clause before accessing clauses[0]\n if (clauses.length === 1) {\n return clauses[0]!\n } else {\n return `(${clauses.join(' AND ')})`\n }\n}\n\n/**\n * Compile a JSON filter to a SQL WHERE clause\n */\nexport function compileFilter(filter: JsonFilter): FilterResult {\n const context: CompileContext = {\n depth: 0,\n operatorCount: 0,\n values: [],\n }\n\n const text = compileFilterRecursive(filter, context)\n\n return Object.freeze({\n text: `(${text})`,\n values: Object.freeze([...context.values]),\n })\n}\n"
|
|
7
8
|
],
|
|
8
|
-
"mappings": "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",
|
|
9
|
-
"debugId": "
|
|
9
|
+
"mappings": "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",
|
|
10
|
+
"debugId": "2601C616902F043764756E2164756E21",
|
|
10
11
|
"names": []
|
|
11
12
|
}
|
package/dist/sql.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../src/sql.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../src/sql.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAgB9D;;GAEG;AACH,iBAAS,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAwB1C;AA4BD;;GAEG;AACH,iBAAS,QAAQ,CACf,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,WAAW,CAAC,EAAE,GACrD,WAAW,CAkEb;AAED;;GAEG;AACH,iBAAS,KAAK,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,GAAG,WAAW,CAuBrD;AAED;;GAEG;AACH,iBAAS,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAS3C;AAED;;GAEG;AACH,iBAAS,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,CASvD;AAED;;GAEG;AACH,iBAAS,OAAO,CACd,SAAS,EAAE,SAAS,WAAW,EAAE,EACjC,SAAS,SAAO,GACf,WAAW,CAab;AAED;;GAEG;AACH,iBAAS,GAAG,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CA6C1E;kBA7CQ,GAAG;;;;;;;;;AAuDZ,OAAO,EAAE,GAAG,EAAE,CAAA"}
|
package/dist/types.d.ts
CHANGED
|
@@ -58,10 +58,11 @@ export interface LogicalOperators {
|
|
|
58
58
|
}
|
|
59
59
|
/**
|
|
60
60
|
* A JSON filter for compiling to SQL WHERE clauses
|
|
61
|
-
* Can be a field-to-condition mapping with implicit AND,
|
|
61
|
+
* Can be a field-to-condition mapping with implicit AND, explicit logical operators,
|
|
62
|
+
* or alias blocks (keys starting with $) containing nested filters
|
|
62
63
|
*/
|
|
63
64
|
export type JsonFilter = LogicalOperators & {
|
|
64
|
-
[field: string]: FieldCondition | readonly JsonFilter[] | undefined;
|
|
65
|
+
[field: string]: FieldCondition | readonly JsonFilter[] | JsonFilter | undefined;
|
|
65
66
|
};
|
|
66
67
|
/**
|
|
67
68
|
* Result of compiling a JSON filter to SQL
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CACpC;AAED;;GAEG;AACH,MAAM,MAAM,QAAQ,GAChB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,GACT,IAAI,GACJ,MAAM,GACN,UAAU,CAAA;AAEd;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,mBAAmB;IACnB,EAAE,CAAC,EAAE,QAAQ,CAAA;IACb,4BAA4B;IAC5B,GAAG,CAAC,EAAE,QAAQ,CAAA;IACd,gBAAgB;IAChB,EAAE,CAAC,EAAE,QAAQ,CAAA;IACb,yBAAyB;IACzB,GAAG,CAAC,EAAE,QAAQ,CAAA;IACd,gBAAgB;IAChB,EAAE,CAAC,EAAE,QAAQ,CAAA;IACb,eAAe;IACf,EAAE,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAA;IACxB,mBAAmB;IACnB,GAAG,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAA;IACzB,mBAAmB;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+DAA+D;IAC/D,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,mBAAmB,CAAA;AAE3D;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gCAAgC;IAChC,GAAG,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;IAC3B,+BAA+B;IAC/B,EAAE,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;CAC3B;AAED
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CACpC;AAED;;GAEG;AACH,MAAM,MAAM,QAAQ,GAChB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,GACT,IAAI,GACJ,MAAM,GACN,UAAU,CAAA;AAEd;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,mBAAmB;IACnB,EAAE,CAAC,EAAE,QAAQ,CAAA;IACb,4BAA4B;IAC5B,GAAG,CAAC,EAAE,QAAQ,CAAA;IACd,gBAAgB;IAChB,EAAE,CAAC,EAAE,QAAQ,CAAA;IACb,yBAAyB;IACzB,GAAG,CAAC,EAAE,QAAQ,CAAA;IACd,gBAAgB;IAChB,EAAE,CAAC,EAAE,QAAQ,CAAA;IACb,eAAe;IACf,EAAE,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAA;IACxB,mBAAmB;IACnB,GAAG,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAA;IACzB,mBAAmB;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iCAAiC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,+DAA+D;IAC/D,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,mBAAmB,CAAA;AAE3D;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,gCAAgC;IAChC,GAAG,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;IAC3B,+BAA+B;IAC/B,EAAE,CAAC,EAAE,SAAS,UAAU,EAAE,CAAA;CAC3B;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,gBAAgB,GAAG;IAC1C,CAAC,KAAK,EAAE,MAAM,GACV,cAAc,GACd,SAAS,UAAU,EAAE,GACrB,UAAU,GACV,SAAS,CAAA;CACd,CAAA;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAA;CACpC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truto/sqlite-builder",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "Safe, zero-dependency template-literal tag for SQLite queries in any JS environment",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sqlite",
|
|
@@ -13,16 +13,16 @@
|
|
|
13
13
|
"database",
|
|
14
14
|
"query-builder"
|
|
15
15
|
],
|
|
16
|
-
"homepage": "https://github.com/
|
|
16
|
+
"homepage": "https://github.com/trutohq/truto-sqlite-builder#readme",
|
|
17
17
|
"bugs": {
|
|
18
|
-
"url": "https://github.com/
|
|
18
|
+
"url": "https://github.com/trutohq/truto-sqlite-builder/issues"
|
|
19
19
|
},
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
22
|
-
"url": "https://github.com/
|
|
22
|
+
"url": "https://github.com/trutohq/truto-sqlite-builder.git"
|
|
23
23
|
},
|
|
24
24
|
"license": "MIT",
|
|
25
|
-
"author": "Truto <eng@truto.
|
|
25
|
+
"author": "Truto <eng@truto.one>",
|
|
26
26
|
"type": "module",
|
|
27
27
|
"exports": {
|
|
28
28
|
".": {
|