Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

sql-formatter

Package Overview
Dependencies
Maintainers
2
Versions
148
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

sql-formatter - npm Package Compare versions

Comparing version 4.0.2 to 6.0.0-beta.1

bin/sql-formatter-cli.js

586

lib/core/Formatter.js

@@ -8,4 +8,2 @@ "use strict";

var _tokenTypes = _interopRequireDefault(require("./tokenTypes"));
var _Indentation = _interopRequireDefault(require("./Indentation"));

@@ -21,6 +19,20 @@

var _formatCommaPositions = _interopRequireDefault(require("./formatCommaPositions"));
var _formatAliasPositions = _interopRequireDefault(require("./formatAliasPositions"));
var _tabularStyle = require("./tabularStyle");
var _AliasAs = _interopRequireDefault(require("./AliasAs"));
var _AsTokenFactory = _interopRequireDefault(require("./AsTokenFactory"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

@@ -30,23 +42,41 @@

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var TABULAR_INDENT = ' '.repeat(10);
/** Main formatter class that produces a final output string from list of tokens */
var Formatter = /*#__PURE__*/function () {
/**
* @param {Object} cfg
* @param {String} cfg.language
* @param {String} cfg.indent
* @param {Boolean} cfg.uppercase
* @param {Integer} cfg.linesBetweenQueries
* @param {Object} cfg.params
*/
function Formatter(cfg) {
_classCallCheck(this, Formatter);
_defineProperty(this, "cfg", void 0);
_defineProperty(this, "indentation", void 0);
_defineProperty(this, "inlineBlock", void 0);
_defineProperty(this, "aliasAs", void 0);
_defineProperty(this, "params", void 0);
_defineProperty(this, "asTokenFactory", void 0);
_defineProperty(this, "currentNewline", true);
_defineProperty(this, "previousReservedToken", _token.EOF_TOKEN);
_defineProperty(this, "previousCommandToken", _token.EOF_TOKEN);
_defineProperty(this, "tokens", []);
_defineProperty(this, "index", -1);
this.cfg = cfg;
this.indentation = new _Indentation["default"](this.cfg.indent);
this.inlineBlock = new _InlineBlock["default"]();
this.indentation = new _Indentation["default"](this.isTabularStyle() ? TABULAR_INDENT : this.cfg.indent);
this.inlineBlock = new _InlineBlock["default"](this.cfg.lineWidth);
this.aliasAs = new _AliasAs["default"](this.cfg.aliasAs, this);
this.params = new _Params["default"](this.cfg.params);
this.previousReservedToken = {};
this.tokens = [];
this.index = 0;
this.asTokenFactory = new _AsTokenFactory["default"](this.cfg.keywordCase);
}

@@ -65,9 +95,5 @@ /**

* Reprocess and modify a token based on parsed context.
*
* @param {Object} token The token to modify
* @param {String} token.type
* @param {String} token.value
* @return {Object} new token or the original
* @return {String} token.type
* @return {String} token.value
* Subclasses can override this to modify tokens during formatting.
* @param {Token} token - The token to modify
* @return {Token} new token or the original
*/

@@ -78,10 +104,8 @@

value: function tokenOverride(token) {
// subclasses can override this to modify tokens during formatting
return token;
}
/**
* Formats whitespace in a SQL string to make it easier to read.
*
* @param {String} query The SQL query string
* @return {String} formatted query
* Formats an SQL query.
* @param {string} query - The SQL query string to be formatted
* @return {string} The formatter query
*/

@@ -93,52 +117,192 @@

this.tokens = this.tokenizer().tokenize(query);
this.asTokenFactory = new _AsTokenFactory["default"](this.cfg.keywordCase, this.tokens);
var formattedQuery = this.getFormattedQueryFromTokens();
return formattedQuery.trim();
var finalQuery = this.postFormat(formattedQuery);
return finalQuery.replace(/^\n*/, '').trimEnd();
}
/**
* Does post-processing on the formatted query.
*/
}, {
key: "postFormat",
value: function postFormat(query) {
if (this.cfg.tabulateAlias) {
query = (0, _formatAliasPositions["default"])(query);
}
if (this.cfg.commaPosition === 'before' || this.cfg.commaPosition === 'tabular') {
query = (0, _formatCommaPositions["default"])(query, this.cfg);
}
return query;
}
/**
* Performs main construction of query from token list, delegates to other methods for formatting based on token criteria
*/
}, {
key: "getFormattedQueryFromTokens",
value: function getFormattedQueryFromTokens() {
var _this = this;
var formattedQuery = '';
this.tokens.forEach(function (token, index) {
_this.index = index;
token = _this.tokenOverride(token);
if (token.type === _tokenTypes["default"].LINE_COMMENT) {
formattedQuery = _this.formatLineComment(token, formattedQuery);
} else if (token.type === _tokenTypes["default"].BLOCK_COMMENT) {
formattedQuery = _this.formatBlockComment(token, formattedQuery);
} else if (token.type === _tokenTypes["default"].RESERVED_TOP_LEVEL) {
formattedQuery = _this.formatTopLevelReservedWord(token, formattedQuery);
_this.previousReservedToken = token;
} else if (token.type === _tokenTypes["default"].RESERVED_TOP_LEVEL_NO_INDENT) {
formattedQuery = _this.formatTopLevelReservedWordNoIndent(token, formattedQuery);
_this.previousReservedToken = token;
} else if (token.type === _tokenTypes["default"].RESERVED_NEWLINE) {
formattedQuery = _this.formatNewlineReservedWord(token, formattedQuery);
_this.previousReservedToken = token;
} else if (token.type === _tokenTypes["default"].RESERVED) {
formattedQuery = _this.formatWithSpaces(token, formattedQuery);
_this.previousReservedToken = token;
} else if (token.type === _tokenTypes["default"].OPEN_PAREN) {
formattedQuery = _this.formatOpeningParentheses(token, formattedQuery);
} else if (token.type === _tokenTypes["default"].CLOSE_PAREN) {
formattedQuery = _this.formatClosingParentheses(token, formattedQuery);
} else if (token.type === _tokenTypes["default"].PLACEHOLDER) {
formattedQuery = _this.formatPlaceholder(token, formattedQuery);
} else if (token.value === ',') {
formattedQuery = _this.formatComma(token, formattedQuery);
} else if (token.value === ':') {
formattedQuery = _this.formatWithSpaceAfter(token, formattedQuery);
} else if (token.value === '.') {
formattedQuery = _this.formatWithoutSpaces(token, formattedQuery);
} else if (token.value === ';') {
formattedQuery = _this.formatQuerySeparator(token, formattedQuery);
for (this.index = 0; this.index < this.tokens.length; this.index++) {
var token = this.tokenOverride(this.tokens[this.index]); // if token is a Reserved Keyword, Command, Binary Command, Dependent Clause, Logical Operator
if ((0, _token.isReserved)(token)) {
this.previousReservedToken = token;
if (token.type !== _token.TokenType.RESERVED_KEYWORD && token.type !== _token.TokenType.RESERVED_JOIN_CONDITION) {
// convert Reserved Command or Logical Operator to tabular format if needed
token = (0, _tabularStyle.toTabularToken)(token, this.cfg.indentStyle);
}
if (token.type === _token.TokenType.RESERVED_COMMAND) {
this.previousCommandToken = token;
}
}
if (token.type === _token.TokenType.LINE_COMMENT) {
formattedQuery = this.formatLineComment(token, formattedQuery);
} else if (token.type === _token.TokenType.BLOCK_COMMENT) {
formattedQuery = this.formatBlockComment(token, formattedQuery);
} else if (token.type === _token.TokenType.RESERVED_COMMAND) {
this.currentNewline = this.checkNewline(token);
formattedQuery = this.formatCommand(token, formattedQuery);
} else if (token.type === _token.TokenType.RESERVED_BINARY_COMMAND) {
formattedQuery = this.formatBinaryCommand(token, formattedQuery);
} else if (token.type === _token.TokenType.RESERVED_DEPENDENT_CLAUSE) {
formattedQuery = this.formatDependentClause(token, formattedQuery);
} else if (token.type === _token.TokenType.RESERVED_JOIN_CONDITION) {
formattedQuery = this.formatJoinCondition(token, formattedQuery);
} else if (token.type === _token.TokenType.RESERVED_LOGICAL_OPERATOR) {
formattedQuery = this.formatLogicalOperator(token, formattedQuery);
} else if (token.type === _token.TokenType.RESERVED_KEYWORD) {
formattedQuery = this.formatKeyword(token, formattedQuery);
} else if (token.type === _token.TokenType.BLOCK_START) {
formattedQuery = this.formatBlockStart(token, formattedQuery);
} else if (token.type === _token.TokenType.BLOCK_END) {
formattedQuery = this.formatBlockEnd(token, formattedQuery);
} else if (token.type === _token.TokenType.PLACEHOLDER) {
formattedQuery = this.formatPlaceholder(token, formattedQuery);
} else if (token.type === _token.TokenType.OPERATOR) {
formattedQuery = this.formatOperator(token, formattedQuery);
} else {
formattedQuery = _this.formatWithSpaces(token, formattedQuery);
formattedQuery = this.formatWord(token, formattedQuery);
}
});
return formattedQuery;
}
return (0, _tabularStyle.replaceTabularPlaceholders)(formattedQuery);
}
/**
* Formats word tokens + any potential AS tokens for aliases
*/
}, {
key: "formatWord",
value: function formatWord(token, query) {
var finalQuery = query;
if (this.aliasAs.shouldAddBefore(token)) {
finalQuery = this.formatWithSpaces(this.asTokenFactory.token(), finalQuery);
}
finalQuery = this.formatWithSpaces(token, finalQuery);
if (this.aliasAs.shouldAddAfter()) {
finalQuery = this.formatWithSpaces(this.asTokenFactory.token(), finalQuery);
}
return finalQuery;
}
/**
* Checks if a newline should currently be inserted
*/
}, {
key: "checkNewline",
value: function checkNewline(token) {
var nextTokens = this.tokensUntilNextCommandOrQueryEnd(); // auto break if SELECT includes CASE statements
if (this.isWithinSelect() && nextTokens.some(_token.isToken.CASE)) {
return true;
}
switch (this.cfg.newline) {
case 'always':
return true;
case 'never':
return false;
case 'lineWidth':
return this.inlineWidth(token, nextTokens) > this.cfg.lineWidth;
default:
// newline mode is a number
return this.countClauses(nextTokens) > this.cfg.newline || this.inlineWidth(token, nextTokens) > this.cfg.lineWidth;
}
}
}, {
key: "inlineWidth",
value: function inlineWidth(token, tokens) {
var tokensString = tokens.map(function (_ref) {
var value = _ref.value;
return value === ',' ? value + ' ' : value;
}).join('');
return "".concat(token.whitespaceBefore).concat(token.value, " ").concat(tokensString).length;
}
/**
* Counts comma-separated clauses (doesn't count commas inside blocks)
* Note: There's always at least one clause.
*/
}, {
key: "countClauses",
value: function countClauses(tokens) {
var count = 1;
var openBlocks = 0;
var _iterator = _createForOfIteratorHelper(tokens),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var _step$value = _step.value,
type = _step$value.type,
value = _step$value.value;
if (value === ',' && openBlocks === 0) {
count++;
}
if (type === _token.TokenType.BLOCK_START) {
openBlocks++;
}
if (type === _token.TokenType.BLOCK_END) {
openBlocks--;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
return count;
}
/** get all tokens between current token and next Reserved Command or query end */
}, {
key: "tokensUntilNextCommandOrQueryEnd",
value: function tokensUntilNextCommandOrQueryEnd() {
var tail = this.tokens.slice(this.index + 1);
return tail.slice(0, tail.length ? tail.findIndex(function (token) {
return (0, _token.isCommand)(token) || token.value === ';';
}) : undefined);
}
/** Formats a line comment onto query */
}, {
key: "formatLineComment",

@@ -148,2 +312,4 @@ value: function formatLineComment(token, query) {

}
/** Formats a block comment onto query */
}, {

@@ -154,2 +320,4 @@ key: "formatBlockComment",

}
/** Aligns comment to current indentation level */
}, {

@@ -160,28 +328,128 @@ key: "indentComment",

}
/**
* Formats a Reserved Command onto query, increasing indentation level where necessary
*/
}, {
key: "formatTopLevelReservedWordNoIndent",
value: function formatTopLevelReservedWordNoIndent(token, query) {
key: "formatCommand",
value: function formatCommand(token, query) {
this.indentation.decreaseTopLevel();
query = this.addNewline(query); // indent tabular formats, except when preceding a (
if (this.isTabularStyle()) {
if (this.tokenLookAhead().value !== '(') {
this.indentation.increaseTopLevel();
}
} else {
this.indentation.increaseTopLevel();
}
query += this.equalizeWhitespace(this.show(token)); // print token onto query
if (this.currentNewline && !this.isTabularStyle()) {
query = this.addNewline(query);
} else {
query += ' ';
}
return query;
}
/**
* Formats a Reserved Binary Command onto query, joining neighbouring tokens
*/
}, {
key: "formatBinaryCommand",
value: function formatBinaryCommand(token, query) {
var isJoin = /JOIN/i.test(token.value); // check if token contains JOIN
if (!isJoin || this.isTabularStyle()) {
// decrease for boolean set operators or in tabular mode
this.indentation.decreaseTopLevel();
}
query = this.addNewline(query) + this.equalizeWhitespace(this.show(token));
return this.addNewline(query);
return isJoin ? query + ' ' : this.addNewline(query);
}
/**
* Formats a Reserved Keyword onto query, skipping AS if disabled
*/
}, {
key: "formatTopLevelReservedWord",
value: function formatTopLevelReservedWord(token, query) {
this.indentation.decreaseTopLevel();
query = this.addNewline(query);
this.indentation.increaseTopLevel();
query += this.equalizeWhitespace(this.show(token));
return this.addNewline(query);
key: "formatKeyword",
value: function formatKeyword(token, query) {
if (_token.isToken.AS(token) && this.aliasAs.shouldRemove()) {
return query;
}
return this.formatWithSpaces(token, query);
}
/**
* Formats a Reserved Dependent Clause token onto query, supporting the keyword that precedes it
*/
}, {
key: "formatNewlineReservedWord",
value: function formatNewlineReservedWord(token, query) {
if ((0, _token.isAnd)(token) && (0, _token.isBetween)(this.tokenLookBehind(2))) {
key: "formatDependentClause",
value: function formatDependentClause(token, query) {
return this.addNewline(query) + this.equalizeWhitespace(this.show(token)) + ' ';
} // Formats ON and USING keywords
}, {
key: "formatJoinCondition",
value: function formatJoinCondition(token, query) {
return query + this.equalizeWhitespace(this.show(token)) + ' ';
}
/**
* Formats an Operator onto query, following rules for specific characters
*/
}, {
key: "formatOperator",
value: function formatOperator(token, query) {
// special operator
if (token.value === ',') {
return this.formatComma(token, query);
} else if (token.value === ';') {
return this.formatQuerySeparator(token, query);
} else if (['$', '['].includes(token.value)) {
return this.formatWithSpaces(token, query, 'before');
} else if ([':', ']'].includes(token.value)) {
return this.formatWithSpaces(token, query, 'after');
} else if (['.', '{', '}', '`'].includes(token.value)) {
return this.formatWithoutSpaces(token, query);
} // regular operator
if (this.cfg.denseOperators && this.tokenLookBehind().type !== _token.TokenType.RESERVED_COMMAND) {
// do not trim whitespace if SELECT *
return this.formatWithoutSpaces(token, query);
}
return this.formatWithSpaces(token, query);
}
/**
* Formats a Logical Operator onto query, joining boolean conditions
*/
}, {
key: "formatLogicalOperator",
value: function formatLogicalOperator(token, query) {
// ignore AND when BETWEEN x [AND] y
if (_token.isToken.AND(token) && _token.isToken.BETWEEN(this.tokenLookBehind(2))) {
return this.formatWithSpaces(token, query);
}
return this.addNewline(query) + this.equalizeWhitespace(this.show(token)) + ' ';
} // Replace any sequence of whitespace characters with single space
if (this.isTabularStyle()) {
this.indentation.decreaseTopLevel();
}
if (this.cfg.logicalOperatorNewline === 'before') {
return (this.currentNewline ? this.addNewline(query) : query) + this.equalizeWhitespace(this.show(token)) + ' ';
} else {
query += this.show(token);
return this.currentNewline ? this.addNewline(query) : query;
}
}
/** Replace any sequence of whitespace characters with single space */
}, {

@@ -191,39 +459,73 @@ key: "equalizeWhitespace",

return string.replace(/[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+/g, ' ');
} // Opening parentheses increase the block indent level and start a new line
}
/**
* Formats a Block Start token (left paren/bracket/brace, CASE) onto query, beginning an Inline Block or increasing indentation where necessary
*/
}, {
key: "formatOpeningParentheses",
value: function formatOpeningParentheses(token, query) {
var _preserveWhitespaceFo, _this$tokenLookBehind;
key: "formatBlockStart",
value: function formatBlockStart(token, query) {
if (_token.isToken.CASE(token)) {
query = this.formatWithSpaces(token, query);
} else {
var _token$whitespaceBefo;
// Take out the preceding space unless there was whitespace there in the original query
// or another opening parens or line comment
var preserveWhitespaceFor = (_preserveWhitespaceFo = {}, _defineProperty(_preserveWhitespaceFo, _tokenTypes["default"].OPEN_PAREN, true), _defineProperty(_preserveWhitespaceFo, _tokenTypes["default"].LINE_COMMENT, true), _defineProperty(_preserveWhitespaceFo, _tokenTypes["default"].OPERATOR, true), _preserveWhitespaceFo);
// Take out the preceding space unless there was whitespace there in the original query
// or another opening parens or line comment
var preserveWhitespaceFor = [_token.TokenType.BLOCK_START, _token.TokenType.LINE_COMMENT, _token.TokenType.OPERATOR];
if (token.whitespaceBefore.length === 0 && !preserveWhitespaceFor[(_this$tokenLookBehind = this.tokenLookBehind()) === null || _this$tokenLookBehind === void 0 ? void 0 : _this$tokenLookBehind.type]) {
query = (0, _utils.trimSpacesEnd)(query);
if (((_token$whitespaceBefo = token.whitespaceBefore) === null || _token$whitespaceBefo === void 0 ? void 0 : _token$whitespaceBefo.length) === 0 && !preserveWhitespaceFor.includes(this.tokenLookBehind().type)) {
query = (0, _utils.trimSpacesEnd)(query);
} else if (!this.cfg.newlineBeforeOpenParen) {
query = query.trimEnd() + ' ';
}
query += this.show(token);
this.inlineBlock.beginIfPossible(this.tokens, this.index);
}
query += this.show(token);
this.inlineBlock.beginIfPossible(this.tokens, this.index);
if (!this.inlineBlock.isActive()) {
this.indentation.increaseBlockLevel();
query = this.addNewline(query);
if (!_token.isToken.CASE(token) || this.cfg.newline === 'always') {
query = this.addNewline(query);
}
}
return query;
} // Closing parentheses decrease the block indent level
}
/**
* Formats a Block End token (right paren/bracket/brace, END) onto query, closing an Inline Block or decreasing indentation where necessary
*/
}, {
key: "formatClosingParentheses",
value: function formatClosingParentheses(token, query) {
key: "formatBlockEnd",
value: function formatBlockEnd(token, query) {
if (this.inlineBlock.isActive()) {
this.inlineBlock.end();
return this.formatWithSpaceAfter(token, query);
if (_token.isToken.END(token)) {
return this.formatWithSpaces(token, query); // add space before END when closing inline block
}
return this.formatWithSpaces(token, query, 'after'); // do not add space before )
} else {
this.indentation.decreaseBlockLevel();
return this.formatWithSpaces(token, this.addNewline(query));
if (this.isTabularStyle()) {
// +1 extra indentation step for the closing paren
query = this.addNewline(query) + this.indentation.getSingleIndent();
} else if (this.cfg.newlineBeforeCloseParen) {
query = this.addNewline(query);
} else {
query = query.trimEnd() + ' ';
}
return this.formatWithSpaces(token, query);
}
}
/**
* Formats a Placeholder item onto query, to be replaced with the value of the placeholder
*/
}, {

@@ -233,3 +535,6 @@ key: "formatPlaceholder",

return query + this.params.get(token) + ' ';
} // Commas start a new line (unless within inline parentheses or SQL "LIMIT" clause)
}
/**
* Formats a comma Operator onto query, ending line unless in an Inline Block
*/

@@ -243,14 +548,13 @@ }, {

return query;
} else if ((0, _token.isLimit)(this.previousReservedToken)) {
} else if (_token.isToken.LIMIT(this.getPreviousReservedToken())) {
return query;
} else if (this.currentNewline) {
return this.addNewline(query);
} else {
return this.addNewline(query);
return query;
}
}
/** Simple append of token onto query */
}, {
key: "formatWithSpaceAfter",
value: function formatWithSpaceAfter(token, query) {
return (0, _utils.trimSpacesEnd)(query) + this.show(token) + ' ';
}
}, {
key: "formatWithoutSpaces",

@@ -260,6 +564,13 @@ value: function formatWithoutSpaces(token, query) {

}
/**
* Add token onto query with spaces - either before, after, or both
*/
}, {
key: "formatWithSpaces",
value: function formatWithSpaces(token, query) {
return query + this.show(token) + ' ';
var addSpace = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'both';
var before = addSpace === 'after' ? (0, _utils.trimSpacesEnd)(query) : query;
var after = addSpace === 'before' ? '' : ' ';
return before + this.show(token) + after;
}

@@ -270,17 +581,26 @@ }, {

this.indentation.resetIndentation();
return (0, _utils.trimSpacesEnd)(query) + this.show(token) + '\n'.repeat(this.cfg.linesBetweenQueries || 1);
} // Converts token to string (uppercasing it if needed)
return [(0, _utils.trimSpacesEnd)(query), this.cfg.newlineBeforeSemicolon ? '\n' : '', this.show(token), '\n'.repeat(this.cfg.linesBetweenQueries + 1)].join('');
}
/** Converts token to string, uppercasing if enabled */
}, {
key: "show",
value: function show(_ref) {
var type = _ref.type,
value = _ref.value;
value: function show(token) {
if ((0, _token.isReserved)(token) || token.type === _token.TokenType.BLOCK_START || token.type === _token.TokenType.BLOCK_END) {
switch (this.cfg.keywordCase) {
case 'preserve':
return token.value;
if (this.cfg.uppercase && (type === _tokenTypes["default"].RESERVED || type === _tokenTypes["default"].RESERVED_TOP_LEVEL || type === _tokenTypes["default"].RESERVED_TOP_LEVEL_NO_INDENT || type === _tokenTypes["default"].RESERVED_NEWLINE || type === _tokenTypes["default"].OPEN_PAREN || type === _tokenTypes["default"].CLOSE_PAREN)) {
return value.toUpperCase();
case 'upper':
return token.value.toUpperCase();
case 'lower':
return token.value.toLowerCase();
}
} else {
return value;
return token.value;
}
}
/** Inserts a newline onto the query */
}, {

@@ -298,7 +618,30 @@ key: "addNewline",

}, {
key: "isTabularStyle",
value: function isTabularStyle() {
return this.cfg.indentStyle === 'tabularLeft' || this.cfg.indentStyle === 'tabularRight';
}
/** Returns the latest encountered reserved keyword token */
}, {
key: "getPreviousReservedToken",
value: function getPreviousReservedToken() {
return this.previousReservedToken;
}
/** True when currently within SELECT command */
}, {
key: "isWithinSelect",
value: function isWithinSelect() {
return _token.isToken.SELECT(this.previousCommandToken);
}
/** Fetches nth previous token from the token stream */
}, {
key: "tokenLookBehind",
value: function tokenLookBehind() {
var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
return this.tokens[this.index - n];
return this.tokens[this.index - n] || _token.EOF_TOKEN;
}
/** Fetches nth next token from the token stream */
}, {

@@ -308,3 +651,3 @@ key: "tokenLookAhead",

var n = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1;
return this.tokens[this.index + n];
return this.tokens[this.index + n] || _token.EOF_TOKEN;
}

@@ -317,2 +660,3 @@ }]);

