happy-sql 2.1.0 → 2.1.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.
Files changed (99) hide show
  1. package/ChangeLog +12 -0
  2. package/lib/parser/visitors/clause/count/count.js +4 -0
  3. package/lib/parser/visitors/clause/delete/fixture/delete-where-between-fix.js +14 -0
  4. package/lib/parser/visitors/clause/delete/fixture/delete-where-between.sql +1 -0
  5. package/lib/parser/visitors/clause/from/fixture/generate-series-fix.js +12 -0
  6. package/lib/parser/visitors/clause/from/fixture/generate-series.sql +1 -0
  7. package/lib/parser/visitors/clause/from/fixture/group-by-order-by-fix.js +17 -0
  8. package/lib/parser/visitors/clause/from/fixture/group-by-order-by.sql +1 -0
  9. package/lib/parser/visitors/clause/from/fixture/group-by-sum-fix.js +14 -0
  10. package/lib/parser/visitors/clause/from/fixture/group-by-sum-having-fix.js +19 -0
  11. package/lib/parser/visitors/clause/from/fixture/group-by-sum-having.sql +1 -0
  12. package/lib/parser/visitors/clause/from/fixture/group-by-sum.sql +1 -0
  13. package/lib/parser/visitors/clause/from/fixture/json-each-fix.js +10 -0
  14. package/lib/parser/visitors/clause/from/fixture/json-each.sql +1 -0
  15. package/lib/parser/visitors/clause/from/fixture/limit-fix.js +11 -0
  16. package/lib/parser/visitors/clause/from/fixture/limit-offset-fix.js +12 -0
  17. package/lib/parser/visitors/clause/from/fixture/limit-offset.sql +1 -0
  18. package/lib/parser/visitors/clause/from/fixture/limit.sql +1 -0
  19. package/lib/parser/visitors/clause/from/fixture/order-by-desc-fix.js +13 -0
  20. package/lib/parser/visitors/clause/from/fixture/order-by-desc.sql +1 -0
  21. package/lib/parser/visitors/clause/from/fixture/order-by-fix.js +11 -0
  22. package/lib/parser/visitors/clause/from/fixture/order-by-multi-fix.js +14 -0
  23. package/lib/parser/visitors/clause/from/fixture/order-by-multi.sql +1 -0
  24. package/lib/parser/visitors/clause/from/fixture/order-by.sql +1 -0
  25. package/lib/parser/visitors/clause/from/fixture/unnest-fix.js +10 -0
  26. package/lib/parser/visitors/clause/from/fixture/unnest.sql +1 -0
  27. package/lib/parser/visitors/clause/from/from.js +29 -1
  28. package/lib/parser/visitors/clause/from/limit.js +18 -0
  29. package/lib/parser/visitors/clause/from/order-by.js +20 -0
  30. package/lib/parser/visitors/clause/from/table-func.js +28 -0
  31. package/lib/parser/visitors/clause/operand.js +10 -0
  32. package/lib/parser/visitors/clause/select/fixture/select-abs-fix.js +8 -0
  33. package/lib/parser/visitors/clause/select/fixture/select-abs.sql +1 -0
  34. package/lib/parser/visitors/clause/select/fixture/select-avg-fix.js +10 -0
  35. package/lib/parser/visitors/clause/select/fixture/select-avg.sql +1 -0
  36. package/lib/parser/visitors/clause/select/fixture/select-count-col-fix.js +10 -0
  37. package/lib/parser/visitors/clause/select/fixture/select-count-col.sql +1 -0
  38. package/lib/parser/visitors/clause/select/fixture/select-distinct-fix.js +10 -0
  39. package/lib/parser/visitors/clause/select/fixture/select-distinct-multi-fix.js +11 -0
  40. package/lib/parser/visitors/clause/select/fixture/select-distinct-multi.sql +1 -0
  41. package/lib/parser/visitors/clause/select/fixture/select-distinct.sql +1 -0
  42. package/lib/parser/visitors/clause/select/fixture/select-min-max-fix.js +13 -0
  43. package/lib/parser/visitors/clause/select/fixture/select-min-max.sql +1 -0
  44. package/lib/parser/visitors/clause/select/fixture/select-sum-fix.js +10 -0
  45. package/lib/parser/visitors/clause/select/fixture/select-sum.sql +1 -0
  46. package/lib/parser/visitors/clause/select/select.js +31 -2
  47. package/lib/parser/visitors/clause/update/fixture/update-where-not-in-fix.js +16 -0
  48. package/lib/parser/visitors/clause/update/fixture/update-where-not-in.sql +1 -0
  49. package/lib/parser/visitors/clause/where/fixture/where-between-fix.js +15 -0
  50. package/lib/parser/visitors/clause/where/fixture/where-between.sql +1 -0
  51. package/lib/parser/visitors/clause/where/fixture/where-not-in-fix.js +16 -0
  52. package/lib/parser/visitors/clause/where/fixture/where-not-in.sql +1 -0
  53. package/lib/parser/visitors/clause/where/where.js +18 -0
  54. package/lib/printer/visitors/call-expression/clauses/avg/avg.js +5 -0
  55. package/lib/printer/visitors/call-expression/clauses/avg/fixture/avg-fix.sql +2 -0
  56. package/lib/printer/visitors/call-expression/clauses/avg/fixture/avg.js +1 -0
  57. package/lib/printer/visitors/call-expression/clauses/between/between.js +9 -0
  58. package/lib/printer/visitors/call-expression/clauses/between/fixture/between-fix.sql +3 -0
  59. package/lib/printer/visitors/call-expression/clauses/between/fixture/between.js +3 -0
  60. package/lib/printer/visitors/call-expression/clauses/clauses.js +20 -0
  61. package/lib/printer/visitors/call-expression/clauses/desc/desc.js +4 -0
  62. package/lib/printer/visitors/call-expression/clauses/desc/fixture/desc-fix.sql +3 -0
  63. package/lib/printer/visitors/call-expression/clauses/desc/fixture/desc.js +13 -0
  64. package/lib/printer/visitors/call-expression/clauses/distinct/distinct.js +12 -0
  65. package/lib/printer/visitors/call-expression/clauses/distinct/fixture/distinct-fix.sql +2 -0
  66. package/lib/printer/visitors/call-expression/clauses/distinct/fixture/distinct-multi-fix.sql +2 -0
  67. package/lib/printer/visitors/call-expression/clauses/distinct/fixture/distinct-multi.js +11 -0
  68. package/lib/printer/visitors/call-expression/clauses/distinct/fixture/distinct.js +10 -0
  69. package/lib/printer/visitors/call-expression/clauses/from/fixture/generate-series-fix.sql +2 -0
  70. package/lib/printer/visitors/call-expression/clauses/from/fixture/generate-series.js +3 -0
  71. package/lib/printer/visitors/call-expression/clauses/from/from.js +45 -5
  72. package/lib/printer/visitors/call-expression/clauses/group-by/fixture/group-by-sum-fix.sql +4 -0
  73. package/lib/printer/visitors/call-expression/clauses/group-by/fixture/group-by-sum.js +19 -0
  74. package/lib/printer/visitors/call-expression/clauses/join/join.js +5 -3
  75. package/lib/printer/visitors/call-expression/clauses/limit/fixture/limit-fix.sql +3 -0
  76. package/lib/printer/visitors/call-expression/clauses/limit/fixture/limit-offset-fix.sql +4 -0
  77. package/lib/printer/visitors/call-expression/clauses/limit/fixture/limit-offset.js +12 -0
  78. package/lib/printer/visitors/call-expression/clauses/limit/fixture/limit.js +11 -0
  79. package/lib/printer/visitors/call-expression/clauses/limit/limit.js +12 -0
  80. package/lib/printer/visitors/call-expression/clauses/max/fixture/max-fix.sql +2 -0
  81. package/lib/printer/visitors/call-expression/clauses/max/fixture/max.js +1 -0
  82. package/lib/printer/visitors/call-expression/clauses/max/max.js +5 -0
  83. package/lib/printer/visitors/call-expression/clauses/min/fixture/min-fix.sql +2 -0
  84. package/lib/printer/visitors/call-expression/clauses/min/fixture/min.js +1 -0
  85. package/lib/printer/visitors/call-expression/clauses/min/min.js +5 -0
  86. package/lib/printer/visitors/call-expression/clauses/not-in-list/fixture/not-in-list-fix.sql +3 -0
  87. package/lib/printer/visitors/call-expression/clauses/not-in-list/fixture/not-in-list.js +3 -0
  88. package/lib/printer/visitors/call-expression/clauses/not-in-list/not-in-list.js +15 -0
  89. package/lib/printer/visitors/call-expression/clauses/order-by/fixture/order-by-fix.sql +3 -0
  90. package/lib/printer/visitors/call-expression/clauses/order-by/fixture/order-by-multi-fix.sql +3 -0
  91. package/lib/printer/visitors/call-expression/clauses/order-by/fixture/order-by-multi.js +14 -0
  92. package/lib/printer/visitors/call-expression/clauses/order-by/fixture/order-by.js +11 -0
  93. package/lib/printer/visitors/call-expression/clauses/order-by/order-by.js +12 -0
  94. package/lib/printer/visitors/call-expression/clauses/returning/returning.js +5 -3
  95. package/lib/printer/visitors/call-expression/clauses/select/select.js +9 -8
  96. package/lib/printer/visitors/call-expression/clauses/sum/fixture/sum-fix.sql +2 -0
  97. package/lib/printer/visitors/call-expression/clauses/sum/fixture/sum.js +1 -0
  98. package/lib/printer/visitors/call-expression/clauses/sum/sum.js +5 -0
  99. package/package.json +1 -1
