prettier-plugin-sql-cst
Advanced tools
Comparing version 0.2.0 to 0.3.0
@@ -6,2 +6,3 @@ "use strict"; | ||
var printSql_1 = require("./printSql"); | ||
var embedJson_1 = require("./embedJson"); | ||
var utils_1 = require("./utils"); | ||
@@ -15,3 +16,3 @@ var transformCst_1 = require("./transform/transformCst"); | ||
name: "SQLite SQL", | ||
parsers: ["sql-parser-cst-sqlite"], | ||
parsers: ["sqlite"], | ||
}, | ||
@@ -21,3 +22,3 @@ { | ||
name: "BigQuery SQL", | ||
parsers: ["sql-parser-cst-bigquery"], | ||
parsers: ["bigquery"], | ||
}, | ||
@@ -39,4 +40,4 @@ ]; | ||
exports.parsers = { | ||
"sql-parser-cst-sqlite": createParser("sqlite"), | ||
"sql-parser-cst-bigquery": createParser("bigquery"), | ||
sqlite: createParser("sqlite"), | ||
bigquery: createParser("bigquery"), | ||
}; | ||
@@ -46,2 +47,3 @@ exports.printers = { | ||
print: printSql_1.printSql, | ||
embed: embedJson_1.embedJson, | ||
printComment: function (path) { | ||
@@ -48,0 +50,0 @@ return path.getValue().text; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isKeyword = exports.isCreateTableStmt = exports.isFuncCall = exports.isValuesClause = void 0; | ||
exports.isStringLiteral = exports.isJsonLiteral = exports.isEmpty = exports.isKeyword = exports.isCreateTableStmt = exports.isFuncCall = exports.isValuesClause = void 0; | ||
var utils_1 = require("./utils"); | ||
@@ -14,1 +14,4 @@ var is = function (type) { | ||
exports.isKeyword = is("keyword"); | ||
exports.isEmpty = is("empty"); | ||
exports.isJsonLiteral = is("json_literal"); | ||
exports.isStringLiteral = is("string_literal"); |
@@ -9,3 +9,3 @@ "use strict"; | ||
since: "0.1.0", | ||
default: "preserve", | ||
default: "upper", | ||
description: "Enforces upper/lower case for SQL keywords", | ||
@@ -21,14 +21,2 @@ choices: [ | ||
}, | ||
sqlAliasAs: { | ||
type: "choice", | ||
category: "SQL", | ||
since: "0.1.1", | ||
default: "preserve", | ||
description: "Enforce or forbid use of AS keyword in aliases", | ||
choices: [ | ||
{ value: "preserve", description: "keeps existing style" }, | ||
{ value: "always", description: "always includes AS keyword" }, | ||
{ value: "never", description: "never include AS keyword" }, | ||
], | ||
}, | ||
}; |
"use strict"; | ||
var _a; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.containsNewline = exports.join = exports.lineSuffix = exports.group = exports.indent = exports.softline = exports.hardline = exports.line = void 0; | ||
exports.containsNewline = exports.join = exports.stripTrailingHardline = exports.ifBreak = exports.lineSuffix = exports.group = exports.indent = exports.softline = exports.hardline = exports.line = void 0; | ||
var prettier_1 = require("prettier"); | ||
var utils_1 = require("./utils"); | ||
exports.line = (_a = prettier_1.doc.builders, _a.line), exports.hardline = _a.hardline, exports.softline = _a.softline, exports.indent = _a.indent, exports.group = _a.group, exports.lineSuffix = _a.lineSuffix; | ||
exports.line = (_a = prettier_1.doc.builders, _a.line), exports.hardline = _a.hardline, exports.softline = _a.softline, exports.indent = _a.indent, exports.group = _a.group, exports.lineSuffix = _a.lineSuffix, exports.ifBreak = _a.ifBreak; | ||
var origJoin = prettier_1.doc.builders.join; | ||
exports.stripTrailingHardline = prettier_1.doc.utils.stripTrailingHardline; | ||
/** Improved join() that also accepts a non-array docs parameter */ | ||
@@ -10,0 +11,0 @@ var join = function (sep, docs) { |
@@ -15,2 +15,5 @@ "use strict"; | ||
data_type: function (print) { return __spreadArray([print.spaced("nameKw")], print(["params"]), true); }, | ||
generic_type_params: function (print) { return ["<", print("params"), ">"]; }, | ||
array_type_param: function (print) { return print("dataType"); }, | ||
struct_type_param: function (print) { return print.spaced(["name", "dataType"]); }, | ||
}; |
@@ -15,6 +15,21 @@ "use strict"; | ||
var node_utils_1 = require("../node_utils"); | ||
var utils_1 = require("../utils"); | ||
exports.exprMap = { | ||
list_expr: function (print, node, path) { | ||
var parent = path.getParentNode(); | ||
return (0, print_utils_1.join)([",", (0, node_utils_1.isValuesClause)(parent) ? print_utils_1.hardline : print_utils_1.line], print("items").map(function (it) { return (0, print_utils_1.group)(it); })); | ||
var children = print("items").map(function (it) { return (0, print_utils_1.group)(it); }); | ||
var lineType = (0, node_utils_1.isValuesClause)(parent) ? print_utils_1.hardline : print_utils_1.line; | ||
// When last item is type:empty, we're dealing with a trailing comma. | ||
// Don't add a space (or newline) after it. | ||
// We still want to print it though, as it might have comments attached. | ||
if ((0, node_utils_1.isEmpty)((0, utils_1.last)(node.items))) { | ||
return [ | ||
(0, print_utils_1.join)([",", lineType], children.slice(0, -1)), | ||
",", | ||
(0, utils_1.last)(children), | ||
]; | ||
} | ||
else { | ||
return (0, print_utils_1.join)([",", lineType], children); | ||
} | ||
}, | ||
@@ -32,3 +47,5 @@ paren_expr: function (print, node, path) { | ||
}, | ||
prefix_op_expr: function (print) { return print.spaced(["operator", "expr"]); }, | ||
prefix_op_expr: function (print, node) { | ||
return ((0, utils_1.isString)(node.operator) ? print : print.spaced)(["operator", "expr"]); | ||
}, | ||
postfix_op_expr: function (print) { return print.spaced(["expr", "operator"]); }, | ||
@@ -66,2 +83,13 @@ between_expr: function (print) { | ||
raise_expr: function (print) { return print(["raiseKw", "args"]); }, | ||
interval_expr: function (print) { return print.spaced(["intervalKw", "expr", "unit"]); }, | ||
interval_unit_range: function (print) { | ||
return print.spaced(["fromUnitKw", "toKw", "toUnitKw"]); | ||
}, | ||
array_expr: function (print) { | ||
return (0, print_utils_1.group)(["[", (0, print_utils_1.indent)([print_utils_1.softline, print("expr")]), print_utils_1.softline, "]"]); | ||
}, | ||
struct_expr: function (print) { | ||
return (0, print_utils_1.group)(["(", (0, print_utils_1.indent)([print_utils_1.softline, print("expr")]), print_utils_1.softline, ")"]); | ||
}, | ||
typed_expr: function (print) { return print(["dataType", "expr"]); }, | ||
number_literal: function (print) { return print("text"); }, | ||
@@ -71,2 +99,9 @@ boolean_literal: function (print) { return print("valueKw"); }, | ||
null_literal: function (print) { return print("nullKw"); }, | ||
numeric_literal: function (print) { return print.spaced(["numericKw", "string"]); }, | ||
bignumeric_literal: function (print) { return print.spaced(["bignumericKw", "string"]); }, | ||
date_literal: function (print) { return print.spaced(["dateKw", "string"]); }, | ||
time_literal: function (print) { return print.spaced(["timeKw", "string"]); }, | ||
datetime_literal: function (print) { return print.spaced(["datetimeKw", "string"]); }, | ||
timestamp_literal: function (print) { return print.spaced(["timestampKw", "string"]); }, | ||
json_literal: function (print) { return print.spaced(["jsonKw", "string"]); }, | ||
identifier: function (print) { return print("text"); }, | ||
@@ -73,0 +108,0 @@ }; |
@@ -6,17 +6,20 @@ "use strict"; | ||
exports.programMap = { | ||
program: function (print, node, path) { return path.map(printLineWith(print), "statements"); }, | ||
program: function (print, node) { return [ | ||
print("statements").map(function (doc, i) { | ||
return printStatement(doc, i, node.statements); | ||
}), | ||
print_utils_1.hardline, | ||
]; }, | ||
}; | ||
var printLineWith = function (print) { | ||
return function (childPath, i, all) { | ||
var node = childPath.getValue(); | ||
if (i === 0) { | ||
return print(childPath); | ||
} | ||
else if (i < all.length - 1 || node.type !== "empty") { | ||
return [";", print_utils_1.hardline, print_utils_1.hardline, print(childPath)]; | ||
} | ||
else { | ||
return [";", print(childPath)]; | ||
} | ||
}; | ||
var printStatement = function (doc, i, statements) { | ||
var node = statements[i]; | ||
if (i === 0) { | ||
return doc; | ||
} | ||
else if (i < statements.length - 1 || node.type !== "empty") { | ||
return [";", print_utils_1.hardline, print_utils_1.hardline, doc]; | ||
} | ||
else { | ||
return [";", doc]; | ||
} | ||
}; |
@@ -27,3 +27,3 @@ "use strict"; | ||
return (0, print_utils_1.group)([ | ||
print.spaced(["selectKw", "distinctKw"]), | ||
print.spaced(["selectKw", "distinctKw", "asStructOrValueKw"]), | ||
(0, print_utils_1.indent)([print_utils_1.line, print("columns")]), | ||
@@ -70,2 +70,3 @@ ]); | ||
}, | ||
group_by_rollup: function (print) { return print(["rollupKw", "columns"]); }, | ||
partition_by_clause: function (print) { | ||
@@ -80,2 +81,5 @@ return (0, print_utils_1.group)([ | ||
}, | ||
qualify_clause: function (print) { | ||
return (0, print_utils_1.group)([print("qualifyKw"), (0, print_utils_1.indent)([print_utils_1.line, print("expr")])]); | ||
}, | ||
returning_clause: function (print) { | ||
@@ -82,0 +86,0 @@ return (0, print_utils_1.group)([print("returningKw"), (0, print_utils_1.indent)([print_utils_1.line, print("columns")])]); |
"use strict"; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.processAliasAs = void 0; | ||
var sql_parser_cst_1 = require("sql-parser-cst"); | ||
var processAliasAs = function (cst, options) { | ||
// Adds AS keyword to aliases if none exists | ||
var processAliasAs = function (cst) { | ||
var mutateAliases = (0, sql_parser_cst_1.cstVisitor)({ | ||
alias: function (node) { | ||
var _a, _b; | ||
switch (options.sqlAliasAs) { | ||
case "preserve": | ||
// do nothing | ||
break; | ||
case "always": | ||
// Add AS keyword if none exists | ||
node.asKw = node.asKw || { type: "keyword", name: "AS", text: "AS" }; | ||
break; | ||
case "never": | ||
// Remove AS keyword and ensure comments attached to it don't get lost | ||
if (node.asKw && (((_a = node.leading) === null || _a === void 0 ? void 0 : _a.length) || ((_b = node.trailing) === null || _b === void 0 ? void 0 : _b.length))) { | ||
var comments = __spreadArray(__spreadArray([], (node.leading || []), true), (node.trailing || []), true); | ||
node.alias.leading = __spreadArray(__spreadArray([], comments, true), (node.alias.leading || []), true); | ||
} | ||
node.asKw = undefined; | ||
} | ||
node.asKw = node.asKw || { type: "keyword", name: "AS", text: "AS" }; | ||
}, | ||
@@ -35,0 +11,0 @@ }); |
@@ -6,3 +6,3 @@ "use strict"; | ||
var aliasAs_1 = require("./aliasAs"); | ||
var transformCst = function (cst, options) { return (0, comments_1.moveCommentsToRoot)((0, aliasAs_1.processAliasAs)(cst, options)); }; | ||
var transformCst = function (cst, options) { return (0, comments_1.moveCommentsToRoot)((0, aliasAs_1.processAliasAs)(cst)); }; | ||
exports.transformCst = transformCst; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.arrayWrap = exports.isNode = exports.isEmptyArray = exports.isArray = exports.isObject = exports.isString = exports.isDefined = void 0; | ||
exports.last = exports.arrayWrap = exports.isNode = exports.isEmptyArray = exports.isArray = exports.isObject = exports.isString = exports.isDefined = void 0; | ||
var isDefined = function (value) { | ||
@@ -29,1 +29,3 @@ return value !== undefined; | ||
exports.arrayWrap = arrayWrap; | ||
var last = function (arr) { return arr[arr.length - 1]; }; | ||
exports.last = last; |
{ | ||
"name": "prettier-plugin-sql-cst", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "Prettier plugin for SQL", | ||
@@ -32,3 +32,3 @@ "author": "Rene Saarsoo <nene@triin.net>", | ||
"prettier": "^2.8.2", | ||
"sql-parser-cst": "^0.11.0" | ||
"sql-parser-cst": "^0.11.1" | ||
}, | ||
@@ -35,0 +35,0 @@ "devDependencies": { |
@@ -43,2 +43,20 @@ # Prettier plugin SQL-CST [![npm version](https://img.shields.io/npm/v/prettier-plugin-sql-cst)](https://www.npmjs.com/package/prettier-plugin-sql-cst) ![build status](https://github.com/nene/prettier-plugin-sql-cst/actions/workflows/build.yml/badge.svg) | ||
## Formatting philosophy | ||
- Adapt formatting based on expression length. | ||
- Stick to one style and avoid configuration options. | ||
- Format embedded languages (like JSON data and JavaScript programs). | ||
- When unsure, preserve existing syntax. | ||
## Non-whitespace formatting | ||
Currently this plugin preserves most of the syntax elements | ||
and concentrates mainly on the layout of whitespace. | ||
For example it does not add/remove paratheses. | ||
There are some opinionated non-whitespace changes though: | ||
- UPPERCASE all keywords. | ||
- Add `AS` keyword to all alias definitions. | ||
## Getting started | ||
@@ -55,2 +73,27 @@ | ||
## Choosing an SQL dialect | ||
By default the plugin will determine SQL dialect based on file extension: | ||
- `.sql` or `.sqlite` - SQLite | ||
- `.bigquery` - BigQuery | ||
You can override this behavior with a prettier configuration: | ||
```json | ||
{ | ||
"overrides": [ | ||
{ | ||
"files": ["*.sql"], | ||
"options": { "parser": "bigquery" } | ||
} | ||
] | ||
} | ||
``` | ||
The plugin provides the following parsers: | ||
- `sqlite` | ||
- `bigquery` | ||
## Configuration | ||
@@ -61,6 +104,5 @@ | ||
| API Option | Default | Description | | ||
| ---------------- | :--------: | ------------------------------------------------------ | | ||
| `sqlKeywordCase` | `preserve` | Converts SQL keywords to `upper` or `lower` case. | | ||
| `sqlAliasAs` | `preserve` | Uses AS keyword in aliases either `always` or `never`. | | ||
| API Option | Default | Description | | ||
| ---------------- | :-----: | ------------------------------------------------------------------------- | | ||
| `sqlKeywordCase` | `upper` | Converts SQL keywords to `upper` or `lower` case, or `preserve` existing. | | ||
@@ -81,18 +123,2 @@ ## Limitations and development status | ||
Unlike Prettier for JavaScript, this plugin currently preserves all the syntax elements. | ||
For example it does not add/remove paratheses or modify the case of keywords (by default). | ||
It only manipulates whitespace. | ||
This will likely change in the future, with the goal of being more opinionated. | ||
Some possibilities: | ||
- capitalize all keywords | ||
- ensure all alias definitions use the `AS` keyword. | ||
- ensure consistent use of quotes (e.g. always quote keywords) | ||
- eliminate redundant parenthesis. | ||
The exact formatting style is also very much still in flux. | ||
The overall goal is to have no options to configure different styles, | ||
but rather to develop one opinionated style of formatting SQL. | ||
[prettier]: https://prettier.io/ | ||
@@ -99,0 +125,0 @@ [printWidth]: https://prettier.io/docs/en/options.html#print-width |
78935
34
912
126
Updatedsql-parser-cst@^0.11.1