UNPKG

sql-formatter

Version:

Formats whitespaces in a SQL query to make it more readable

1,513 lines (1,182 loc) 102 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["sqlFormatter"] = factory(); else root["sqlFormatter"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var _Db2Formatter = __webpack_require__(25); var _Db2Formatter2 = _interopRequireDefault(_Db2Formatter); var _N1qlFormatter = __webpack_require__(26); var _N1qlFormatter2 = _interopRequireDefault(_N1qlFormatter); var _StandardSqlFormatter = __webpack_require__(27); var _StandardSqlFormatter2 = _interopRequireDefault(_StandardSqlFormatter); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } exports["default"] = { /** * Format whitespaces 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 {Object} cfg.params Collection of params for placeholder replacement * @return {String} */ format: function format(query, cfg) { cfg = cfg || {}; switch (cfg.language) { case "db2": return new _Db2Formatter2["default"](cfg).format(query); case "n1ql": return new _N1qlFormatter2["default"](cfg).format(query); default: return new _StandardSqlFormatter2["default"](cfg).format(query); } } }; module.exports = exports["default"]; /***/ }), /* 1 */ /***/ (function(module, exports) { "use strict"; exports.__esModule = true; exports.default = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { var freeGlobal = __webpack_require__(13); /** Detect free variable `self`. */ var freeSelf = typeof self == 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function('return this')(); module.exports = root; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { var Symbol = __webpack_require__(10), getRawTag = __webpack_require__(48), objectToString = __webpack_require__(57); /** `Object#toString` result references. */ var nullTag = '[object Null]', undefinedTag = '[object Undefined]'; /** Built-in value references. */ var symToStringTag = Symbol ? Symbol.toStringTag : undefined; /** * The base implementation of `getTag` without fallbacks for buggy environments. * * @private * @param {*} value The value to query. * @returns {string} Returns the `toStringTag`. */ function baseGetTag(value) { if (value == null) { return value === undefined ? undefinedTag : nullTag; } return (symToStringTag && symToStringTag in Object(value)) ? getRawTag(value) : objectToString(value); } module.exports = baseGetTag; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { var baseIsNative = __webpack_require__(39), getValue = __webpack_require__(50); /** * Gets the native function at `key` of `object`. * * @private * @param {Object} object The object to query. * @param {string} key The key of the method to get. * @returns {*} Returns the function if it's native, else `undefined`. */ function getNative(object, key) { var value = getValue(object, key); return baseIsNative(value) ? value : undefined; } module.exports = getNative; /***/ }), /* 5 */ /***/ (function(module, exports) { /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = typeof value; return value != null && (type == 'object' || type == 'function'); } module.exports = isObject; /***/ }), /* 6 */ /***/ (function(module, exports) { /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return value != null && typeof value == 'object'; } module.exports = isObjectLike; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var _classCallCheck2 = __webpack_require__(1); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _trimEnd = __webpack_require__(74); var _trimEnd2 = _interopRequireDefault(_trimEnd); var _tokenTypes = __webpack_require__(9); var _tokenTypes2 = _interopRequireDefault(_tokenTypes); var _Indentation = __webpack_require__(22); var _Indentation2 = _interopRequireDefault(_Indentation); var _InlineBlock = __webpack_require__(23); var _InlineBlock2 = _interopRequireDefault(_InlineBlock); var _Params = __webpack_require__(24); var _Params2 = _interopRequireDefault(_Params); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var Formatter = function () { /** * @param {Object} cfg * @param {Object} cfg.indent * @param {Object} cfg.params * @param {Tokenizer} tokenizer */ function Formatter(cfg, tokenizer) { (0, _classCallCheck3["default"])(this, Formatter); this.cfg = cfg || {}; this.indentation = new _Indentation2["default"](this.cfg.indent); this.inlineBlock = new _InlineBlock2["default"](); this.params = new _Params2["default"](this.cfg.params); this.tokenizer = tokenizer; this.previousReservedWord = {}; } /** * Formats whitespaces in a SQL string to make it easier to read. * * @param {String} query The SQL query string * @return {String} formatted query */ Formatter.prototype.format = function format(query) { var tokens = this.tokenizer.tokenize(query); var formattedQuery = this.getFormattedQueryFromTokens(tokens); return formattedQuery.trim(); }; Formatter.prototype.getFormattedQueryFromTokens = function getFormattedQueryFromTokens(tokens) { var _this = this; var formattedQuery = ""; tokens.forEach(function (token, index) { if (token.type === _tokenTypes2["default"].WHITESPACE) { return; } else if (token.type === _tokenTypes2["default"].LINE_COMMENT) { formattedQuery = _this.formatLineComment(token, formattedQuery); } else if (token.type === _tokenTypes2["default"].BLOCK_COMMENT) { formattedQuery = _this.formatBlockComment(token, formattedQuery); } else if (token.type === _tokenTypes2["default"].RESERVED_TOPLEVEL) { formattedQuery = _this.formatToplevelReservedWord(token, formattedQuery); _this.previousReservedWord = token; } else if (token.type === _tokenTypes2["default"].RESERVED_NEWLINE) { formattedQuery = _this.formatNewlineReservedWord(token, formattedQuery); _this.previousReservedWord = token; } else if (token.type === _tokenTypes2["default"].RESERVED) { formattedQuery = _this.formatWithSpaces(token, formattedQuery); _this.previousReservedWord = token; } else if (token.type === _tokenTypes2["default"].OPEN_PAREN) { formattedQuery = _this.formatOpeningParentheses(tokens, index, formattedQuery); } else if (token.type === _tokenTypes2["default"].CLOSE_PAREN) { formattedQuery = _this.formatClosingParentheses(token, formattedQuery); } else if (token.type === _tokenTypes2["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 === "." || token.value === ";") { formattedQuery = _this.formatWithoutSpaces(token, formattedQuery); } else { formattedQuery = _this.formatWithSpaces(token, formattedQuery); } }); return formattedQuery; }; Formatter.prototype.formatLineComment = function formatLineComment(token, query) { return this.addNewline(query + token.value); }; Formatter.prototype.formatBlockComment = function formatBlockComment(token, query) { return this.addNewline(this.addNewline(query) + this.indentComment(token.value)); }; Formatter.prototype.indentComment = function indentComment(comment) { return comment.replace(/\n/g, "\n" + this.indentation.getIndent()); }; Formatter.prototype.formatToplevelReservedWord = function formatToplevelReservedWord(token, query) { this.indentation.decreaseTopLevel(); query = this.addNewline(query); this.indentation.increaseToplevel(); query += this.equalizeWhitespace(token.value); return this.addNewline(query); }; Formatter.prototype.formatNewlineReservedWord = function formatNewlineReservedWord(token, query) { return this.addNewline(query) + this.equalizeWhitespace(token.value) + " "; }; // Replace any sequence of whitespace characters with single space Formatter.prototype.equalizeWhitespace = function equalizeWhitespace(string) { return string.replace(/\s+/g, " "); }; // Opening parentheses increase the block indent level and start a new line Formatter.prototype.formatOpeningParentheses = function formatOpeningParentheses(tokens, index, query) { // Take out the preceding space unless there was whitespace there in the original query or another opening parens var previousToken = tokens[index - 1]; if (previousToken && previousToken.type !== _tokenTypes2["default"].WHITESPACE && previousToken.type !== _tokenTypes2["default"].OPEN_PAREN) { query = (0, _trimEnd2["default"])(query); } query += tokens[index].value; this.inlineBlock.beginIfPossible(tokens, index); if (!this.inlineBlock.isActive()) { this.indentation.increaseBlockLevel(); query = this.addNewline(query); } return query; }; // Closing parentheses decrease the block indent level Formatter.prototype.formatClosingParentheses = function formatClosingParentheses(token, query) { if (this.inlineBlock.isActive()) { this.inlineBlock.end(); return this.formatWithSpaceAfter(token, query); } else { this.indentation.decreaseBlockLevel(); return this.formatWithSpaces(token, this.addNewline(query)); } }; Formatter.prototype.formatPlaceholder = function formatPlaceholder(token, query) { return query + this.params.get(token) + " "; }; // Commas start a new line (unless within inline parentheses or SQL "LIMIT" clause) Formatter.prototype.formatComma = function formatComma(token, query) { query = (0, _trimEnd2["default"])(query) + token.value + " "; if (this.inlineBlock.isActive()) { return query; } else if (/^LIMIT$/i.test(this.previousReservedWord.value)) { return query; } else { return this.addNewline(query); } }; Formatter.prototype.formatWithSpaceAfter = function formatWithSpaceAfter(token, query) { return (0, _trimEnd2["default"])(query) + token.value + " "; }; Formatter.prototype.formatWithoutSpaces = function formatWithoutSpaces(token, query) { return (0, _trimEnd2["default"])(query) + token.value; }; Formatter.prototype.formatWithSpaces = function formatWithSpaces(token, query) { return query + token.value + " "; }; Formatter.prototype.addNewline = function addNewline(query) { return (0, _trimEnd2["default"])(query) + "\n" + this.indentation.getIndent(); }; return Formatter; }(); exports["default"] = Formatter; module.exports = exports["default"]; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var _classCallCheck2 = __webpack_require__(1); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _isEmpty = __webpack_require__(66); var _isEmpty2 = _interopRequireDefault(_isEmpty); var _escapeRegExp = __webpack_require__(63); var _escapeRegExp2 = _interopRequireDefault(_escapeRegExp); var _tokenTypes = __webpack_require__(9); var _tokenTypes2 = _interopRequireDefault(_tokenTypes); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var Tokenizer = 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.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 # */ function Tokenizer(cfg) { (0, _classCallCheck3["default"])(this, Tokenizer); this.WHITESPACE_REGEX = /^(\s+)/; this.NUMBER_REGEX = /^((-\s*)?[0-9]+(\.[0-9]+)?|0x[0-9a-fA-F]+|0b[01]+)\b/; this.OPERATOR_REGEX = /^(!=|<>|==|<=|>=|!<|!>|\|\||::|->>|->|.)/; this.BLOCK_COMMENT_REGEX = /^(\/\*[^]*?(?:\*\/|$))/; this.LINE_COMMENT_REGEX = this.createLineCommentRegex(cfg.lineCommentTypes); this.RESERVED_TOPLEVEL_REGEX = this.createReservedWordRegex(cfg.reservedToplevelWords); this.RESERVED_NEWLINE_REGEX = this.createReservedWordRegex(cfg.reservedNewlineWords); this.RESERVED_PLAIN_REGEX = this.createReservedWordRegex(cfg.reservedWords); this.WORD_REGEX = this.createWordRegex(cfg.specialWordChars); this.STRING_REGEX = this.createStringRegex(cfg.stringTypes); this.OPEN_PAREN_REGEX = this.createParenRegex(cfg.openParens); this.CLOSE_PAREN_REGEX = this.createParenRegex(cfg.closeParens); this.INDEXED_PLACEHOLDER_REGEX = this.createPlaceholderRegex(cfg.indexedPlaceholderTypes, "[0-9]*"); this.IDENT_NAMED_PLACEHOLDER_REGEX = this.createPlaceholderRegex(cfg.namedPlaceholderTypes, "[a-zA-Z0-9._$]+"); this.STRING_NAMED_PLACEHOLDER_REGEX = this.createPlaceholderRegex(cfg.namedPlaceholderTypes, this.createStringPattern(cfg.stringTypes)); } Tokenizer.prototype.createLineCommentRegex = function createLineCommentRegex(lineCommentTypes) { return new RegExp("^((?:" + lineCommentTypes.map(function (c) { return (0, _escapeRegExp2["default"])(c); }).join("|") + ").*?(?:\n|$))"); }; Tokenizer.prototype.createReservedWordRegex = function createReservedWordRegex(reservedWords) { var reservedWordsPattern = reservedWords.join("|").replace(/ /g, "\\s+"); return new RegExp("^(" + reservedWordsPattern + ")\\b", "i"); }; Tokenizer.prototype.createWordRegex = function createWordRegex() { var specialChars = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; return new RegExp("^([\\w" + specialChars.join("") + "]+)"); }; Tokenizer.prototype.createStringRegex = function createStringRegex(stringTypes) { return new RegExp("^(" + this.createStringPattern(stringTypes) + ")"); }; // This enables the following string patterns: // 1. backtick quoted string using `` to escape // 2. square bracket quoted string (SQL Server) using ]] to escape // 3. double quoted string using "" or \" to escape // 4. single quoted string using '' or \' to escape // 5. national character quoted string using N'' or N\' to escape Tokenizer.prototype.createStringPattern = function createStringPattern(stringTypes) { var patterns = { "``": "((`[^`]*($|`))+)", "[]": "((\\[[^\\]]*($|\\]))(\\][^\\]]*($|\\]))*)", "\"\"": "((\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*(\"|$))+)", "''": "(('[^'\\\\]*(?:\\\\.[^'\\\\]*)*('|$))+)", "N''": "((N'[^N'\\\\]*(?:\\\\.[^N'\\\\]*)*('|$))+)" }; return stringTypes.map(function (t) { return patterns[t]; }).join("|"); }; Tokenizer.prototype.createParenRegex = function createParenRegex(parens) { return new RegExp("^(" + parens.map(function (p) { return (0, _escapeRegExp2["default"])(p); }).join("|") + ")"); }; Tokenizer.prototype.createPlaceholderRegex = function createPlaceholderRegex(types, pattern) { if ((0, _isEmpty2["default"])(types)) { return false; } var typesRegex = types.map(_escapeRegExp2["default"]).join("|"); return new RegExp("^((?:" + typesRegex + ")(?:" + pattern + "))"); }; /** * Takes a SQL string and breaks it into tokens. * Each token is an object with type and value. * * @param {String} input The SQL string * @return {Object[]} tokens An array of tokens. * @return {String} token.type * @return {String} token.value */ Tokenizer.prototype.tokenize = function tokenize(input) { var tokens = []; var token = void 0; // Keep processing the string until it is empty while (input.length) { // Get the next token and the token type token = this.getNextToken(input, token); // Advance the string input = input.substring(token.value.length); tokens.push(token); } return tokens; }; Tokenizer.prototype.getNextToken = function getNextToken(input, previousToken) { return this.getWhitespaceToken(input) || 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); }; Tokenizer.prototype.getWhitespaceToken = function getWhitespaceToken(input) { return this.getTokenOnFirstMatch({ input: input, type: _tokenTypes2["default"].WHITESPACE, regex: this.WHITESPACE_REGEX }); }; Tokenizer.prototype.getCommentToken = function getCommentToken(input) { return this.getLineCommentToken(input) || this.getBlockCommentToken(input); }; Tokenizer.prototype.getLineCommentToken = function getLineCommentToken(input) { return this.getTokenOnFirstMatch({ input: input, type: _tokenTypes2["default"].LINE_COMMENT, regex: this.LINE_COMMENT_REGEX }); }; Tokenizer.prototype.getBlockCommentToken = function getBlockCommentToken(input) { return this.getTokenOnFirstMatch({ input: input, type: _tokenTypes2["default"].BLOCK_COMMENT, regex: this.BLOCK_COMMENT_REGEX }); }; Tokenizer.prototype.getStringToken = function getStringToken(input) { return this.getTokenOnFirstMatch({ input: input, type: _tokenTypes2["default"].STRING, regex: this.STRING_REGEX }); }; Tokenizer.prototype.getOpenParenToken = function getOpenParenToken(input) { return this.getTokenOnFirstMatch({ input: input, type: _tokenTypes2["default"].OPEN_PAREN, regex: this.OPEN_PAREN_REGEX }); }; Tokenizer.prototype.getCloseParenToken = function getCloseParenToken(input) { return this.getTokenOnFirstMatch({ input: input, type: _tokenTypes2["default"].CLOSE_PAREN, regex: this.CLOSE_PAREN_REGEX }); }; Tokenizer.prototype.getPlaceholderToken = function getPlaceholderToken(input) { return this.getIdentNamedPlaceholderToken(input) || this.getStringNamedPlaceholderToken(input) || this.getIndexedPlaceholderToken(input); }; Tokenizer.prototype.getIdentNamedPlaceholderToken = function getIdentNamedPlaceholderToken(input) { return this.getPlaceholderTokenWithKey({ input: input, regex: this.IDENT_NAMED_PLACEHOLDER_REGEX, parseKey: function parseKey(v) { return v.slice(1); } }); }; Tokenizer.prototype.getStringNamedPlaceholderToken = function getStringNamedPlaceholderToken(input) { var _this = this; return this.getPlaceholderTokenWithKey({ input: input, regex: this.STRING_NAMED_PLACEHOLDER_REGEX, parseKey: function parseKey(v) { return _this.getEscapedPlaceholderKey({ key: v.slice(2, -1), quoteChar: v.slice(-1) }); } }); }; Tokenizer.prototype.getIndexedPlaceholderToken = function getIndexedPlaceholderToken(input) { return this.getPlaceholderTokenWithKey({ input: input, regex: this.INDEXED_PLACEHOLDER_REGEX, parseKey: function parseKey(v) { return v.slice(1); } }); }; Tokenizer.prototype.getPlaceholderTokenWithKey = function getPlaceholderTokenWithKey(_ref) { var input = _ref.input, regex = _ref.regex, parseKey = _ref.parseKey; var token = this.getTokenOnFirstMatch({ input: input, regex: regex, type: _tokenTypes2["default"].PLACEHOLDER }); if (token) { token.key = parseKey(token.value); } return token; }; Tokenizer.prototype.getEscapedPlaceholderKey = function getEscapedPlaceholderKey(_ref2) { var key = _ref2.key, quoteChar = _ref2.quoteChar; return key.replace(new RegExp((0, _escapeRegExp2["default"])("\\") + quoteChar, "g"), quoteChar); }; // Decimal, binary, or hex numbers Tokenizer.prototype.getNumberToken = function getNumberToken(input) { return this.getTokenOnFirstMatch({ input: input, type: _tokenTypes2["default"].NUMBER, regex: this.NUMBER_REGEX }); }; // Punctuation and symbols Tokenizer.prototype.getOperatorToken = function getOperatorToken(input) { return this.getTokenOnFirstMatch({ input: input, type: _tokenTypes2["default"].OPERATOR, regex: this.OPERATOR_REGEX }); }; Tokenizer.prototype.getReservedWordToken = function getReservedWordToken(input, previousToken) { // 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 === ".") { return; } return this.getToplevelReservedToken(input) || this.getNewlineReservedToken(input) || this.getPlainReservedToken(input); }; Tokenizer.prototype.getToplevelReservedToken = function getToplevelReservedToken(input) { return this.getTokenOnFirstMatch({ input: input, type: _tokenTypes2["default"].RESERVED_TOPLEVEL, regex: this.RESERVED_TOPLEVEL_REGEX }); }; Tokenizer.prototype.getNewlineReservedToken = function getNewlineReservedToken(input) { return this.getTokenOnFirstMatch({ input: input, type: _tokenTypes2["default"].RESERVED_NEWLINE, regex: this.RESERVED_NEWLINE_REGEX }); }; Tokenizer.prototype.getPlainReservedToken = function getPlainReservedToken(input) { return this.getTokenOnFirstMatch({ input: input, type: _tokenTypes2["default"].RESERVED, regex: this.RESERVED_PLAIN_REGEX }); }; Tokenizer.prototype.getWordToken = function getWordToken(input) { return this.getTokenOnFirstMatch({ input: input, type: _tokenTypes2["default"].WORD, regex: this.WORD_REGEX }); }; Tokenizer.prototype.getTokenOnFirstMatch = function getTokenOnFirstMatch(_ref3) { var input = _ref3.input, type = _ref3.type, regex = _ref3.regex; var matches = input.match(regex); if (matches) { return { type: type, value: matches[1] }; } }; return Tokenizer; }(); exports["default"] = Tokenizer; module.exports = exports["default"]; /***/ }), /* 9 */ /***/ (function(module, exports) { "use strict"; exports.__esModule = true; /** * Constants for token types */ exports["default"] = { WHITESPACE: "whitespace", WORD: "word", STRING: "string", RESERVED: "reserved", RESERVED_TOPLEVEL: "reserved-toplevel", RESERVED_NEWLINE: "reserved-newline", OPERATOR: "operator", OPEN_PAREN: "open-paren", CLOSE_PAREN: "close-paren", LINE_COMMENT: "line-comment", BLOCK_COMMENT: "block-comment", NUMBER: "number", PLACEHOLDER: "placeholder" }; module.exports = exports["default"]; /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { var root = __webpack_require__(2); /** Built-in value references. */ var Symbol = root.Symbol; module.exports = Symbol; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { var baseToString = __webpack_require__(12); /** * Converts `value` to a string. An empty string is returned for `null` * and `undefined` values. The sign of `-0` is preserved. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to convert. * @returns {string} Returns the converted string. * @example * * _.toString(null); * // => '' * * _.toString(-0); * // => '-0' * * _.toString([1, 2, 3]); * // => '1,2,3' */ function toString(value) { return value == null ? '' : baseToString(value); } module.exports = toString; /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { var Symbol = __webpack_require__(10), arrayMap = __webpack_require__(33), isArray = __webpack_require__(16), isSymbol = __webpack_require__(20); /** Used as references for various `Number` constants. */ var INFINITY = 1 / 0; /** Used to convert symbols to primitives and strings. */ var symbolProto = Symbol ? Symbol.prototype : undefined, symbolToString = symbolProto ? symbolProto.toString : undefined; /** * The base implementation of `_.toString` which doesn't convert nullish * values to empty strings. * * @private * @param {*} value The value to process. * @returns {string} Returns the string. */ function baseToString(value) { // Exit early for strings to avoid a performance hit in some environments. if (typeof value == 'string') { return value; } if (isArray(value)) { // Recursively convert values (susceptible to call stack limits). return arrayMap(value, baseToString) + ''; } if (isSymbol(value)) { return symbolToString ? symbolToString.call(value) : ''; } var result = (value + ''); return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; } module.exports = baseToString; /***/ }), /* 13 */ /***/ (function(module, exports) { /* WEBPACK VAR INJECTION */(function(global) {/** Detect free variable `global` from Node.js. */ var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; module.exports = freeGlobal; /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) /***/ }), /* 14 */ /***/ (function(module, exports) { /** Used for built-in method references. */ var objectProto = Object.prototype; /** * Checks if `value` is likely a prototype object. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. */ function isPrototype(value) { var Ctor = value && value.constructor, proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; return value === proto; } module.exports = isPrototype; /***/ }), /* 15 */ /***/ (function(module, exports) { /** Used for built-in method references. */ var funcProto = Function.prototype; /** Used to resolve the decompiled source of functions. */ var funcToString = funcProto.toString; /** * Converts `func` to its source code. * * @private * @param {Function} func The function to convert. * @returns {string} Returns the source code. */ function toSource(func) { if (func != null) { try { return funcToString.call(func); } catch (e) {} try { return (func + ''); } catch (e) {} } return ''; } module.exports = toSource; /***/ }), /* 16 */ /***/ (function(module, exports) { /** * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an array, else `false`. * @example * * _.isArray([1, 2, 3]); * // => true * * _.isArray(document.body.children); * // => false * * _.isArray('abc'); * // => false * * _.isArray(_.noop); * // => false */ var isArray = Array.isArray; module.exports = isArray; /***/ }), /* 17 */ /***/ (function(module, exports, __webpack_require__) { var isFunction = __webpack_require__(18), isLength = __webpack_require__(19); /** * Checks if `value` is array-like. A value is considered array-like if it's * not a function and has a `value.length` that's an integer greater than or * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is array-like, else `false`. * @example * * _.isArrayLike([1, 2, 3]); * // => true * * _.isArrayLike(document.body.children); * // => true * * _.isArrayLike('abc'); * // => true * * _.isArrayLike(_.noop); * // => false */ function isArrayLike(value) { return value != null && isLength(value.length) && !isFunction(value); } module.exports = isArrayLike; /***/ }), /* 18 */ /***/ (function(module, exports, __webpack_require__) { var baseGetTag = __webpack_require__(3), isObject = __webpack_require__(5); /** `Object#toString` result references. */ var asyncTag = '[object AsyncFunction]', funcTag = '[object Function]', genTag = '[object GeneratorFunction]', proxyTag = '[object Proxy]'; /** * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a function, else `false`. * @example * * _.isFunction(_); * // => true * * _.isFunction(/abc/); * // => false */ function isFunction(value) { if (!isObject(value)) { return false; } // The use of `Object#toString` avoids issues with the `typeof` operator // in Safari 9 which returns 'object' for typed arrays and other constructors. var tag = baseGetTag(value); return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; } module.exports = isFunction; /***/ }), /* 19 */ /***/ (function(module, exports) { /** Used as references for various `Number` constants. */ var MAX_SAFE_INTEGER = 9007199254740991; /** * Checks if `value` is a valid array-like length. * * **Note:** This method is loosely based on * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. * @example * * _.isLength(3); * // => true * * _.isLength(Number.MIN_VALUE); * // => false * * _.isLength(Infinity); * // => false * * _.isLength('3'); * // => false */ function isLength(value) { return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } module.exports = isLength; /***/ }), /* 20 */ /***/ (function(module, exports, __webpack_require__) { var baseGetTag = __webpack_require__(3), isObjectLike = __webpack_require__(6); /** `Object#toString` result references. */ var symbolTag = '[object Symbol]'; /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return typeof value == 'symbol' || (isObjectLike(value) && baseGetTag(value) == symbolTag); } module.exports = isSymbol; /***/ }), /* 21 */ /***/ (function(module, exports) { module.exports = function(module) { if(!module.webpackPolyfill) { module.deprecate = function() {}; module.paths = []; // module.parent = undefined by default module.children = []; module.webpackPolyfill = 1; } return module; } /***/ }), /* 22 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var _classCallCheck2 = __webpack_require__(1); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _repeat = __webpack_require__(69); var _repeat2 = _interopRequireDefault(_repeat); var _last = __webpack_require__(68); var _last2 = _interopRequireDefault(_last); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var INDENT_TYPE_TOP_LEVEL = "top-level"; var INDENT_TYPE_BLOCK_LEVEL = "block-level"; /** * Manages indentation levels. * * There are two types of indentation levels: * * - BLOCK_LEVEL : increased by open-parenthesis * - TOP_LEVEL : increased by RESERVED_TOPLEVEL words */ var Indentation = function () { /** * @param {String} indent Indent value, default is " " (2 spaces) */ function Indentation(indent) { (0, _classCallCheck3["default"])(this, Indentation); this.indent = indent || " "; this.indentTypes = []; } /** * Returns current indentation string. * @return {String} */ Indentation.prototype.getIndent = function getIndent() { return (0, _repeat2["default"])(this.indent, this.indentTypes.length); }; /** * Increases indentation by one top-level indent. */ Indentation.prototype.increaseToplevel = function increaseToplevel() { this.indentTypes.push(INDENT_TYPE_TOP_LEVEL); }; /** * Increases indentation by one block-level indent. */ Indentation.prototype.increaseBlockLevel = function increaseBlockLevel() { this.indentTypes.push(INDENT_TYPE_BLOCK_LEVEL); }; /** * Decreases indentation by one top-level indent. * Does nothing when the previous indent is not top-level. */ Indentation.prototype.decreaseTopLevel = function decreaseTopLevel() { if ((0, _last2["default"])(this.indentTypes) === INDENT_TYPE_TOP_LEVEL) { this.indentTypes.pop(); } }; /** * Decreases indentation by one block-level indent. * If there are top-level indents within the block-level indent, * throws away these as well. */ Indentation.prototype.decreaseBlockLevel = function decreaseBlockLevel() { while (this.indentTypes.length > 0) { var type = this.indentTypes.pop(); if (type !== INDENT_TYPE_TOP_LEVEL) { break; } } }; return Indentation; }(); exports["default"] = Indentation; module.exports = exports["default"]; /***/ }), /* 23 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var _classCallCheck2 = __webpack_require__(1); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _tokenTypes = __webpack_require__(9); var _tokenTypes2 = _interopRequireDefault(_tokenTypes); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var INLINE_MAX_LENGTH = 50; /** * 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 * expressions where open-parenthesis causes newline and increase of indentation. */ var InlineBlock = function () { function InlineBlock() { (0, _classCallCheck3["default"])(this, InlineBlock); this.level = 0; } /** * Begins inline block when lookahead through upcoming tokens determines * that the block would be smaller than INLINE_MAX_LENGTH. * @param {Object[]} tokens Array of all tokens * @param {Number} index Current token position */ InlineBlock.prototype.beginIfPossible = function beginIfPossible(tokens, index) { if (this.level === 0 && this.isInlineBlock(tokens, index)) { this.level = 1; } else if (this.level > 0) { this.level++; } else { this.level = 0; } }; /** * Finishes current inline block. * There might be several nested ones. */ InlineBlock.prototype.end = function end() { this.level--; }; /** * True when inside an inline block * @return {Boolean} */ InlineBlock.prototype.isActive = function isActive() { return this.level > 0; }; // Check if this should be an inline parentheses block // Examples are "NOW()", "COUNT(*)", "int(10)", key(`somecolumn`), DECIMAL(7,2) InlineBlock.prototype.isInlineBlock = function isInlineBlock(tokens, index) { var length = 0; var level = 0; for (var i = index; i < tokens.length; i++) { var token = tokens[i]; length += token.value.length; // Overran max length if (length > INLINE_MAX_LENGTH) { return false; } if (token.type === _tokenTypes2["default"].OPEN_PAREN) { level++; } else if (token.type === _tokenTypes2["default"].CLOSE_PAREN) { level--; if (level === 0) { return true; } } if (this.isForbiddenToken(token)) { return false; } } return false; }; // Reserved words that cause newlines, comments and semicolons // are not allowed inside inline parentheses block InlineBlock.prototype.isForbiddenToken = function isForbiddenToken(_ref) { var type = _ref.type, value = _ref.value; return type === _tokenTypes2["default"].RESERVED_TOPLEVEL || type === _tokenTypes2["default"].RESERVED_NEWLINE || type === _tokenTypes2["default"].COMMENT || type === _tokenTypes2["default"].BLOCK_COMMENT || value === ";"; }; return InlineBlock; }(); exports["default"] = InlineBlock; module.exports = exports["default"]; /***/ }), /* 24 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var _classCallCheck2 = __webpack_require__(1); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } /** * Handles placeholder replacement with given params. */ var Params = function () { /** * @param {Object} params */ function Params(params) { (0, _classCallCheck3["default"])(this, Params); this.params = params; 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 */ Params.prototype.get = function get(_ref) { var key = _ref.key, value = _ref.value; if (!this.params) { return value; } if (key) { return this.params[key]; } return this.params[this.index++]; }; return Params; }(); exports["default"] = Params; module.exports = exports["default"]; /***/ }), /* 25 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; exports.__esModule = true; var _classCallCheck2 = __webpack_require__(1); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _Formatter = __webpack_require__(7); var _Formatter2 = _interopRequireDefault(_Formatter); var _Tokenizer = __webpack_require__(8); var _Tokenizer2 = _interopRequireDefault(_Tokenizer); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } var reservedWords = ["ABS", "ACTIVATE", "ALIAS", "ALL", "ALLOCATE", "ALLOW", "ALTER", "ANY", "ARE", "ARRAY", "AS", "ASC", "ASENSITIVE", "ASSOCIATE", "ASUTIME", "ASYMMETRIC", "AT", "ATOMIC", "ATTRIBUTES", "AUDIT", "AUTHORIZATION", "AUX", "AUXILIARY", "AVG", "BEFORE", "BEGIN", "BETWEEN", "BIGINT", "BINARY", "BLOB", "BOOLEAN", "BOTH", "BUFFERPOOL", "BY", "CACHE", "CALL", "CALLED", "CAPTURE", "CARDINALITY", "CASCADED", "CASE", "CAST", "CCSID", "CEIL", "CEILING", "CHAR", "CHARACTER", "CHARACTER_LENGTH", "CHAR_LENGTH", "CHECK", "CLOB", "CLONE", "CLOSE", "CLUSTER", "COALESCE", "COLLATE", "COLLECT", "COLLECTION", "COLLID", "COLUMN", "COMMENT", "COMMIT", "CONCAT", "CONDITION", "CONNECT", "CONNECTION", "CONSTRAINT", "CONTAINS", "CONTINUE", "CONVERT", "CORR", "CORRESPONDING", "COUNT", "COUNT_BIG", "COVAR_POP", "COVAR_SAMP", "CREATE", "CROSS", "CUBE", "CUME_DIST", "CURRENT", "CURRENT_DATE", "CURRENT_DEFAULT_TRANSFORM_GROUP", "CURRENT_LC_CTYPE", "CURRENT_PATH", "CURRENT_ROLE", "CURRENT_SCHEMA", "CURRENT_SERVER", "CURRENT_TIME", "CURRENT_TIMESTAMP", "CURRENT_TIMEZONE", "CURRENT_TRANSFORM_GROUP_FOR_TYPE", "CURRENT_USER", "CURSOR", "CYCLE", "DATA", "DATABASE", "DATAPARTITIONNAME", "DATAPARTITIONNUM", "DATE", "DAY", "DAYS", "DB2GENERAL", "DB2GENRL", "DB2SQL", "DBINFO", "DBPARTITIONNAME", "DBPARTITIONNUM", "DEALLOCATE", "DEC", "DECIMAL", "DECLARE", "DEFAULT", "DEFAULTS", "DEFINITION", "DELETE", "DENSERANK", "DENSE_RANK", "DEREF", "DESCRIBE", "DESCRIPTOR", "DETERMINISTIC", "DIAGNOSTICS", "DISABLE", "DISALLOW", "DISCONNECT", "DISTINCT", "DO", "DOCUMENT", "DOUBLE", "DROP", "DSSIZE", "DYNAMIC", "EACH", "EDITPROC", "ELEMENT", "ELSE", "ELSEIF", "ENABLE", "ENCODING", "ENCRYPTION", "END", "END-EXEC", "ENDING", "ERASE", "ESCAPE", "EVERY", "EXCEPTION", "EXCLUDING", "EXCLUSIVE", "EXEC", "EXECUTE", "EXISTS", "EXIT", "EXP", "EXPLAIN", "EXTENDED", "EXTERNAL", "EXTRACT", "FALSE", "FENCED", "FETCH", "FIELDPROC", "FILE", "FILTER", "FINAL", "FLOAT", "FLOOR", "FOR", "FOREIGN", "FREE", "FULL", "FUNCTION", "FUSION", "GENERAL", "GENERATED", "GET", "GLOBAL", "GOTO", "GRANT", "GRAPHIC", "GROUP", "GROUPING", "HANDLER", "HASH", "HASHED_VALUE", "HINT", "HOLD", "HOUR", "HOURS", "IDENTITY", "IF", "IMMEDIATE", "IN", "INCLUDING", "INCLUSIVE", "INCREMENT", "INDEX", "INDICATOR", "INDICATORS", "INF", "INFINITY", "INHERIT", "INNER", "INOUT", "INSENSITIVE", "INSERT", "INT", "INTEGER", "INTEGRITY", "INTERSECTION", "INTERVAL", "INTO", "IS", "ISOBID", "ISOLATION", "ITERATE", "JAR", "JAVA", "KEEP", "KEY", "LABEL", "LANGUAGE", "LARGE", "LATERAL", "LC_CTYPE", "LEADING", "LEAVE", "LEFT", "LIKE", "LINKTYPE", "LN", "LOCAL", "LOCALDATE", "LOCALE", "LOCALTIME", "LOCALTIMESTAMP", "LOCATOR", "LOCATORS", "LOCK", "LOCKMAX", "LOCKSIZE", "LONG", "LOOP", "LOWER", "MAINTAINED", "MATCH", "MATERIALIZED", "MAX", "MAXVALUE", "MEMBER", "MERGE", "METHOD", "MICROSECOND", "MICROSECONDS", "MIN", "MINUTE", "MINUTES", "MINVALUE", "MOD", "MODE", "MODIFIES", "MODULE", "MONTH", "MONTHS", "MULTISET", "NAN", "NATIONAL", "NATURAL", "NCHAR", "NCLOB", "NEW", "NEW_TABLE", "NEXTVAL", "NO", "NOCACHE", "NOCYCLE", "NODENAME", "NODENUMBER", "NOMAXVALUE", "NOMINVALUE", "NONE", "NOORDER", "NORMALIZE", "NORMALIZED", "NOT", "NULL", "NULLIF", "NULLS", "NUMERIC", "NUMPARTS", "OBID", "OCTET_LENGTH", "OF", "OFFSET", "OLD", "OLD_TABLE", "ON", "ONLY", "OPEN", "OPTIMIZATION", "OPTIMIZE", "OPTION", "ORDER", "OUT", "OUTER", "OVER", "OVERLAPS", "OVERLAY", "OVERRIDING", "PACKAGE", "PADDED", "PAGESIZE", "PARAMETER", "PART", "PARTITION", "PARTITIONED", "PARTITIONING", "PARTITIONS", "PASSWORD", "PATH", "PERCENTILE_CONT", "PERCENTILE_DISC", "PERCENT_RANK", "PIECESIZE", "PLAN", "POSITION", "POWER", "PRECISION", "PREPARE", "PREVVAL", "PRIMARY", "PRIQTY", "PRIVILEGES", "PROCEDURE", "PROGRAM", "PSID", "PUBLIC", "QUERY", "QUERYNO", "RANGE", "RANK", "READ", "READS", "REAL", "RECOVERY", "RECURSIVE", "REF", "REFERENCES", "REFERENCING", "REFRESH", "REGR_AVGX", "REGR_AVGY", "REGR_COUNT", "REGR_INTERCEPT", "REGR_R2", "REGR_SLOPE", "REGR_SXX", "REGR_SXY", "REGR_SYY", "RELEASE", "RENAME", "REPEAT", "RESET", "RESIGNAL", "RESTART", "RESTRICT", "RESULT", "RESULT_SET_LOCATOR", "RETURN", "RETURNS", "REVOKE", "RIGHT", "ROLE", "ROLLBACK", "ROLLUP", "ROUND_CEILING", "ROUND_DOWN", "ROUND_FLOOR", "ROUND_HALF_DOWN", "ROUND_HALF_EVEN", "ROUND_HALF_UP", "ROUND_UP", "ROUTINE", "ROW", "ROWNUMBER", "ROWS", "ROWSET", "ROW_NUMBER", "RRN", "RUN", "SAVEPOINT", "SCHEMA", "SCOPE", "SCRATCHPAD", "SCROLL", "SEARCH", "SECOND", "SECONDS", "SECQTY", "SECURITY", "SENSITIVE", "SEQUENCE", "SESSION", "SESSION_USER", "SIGNAL", "SIMILAR", "SIMPLE", "SMALLINT", "SNAN", "SOME", "SOURCE", "SPECIFIC", "SPECIFICTYPE", "SQL", "SQLEXCEPTION", "