happy-sql 1.7.1 → 2.0.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/ChangeLog CHANGED
@@ -1,3 +1,13 @@
1
+ 2026.08.19, v2.0.1
2
+
3
+ fix:
4
+ - c1629b0 happy-sql: keep :x unquoted
5
+
6
+ 2026.08.19, v2.0.0
7
+
8
+ feature:
9
+ - f34faef happy-sql: parseSqlNode -> parseSql
10
+
1
11
  2026.08.19, v1.7.1
2
12
 
3
13
  fix:
package/README.md CHANGED
@@ -9,24 +9,74 @@
9
9
 
10
10
  <img width="600" height="428" alt="image" src="https://github.com/user-attachments/assets/aefbd055-957e-4de3-aca5-c30e5e3ee3f9" />
11
11
 
12
- SQL to JS AST parser and printer.
12
+ Write SQL as JavaScript function calls: parse, print, convert.
13
+
14
+ SQL written as JS lives in `.js` files it gets linted, formatted, and transformed by standard tooling. **Happy Sql** is the engine that converts between the two representations and exposes the underlying AST for tools that need it.
13
15
 
14
16
  ## Install
15
17
 
16
18
  ```
17
- npm i happy-sql --save
19
+ npm i happy-sql
20
+ ```
21
+
22
+ ## CLI
23
+
24
+ The CLI reads from stdin and auto-detects direction: SQL in → JS out, JS in → SQL out.
25
+
26
+ ```sh
27
+ # SQL → JS
28
+ echo "SELECT * FROM users WHERE id = :id" | happy-sql
29
+ # [
30
+ # select('*', from(users), where(id === ':id')),
31
+ # ];
32
+ # JS → SQL (pipe the output back)
33
+ echo "[\n select('*', from(users), where(id === ':id')),\n];" | happy-sql
34
+ # SELECT *
35
+ # FROM users
36
+ # WHERE id = :id
18
37
  ```
19
38
 
20
39
  ## API
21
40
 
22
41
  ```js
23
- const source = `select(count('*'), from(users))`;
42
+ import {
43
+ convertSqlToJs,
44
+ convertJsToSql,
45
+ parseSql,
46
+ printSql,
47
+ } from 'happy-sql';
48
+ ```
49
+
50
+ ### `convertSqlToJs(sql)`
51
+
52
+ ```js
53
+ convertSqlToJs('SELECT COUNT(*)\nFROM users\n');
54
+ // [
55
+ // select(count('*'), from(users)),
56
+ // ];
57
+ ```
58
+
59
+ ### `convertJsToSql(js)`
24
60
 
25
- convertJsToSql(source);
26
- // returns
27
- 'SELECT COUNT(*)\nFROM users\n';
61
+ ```js
62
+ convertJsToSql('select(count(\'*\'), from(users))');
63
+ // "SELECT COUNT(*)\nFROM users\n"
28
64
  ```
29
65
 