exports["default"] = Formatter;
module.exports = exports.default;
module.exports = exports.default;
//# sourceMappingURL=Formatter.js.map

@@ -14,4 +14,6 @@ "use strict";

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var INDENT_TYPE_TOP_LEVEL = 'top-level';

@@ -25,3 +27,3 @@ var INDENT_TYPE_BLOCK_LEVEL = 'block-level';

* - BLOCK_LEVEL : increased by open-parenthesis
* - TOP_LEVEL : increased by RESERVED_TOP_LEVEL words
* - TOP_LEVEL : increased by RESERVED_COMMAND words
*/

@@ -31,3 +33,3 @@

/**
* @param {String} indent Indent value, default is " " (2 spaces)
* @param {string} indent A string to indent with
*/

@@ -37,8 +39,8 @@ function Indentation(indent) {

this.indent = indent || ' ';
this.indentTypes = [];
this.indent = indent;
_defineProperty(this, "indentTypes", []);
}
/**
* Returns current indentation string.
* @return {String}
* Returns indentation string for single indentation step.
*/

@@ -48,2 +50,12 @@

_createClass(Indentation, [{
key: "getSingleIndent",
value: function getSingleIndent() {
return this.indent;
}
/**
* Returns current indentation string.
* @return {string} indentation string based on indentTypes
*/
}, {
key: "getIndent",

@@ -100,2 +112,4 @@ value: function getIndent() {

}
/** Clears all indentation */
}, {

@@ -112,2 +126,3 @@ key: "resetIndentation",

exports["default"] = Indentation;
module.exports = exports.default;
module.exports = exports.default;
//# sourceMappingURL=Indentation.js.map

@@ -8,6 +8,4 @@ "use strict";

var _tokenTypes = _interopRequireDefault(require("./tokenTypes"));
var _token = require("./token");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

@@ -17,18 +15,23 @@

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
var INLINE_MAX_LENGTH = 50;
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**
* Bookkeeper for inline blocks.
*
* Inline blocks are parenthized expressions that are shorter than INLINE_MAX_LENGTH.
* These blocks are formatted on a single line, unlike longer parenthized
* Inline blocks are parenthesised expressions that are shorter than INLINE_MAX_LENGTH.
* These blocks are formatted on a single line, unlike longer parenthesised
* expressions where open-parenthesis causes newline and increase of indentation.
*/
var InlineBlock = /*#__PURE__*/function () {
function InlineBlock() {
function InlineBlock(lineWidth) {
_classCallCheck(this, InlineBlock);
_defineProperty(this, "level", void 0);
_defineProperty(this, "lineWidth", void 0);
this.level = 0;
this.lineWidth = lineWidth;
}

@@ -38,3 +41,3 @@ /**

* that the block would be smaller than INLINE_MAX_LENGTH.
* @param {Object[]} tokens Array of all tokens
* @param {Token[]} tokens Array of all tokens
* @param {Number} index Current token position

@@ -67,3 +70,2 @@ */

* True when inside an inline block
* @return {Boolean}
*/

@@ -75,4 +77,7 @@

return this.level > 0;
} // Check if this should be an inline parentheses block
// Examples are "NOW()", "COUNT(*)", "int(10)", key(`somecolumn`), DECIMAL(7,2)
}
/**
* Check if this should be an inline parentheses block
* Examples are "NOW()", "COUNT(*)", "int(10)", key(`somecolumn`), DECIMAL(7,2)
*/

@@ -87,11 +92,16 @@ }, {

var token = tokens[i];
length += token.value.length; // Overran max length
length += token.value.length;
if (length > INLINE_MAX_LENGTH) {
if (this.isForbiddenToken(token)) {
return false;
} // Overran max length
if (length > this.lineWidth) {
return false;
}
if (token.type === _tokenTypes["default"].OPEN_PAREN) {
if (token.type === _token.TokenType.BLOCK_START) {
level++;
} else if (token.type === _tokenTypes["default"].CLOSE_PAREN) {
} else if (token.type === _token.TokenType.BLOCK_END) {
level--;

@@ -103,6 +113,2 @@

}
if (this.isForbiddenToken(token)) {
return false;
}
}

@@ -119,3 +125,8 @@

value = _ref.value;
return type === _tokenTypes["default"].RESERVED_TOP_LEVEL || type === _tokenTypes["default"].RESERVED_NEWLINE || type === _tokenTypes["default"].COMMENT || type === _tokenTypes["default"].BLOCK_COMMENT || value === ';';
return type === _token.TokenType.RESERVED_COMMAND || type === _token.TokenType.RESERVED_LOGICAL_OPERATOR || // type === TokenType.LINE_COMMENT ||
type === _token.TokenType.BLOCK_COMMENT || value === ';' || _token.isToken.CASE({
type: type,
value: value
}) // CASE cannot have inline blocks
;
}

@@ -128,2 +139,3 @@ }]);