@@ -34,6 +34,12 @@ const SQL_TO_JS_OP = {
34
34
  const convertAnd = (node) => logicalExpression('&&', convertCondition(node.left), convertCondition(node.right));
35
35
  const convertOr = (node) => logicalExpression('||', convertCondition(node.left), convertCondition(node.right));
36
36
 
37
+ export const convertBetween = (node) => callExpression(identifier('between'), [
38
+ convertOperand(node.left),
39
+ convertOperand(node.begin),
40
+ convertOperand(node.end),
41
+ ]);
42
+
37
43
  const convertBinary = (node) => {
38
44
  const op = opName(node.operator);
39
45
 
@@ -62,6 +68,15 @@ const convertBinary = (node) => {
62
68
  ]);
63
69
  }
64
70
 
71
+ if (op === 'NOT IN') {
72
+ const items = node.right.expr.items.map(convertOperand);
73
+
74
+ return callExpression(identifier('notInList'), [
75
+ convertOperand(node.left),
76
+ ...items,
77
+ ]);
78
+ }
79
+
65
80
  const jsOp = SQL_TO_JS_OP[op] ?? '===';
66
81
 
67
82
  return binaryExpression(
@@ -78,6 +93,9 @@ export const convertCondition = (node) => {
78
93
  if (node.operator?.name === 'OR')
79
94
  return convertOr(node);
80
95
 
96
+ if (node.type === 'between_expr')
97
+ return convertBetween(node);
98
+
81
99
  return convertBinary(node);
82
100
  };
83
101
 
@@ -0,0 +1,5 @@
1
+ export const avg = (path, {write, traverse}) => {
2
+ write('AVG(');
3
+ traverse(path.get('arguments')[0]);
4
+ write(')');
5
+ };
@@ -0,0 +1,2 @@
1
+ SELECT AVG(score)
2
+ FROM results
@@ -0,0 +1 @@
1
+ select(avg(score), from(results));
@@ -0,0 +1,9 @@
1
+ export const between = (path, {write, traverse}) => {
2
+ const [col, lo, hi] = path.get('arguments');
3
+
4
+ traverse(col);
5
+ write(' BETWEEN ');
6
+ traverse(lo);
7
+ write(' AND ');
8
+ traverse(hi);
9
+ };
@@ -0,0 +1,3 @@
1
+ SELECT *
2
+ FROM users
3
+ WHERE age BETWEEN 18 AND 65
@@ -0,0 +1,3 @@
1
+ [
2
+ select('*', from(users, where(between(age, 18, 65)))),
3
+ ];
@@ -18,6 +18,16 @@ import {withRecursive} from './with-recursive/with-recursive.js';
18
18
  import {unionAll} from './union-all/union-all.js';
19
19
  import {groupBy} from './group-by/group-by.js';
20
20
  import {having} from './having/having.js';
21
+ import {sum} from './sum/sum.js';
22
+ import {avg} from './avg/avg.js';
23
+ import {min} from './min/min.js';
24
+ import {max} from './max/max.js';
25
+ import {orderBy} from './order-by/order-by.js';
26
+ import {desc} from './desc/desc.js';
27
+ import {limit} from './limit/limit.js';
28
+ import {distinct} from './distinct/distinct.js';
29
+ import {notInList} from './not-in-list/not-in-list.js';
30
+ import {between} from './between/between.js';
21
31
  import {createTable} from './create-table/create-table.js';
22
32
  import {createSequence} from './create-sequence/create-sequence.js';
23
33
  import {column} from './column/column.js';
@@ -56,6 +66,16 @@ export const clauses = {
56
66
  unionAll,
57
67
  groupBy,
58
68
  having,
69
+ sum,
70
+ avg,
71
+ min,
72
+ max,
73
+ orderBy,
74
+ desc,
75
+ limit,
76
+ distinct,
77
+ notInList,
78
+ between,
59
79
  createTable,
60
80
  createSequence,
61
81
  column,
@@ -0,0 +1,4 @@
1
+ export const desc = (path, {write, traverse}) => {
2
+ traverse(path.get('arguments')[0]);
3
+ write(' DESC');
4
+ };
@@ -0,0 +1,3 @@
1
+ SELECT id
2
+ FROM users
3
+ ORDER BY id DESC
@@ -0,0 +1,13 @@
1
+ [
2
+ select(
3
+ id,
4
+ from(
5
+ users,
6
+ orderBy(
7
+ desc(
8
+ id,
9
+ ),
10
+ ),
11
+ ),
12
+ ),
13
+ ];
@@ -0,0 +1,12 @@
1
+ export const distinct = (path, {write, traverse}) => {
2
+ write('DISTINCT ');
3
+
4
+ const args = path.get('arguments');
5
+
6
+ for (const [i, arg] of args.entries()) {
7
+ if (i > 0)
8
+ write(', ');
9
+
10
+ traverse(arg);
11
+ }
12
+ };
@@ -0,0 +1,2 @@
1
+ SELECT DISTINCT name
2
+ FROM users
@@ -0,0 +1,2 @@
1
+ SELECT DISTINCT name, age
2
+ FROM users
@@ -0,0 +1,11 @@
1
+ [
2
+ select(
3
+ distinct(
4
+ name,
5
+ age,
6
+ ),
7
+ from(
8
+ users,
9
+ ),
10
+ ),
11
+ ];
@@ -0,0 +1,10 @@
1
+ [
2
+ select(
3
+ distinct(
4
+ name,
5
+ ),
6
+ from(
7
+ users,
8
+ ),
9
+ ),
10
+ ];
@@ -0,0 +1,2 @@
1
+ SELECT *
2
+ FROM generate_series(1, 10, 2)
@@ -0,0 +1,3 @@
1
+ [
2
+ select('*', from(generateSeries(1, 10, 2))),
3
+ ];
@@ -1,6 +1,9 @@
1
1
  import {types} from '@putout/babel';
2
2
 
3
- const {isTSAsExpression} = types;
3
+ const {
4
+ isTSAsExpression,
5
+ isCallExpression,
6
+ } = types;
4
7
 
5
8
  const printAsExpression = (path, {write, traverse}) => {
6
9
  traverse(path.get('expression'));
@@ -11,15 +14,51 @@ const CLAUSE_NAMES = [
11
14
  'where',
12
15
  'groupBy',
13
16
  'having',
17
+ 'orderBy',
18
+ 'limit',
19
+ ];
20
+
21
+ const TABLE_ARG_NAMES = [
22
+ ...CLAUSE_NAMES,
23
+ 'join',
24
+ 'on',
14
25
  ];
15
26
 
16
27
  const isClause = ({node}) => node.type === 'CallExpression' && CLAUSE_NAMES.includes(node.callee?.name);
17
28
 
18
- const printArg = (path, ctx) => {
19
- if (isTSAsExpression(path.node))
20
- return printAsExpression(path, ctx);
29
+ const CAMEL_RE = /([A-Z])/g;
30
+ const toSnake = (a) => a.replace(CAMEL_RE, (_, c) => `_${c.toLowerCase()}`);
31
+
32
+ const isTableFunc = (node) => isCallExpression(node) && !TABLE_ARG_NAMES.includes(node.callee.name);
33
+
34
+ const printTableFunc = (path, {write, traverse}) => {
35
+ const {name} = path.node.callee;
36
+ const args = path.get('arguments');
37
+
38
+ write(toSnake(name));
39
+ write('(');
40
+
41
+ for (const [i, arg] of args.entries()) {
42
+ if (i > 0)
43
+ write(', ');
44
+
45
+ traverse(arg);
46
+ }
47
+
48
+ write(')');
49
+ };
50
+
51
+ const printArg = (path, printer) => {
52
+ const {node} = path;
53
+ const {traverse} = printer;
21
54
 
22
- ctx.traverse(path);
55
+ if (isTSAsExpression(node))
56
+ return printAsExpression(path, printer);
57
+
58
+ if (isTableFunc(node))
59
+ return printTableFunc(path, printer);
60
+
61
+ traverse(path);
23
62
  };
24
63
 
25
64
  export const from = (path, {write, traverse}) => {
@@ -44,3 +83,4 @@ export const from = (path, {write, traverse}) => {
44
83
  traverse(clause);
45
84
  }
46
85
  };
86
+
@@ -0,0 +1,4 @@
1
+ SELECT dept, SUM(salary)
2
+ FROM emp
3
+ GROUP BY dept
4
+ HAVING SUM(salary) > 1000
@@ -0,0 +1,19 @@
1
+ [
2
+ select(
3
+ dept,
4
+ sum(
5
+ salary,
6
+ ),
7
+ from(
8
+ emp,
9
+ groupBy(
10
+ dept,
11
+ ),
12
+ having(
13
+ sum(
14
+ salary,
15
+ ) > 1000,
16
+ ),
17
+ ),
18
+ ),
19
+ ];
@@ -7,11 +7,13 @@ const printAsExpression = (path, {write, traverse}) => {
7
7
  write(` AS ${path.node.typeAnnotation.literal.value}`);
8
8
  };
9
9
 
10
- const printTable = (path, ctx) => {
10
+ const printTable = (path, printer) => {
11
+ const {traverse} = printer;
12
+
11
13
  if (isTSAsExpression(path.node))
12
- return printAsExpression(path, ctx);
14
+ return printAsExpression(path, printer);
13
15
 
14
- ctx.traverse(path);
16
+ traverse(path);
15
17
  };
16
18
 
17
19
  export const join = (path, {write, traverse}) => {
@@ -0,0 +1,3 @@
1
+ SELECT id
2
+ FROM users
3
+ LIMIT 10
@@ -0,0 +1,4 @@
1
+ SELECT id
2
+ FROM users
3
+ LIMIT 10
4
+ OFFSET 5
@@ -0,0 +1,12 @@
1
+ [
2
+ select(
3
+ id,
4
+ from(
5
+ users,
6
+ limit(
7
+ 10,
8
+ 5,
9
+ ),
10
+ ),
11
+ ),
12
+ ];
@@ -0,0 +1,11 @@
1
+ [
2
+ select(
3
+ id,
4
+ from(
5
+ users,
6
+ limit(
7
+ 10,
8
+ ),
9
+ ),
10
+ ),
11
+ ];
@@ -0,0 +1,12 @@
1
+ export const limit = (path, {write, traverse}) => {
2
+ const args = path.get('arguments');
3
+
4
+ write('LIMIT ');
5
+ traverse(args[0]);
6
+
7
+ if (args.length > 1) {
8
+ write.breakline();
9
+ write('OFFSET ');
10
+ traverse(args[1]);
11
+ }
12
+ };
@@ -0,0 +1,2 @@
1
+ SELECT MAX(price)
2
+ FROM products
@@ -0,0 +1 @@
1
+ select(max(price), from(products));
@@ -0,0 +1,5 @@
1
+ export const max = (path, {write, traverse}) => {
2
+ write('MAX(');
3
+ traverse(path.get('arguments')[0]);
4
+ write(')');
5
+ };
@@ -0,0 +1,2 @@
1
+ SELECT MIN(price)
2
+ FROM products
@@ -0,0 +1 @@
1
+ select(min(price), from(products));
@@ -0,0 +1,5 @@
1
+ export const min = (path, {write, traverse}) => {
2
+ write('MIN(');
3
+ traverse(path.get('arguments')[0]);
4
+ write(')');
5
+ };
@@ -0,0 +1,3 @@
1
+ SELECT *
2
+ FROM users
3
+ WHERE id NOT IN (1, 2, 3)
@@ -0,0 +1,3 @@
1
+ [
2
+ select('*', from(users, where(notInList(id, 1, 2, 3)))),
3
+ ];
@@ -0,0 +1,15 @@
1
+ export const notInList = (path, {write, traverse}) => {
2
+ const [head, ...items] = path.get('arguments');
3
+
4
+ traverse(head);
5
+ write(' NOT IN (');
6
+
7
+ for (let i = 0; i < items.length; i++) {
8
+ if (i > 0)
9
+ write(', ');
10
+
11
+ traverse(items[i]);
12
+ }
13
+
14
+ write(')');
15
+ };
@@ -0,0 +1,3 @@
1
+ SELECT id
2
+ FROM users
3
+ ORDER BY name
@@ -0,0 +1,3 @@
1
+ SELECT id
2
+ FROM users
3
+ ORDER BY name, id DESC
@@ -0,0 +1,14 @@
1
+ [
2
+ select(
3
+ id,
4
+ from(
5
+ users,
6
+ orderBy(
7
+ name,
8
+ desc(
9
+ id,
10
+ ),
11
+ ),
12
+ ),
13
+ ),
14
+ ];
@@ -0,0 +1,11 @@
1
+ [
2
+ select(
3
+ id,
4
+ from(
5
+ users,
6
+ orderBy(
7
+ name,
8
+ ),
9
+ ),
10
+ ),
11
+ ];
@@ -0,0 +1,12 @@
1
+ export const orderBy = (path, {write, traverse}) => {
2
+ const args = path.get('arguments');
3
+
4
+ write('ORDER BY ');
5
+
6
+ for (const [i, arg] of args.entries()) {
7
+ if (i > 0)
8
+ write(', ');
9
+
10
+ traverse(arg);
11
+ }
12
+ };
@@ -7,11 +7,13 @@ const printAsExpression = (path, {write, traverse}) => {
7
7
  write(` AS ${path.node.typeAnnotation.literal.value}`);
8
8
  };
9
9
 
10
- const printItem = (path, ctx) => {
10
+ const printItem = (path, printer) => {
11
+ const {traverse} = printer;
12
+
11
13
  if (isTSAsExpression(path.node))
12
- return printAsExpression(path, ctx);
14
+ return printAsExpression(path, printer);
13
15
 
14
- ctx.traverse(path);
16
+ traverse(path);
15
17
  };
16
18
 
17
19
  export const returning = (path, {write, traverse}) => {
@@ -7,14 +7,17 @@ const printAsExpression = (path, {write, traverse}) => {
7
7
  write(` AS ${path.node.typeAnnotation.literal.value}`);
8
8
  };
9
9
 
10
- const printItem = (path, ctx) => {
10
+ const printItem = (path, printer) => {
11
+ const {traverse} = printer;
12
+
11
13
  if (isTSAsExpression(path.node))
12
- return printAsExpression(path, ctx);
14
+ return printAsExpression(path, printer);
13
15
 
14
- ctx.traverse(path);
16
+ traverse(path);
15
17
  };
16
18
 
17
- export const select = (path, {write, traverse}) => {
19
+ export const select = (path, printer) => {
20
+ const {write, traverse} = printer;
18
21
  const args = path.get('arguments');
19
22
  const lastArg = args.at(-1);
20
23
  const hasFrom = lastArg?.node?.callee?.name === 'from';
@@ -27,10 +30,7 @@ export const select = (path, {write, traverse}) => {
27
30
  if (i > 0)
28
31
  write(', ');
29
32
 
30
- printItem(cols[i], {
31
- write,
32
- traverse,
33
- });
33
+ printItem(cols[i], printer);
34
34
  }
35
35
 
36
36
  if (fromArg) {
@@ -38,3 +38,4 @@ export const select = (path, {write, traverse}) => {
38
38
  traverse(fromArg);
39
39
  }
40
40
  };
41
+
@@ -0,0 +1,2 @@
1
+ SELECT SUM(amount)
2
+ FROM orders
@@ -0,0 +1 @@
1
+ select(sum(amount), from(orders));
@@ -0,0 +1,5 @@
1
+ export const sum = (path, {write, traverse}) => {
2
+ write('SUM(');
3
+ traverse(path.get('arguments')[0]);
4
+ write(')');
5
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "happy-sql",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "type": "module",
5
5
  "description": "sql to js ast parser and printer",
6
6
  "exports": {