66
+ ### `parseSql(sql)`
67
+
68
+ Returns a Babel-compatible AST node. Use when you need to inspect or transform the tree directly.
69
+
70
+ ### `printSql(ast)`
71
+
72
+ Prints a Babel AST node back to a SQL string.
73
+
74
+ ## Used by
75
+
76
+ - [`@putout/processor-sql`](https://github.com/coderaiser/putout/tree/master/packages/processor-sql) — lets 🐊[Putout](https://github.com/coderaiser/putout) lint and transform `.sql` files
77
+ - [`@putout/plugin-sql`](https://github.com/coderaiser/putout/tree/master/packages/plugin-sql) — SQL-specific rules for Putout (`apply-count`, `postgres`, SQLite↔Postgres conversions)
78
+ - [`putnik`](https://github.com/coderaiser/putnik) — code transformation engine that writes AST into SQLite and runs SQL-aware plugins against it
79
+
30
80
  ## License
31
81
 
32
82
  MIT
package/lib/happy-sql.js CHANGED
@@ -1,11 +1,11 @@
1
1
  import {parse} from '@putout/babel';
2
2
  import {print} from '@putout/printer';
3
- import {parseSqlNode} from '#parser';
3
+ import {parseSql} from '#parser';
4
4
  import {printSql} from '#printer';
5
5
 
6
6
  export {printSql} from '#printer';
7
- export {parseSqlNode} from '#parser';
7
+ export {parseSql} from '#parser';
8
8
 
9
- export const convertSqlToJs = (sql) => print(parseSqlNode(sql));
9
+ export const convertSqlToJs = (sql) => print(parseSql(sql));
10
10
 
11
11
  export const convertJsToSql = (js) => printSql(parse(js));
@@ -25,7 +25,7 @@ const parseCstDialect = (source, dialect) => parseCst(source, {
25
25
  includeComments: true,
26
26
  });
27
27
 
28
- export const parseSqlNode = (source) => {
28
+ export const parseSql = (source) => {
29
29
  for (const dialect of DIALECTS) {
30
30
  const [, cst] = tryCatch(parseCstDialect, source, dialect);
31
31
 
@@ -1 +1 @@
1
- INSERT INTO t (x) VALUES (':x')
1
+ INSERT INTO t (x) VALUES (:x)
@@ -1 +1 @@
1
- INSERT INTO t (x) VALUES (':x')
1
+ INSERT INTO t (x) VALUES (:x)
@@ -1 +1 @@
1
- INSERT INTO t (x) VALUES (':x') ON CONFLICT (x) DO UPDATE SET x = :x
1
+ INSERT INTO t (x) VALUES (:x) ON CONFLICT (x) DO UPDATE SET x = :x
@@ -1 +1 @@
1
- INSERT INTO t (x) VALUES (':x') ON CONFLICT (x, y) DO UPDATE SET x = :x
1
+ INSERT INTO t (x) VALUES (:x) ON CONFLICT (x, y) DO UPDATE SET x = :x
@@ -1 +1 @@
1
- INSERT INTO t (x) VALUES (':x') ON CONFLICT (x) DO UPDATE SET y = :y RETURNING id
1
+ INSERT INTO t (x) VALUES (:x) ON CONFLICT (x) DO UPDATE SET y = :y RETURNING id
@@ -1 +1 @@
1
- INSERT INTO CallExpression (parent_id) VALUES (':parent_id') RETURNING id AS call_id
1
+ INSERT INTO CallExpression (parent_id) VALUES (:parent_id) RETURNING id AS call_id
@@ -1 +1 @@
1
- INSERT INTO CallExpression (parent_id) VALUES (':parent_id') RETURNING id
1
+ INSERT INTO CallExpression (parent_id) VALUES (:parent_id) RETURNING id
@@ -1 +1 @@
1
- INSERT INTO t (x) VALUES (':x') RETURNING id, created_at
1
+ INSERT INTO t (x) VALUES (:x) RETURNING id, created_at
@@ -1 +1 @@
1
- VALUES (':x')
1
+ VALUES (:x)
@@ -1 +1 @@
1
- VALUES (':file', ':parent_id')
1
+ VALUES (:file, :parent_id)
@@ -1,7 +1,3 @@
1
- import {types} from '@putout/babel';
2
-
3
- const {isStringLiteral} = types;
4
-
5
1
  export const values = (path, {write, traverse}) => {
6
2
  const args = path.get('arguments');
7
3
  write('VALUES (');
@@ -9,12 +5,7 @@ export const values = (path, {write, traverse}) => {
9
5
  if (i > 0)
10
6
  write(', ');
11
7
 
12
- const arg = args[i];
13
-
14
- if (isStringLiteral(arg.node))
15
- write(`'${arg.node.value}'`);
16
- else
17
- traverse(arg);
8
+ traverse(args[i]);
18
9
  }
19
10
 
20
11
  write(')');
@@ -1,6 +1,6 @@
1
1
  WITH
2
2
  call AS (
3
- INSERT INTO CallExpression (file, parent_id) VALUES (':file', ':parent_id') RETURNING id
3
+ INSERT INTO CallExpression (file, parent_id) VALUES (:file, :parent_id) RETURNING id
4
4
  ),
5
5
  member AS (
6
6
  INSERT INTO MemberExpression (file, parent_id) SELECT :file, id
@@ -1,6 +1,6 @@
1
1
  WITH
2
2
  call AS (
3
- INSERT INTO CallExpression (parent_id) VALUES (':parent_id') RETURNING id
3
+ INSERT INTO CallExpression (parent_id) VALUES (:parent_id) RETURNING id
4
4
  ),
5
5
  member AS (
6
6
  INSERT INTO MemberExpression (parent_id) SELECT id
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "happy-sql",
3
- "version": "1.7.1",
3
+ "version": "2.0.1",
4
4
  "type": "module",
5
5
  "description": "sql to js ast parser and printer",
6
6
  "exports": {