exports["default"] = InlineBlock;
module.exports = exports.default;
module.exports = exports.default;
//# sourceMappingURL=InlineBlock.js.map

@@ -12,4 +12,6 @@ "use strict";

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**

@@ -20,3 +22,3 @@ * Handles placeholder replacement with given params.

/**
* @param {Object} params
* @param {ParamItems} params
*/

@@ -26,2 +28,6 @@ function Params(params) {

_defineProperty(this, "params", void 0);
_defineProperty(this, "index", void 0);
this.params = params;

@@ -32,6 +38,4 @@ this.index = 0;

* Returns param value that matches given placeholder with param key.
* @param {Object} token
* @param {String} token.key Placeholder key
* @param {String} token.value Placeholder value
* @return {String} param or token.value when params are missing
* @param {Token} token
* @return {string} param or token.value when params are missing
*/

@@ -62,2 +66,3 @@

exports["default"] = Params;
module.exports = exports.default;
module.exports = exports.default;
//# sourceMappingURL=Params.js.map

@@ -6,40 +6,69 @@ "use strict";

});
exports.createOperatorRegex = createOperatorRegex;
exports.createLineCommentRegex = createLineCommentRegex;
exports.createReservedWordRegex = createReservedWordRegex;
exports.createWordRegex = createWordRegex;
exports.createStringRegex = createStringRegex;
exports.createStringPattern = createStringPattern;
exports.createParenRegex = createParenRegex;
exports.createPlaceholderRegex = createPlaceholderRegex;
exports.createWordRegex = exports.createStringRegex = exports.createStringPattern = exports.createReservedWordRegex = exports.createPlaceholderRegex = exports.createParenRegex = exports.createOperatorRegex = exports.createLineCommentRegex = void 0;
var _utils = require("../utils");
function createOperatorRegex(multiLetterOperators) {
return new RegExp("^(".concat((0, _utils.sortByLengthDesc)(multiLetterOperators).map(_utils.escapeRegExp).join('|'), "|.)"), 'u');
}
/**
* Builds a RegExp containing all operators for a SQL dialect
* @param {string} monadOperators - concatenated string of all 1-length operators
* @param {string[]} polyadOperators - list of strings of all >1-length operators
*/
var createOperatorRegex = function createOperatorRegex(monadOperators, polyadOperators) {
return new RegExp("^(".concat((0, _utils.sortByLengthDesc)(polyadOperators).map(_utils.escapeRegExp).join('|'), "|") + "[".concat(monadOperators.split('').map(_utils.escapeRegExp).join(''), "])"), 'u');
};
/**
* Builds a RegExp for valid line comments in a SQL dialect
* @param {string[]} lineCommentTypes - list of character strings that denote line comments
*/
function createLineCommentRegex(lineCommentTypes) {
exports.createOperatorRegex = createOperatorRegex;
var createLineCommentRegex = function createLineCommentRegex(lineCommentTypes) {
return new RegExp("^((?:".concat(lineCommentTypes.map(function (c) {
return (0, _utils.escapeRegExp)(c);
}).join('|'), ").*?)(?:\r\n|\r|\n|$)"), 'u');
}
};
/**
* Builds a RegExp for all Reserved Keywords in a SQL dialect
* @param {string[]} reservedKeywords - list of strings of all Reserved Keywords
* @param {string} specialWordChars - concatenated string of all special chars that can appear in valid identifiers (and not in Reserved Keywords)
*/
function createReservedWordRegex(reservedWords) {
if (reservedWords.length === 0) {
return new RegExp("^\b$", 'u');
exports.createLineCommentRegex = createLineCommentRegex;
var createReservedWordRegex = function createReservedWordRegex(reservedKeywords) {
var specialWordChars = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
if (reservedKeywords.length === 0) {
return /^\b$/;
}
var reservedWordsPattern = (0, _utils.sortByLengthDesc)(reservedWords).join('|').replace(/ /g, '\\s+');
return new RegExp("^(".concat(reservedWordsPattern, ")\\b"), 'iu');
}
var reservedKeywordsPattern = (0, _utils.sortByLengthDesc)(reservedKeywords).join('|').replace(/ /g, '\\s+');
return new RegExp("^(".concat(reservedKeywordsPattern, ")(?![").concat((0, _utils.escapeRegExp)(specialWordChars), "]+)\\b"), 'iu');
};
/**
* Builds a RegExp for valid identifiers in a SQL dialect
* @param {Object} specialChars
* @param {string} specialChars.any - concatenated string of chars that can appear anywhere in a valid identifier
* @param {string} specialChars.prefix - concatenated string of chars that only appear at the beginning of a valid identifier
* @param {string} specialChars.suffix - concatenated string of chars that only appear at the end of a valid identifier
*/
function createWordRegex() {
var specialChars = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
return new RegExp("^([\\p{Alphabetic}\\p{Mark}\\p{Decimal_Number}\\p{Connector_Punctuation}\\p{Join_Control}".concat(specialChars.join(''), "]+)"), 'u');
}
function createStringRegex(stringTypes) {
return new RegExp('^(' + createStringPattern(stringTypes) + ')', 'u');
} // This enables the following string patterns:
exports.createReservedWordRegex = createReservedWordRegex;
var createWordRegex = function createWordRegex() {
var _specialChars$prefix, _specialChars$suffix, _specialChars$any;
var specialChars = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var prefixLookBehind = "[".concat((0, _utils.escapeRegExp)((_specialChars$prefix = specialChars.prefix) !== null && _specialChars$prefix !== void 0 ? _specialChars$prefix : ''), "]*");
var suffixLookAhead = "[".concat((0, _utils.escapeRegExp)((_specialChars$suffix = specialChars.suffix) !== null && _specialChars$suffix !== void 0 ? _specialChars$suffix : ''), "]*");
var unicodeWordChar = '\\p{Alphabetic}\\p{Mark}\\p{Decimal_Number}\\p{Connector_Punctuation}\\p{Join_Control}';
var specialWordChars = "".concat((0, _utils.escapeRegExp)((_specialChars$any = specialChars.any) !== null && _specialChars$any !== void 0 ? _specialChars$any : ''));
var arrayAccessor = '\\[\\d\\]';
var mapAccessor = "\\[['\"][".concat(unicodeWordChar, "]+['\"]\\]");
return new RegExp("^((".concat(prefixLookBehind, "([").concat(unicodeWordChar).concat(specialWordChars, "]+)").concat(suffixLookAhead, ")(").concat(arrayAccessor, "|").concat(mapAccessor, ")?)"), 'u');
}; // This enables the following string patterns:
// 1. backtick quoted string using `` to escape

@@ -55,24 +84,43 @@ // 2. square bracket quoted string (SQL Server) using ]] to escape

function createStringPattern(stringTypes) {
var patterns = {
'``': '((`[^`]*($|`))+)',
'{}': '((\\{[^\\}]*($|\\}))+)',
'[]': '((\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*)',
'""': '(("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+)',
"''": "(('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)",
"N''": "((N'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)",
"U&''": "((U&'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)",
'U&""': '((U&"[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+)',
$$: '((?<tag>\\$\\w*\\$)[\\s\\S]*?(?:\\k<tag>|$))'
};
exports.createWordRegex = createWordRegex;
var patterns = {
'``': '((`[^`]*($|`))+)',
'{}': '((\\{[^\\}]*($|\\}))+)',
'[]': '((\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*)',
'""': '(("[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+)',
"''": "(('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)",
"N''": "((N'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)",
"x''": "(([xX]'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)",
"E''": "((E'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)",
"U&''": "((U&'[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)",
'U&""': '((U&"[^"\\\\]*(?:\\\\.[^"\\\\]*)*("|$))+)',
'$$': '((?<tag>\\$\\w*\\$)[\\s\\S]*?(?:\\k<tag>|$))'
};
/**
* Builds a string pattern for matching string patterns for all given string types
* @param {StringPatternType[]} stringTypes - list of strings that denote string patterns
*/
var createStringPattern = function createStringPattern(stringTypes) {
return stringTypes.map(function (t) {
return patterns[t];
}).join('|');
}
};
/**
* Builds a RegExp for matching string patterns using `createStringPattern`
* @param {StringPatternType[]} stringTypes - list of strings that denote string patterns
*/
function createParenRegex(parens) {
return new RegExp('^(' + parens.map(escapeParen).join('|') + ')', 'iu');
}
function escapeParen(paren) {
exports.createStringPattern = createStringPattern;
var createStringRegex = function createStringRegex(stringTypes) {
return new RegExp('^(' + createStringPattern(stringTypes) + ')', 'u');
};
/** Escapes paren characters for RegExp patterns */
exports.createStringRegex = createStringRegex;
var escapeParen = function escapeParen(paren) {
if (paren.length === 1) {

@@ -85,7 +133,24 @@ // A single punctuation character

}
}
};
/**
* Builds a RegExp for matching parenthesis patterns, escaping them with `escapeParen`
* @param {string[]} parens - list of strings that denote parenthesis patterns
*/
function createPlaceholderRegex(types, pattern) {
var createParenRegex = function createParenRegex(parens) {
return new RegExp('^(' + parens.map(escapeParen).join('|') + ')', 'iu');
};
/**
* Builds a RegExp for placeholder patterns
* @param {string[]} types - list of strings that denote placeholder types
* @param {string} pattern - string that denotes placeholder pattern
*/
exports.createParenRegex = createParenRegex;
var createPlaceholderRegex = function createPlaceholderRegex(types, pattern) {
if ((0, _utils.isEmpty)(types)) {
return false;
return undefined;
}

@@ -95,2 +160,5 @@

return new RegExp("^((?:".concat(typesRegex, ")(?:").concat(pattern, "))"), 'u');
}
};
exports.createPlaceholderRegex = createPlaceholderRegex;
//# sourceMappingURL=regexFactory.js.map

@@ -6,27 +6,135 @@ "use strict";

});
exports.isEnd = exports.isWindow = exports.isBy = exports.isSet = exports.isLimit = exports.isBetween = exports.isAnd = void 0;
exports.testToken = exports.isToken = exports.isReserved = exports.isCommand = exports.ZWS = exports.TokenType = exports.EOF_TOKEN = void 0;
var _tokenTypes = _interopRequireDefault(require("./tokenTypes"));
/** Token type enum for all possible Token categories */
var TokenType;
/** Struct to store the most basic cohesive unit of language grammar */
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
exports.TokenType = TokenType;
var isToken = function isToken(type, regex) {
(function (TokenType) {
TokenType["WORD"] = "WORD";
TokenType["STRING"] = "STRING";
TokenType["RESERVED_KEYWORD"] = "RESERVED_KEYWORD";
TokenType["RESERVED_LOGICAL_OPERATOR"] = "RESERVED_LOGICAL_OPERATOR";
TokenType["RESERVED_DEPENDENT_CLAUSE"] = "RESERVED_DEPENDENT_CLAUSE";
TokenType["RESERVED_BINARY_COMMAND"] = "RESERVED_BINARY_COMMAND";
TokenType["RESERVED_COMMAND"] = "RESERVED_COMMAND";
TokenType["RESERVED_JOIN_CONDITION"] = "RESERVED_JOIN_CONDITION";
TokenType["OPERATOR"] = "OPERATOR";
TokenType["BLOCK_START"] = "BLOCK_START";
TokenType["BLOCK_END"] = "BLOCK_END";
TokenType["LINE_COMMENT"] = "LINE_COMMENT";
TokenType["BLOCK_COMMENT"] = "BLOCK_COMMENT";
TokenType["NUMBER"] = "NUMBER";
TokenType["PLACEHOLDER"] = "PLACEHOLDER";
TokenType["EOF"] = "EOF";
})(TokenType || (exports.TokenType = TokenType = {}));
/**
* For use as a "missing token"
* e.g. in lookAhead and lookBehind to avoid dealing with null values
*/
var EOF_TOKEN = {
type: TokenType.EOF,
value: '«EOF»'
};
/** Special Unicode character to serve as a placeholder for tabular formats as \w whitespace is unavailable */
exports.EOF_TOKEN = EOF_TOKEN;
var ZWS = '​'; // uses zero-width space (&#8203; / U+200B)
exports.ZWS = ZWS;
var ZWS_REGEX = "\u200B";
var spaces = "[".concat(ZWS_REGEX, "\\s]");
/** Checks if two tokens are equivalent */
var testToken = function testToken(compareToken) {
return function (token) {
return (token === null || token === void 0 ? void 0 : token.type) === type && regex.test(token === null || token === void 0 ? void 0 : token.value);
return token.type === compareToken.type && new RegExp("^".concat(spaces, "*").concat(compareToken.value).concat(spaces, "*$"), 'iu').test(token.value);
};
};
/** Util object that allows for easy checking of Reserved Keywords */
var isAnd = isToken(_tokenTypes["default"].RESERVED_NEWLINE, /^AND$/i);
exports.isAnd = isAnd;
var isBetween = isToken(_tokenTypes["default"].RESERVED, /^BETWEEN$/i);
exports.isBetween = isBetween;
var isLimit = isToken(_tokenTypes["default"].RESERVED_TOP_LEVEL, /^LIMIT$/i);
exports.isLimit = isLimit;
var isSet = isToken(_tokenTypes["default"].RESERVED_TOP_LEVEL, /^[S\u017F]ET$/i);
exports.isSet = isSet;
var isBy = isToken(_tokenTypes["default"].RESERVED, /^BY$/i);
exports.isBy = isBy;
var isWindow = isToken(_tokenTypes["default"].RESERVED_TOP_LEVEL, /^WINDOW$/i);
exports.isWindow = isWindow;
var isEnd = isToken(_tokenTypes["default"].CLOSE_PAREN, /^END$/i);
exports.isEnd = isEnd;
exports.testToken = testToken;
var isToken = {
AS: testToken({
value: 'AS',
type: TokenType.RESERVED_KEYWORD
}),
AND: testToken({
value: 'AND',
type: TokenType.RESERVED_LOGICAL_OPERATOR
}),
BETWEEN: testToken({
value: 'BETWEEN',
type: TokenType.RESERVED_KEYWORD
}),
CASE: testToken({
value: 'CASE',
type: TokenType.BLOCK_START
}),
CAST: testToken({
value: 'CAST',
type: TokenType.RESERVED_KEYWORD
}),
BY: testToken({
value: 'BY',
type: TokenType.RESERVED_KEYWORD
}),
END: testToken({
value: 'END',
type: TokenType.BLOCK_END
}),
FROM: testToken({
value: 'FROM',
type: TokenType.RESERVED_COMMAND
}),
LATERAL: testToken({
value: 'LATERAL',
type: TokenType.RESERVED_DEPENDENT_CLAUSE
}),
LIMIT: testToken({
value: 'LIMIT',
type: TokenType.RESERVED_COMMAND
}),
SELECT: testToken({
value: 'SELECT',
type: TokenType.RESERVED_COMMAND
}),
SET: testToken({
value: 'SET',
type: TokenType.RESERVED_COMMAND
}),
TABLE: testToken({
value: 'TABLE',
type: TokenType.RESERVED_KEYWORD
}),
WINDOW: testToken({
value: 'WINDOW',
type: TokenType.RESERVED_COMMAND
}),
WITH: testToken({
value: 'WITH',
type: TokenType.RESERVED_COMMAND
})
};
/** Checks if token is a Reserved Command or Reserved Binary Command */
exports.isToken = isToken;
var isCommand = function isCommand(token) {
return token.type === TokenType.RESERVED_COMMAND || token.type === TokenType.RESERVED_BINARY_COMMAND;
};
/** Checks if token is any Reserved Keyword or Command */
exports.isCommand = isCommand;
var isReserved = function isReserved(token) {
return token.type === TokenType.RESERVED_KEYWORD || token.type === TokenType.RESERVED_LOGICAL_OPERATOR || token.type === TokenType.RESERVED_DEPENDENT_CLAUSE || token.type === TokenType.RESERVED_JOIN_CONDITION || token.type === TokenType.RESERVED_COMMAND || token.type === TokenType.RESERVED_BINARY_COMMAND;
};
exports.isReserved = isReserved;
//# sourceMappingURL=token.js.map
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }

