sqyrl 0.0.2
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 +54 -0
- package/dist/index.d.mts +78 -0
- package/dist/index.mjs +1459 -0
- package/package.json +53 -0
package/README.md
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# sqyrl
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<img src="https://cdn.jsdelivr.net/gh/carderne/sqyrl@main/docs/logo.png" alt="sqyrl logo" width="200">
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
Sanitise agent-written SQL for multi-tenant DBs.
|
|
8
|
+
|
|
9
|
+
## Quickstart
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install sqyrl
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { sqyrl } from "sqyrl";
|
|
17
|
+
|
|
18
|
+
const sql = sqyrl(`SELECT id, name FROM public.users WHERE status = 'active' LIMIT 10`, {
|
|
19
|
+
schema: "public",
|
|
20
|
+
table: "users",
|
|
21
|
+
column: "tenant_id",
|
|
22
|
+
value: "acme",
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
console.log(sql);
|
|
26
|
+
// SELECT id, name FROM public.users WHERE public.users.tenant_id = 'acme' AND status = 'active' LIMIT 10
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`sqyrl` parses the SQL, enforces a mandatory equality filter on the given column as the outermost `AND` condition (so it cannot be short-circuited by agent-supplied `OR` clauses), and returns the sanitised SQL string.
|
|
30
|
+
|
|
31
|
+
## Ideas
|
|
32
|
+
|
|
33
|
+
- Inspiration: https://x.com/thomas_ankcorn/status/2033931057133748330
|
|
34
|
+
- Grammar ideas: https://github.com/iamwilhelm/ohm-grammar-sql
|
|
35
|
+
|
|
36
|
+
## Development
|
|
37
|
+
|
|
38
|
+
Install dependencies:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
vp install
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Run the unit tests:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
vp test
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Build the library:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
vp pack
|
|
54
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
//#region src/ast.d.ts
|
|
2
|
+
interface SelectStatement {
|
|
3
|
+
type: "select";
|
|
4
|
+
columns: Column[];
|
|
5
|
+
from: TableRef;
|
|
6
|
+
where: WhereExpr | null;
|
|
7
|
+
limit: number | null;
|
|
8
|
+
}
|
|
9
|
+
type WhereExpr = WhereAnd | WhereOr | WhereComparison;
|
|
10
|
+
interface WhereAnd {
|
|
11
|
+
type: "and";
|
|
12
|
+
left: WhereExpr;
|
|
13
|
+
right: WhereExpr;
|
|
14
|
+
}
|
|
15
|
+
interface WhereOr {
|
|
16
|
+
type: "or";
|
|
17
|
+
left: WhereExpr;
|
|
18
|
+
right: WhereExpr;
|
|
19
|
+
}
|
|
20
|
+
interface WhereComparison {
|
|
21
|
+
type: "comparison";
|
|
22
|
+
operator: "=";
|
|
23
|
+
column: ColumnRefNode;
|
|
24
|
+
value: string;
|
|
25
|
+
}
|
|
26
|
+
interface ColumnRefNode {
|
|
27
|
+
type: "column_ref";
|
|
28
|
+
table?: string;
|
|
29
|
+
name: string;
|
|
30
|
+
}
|
|
31
|
+
interface Column {
|
|
32
|
+
type: "wildcard" | "qualified_wildcard" | "qualified" | "simple";
|
|
33
|
+
table?: string;
|
|
34
|
+
name?: string;
|
|
35
|
+
alias?: string;
|
|
36
|
+
}
|
|
37
|
+
interface TableRef {
|
|
38
|
+
type: "table";
|
|
39
|
+
schema?: string;
|
|
40
|
+
name: string;
|
|
41
|
+
alias?: string;
|
|
42
|
+
}
|
|
43
|
+
//#endregion
|
|
44
|
+
//#region src/output.d.ts
|
|
45
|
+
declare function outputSql(ast: SelectStatement): string;
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/parse.d.ts
|
|
48
|
+
declare function parseSql(expr: string): SelectStatement;
|
|
49
|
+
//#endregion
|
|
50
|
+
//#region src/sanitise.d.ts
|
|
51
|
+
declare function sanitiseSql({
|
|
52
|
+
ast,
|
|
53
|
+
schema,
|
|
54
|
+
table,
|
|
55
|
+
col,
|
|
56
|
+
value
|
|
57
|
+
}: {
|
|
58
|
+
ast: SelectStatement;
|
|
59
|
+
schema: string;
|
|
60
|
+
table: string;
|
|
61
|
+
col: string;
|
|
62
|
+
value: string;
|
|
63
|
+
}): SelectStatement;
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/index.d.ts
|
|
66
|
+
declare function sqyrl(expr: string, {
|
|
67
|
+
schema,
|
|
68
|
+
table,
|
|
69
|
+
column,
|
|
70
|
+
value
|
|
71
|
+
}: {
|
|
72
|
+
schema: string;
|
|
73
|
+
table: string;
|
|
74
|
+
column: string;
|
|
75
|
+
value: string;
|
|
76
|
+
}): string;
|
|
77
|
+
//#endregion
|
|
78
|
+
export { outputSql, parseSql, sanitiseSql, sqyrl };
|