@@ -8,6 +8,4 @@ Object.defineProperty(exports, "__esModule", {

});
exports["default"] = void 0;
exports["default"] = exports.WHITESPACE_REGEX = void 0;
var _tokenTypes = _interopRequireDefault(require("./tokenTypes"));
var regexFactory = _interopRequireWildcard(require("./regexFactory"));

@@ -17,14 +15,12 @@

function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
var _token = require("./token");
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }

@@ -36,3 +32,3 @@

function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }

@@ -47,37 +43,63 @@ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
// convert to partial type import in TS 4.5
var WHITESPACE_REGEX = /^([\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+)/;
exports.WHITESPACE_REGEX = WHITESPACE_REGEX;
var NULL_REGEX = /(?!)/; // zero-width negative lookahead, matches nothing
/** Struct that defines how a SQL language can be broken into tokens */
/** Converts SQL language string into a token stream */
var Tokenizer = /*#__PURE__*/function () {
/**
* @param {Object} cfg
* @param {String[]} cfg.reservedWords Reserved words in SQL
* @param {String[]} cfg.reservedTopLevelWords Words that are set to new line separately
* @param {String[]} cfg.reservedNewlineWords Words that are set to newline
* @param {String[]} cfg.reservedTopLevelWordsNoIndent Words that are top level but have no indentation
* @param {String[]} cfg.stringTypes String types to enable: "", '', ``, [], N''
* @param {String[]} cfg.openParens Opening parentheses to enable, like (, [
* @param {String[]} cfg.closeParens Closing parentheses to enable, like ), ]
* @param {String[]} cfg.indexedPlaceholderTypes Prefixes for indexed placeholders, like ?
* @param {String[]} cfg.namedPlaceholderTypes Prefixes for named placeholders, like @ and :
* @param {String[]} cfg.lineCommentTypes Line comments to enable, like # and --
* @param {String[]} cfg.specialWordChars Special chars that can be found inside of words, like @ and #
* @param {String[]} [cfg.operator] Additional operators to recognize
* @param {TokenizerOptions} cfg
* @param {string[]} cfg.reservedKeywords - Reserved words in SQL
* @param {string[]} cfg.reservedDependentClauses - Words that following a specific Statement and must have data attached
* @param {string[]} cfg.reservedLogicalOperators - Words that are set to newline
* @param {string[]} cfg.reservedCommands - Words that are set to new line separately
* @param {string[]} cfg.reservedBinaryCommands - Words that are top level but have no indentation
* @param {string[]} cfg.reservedJoinConditions - ON and USING
* @param {string[]} cfg.stringTypes - string types to enable - "", '', ``, [], N''
* @param {string[]} cfg.blockStart - Opening parentheses to enable, like (, [
* @param {string[]} cfg.blockEnd - Closing parentheses to enable, like ), ]
* @param {string[]} cfg.indexedPlaceholderTypes - Prefixes for indexed placeholders, like ?
* @param {string[]} cfg.namedPlaceholderTypes - Prefixes for named placeholders, like @ and :
* @param {string[]} cfg.lineCommentTypes - Line comments to enable, like # and --
* @param {string[]} cfg.specialWordChars - Special chars that can be found inside of words, like @ and #
* @param {string[]} cfg.operators - Additional operators to recognize
*/
function Tokenizer(cfg) {
var _this = this,
_cfg$specialWordChars,
_cfg$reservedDependen,
_cfg$operators,
_this$REGEX_MAP,
_cfg$indexedPlacehold;
_classCallCheck(this, Tokenizer);
this.WHITESPACE_REGEX = /^([\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]+)/;
this.NUMBER_REGEX = /^((\x2D[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*)?[0-9]+(\.[0-9]+)?([Ee]\x2D?[0-9]+(\.[0-9]+)?)?|0x[0-9A-Fa-f]+|0b[01]+)\b/;
this.OPERATOR_REGEX = regexFactory.createOperatorRegex(['<>', '<=', '>='].concat(_toConsumableArray(cfg.operators || [])));
this.BLOCK_COMMENT_REGEX = /^(\/\*(?:(?![])[\s\S])*?(?:\*\/|$))/;
this.LINE_COMMENT_REGEX = regexFactory.createLineCommentRegex(cfg.lineCommentTypes);
this.RESERVED_TOP_LEVEL_REGEX = regexFactory.createReservedWordRegex(cfg.reservedTopLevelWords);
this.RESERVED_TOP_LEVEL_NO_INDENT_REGEX = regexFactory.createReservedWordRegex(cfg.reservedTopLevelWordsNoIndent);
this.RESERVED_NEWLINE_REGEX = regexFactory.createReservedWordRegex(cfg.reservedNewlineWords);
this.RESERVED_PLAIN_REGEX = regexFactory.createReservedWordRegex(cfg.reservedWords);
this.WORD_REGEX = regexFactory.createWordRegex(cfg.specialWordChars);
this.STRING_REGEX = regexFactory.createStringRegex(cfg.stringTypes);
this.OPEN_PAREN_REGEX = regexFactory.createParenRegex(cfg.openParens);
this.CLOSE_PAREN_REGEX = regexFactory.createParenRegex(cfg.closeParens);
this.INDEXED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex(cfg.indexedPlaceholderTypes, '[0-9]*');
_defineProperty(this, "REGEX_MAP", void 0);
_defineProperty(this, "INDEXED_PLACEHOLDER_REGEX", void 0);
_defineProperty(this, "IDENT_NAMED_PLACEHOLDER_REGEX", void 0);
_defineProperty(this, "STRING_NAMED_PLACEHOLDER_REGEX", void 0);
_defineProperty(this, "matchToken", function (tokenType) {
return function (input) {
return _this.getTokenOnFirstMatch({
input: input,
type: tokenType,
regex: _this.REGEX_MAP[tokenType]
});
};
});
var specialWordCharsAll = Object.values((_cfg$specialWordChars = cfg.specialWordChars) !== null && _cfg$specialWordChars !== void 0 ? _cfg$specialWordChars : {}).join('');
this.REGEX_MAP = (_this$REGEX_MAP = {}, _defineProperty(_this$REGEX_MAP, _token.TokenType.WORD, regexFactory.createWordRegex(cfg.specialWordChars)), _defineProperty(_this$REGEX_MAP, _token.TokenType.STRING, regexFactory.createStringRegex(cfg.stringTypes)), _defineProperty(_this$REGEX_MAP, _token.TokenType.RESERVED_KEYWORD, regexFactory.createReservedWordRegex(cfg.reservedKeywords, specialWordCharsAll)), _defineProperty(_this$REGEX_MAP, _token.TokenType.RESERVED_DEPENDENT_CLAUSE, regexFactory.createReservedWordRegex((_cfg$reservedDependen = cfg.reservedDependentClauses) !== null && _cfg$reservedDependen !== void 0 ? _cfg$reservedDependen : [], specialWordCharsAll)), _defineProperty(_this$REGEX_MAP, _token.TokenType.RESERVED_LOGICAL_OPERATOR, regexFactory.createReservedWordRegex(cfg.reservedLogicalOperators, specialWordCharsAll)), _defineProperty(_this$REGEX_MAP, _token.TokenType.RESERVED_COMMAND, regexFactory.createReservedWordRegex(cfg.reservedCommands, specialWordCharsAll)), _defineProperty(_this$REGEX_MAP, _token.TokenType.RESERVED_BINARY_COMMAND, regexFactory.createReservedWordRegex(cfg.reservedBinaryCommands, specialWordCharsAll)), _defineProperty(_this$REGEX_MAP, _token.TokenType.RESERVED_JOIN_CONDITION, regexFactory.createReservedWordRegex(cfg.reservedJoinConditions, specialWordCharsAll)), _defineProperty(_this$REGEX_MAP, _token.TokenType.OPERATOR, regexFactory.createOperatorRegex('+-/*%&|^><=.,;[]{}`:$', ['<>', '<=', '>=', '!='].concat(_toConsumableArray((_cfg$operators = cfg.operators) !== null && _cfg$operators !== void 0 ? _cfg$operators : [])))), _defineProperty(_this$REGEX_MAP, _token.TokenType.BLOCK_START, regexFactory.createParenRegex(cfg.blockStart)), _defineProperty(_this$REGEX_MAP, _token.TokenType.BLOCK_END, regexFactory.createParenRegex(cfg.blockEnd)), _defineProperty(_this$REGEX_MAP, _token.TokenType.LINE_COMMENT, regexFactory.createLineCommentRegex(cfg.lineCommentTypes)), _defineProperty(_this$REGEX_MAP, _token.TokenType.BLOCK_COMMENT, /^(\/\*(?:(?![])[\s\S])*?(?:\*\/|$))/), _defineProperty(_this$REGEX_MAP, _token.TokenType.NUMBER, /^(0x[0-9A-Fa-f]+|0b[01]+|(\x2D[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*)?[0-9]+(\.[0-9]*)?([Ee][\+\x2D]?[0-9]+(\.[0-9]+)?)?)/), _defineProperty(_this$REGEX_MAP, _token.TokenType.PLACEHOLDER, NULL_REGEX), _defineProperty(_this$REGEX_MAP, _token.TokenType.EOF, NULL_REGEX), _this$REGEX_MAP);
this.INDEXED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex((_cfg$indexedPlacehold = cfg.indexedPlaceholderTypes) !== null && _cfg$indexedPlacehold !== void 0 ? _cfg$indexedPlacehold : [], '[0-9]*');
this.IDENT_NAMED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex(cfg.namedPlaceholderTypes, '[a-zA-Z0-9._$]+');

@@ -90,7 +112,4 @@ this.STRING_NAMED_PLACEHOLDER_REGEX = regexFactory.createPlaceholderRegex(cfg.namedPlaceholderTypes, regexFactory.createStringPattern(cfg.stringTypes));

*
* @param {String} input The SQL string
* @return {Object[]} tokens An array of tokens.
* @return {String} token.type
* @return {String} token.value
* @return {String} token.whitespaceBefore Preceding whitespace
* @param {string} input - The SQL string
* @returns {Token[]} output token stream
*/

@@ -123,89 +142,43 @@

}
/** Matches preceding whitespace if present */
}, {
key: "getWhitespace",
value: function getWhitespace(input) {
var matches = input.match(this.WHITESPACE_REGEX);
var matches = input.match(WHITESPACE_REGEX);
return matches ? matches[1] : '';
}
/** Curried function of `getTokenOnFirstMatch` that allows token type to be passed first */
}, {
key: "getNextToken",
value: function getNextToken(input, previousToken) {
return this.getCommentToken(input) || this.getStringToken(input) || this.getOpenParenToken(input) || this.getCloseParenToken(input) || this.getPlaceholderToken(input) || this.getNumberToken(input) || this.getReservedWordToken(input, previousToken) || this.getWordToken(input) || this.getOperatorToken(input);
value:
/** Attempts to match next token from input string, tests RegExp patterns in decreasing priority */
function getNextToken(input, previousToken) {
return this.matchToken(_token.TokenType.LINE_COMMENT)(input) || this.matchToken(_token.TokenType.BLOCK_COMMENT)(input) || this.matchToken(_token.TokenType.STRING)(input) || this.matchToken(_token.TokenType.BLOCK_START)(input) || this.matchToken(_token.TokenType.BLOCK_END)(input) || this.getPlaceholderToken(input) || this.matchToken(_token.TokenType.NUMBER)(input) || this.getReservedWordToken(input, previousToken) || this.matchToken(_token.TokenType.WORD)(input) || this.matchToken(_token.TokenType.OPERATOR)(input);
}
/**
* Attempts to match a placeholder token pattern
* @return {Token | undefined} - The placeholder token if found, otherwise undefined
*/
}, {
key: "getCommentToken",
value: function getCommentToken(input) {
return this.getLineCommentToken(input) || this.getBlockCommentToken(input);
}
}, {
key: "getLineCommentToken",
value: function getLineCommentToken(input) {
return this.getTokenOnFirstMatch({
input: input,
type: _tokenTypes["default"].LINE_COMMENT,
regex: this.LINE_COMMENT_REGEX
});
}
}, {
key: "getBlockCommentToken",
value: function getBlockCommentToken(input) {
return this.getTokenOnFirstMatch({
input: input,
type: _tokenTypes["default"].BLOCK_COMMENT,
regex: this.BLOCK_COMMENT_REGEX
});
}
}, {
key: "getStringToken",
value: function getStringToken(input) {
return this.getTokenOnFirstMatch({
input: input,
type: _tokenTypes["default"].STRING,
regex: this.STRING_REGEX
});
}
}, {
key: "getOpenParenToken",
value: function getOpenParenToken(input) {
return this.getTokenOnFirstMatch({
input: input,
type: _tokenTypes["default"].OPEN_PAREN,
regex: this.OPEN_PAREN_REGEX
});
}
}, {
key: "getCloseParenToken",
value: function getCloseParenToken(input) {
return this.getTokenOnFirstMatch({
input: input,
type: _tokenTypes["default"].CLOSE_PAREN,
regex: this.CLOSE_PAREN_REGEX
});
}
}, {
key: "getPlaceholderToken",
value: function getPlaceholderToken(input) {
return this.getIdentNamedPlaceholderToken(input) || this.getStringNamedPlaceholderToken(input) || this.getIndexedPlaceholderToken(input);
}
}, {
key: "getIdentNamedPlaceholderToken",
value: function getIdentNamedPlaceholderToken(input) {
return this.getPlaceholderTokenWithKey({
input: input,
regex: this.IDENT_NAMED_PLACEHOLDER_REGEX,
var _this$IDENT_NAMED_PLA,
_this$STRING_NAMED_PL,
_this2 = this,
_this$INDEXED_PLACEHO;
var placeholderTokenRegexMap = [// pattern for placeholder with identifier name
{
regex: (_this$IDENT_NAMED_PLA = this.IDENT_NAMED_PLACEHOLDER_REGEX) !== null && _this$IDENT_NAMED_PLA !== void 0 ? _this$IDENT_NAMED_PLA : NULL_REGEX,
parseKey: function parseKey(v) {
return v.slice(1);
}
});
}
}, {
key: "getStringNamedPlaceholderToken",
value: function getStringNamedPlaceholderToken(input) {
var _this = this;
return this.getPlaceholderTokenWithKey({
input: input,
regex: this.STRING_NAMED_PLACEHOLDER_REGEX,
}, // pattern for placeholder with string name
{
regex: (_this$STRING_NAMED_PL = this.STRING_NAMED_PLACEHOLDER_REGEX) !== null && _this$STRING_NAMED_PL !== void 0 ? _this$STRING_NAMED_PL : NULL_REGEX,
parseKey: function parseKey(v) {
return _this.getEscapedPlaceholderKey({
return _this2.getEscapedPlaceholderKey({
key: v.slice(2, -1),

@@ -215,32 +188,23 @@ quoteChar: v.slice(-1)

}
});
}
}, {
key: "getIndexedPlaceholderToken",
value: function getIndexedPlaceholderToken(input) {
return this.getPlaceholderTokenWithKey({
input: input,
regex: this.INDEXED_PLACEHOLDER_REGEX,
}, // pattern for placeholder with numeric index
{
regex: (_this$INDEXED_PLACEHO = this.INDEXED_PLACEHOLDER_REGEX) !== null && _this$INDEXED_PLACEHO !== void 0 ? _this$INDEXED_PLACEHO : NULL_REGEX,
parseKey: function parseKey(v) {
return v.slice(1);
}
});
}
}, {
key: "getPlaceholderTokenWithKey",
value: function getPlaceholderTokenWithKey(_ref) {
var input = _ref.input,
regex = _ref.regex,
parseKey = _ref.parseKey;
var token = this.getTokenOnFirstMatch({
input: input,
regex: regex,
type: _tokenTypes["default"].PLACEHOLDER
});
}];
return placeholderTokenRegexMap.reduce(function (acc, _ref) {
var regex = _ref.regex,
parseKey = _ref.parseKey;
if (token) {
token.key = parseKey(token.value);
}
var token = _this2.getTokenOnFirstMatch({
input: input,
regex: regex,
type: _token.TokenType.PLACEHOLDER
});
return token;
return token ? _objectSpread(_objectSpread({}, token), {}, {
key: parseKey(token.value)
}) : acc;
}, undefined);
}

@@ -253,80 +217,34 @@ }, {

return key.replace(new RegExp((0, _utils.escapeRegExp)('\\' + quoteChar), 'gu'), quoteChar);
} // Decimal, binary, or hex numbers
}
/**
* Attempts to match a Reserved word token pattern, avoiding edge cases of Reserved words within string tokens
* @return {Token | undefined} - The Reserved word token if found, otherwise undefined
*/
}, {
key: "getNumberToken",
value: function getNumberToken(input) {
return this.getTokenOnFirstMatch({
input: input,
type: _tokenTypes["default"].NUMBER,
regex: this.NUMBER_REGEX
});
} // Punctuation and symbols
}, {
key: "getOperatorToken",
value: function getOperatorToken(input) {
return this.getTokenOnFirstMatch({
input: input,
type: _tokenTypes["default"].OPERATOR,
regex: this.OPERATOR_REGEX
});
}
}, {
key: "getReservedWordToken",
value: function getReservedWordToken(input, previousToken) {
// A reserved word cannot be preceded by a "."
var _this3 = this;
// A reserved word cannot be preceded by a '.'
// this makes it so in "mytable.from", "from" is not considered a reserved word
if (previousToken && previousToken.value && previousToken.value === '.') {
if ((previousToken === null || previousToken === void 0 ? void 0 : previousToken.value) === '.') {
return undefined;
}
} // prioritised list of Reserved token types
return this.getTopLevelReservedToken(input) || this.getNewlineReservedToken(input) || this.getTopLevelReservedTokenNoIndent(input) || this.getPlainReservedToken(input);
var reservedTokenList = [_token.TokenType.RESERVED_COMMAND, _token.TokenType.RESERVED_BINARY_COMMAND, _token.TokenType.RESERVED_DEPENDENT_CLAUSE, _token.TokenType.RESERVED_LOGICAL_OPERATOR, _token.TokenType.RESERVED_JOIN_CONDITION, _token.TokenType.RESERVED_KEYWORD];
return reservedTokenList.reduce(function (matchedToken, tokenType) {
return matchedToken || _this3.matchToken(tokenType)(input);
}, undefined);
}
/**
* Attempts to match RegExp from head of input, returning undefined if not found
* @param {string} _.input - The string to match
* @param {TokenType} _.type - The type of token to match against
* @param {RegExp} _.regex - The regex to match
* @return {Token | undefined} - The matched token if found, otherwise undefined
*/
}, {
key: "getTopLevelReservedToken",
value: function getTopLevelReservedToken(input) {
return this.getTokenOnFirstMatch({
input: input,
type: _tokenTypes["default"].RESERVED_TOP_LEVEL,
regex: this.RESERVED_TOP_LEVEL_REGEX
});
}
}, {
key: "getNewlineReservedToken",
value: function getNewlineReservedToken(input) {
return this.getTokenOnFirstMatch({
input: input,
type: _tokenTypes["default"].RESERVED_NEWLINE,
regex: this.RESERVED_NEWLINE_REGEX
});
}
}, {
key: "getTopLevelReservedTokenNoIndent",
value: function getTopLevelReservedTokenNoIndent(input) {
return this.getTokenOnFirstMatch({
input: input,
type: _tokenTypes["default"].RESERVED_TOP_LEVEL_NO_INDENT,
regex: this.RESERVED_TOP_LEVEL_NO_INDENT_REGEX
});
}
}, {
key: "getPlainReservedToken",
value: function getPlainReservedToken(input) {
return this.getTokenOnFirstMatch({
input: input,
type: _tokenTypes["default"].RESERVED,
regex: this.RESERVED_PLAIN_REGEX
});
}
}, {
key: "getWordToken",
value: function getWordToken(input) {
return this.getTokenOnFirstMatch({
input: input,
type: _tokenTypes["default"].WORD,
regex: this.WORD_REGEX
});
}
}, {
key: "getTokenOnFirstMatch",

@@ -349,2 +267,2 @@ value: function getTokenOnFirstMatch(_ref3) {

exports["default"] = Tokenizer;
module.exports = exports.default;
//# sourceMappingURL=Tokenizer.js.map

@@ -6,51 +6,80 @@ "use strict";

});
exports.supportedDialects = exports.format = void 0;
exports.supportedDialects = exports.formatters = exports.format = void 0;
var _Db2Formatter = _interopRequireDefault(require("./languages/Db2Formatter"));
var _bigquery = _interopRequireDefault(require("./languages/bigquery.formatter"));
var _MariaDbFormatter = _interopRequireDefault(require("./languages/MariaDbFormatter"));
var _db = _interopRequireDefault(require("./languages/db2.formatter"));
var _MySqlFormatter = _interopRequireDefault(require("./languages/MySqlFormatter"));
var _hive = _interopRequireDefault(require("./languages/hive.formatter"));
var _N1qlFormatter = _interopRequireDefault(require("./languages/N1qlFormatter"));
var _mariadb = _interopRequireDefault(require("./languages/mariadb.formatter"));
var _PlSqlFormatter = _interopRequireDefault(require("./languages/PlSqlFormatter"));
var _mysql = _interopRequireDefault(require("./languages/mysql.formatter"));
var _PostgreSqlFormatter = _interopRequireDefault(require("./languages/PostgreSqlFormatter"));
var _n1ql = _interopRequireDefault(require("./languages/n1ql.formatter"));
var _RedshiftFormatter = _interopRequireDefault(require("./languages/RedshiftFormatter"));
var _plsql = _interopRequireDefault(require("./languages/plsql.formatter"));
var _SparkSqlFormatter = _interopRequireDefault(require("./languages/SparkSqlFormatter"));
var _postgresql = _interopRequireDefault(require("./languages/postgresql.formatter"));
var _StandardSqlFormatter = _interopRequireDefault(require("./languages/StandardSqlFormatter"));
var _redshift = _interopRequireDefault(require("./languages/redshift.formatter"));
var _TSqlFormatter = _interopRequireDefault(require("./languages/TSqlFormatter"));
var _sparksql = _interopRequireDefault(require("./languages/sparksql.formatter"));
var _standardsql = _interopRequireDefault(require("./languages/standardsql.formatter"));
var _tsql = _interopRequireDefault(require("./languages/tsql.formatter"));
var _utils = require("./utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
var formatters = {
db2: _Db2Formatter["default"],
mariadb: _MariaDbFormatter["default"],
mysql: _MySqlFormatter["default"],
n1ql: _N1qlFormatter["default"],
plsql: _PlSqlFormatter["default"],
postgresql: _PostgreSqlFormatter["default"],
redshift: _RedshiftFormatter["default"],
spark: _SparkSqlFormatter["default"],
sql: _StandardSqlFormatter["default"],
tsql: _TSqlFormatter["default"]
bigquery: _bigquery["default"],
db2: _db["default"],
hive: _hive["default"],
mariadb: _mariadb["default"],
mysql: _mysql["default"],
n1ql: _n1ql["default"],
plsql: _plsql["default"],
postgresql: _postgresql["default"],
redshift: _redshift["default"],
spark: _sparksql["default"],
sql: _standardsql["default"],
tsql: _tsql["default"]
};
exports.formatters = formatters;
var supportedDialects = Object.keys(formatters);
exports.supportedDialects = supportedDialects;
var defaultOptions = {
language: 'sql',
indent: ' ',
keywordCase: 'preserve',
indentStyle: 'standard',
newline: 'always',
logicalOperatorNewline: 'before',
aliasAs: 'preserve',
tabulateAlias: false,
commaPosition: 'after',
newlineBeforeOpenParen: true,
newlineBeforeCloseParen: true,
lineWidth: 50,
linesBetweenQueries: 1,
denseOperators: false,
newlineBeforeSemicolon: false
};
/**
* Format whitespace in a query to make it easier to read.
*
* @param {String} query
* @param {Object} cfg
* @param {String} cfg.language Query language, default is Standard SQL
* @param {String} cfg.indent Characters used for indentation, default is " " (2 spaces)
* @param {Boolean} cfg.uppercase Converts keywords to uppercase
* @param {Integer} cfg.linesBetweenQueries How many line breaks between queries
* @param {Object} cfg.params Collection of params for placeholder replacement
* @return {String}
* @param {string} query - input SQL query string
* @param {FormatOptions} cfg Configuration options (see docs in README)
* @return {string} formatted query
*/

@@ -62,20 +91,31 @@

if (typeof query !== 'string') {
throw new Error('Invalid query argument. Extected string, instead got ' + _typeof(query));
throw new Error('Invalid query argument. Expected string, instead got ' + _typeof(query));
}
var Formatter = _StandardSqlFormatter["default"];
var options = validateConfig(_objectSpread(_objectSpread({}, defaultOptions), cfg));
var Formatter = formatters[options.language];
return new Formatter(options).format(query);
};
if (cfg.language !== undefined) {
Formatter = formatters[cfg.language];
exports.format = format;
function validateConfig(cfg) {
if (!supportedDialects.includes(cfg.language)) {
throw new Error("Unsupported SQL dialect: ".concat(cfg.language));
}
if (Formatter === undefined) {
throw Error("Unsupported SQL dialect: ".concat(cfg.language));
if ((0, _utils.isNumber)(cfg.newline) && cfg.newline <= 0) {
throw new Error('newline config must be a positive number.');
}
return new Formatter(cfg).format(query);
};
if (cfg.lineWidth <= 0) {
throw new Error("lineWidth config must be positive number. Received ".concat(cfg.lineWidth, " instead."));
}
exports.format = format;
var supportedDialects = Object.keys(formatters);
exports.supportedDialects = supportedDialects;
if (cfg.commaPosition === 'before' && cfg.indent === '\t') {
throw new Error('commaPosition: before does not work when tabs are used for indentation.');
}
return cfg;
}
//# sourceMappingURL=sqlFormatter.js.map

@@ -6,5 +6,23 @@ "use strict";

});
exports.sortByLengthDesc = exports.escapeRegExp = exports.isEmpty = exports.last = exports.trimSpacesEnd = void 0;
exports.trimSpacesEnd = exports.sortByLengthDesc = exports.maxLength = exports.last = exports.isNumber = exports.isEmpty = exports.escapeRegExp = exports.dedupe = void 0;
// Only removes spaces, not newlines
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
var dedupe = function dedupe(arr) {
return _toConsumableArray(new Set(arr));
}; // Only removes spaces, not newlines
exports.dedupe = dedupe;
var trimSpacesEnd = function trimSpacesEnd(str) {

@@ -44,3 +62,20 @@ return str.replace(/[\t ]+$/, '');

};
/** Get length of longest string in list of strings */
exports.sortByLengthDesc = sortByLengthDesc;
exports.sortByLengthDesc = sortByLengthDesc;
var maxLength = function maxLength(strings) {
return strings.reduce(function (max, cur) {
return Math.max(max, cur.length);
}, 0);
};
exports.maxLength = maxLength;
var isNumber = function isNumber(value) {
return typeof value === 'number';
};
exports.isNumber = isNumber;
//# sourceMappingURL=utils.js.map
{
"name": "sql-formatter",
"version": "4.0.2",
"version": "6.0.0-beta.1",
"description": "Format whitespace in a SQL query to make it more readable",
"license": "MIT",
"main": "lib/sqlFormatter.js",
"types": "src/sqlFormatter.d.ts",
"main": "lib/index.js",
"module": "dist/sql-formatter.min.js",
"types": "lib/index.d.ts",
"bin": {
"sql-formatter": "./bin/sqlfmt.js"
"sql-formatter": "./bin/sql-formatter-cli.js"
},

@@ -28,2 +29,3 @@ "keywords": [

"Adrien Pyke <adpyke@gmail.com>",
"Alexandr Kozhevnikov <aedkozhevnikov@sberbank.ru>",
"Andrew",

@@ -36,5 +38,7 @@ "Benjamin Bellamy",

"George Leslie-Waksman <waksman@gmail.com>",
"htaketani <h.taketani@gmail.com>",
"Ian Campbell <icampbell@immuta.com>",
"ivan baktsheev",
"João Pimentel Ferreira",
"Justin Dane Vallar <jdvallar@gmail.com>",
"Martin Nowak <code@dawg.eu>",

@@ -50,6 +54,11 @@ "Matheus Salmi <mathsalmi@gmail.com>",

"Rodrigo Stuchi",
"Romain Rigaux <hello@getromain.com>",
"Sasha Aliashkevich <olsender@gmail.com>",
"Sean Song <mail@seansong.dev>",
"Sergei Egorov <sergei.egorov@zeroturnaround.com>",
"Steven Yung <stevenyung@fastmail.com>",
"Toliver <teejae@gmail.com>",
"Tyler Jones <tyler.jones@txwormhole.com>",
"Uku Pattak <ukupat@gmail.com>"
"Uku Pattak <ukupat@gmail.com>",
"Xin Hu <hoosin.git@gmail.com>"
],

@@ -59,19 +68,25 @@ "files": [

"dist",
"lib",
"src"
"lib"
],
"scripts": {
"clean": "rimraf lib dist",
"clean": "rimraf lib dist coverage",
"ts:check": "tsc --noEmit",
"lint": "eslint .",
"pretty": "prettier --write .",
"fix": "yarn pretty && eslint --fix .",
"pretty:check": "prettier --check .",
"test": "jest",
"test:watch": "npm run test -- --watch",
"check": "npm run pretty:check && npm run lint && npm run test",
"build": "npm run build:commonjs && npm run build:umd && npm run build:umd:min",
"build:commonjs": "babel src --out-dir lib",
"test:watch": "yarn test -- --watch",
"check": "yarn ts:check && yarn pretty:check && yarn lint && yarn test",
"prepare": "yarn clean && yarn fix && yarn check && yarn build",
"build:commonjs": "babel src --out-dir lib --extensions .ts --source-maps && tsc --module commonjs --emitDeclarationOnly --isolatedModules",
"build:umd": "webpack --config webpack.dev.js",
"build:umd:min": "webpack --config webpack.prod.js",
"prepare": "npm run clean && npm run check && npm run build"
"build": "yarn build:commonjs && yarn build:umd && yarn build:umd:min",
"release": "release-it"
},
"pre-push": [
"ts:check",
"lint"
],
"repository": {

@@ -84,2 +99,5 @@ "type": "git",

},
"dependencies": {
"argparse": "^2.0.1"
},
"devDependencies": {

@@ -90,29 +108,41 @@ "@babel/cli": "^7.10.4",

"@babel/preset-env": "^7.10.4",
"@babel/preset-typescript": "^7.15.0",
"@jest/globals": "^28.0.2",
"@types/babel__core": "^7.1.15",
"@types/jest": "^27.5.0",
"@typescript-eslint/eslint-plugin": "^5.21.0",
"@typescript-eslint/parser": "^5.21.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.1.0",
"babel-jest": "^28.0.2",
"babel-loader": "^8.1.0",
"babel-plugin-add-module-exports": "^1.0.2",
"dedent-js": "^1.0.1",
"eslint": "^7.4.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-config-prettier": "^6.11.0",
"eslint": "^8.14.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-airbnb-typescript": "^17.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-prettier": "^3.1.4",
"jest": "^26.1.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "^28.0.2",
"pre-push": "^0.1.2",
"prettier": "^2.0.5",
"release-it": "^14.11.7",
"rimraf": "^3.0.2",
"webpack": "^4.43.0",
"webpack-cli": "^3.3.12",
"webpack-merge": "^5.0.8"
"ts-jest": "^28.0.0",
"ts-loader": "^9.2.6",
"typescript": "^4.3.5",
"webpack": "^5.64.1",
"webpack-cli": "^4.9.1",
"webpack-merge": "^5.8.0"
},
"jest": {
"preset": "ts-jest",
"roots": [
"test"
],
"testRegex": ".*Test",
"collectCoverage": true
},
"dependencies": {
"argparse": "^2.0.1"
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.ts"
]
}
}

@@ -1,19 +0,16 @@

# SQL Formatter [![NPM version](https://img.shields.io/npm/v/sql-formatter.svg)](https://npmjs.com/package/sql-formatter) [![Build Status](https://travis-ci.org/zeroturnaround/sql-formatter.svg?branch=master)](https://travis-ci.org/zeroturnaround/sql-formatter) [![Coverage Status](https://coveralls.io/repos/github/zeroturnaround/sql-formatter/badge.svg?branch=master)](https://coveralls.io/github/zeroturnaround/sql-formatter?branch=master)
<a href='https://github.com/zeroturnaround/sql-formatter'><img src="static/prettier-sql-clean.svg" width="128"/></a>
# SQL Formatter [![NPM version](https://img.shields.io/npm/v/sql-formatter.svg)](https://npmjs.com/package/sql-formatter) ![Build status](https://img.shields.io/github/workflow/status/zeroturnaround/sql-formatter/coveralls/master?label=Build&logo=Github) ![Coverage status](https://img.shields.io/coveralls/github/zeroturnaround/sql-formatter?branch=master&label=Coverage&logo=coveralls&style=plastic) [![VSCode](https://img.shields.io/visual-studio-marketplace/v/inferrinizzard.prettier-sql-vscode?label=vscode)](https://marketplace.visualstudio.com/items?itemName=inferrinizzard.prettier-sql-vscode)
**SQL Formatter** is a JavaScript library for pretty-printing SQL queries.
**Note.** The docs here are for the latest dev version.
For the latest release, see [v4.0.2](https://github.com/zeroturnaround/sql-formatter/tree/v4.0.2).
It started as a port of a [PHP Library][], but has since considerably diverged.
SQL formatter supports the following dialects:
It supports various SQL dialects:
GCP BigQuery, IBM DB2, Apache Hive, MariaDB, MySQL, Couchbase N1QL, Oracle PL/SQL, PostgreSQL, Amazon Redshift, Spark, SQL Server Transact-SQL.
See [language option docs](docs/language.md) for more details.
- **sql** - [Standard SQL][]
- **mariadb** - [MariaDB][]
- **mysql** - [MySQL][]
- **postgresql** - [PostgreSQL][]
- **db2** - [IBM DB2][]
- **plsql** - [Oracle PL/SQL][]
- **n1ql** - [Couchbase N1QL][]
- **redshift** - [Amazon Redshift][]
- **spark** - [Spark][]
- **tsql** - [SQL Server Transact-SQL][tsql]
It does not support:

@@ -24,3 +21,3 @@

&rarr; [Try the demo.](https://zeroturnaround.github.io/sql-formatter/)
→ [Try the demo.](https://zeroturnaround.github.io/sql-formatter)

@@ -35,4 +32,12 @@ ## Install

## Usage as library
Also available with yarn:
```sh
yarn add sql-formatter
```
## Usage
### Usage as library
```js

@@ -57,6 +62,6 @@ import { format } from 'sql-formatter';

format('SELECT * FROM tbl', {
language: 'spark', // Defaults to "sql" (see the above list of supported dialects)
indent: ' ', // Defaults to two spaces
uppercase: bool, // Defaults to false
linesBetweenQueries: 2, // Defaults to 1
language: 'spark',
indent: ' ',
keywordCase: 'upper',
linesBetweenQueries: 2,
});

@@ -67,17 +72,13 @@ ```

In addition to formatting, this library can also perform placeholder replacement in prepared SQL statements:
```js
// Named placeholders
format("SELECT * FROM tbl WHERE foo = @foo", {
params: {foo: "'bar'"}
}));
// Indexed placeholders
format("SELECT * FROM tbl WHERE foo = ?", {
params: ["'bar'"]
}));
format('SELECT * FROM tbl WHERE foo = ?', {
params: ["'bar'"],
});
```
Both result in:
Results in:
```
```sql
SELECT

@@ -91,4 +92,6 @@ *

## Usage from command line
For more details see [docs of params option.](docs/params.md)
### Usage from command line
The CLI tool will be installed under `sql-formatter`

@@ -102,4 +105,4 @@ and may be invoked via `npx sql-formatter`:

```
usage: sql-formatter [-h] [-o OUTPUT] [-l {db2,mariadb,mysql,n1ql,plsql,postgresql,redshift,spark,sql,tsql}]
[-i N | -t] [-u] [--lines-between-queries N] [--version] [FILE]
usage: sqlfmt.js [-h] [-o OUTPUT] \
[-l {bigquery,db2,hive,mariadb,mysql,n1ql,plsql,postgresql,redshift,spark,sql,tsql}] [-c CONFIG] [--version] [FILE]

@@ -109,17 +112,13 @@ SQL Formatter

positional arguments:
FILE Input SQL file (defaults to stdin)
FILE Input SQL file (defaults to stdin)
optional arguments:
-h, --help show this help message and exit
-o OUTPUT, --output OUTPUT
File to write SQL output (defaults to stdout)
-l {db2,mariadb,mysql,n1ql,plsql,postgresql,redshift,spark,sql,tsql},
--language {db2,mariadb,mysql,n1ql,plsql,postgresql,redshift,spark,sql,tsql}
SQL Formatter dialect (defaults to basic sql)
-i N, --indent N Number of spaces to indent query blocks (defaults to 2)
-t, --tab-indent Indent query blocks with tabs instead of spaces
-u, --uppercase Capitalize language keywords
--lines-between-queries N
How many newlines to insert between queries (separated by ";")
--version show program's version number and exit
-h, --help show this help message and exit
-o, --output OUTPUT
File to write SQL output (defaults to stdout)
-l, --language {bigquery,db2,hive,mariadb,mysql,n1ql,plsql,postgresql,redshift,spark,sql,tsql}
SQL dialect (defaults to standard sql)
-c, --config CONFIG
Path to config json file (will use default configs if unspecified)
--version show program's version number and exit
```

@@ -131,43 +130,66 @@

```sh
echo 'select * from tbl where id = 3' | sql-formatter -u
echo 'select * from tbl where id = 3' | sql-formatter
```
```sql
SELECT
select
*
FROM
from
tbl
WHERE
where
id = 3
```
## Usage without NPM
The tool also accepts a JSON config file with the `--config` option that takes this form:
```ts
{
"language": "spark",
"indent": " ",
"keywordCase": "upper",
"linesBetweenQueries": 2,
}
```
All fields are optional and all fields that are not specified will be filled with their default values.
### Configuration options
- [**`language`**](docs/language.md) the SQL dialect to use.
- [**`indent`**](docs/indent.md) amount of indentation to use (and whether to use tabs).
- [**`keywordCase`**](docs/keywordCase.md) uppercases or lowercases keywords.
- [**`indentStyle`**](docs/indentStyle.md) defines overall indentation style.
- [**`newline`**](docs/newline.md) determines when to break lists of items to multiple lines.
- [**`logicalOperatorNewline`**](docs/logicalOperatorNewline.md) newline before or after boolean operator (AND, OR, XOR).
- [**`aliasAs`**](docs/aliasAs.md) enforces or forbids use of AS keyword for aliases.
- [**`tabulateAlias`**](docs/tabulateAlias.md) aligns column aliases vertically.
- [**`commaPosition`**](docs/commaPosition.md) where to place the comma in column lists.
- [**`newlineBeforeOpenParen`**](docs/newlineBeforeOpenParen.md) placement of opening parenthesis.
- [**`newlineBeforeCloseParen`**](docs/newlineBeforeCloseParen.md) placement of closing parenthesis.
- [**`lineWidth`**](docs/lineWidth.md) maximum number of characters in parenthesized expressions to be kept on single line.
- [**`linesBetweenQueries`**](docs/linesBetweenQueries.md) how many newlines to insert between queries.
- [**`denseOperators`**](docs/denseOperators.md) packs operators densely without spaces.
- [**`newlineBeforeSemicolon`**](docs/newlineBeforeSemicolon.md) places semicolon on separate line.
- [**`params`**](docs/params.md) collection of values for placeholder replacement.
### Usage without NPM
If you don't use a module bundler, clone the repository, run `npm install` and grab a file from `/dist` directory to use inside a `<script>` tag.
This makes SQL Formatter available as a global variable `window.sqlFormatter`.
### Usage in editors
- [VSCode extension](https://marketplace.visualstudio.com/items?itemName=inferrinizzard.prettier-sql-vscode)
- [Vim extension](https://github.com/fannheyward/coc-sql/)
## Contributing
Make sure to run all checks:
Please see [CONTRIBUTING.md](CONTRIBUTING.md)
```sh
npm run check
```
You can read more about how the library works in [DOC.md](DOC.md)
...and you're ready to poke us with a pull request.
## License
[MIT](https://github.com/zeroturnaround/sql-formatter/blob/master/LICENSE)
[MIT](LICENSE)
[php library]: https://github.com/jdorn/sql-formatter
[standard sql]: https://en.wikipedia.org/wiki/SQL:2011
[couchbase n1ql]: http://www.couchbase.com/n1ql
[ibm db2]: https://www.ibm.com/analytics/us/en/technology/db2/
[oracle pl/sql]: http://www.oracle.com/technetwork/database/features/plsql/index.html
[amazon redshift]: https://docs.aws.amazon.com/redshift/latest/dg/cm_chap_SQLCommandRef.html
[spark]: https://spark.apache.org/docs/latest/api/sql/index.html
[postgresql]: https://www.postgresql.org/
[mariadb]: https://mariadb.com/
[mysql]: https://www.mysql.com/
[tsql]: https://docs.microsoft.com/en-us/sql/sql-server/

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc