├── .gitignore ├── LICENSE ├── README.md ├── carbon.png ├── package-lock.json ├── package.json ├── src ├── index.ts ├── keywords.ts └── types │ └── index.d.ts ├── test └── index.test.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # File created using '.gitignore Generator' for Visual Studio Code: https://bit.ly/vscode-gig 2 | 3 | # Created by https://www.gitignore.io/api/macos,visualstudiocode,node 4 | # Edit at https://www.gitignore.io/?templates=macos,visualstudiocode,node 5 | 6 | ### macOS ### 7 | # General 8 | .DS_Store 9 | .AppleDouble 10 | .LSOverride 11 | 12 | # Icon must end with two \r 13 | Icon 14 | 15 | # Thumbnails 16 | ._* 17 | 18 | # Files that might appear in the root of a volume 19 | .DocumentRevisions-V100 20 | .fseventsd 21 | .Spotlight-V100 22 | .TemporaryItems 23 | .Trashes 24 | .VolumeIcon.icns 25 | .com.apple.timemachine.donotpresent 26 | 27 | # Directories potentially created on remote AFP share 28 | .AppleDB 29 | .AppleDesktop 30 | Network Trash Folder 31 | Temporary Items 32 | .apdisk 33 | 34 | ### Node ### 35 | # Logs 36 | logs 37 | *.log 38 | npm-debug.log* 39 | yarn-debug.log* 40 | yarn-error.log* 41 | lerna-debug.log* 42 | 43 | # Diagnostic reports (https://nodejs.org/api/report.html) 44 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 45 | 46 | # Runtime data 47 | pids 48 | *.pid 49 | *.seed 50 | *.pid.lock 51 | 52 | # Directory for instrumented libs generated by jscoverage/JSCover 53 | lib-cov 54 | 55 | # Coverage directory used by tools like istanbul 56 | coverage 57 | *.lcov 58 | 59 | # nyc test coverage 60 | .nyc_output 61 | 62 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 63 | .grunt 64 | 65 | # Bower dependency directory (https://bower.io/) 66 | bower_components 67 | 68 | # node-waf configuration 69 | .lock-wscript 70 | 71 | # Compiled binary addons (https://nodejs.org/api/addons.html) 72 | build/Release 73 | 74 | # Dependency directories 75 | node_modules/ 76 | jspm_packages/ 77 | 78 | # TypeScript v1 declaration files 79 | typings/ 80 | 81 | # TypeScript cache 82 | *.tsbuildinfo 83 | 84 | # Optional npm cache directory 85 | .npm 86 | 87 | # Optional eslint cache 88 | .eslintcache 89 | 90 | # Optional REPL history 91 | .node_repl_history 92 | 93 | # Output of 'npm pack' 94 | *.tgz 95 | 96 | # Yarn Integrity file 97 | .yarn-integrity 98 | 99 | # dotenv environment variables file 100 | .env 101 | .env.test 102 | 103 | # parcel-bundler cache (https://parceljs.org/) 104 | .cache 105 | 106 | # next.js build output 107 | .next 108 | 109 | # nuxt.js build output 110 | .nuxt 111 | 112 | # react / gatsby 113 | public/ 114 | 115 | # vuepress build output 116 | .vuepress/dist 117 | 118 | # Serverless directories 119 | .serverless/ 120 | 121 | # FuseBox cache 122 | .fusebox/ 123 | 124 | # DynamoDB Local files 125 | .dynamodb/ 126 | 127 | ### VisualStudioCode ### 128 | .vscode/* 129 | !.vscode/settings.json 130 | !.vscode/tasks.json 131 | !.vscode/launch.json 132 | !.vscode/extensions.json 133 | 134 | ### VisualStudioCode Patch ### 135 | # Ignore all local history of files 136 | .history 137 | 138 | # End of https://www.gitignore.io/api/macos,visualstudiocode,node 139 | 140 | # Custom rules (everything added below won't be overriden by 'Generate .gitignore File' if you use 'Update' option) 141 | dist -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Zdravko Curic 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SQL log prettifier 2 | 3 | SQL query prettifier for your favorite logger 4 | 5 | ## Usage 6 | 7 | ```sh 8 | npm install sql-log-prettifier 9 | # or 10 | yarn add sql-log-prettifier 11 | ``` 12 | 13 | In your project require or import `sql-log-prettifier` 14 | ```js 15 | const { prettify } = require('sql-log-prettifier'); 16 | // import { prettify } from 'sql-log-prettifier'; 17 | 18 | const unformattedAndUglySql = `SELECT * FROM custom_table WHERE id = 1 AND name = 'Test'`; 19 | console.log(prettify(unformattedAndUglySql)); 20 | ``` 21 | Output will look something like this: 22 | 23 | 24 | 25 | ## Settings 26 | 27 | `prettify` function accepts `settings` as the second argument. 28 | 29 | Default settings are: 30 | ```js 31 | const defaultSettings = { 32 | format: true, 33 | noColors: false, 34 | settings: { 35 | functions: { 36 | color: '#ff5555', 37 | modifiers: ['bold'], 38 | }, 39 | keywords: { 40 | color: '#ff5555', 41 | modifiers: ['bold'], 42 | }, 43 | operators: { 44 | color: '#91B859', 45 | modifiers: ['bold'], 46 | }, 47 | strings: { 48 | color: '#FFFFF', 49 | }, 50 | numbers: { 51 | color: '#50fa7b', 52 | }, 53 | }, 54 | }; 55 | ``` 56 | 57 | ### TODO: 58 | - Add examples for popular loggers (`pino`, `winston`) 59 | - Update README.md 60 | - Anything else that needs to be done :construction_worker: 61 | 62 | 63 | ## Development 64 | 65 | `sql-log-prettifer` is built with [`tsdx`](https://github.com/jaredpalmer/tsdx). 66 | 67 | ``` 68 | # Running examples 69 | npm run start 70 | 71 | # Running tests 72 | npm run test 73 | 74 | # Running build 75 | npm run build 76 | ``` 77 | 78 | ## Contributing 79 | 80 | All contributions are welcome. 81 | 82 | ## License 83 | 84 | MIT @ Zdravko Ćurić [(zcuric)](https://github.com/zcuric) -------------------------------------------------------------------------------- /carbon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zcuric/sql-log-prettifier/4b3352a6e0cf624d87e0f7e9ded8aba85f1145c7/carbon.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sql-log-prettifier", 3 | "version": "0.1.2", 4 | "description": "SQL query prettifier for your favorite logger", 5 | "main": "dist/index.js", 6 | "types": "dist/index.d.ts", 7 | "repository": { 8 | "url": "zcuric/sql-log-prettifier", 9 | "type": "git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/zcuric/sql-log-prettifier/issues" 13 | }, 14 | "homepage": "https://github.com/zcuric/sql-log-prettifier#readme", 15 | "scripts": { 16 | "start": "tsdx watch", 17 | "build": "tsdx build", 18 | "test": "tsdx test", 19 | "lint": "tsdx lint" 20 | }, 21 | "keywords": [ 22 | "sql", 23 | "logger", 24 | "log", 25 | "pretty print", 26 | "sequelize", 27 | "logging" 28 | ], 29 | "author": "Zdravko Ćurić ", 30 | "license": "MIT", 31 | "dependencies": { 32 | "chalk": "^4.1.0", 33 | "sql-formatter": "^2.3.3" 34 | }, 35 | "devDependencies": { 36 | "@types/chalk": "^2.2.0", 37 | "@types/jest": "^26.0.14", 38 | "@types/node": "^14.11.8", 39 | "@types/sql-formatter": "^2.3.0", 40 | "@typescript-eslint/eslint-plugin": "^4.4.1", 41 | "@typescript-eslint/parser": "^4.4.1", 42 | "eslint": "^7.11.0", 43 | "husky": "^4.3.0", 44 | "tsdx": "^0.14.0", 45 | "tslib": "^2.0.3", 46 | "typescript": "^4.0.3" 47 | }, 48 | "husky": { 49 | "hooks": { 50 | "pre-commit": "tsdx lint" 51 | } 52 | }, 53 | "prettier": { 54 | "printWidth": 80, 55 | "semi": true, 56 | "singleQuote": true, 57 | "trailingComma": "es5" 58 | }, 59 | "files": [ 60 | "dist", 61 | "src" 62 | ] 63 | } 64 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import chalk from 'chalk'; 2 | import sqlFormatter from 'sql-formatter'; 3 | import keywords from './keywords'; 4 | import { Options, OutputSettings, Settings } from 'types'; 5 | 6 | const defaultOptions: Options = { 7 | format: true, 8 | noColors: false, 9 | settings: { 10 | functions: { 11 | color: '#ff5555', 12 | modifiers: ['bold'], 13 | }, 14 | keywords: { 15 | color: '#ff5555', 16 | modifiers: ['bold'], 17 | }, 18 | operators: { 19 | color: '#91B859', 20 | modifiers: ['bold'], 21 | }, 22 | strings: { 23 | color: '#FFFFF', 24 | }, 25 | numbers: { 26 | color: '#50fa7b', 27 | }, 28 | }, 29 | }; 30 | 31 | const substitute = ( 32 | word: string, 33 | { color = '#FFFFFF', modifiers = [] }: OutputSettings 34 | ) => { 35 | const ctx = new chalk.Instance({ level: 3 }); 36 | // @ts-ignore 37 | ctx.customColor = ctx.hex(color); 38 | const chalkModifiers = ['customColor', ...modifiers].join('.'); 39 | return ctx`{${chalkModifiers} ${word}}`; 40 | }; 41 | 42 | const colorKeywords = (query: string, words: Object, settings: Settings) => { 43 | const pattern = (word: string) => new RegExp(`\\b${word}\\b`, 'gmi'); 44 | 45 | Object.keys(words).forEach((key: string) => { 46 | words[key].forEach((word: string) => { 47 | query = query.replace(pattern(word), substitute(word, settings[key])); 48 | }); 49 | }); 50 | 51 | return query; 52 | }; 53 | 54 | const colorValues = (query: string, settings: Settings) => { 55 | const regexes = { 56 | strings: /('\w+')/gim, 57 | numbers: /(\s\b\d+\b)/gim, 58 | }; 59 | 60 | Object.keys(regexes).forEach((reg: string) => { 61 | query = query.replace(regexes[reg], substitute('$1', settings[reg])); 62 | }); 63 | 64 | return query; 65 | }; 66 | 67 | export const prettify = (query: string, options: Options = {}) => { 68 | const { format, noColors } = { ...defaultOptions, ...options }; 69 | const settings = { ...defaultOptions.settings, ...options.settings }; 70 | if (format) query = sqlFormatter.format(query); 71 | if (noColors) return query; 72 | query = colorKeywords(query, keywords, settings); 73 | query = colorValues(query, settings); 74 | return query; 75 | }; 76 | -------------------------------------------------------------------------------- /src/keywords.ts: -------------------------------------------------------------------------------- 1 | const operators = [ 2 | 'AND', 3 | 'BETWEEN', 4 | 'IN', 5 | 'LIKE', 6 | 'NOT', 7 | 'OR', 8 | 'IS', 9 | 'DIV', 10 | 'REGEXP', 11 | 'RLIKE', 12 | 'SOUNDS LIKE', 13 | 'XOR', 14 | ]; 15 | 16 | const functions = [ 17 | 'ASCII', 18 | 'CHAR_LENGTH', 19 | 'CHARACTER_LENGTH', 20 | 'CONCAT', 21 | 'CONCAT_WS', 22 | 'FIELD', 23 | 'FIND_IN_SET', 24 | 'FORMAT', 25 | 'INSERT', 26 | 'INSTR', 27 | 'LCASE', 28 | 'LEFT', 29 | 'LENGTH', 30 | 'LOCATE', 31 | 'LOWER', 32 | 'LPAD', 33 | 'LTRIM', 34 | 'MID', 35 | 'POSITION', 36 | 'REPEAT', 37 | 'REPLACE', 38 | 'REVERSE', 39 | 'RIGHT', 40 | 'RPAD', 41 | 'RTRIM', 42 | 'SPACE', 43 | 'STRCMP', 44 | 'SUBSTR', 45 | 'SUBSTRING', 46 | 'SUBSTRING_INDEX', 47 | 'TRIM', 48 | 'UCASE', 49 | 'UPPER', 50 | 'ABS', 51 | 'ACOS', 52 | 'ASIN', 53 | 'ATAN', 54 | 'ATAN2', 55 | 'AVG', 56 | 'CEIL', 57 | 'CEILING', 58 | 'COS', 59 | 'COT', 60 | 'COUNT', 61 | 'DEGREES', 62 | 'DIV', 63 | 'EXP', 64 | 'FLOOR', 65 | 'GREATEST', 66 | 'LEAST', 67 | 'LN', 68 | 'LOG', 69 | 'LOG10', 70 | 'LOG2', 71 | 'MAX', 72 | 'MIN', 73 | 'MOD', 74 | 'PI', 75 | 'POW', 76 | 'POWER', 77 | 'RADIANS', 78 | 'RAND', 79 | 'ROUND', 80 | 'SIGN', 81 | 'SIN', 82 | 'SQRT', 83 | 'SUM', 84 | 'TAN', 85 | 'TRUNCATE', 86 | 'ADDDATE', 87 | 'ADDTIME', 88 | 'CURDATE', 89 | 'CURRENT_DATE', 90 | 'CURRENT_TIME', 91 | 'CURRENT_TIMESTAMP', 92 | 'CURTIME', 93 | 'DATE', 94 | 'DATEDIFF', 95 | 'DATE_ADD', 96 | 'DATE_FORMAT', 97 | 'DATE_SUB', 98 | 'DAY', 99 | 'DAYNAME', 100 | 'DAYOFMONTH', 101 | 'DAYOFWEEK', 102 | 'DAYOFYEAR', 103 | 'EXTRACT', 104 | 'FROM_DAYS', 105 | 'HOUR', 106 | 'LAST_DAY', 107 | 'LOCALTIME', 108 | 'LOCALTIMESTAMP', 109 | 'MAKEDATE', 110 | 'MAKETIME', 111 | 'MICROSECOND', 112 | 'MINUTE', 113 | 'MONTH', 114 | 'MONTHNAME', 115 | 'NOW', 116 | 'PERIOD_ADD', 117 | 'PERIOD_DIFF', 118 | 'QUARTER', 119 | 'SECOND', 120 | 'SEC_TO_TIME', 121 | 'STR_TO_DATE', 122 | 'SUBDATE', 123 | 'SUBTIME', 124 | 'SYSDATE', 125 | 'TIME', 126 | 'TIME_FORMAT', 127 | 'TIME_TO_SEC', 128 | 'TIMEDIFF', 129 | 'TIMESTAMP', 130 | 'TO_DAYS', 131 | 'WEEK', 132 | 'WEEKDAY', 133 | 'WEEKOFYEAR', 134 | 'YEAR', 135 | 'YEARWEEK', 136 | 'BIN', 137 | 'BINARY', 138 | 'CASE', 139 | 'CAST', 140 | 'COALESCE', 141 | 'CONNECTION_ID', 142 | 'CONV', 143 | 'CONVERT', 144 | 'CURRENT_USER', 145 | 'DATABASE', 146 | 'IF', 147 | 'IFNULL', 148 | 'ISNULL', 149 | 'LAST_INSERT_ID', 150 | 'NULLIF', 151 | 'SESSION_USER', 152 | 'SYSTEM_USER', 153 | 'USER', 154 | 'VERSION', 155 | ]; 156 | 157 | const keywords = [ 158 | 'ACCESSIBLE', 159 | 'ACTION', 160 | 'ADD CONSTRAINT', 161 | 'ADD', 162 | 'AGAINST', 163 | 'AGGREGATE', 164 | 'ALGORITHM', 165 | 'ALL', 166 | 'ALTER COLUMN', 167 | 'ALTER TABLE', 168 | 'ALTER', 169 | 'ANALYSE', 170 | 'ANALYZE', 171 | 'AND', 172 | 'ANY', 173 | 'AS', 174 | 'ASC', 175 | 'AUTO_INCREMENT', 176 | 'AUTOCOMMIT', 177 | 'BACKUP DATABASE', 178 | 'BACKUP', 179 | 'BEGIN', 180 | 'BETWEEN', 181 | 'BINLOG', 182 | 'BOTH', 183 | 'CASCADE', 184 | 'CASE', 185 | 'CHANGE', 186 | 'CHANGED', 187 | 'CHARACTER SET', 188 | 'CHARSET', 189 | 'CHECK', 190 | 'CHECKSUM', 191 | 'COLLATE', 192 | 'COLLATION', 193 | 'COLUMN', 194 | 'COLUMNS', 195 | 'COMMENT', 196 | 'COMMIT', 197 | 'COMMITTED', 198 | 'COMPRESSED', 199 | 'CONCURRENT', 200 | 'CONSTRAINT', 201 | 'CONTAINS', 202 | 'CREATE DATABASE', 203 | 'CREATE INDEX', 204 | 'CREATE OR REPLACE VIEW', 205 | 'CREATE PROCEDURE', 206 | 'CREATE TABLE', 207 | 'CREATE UNIQUE INDEX', 208 | 'CREATE VIEW', 209 | 'CREATE', 210 | 'CROSS', 211 | 'DATABASE', 212 | 'DATABASES', 213 | 'DAY_HOUR', 214 | 'DAY_MINUTE', 215 | 'DAY_SECOND', 216 | 'DEFAULT', 217 | 'DEFINER', 218 | 'DELAYED', 219 | 'DELETE', 220 | 'DESC', 221 | 'DESCRIBE', 222 | 'DETERMINISTIC', 223 | 'DISTINCT', 224 | 'DISTINCTROW', 225 | 'DO', 226 | 'DROP COLUMN', 227 | 'DROP CONSTRAINT', 228 | 'DROP DATABASE', 229 | 'DROP DEFAULT', 230 | 'DROP INDEX', 231 | 'DROP TABLE', 232 | 'DROP VIEW', 233 | 'DROP', 234 | 'DUMPFILE', 235 | 'DUPLICATE', 236 | 'DYNAMIC', 237 | 'ELSE', 238 | 'ENCLOSED', 239 | 'END', 240 | 'ENGINE_TYPE', 241 | 'ENGINE', 242 | 'ENGINES', 243 | 'ESCAPE', 244 | 'ESCAPED', 245 | 'EVENTS', 246 | 'EXEC', 247 | 'EXECUTE', 248 | 'EXISTS', 249 | 'EXPLAIN', 250 | 'EXTENDED', 251 | 'FAST', 252 | 'FETCH', 253 | 'FIELDS', 254 | 'FILE', 255 | 'FIRST', 256 | 'FIXED', 257 | 'FLUSH', 258 | 'FOR', 259 | 'FORCE', 260 | 'FOREIGN KEY', 261 | 'FOREIGN', 262 | 'FROM', 263 | 'FULL OUTER JOIN', 264 | 'FULL', 265 | 'FULLTEXT', 266 | 'FUNCTION', 267 | 'GLOBAL', 268 | 'GRANT', 269 | 'GRANTS', 270 | 'GROUP BY', 271 | 'GROUP_CONCAT', 272 | 'HAVING', 273 | 'HEAP', 274 | 'HIGH_PRIORITY', 275 | 'HOSTS', 276 | 'HOUR_MINUTE', 277 | 'HOUR_SECOND', 278 | 'IDENTIFIED', 279 | 'IGNORE', 280 | 'IN', 281 | 'INDEX', 282 | 'INDEXES', 283 | 'INFILE', 284 | 'INNER JOIN', 285 | 'INSERT INTO SELECT', 286 | 'INSERT INTO', 287 | 'INSERT_ID', 288 | 'INSERT_METHOD', 289 | 'INTERVAL', 290 | 'INTO', 291 | 'INVOKER', 292 | 'IS NOT NULL', 293 | 'IS NULL', 294 | 'ISOLATION', 295 | 'JOIN', 296 | 'KEY', 297 | 'KEYS', 298 | 'KILL', 299 | 'LEADING', 300 | 'LEFT JOIN', 301 | 'LEVEL', 302 | 'LIKE', 303 | 'LIMIT', 304 | 'LINEAR', 305 | 'LINES', 306 | 'LOAD', 307 | 'LOCAL', 308 | 'LOCK', 309 | 'LOCKS', 310 | 'LOGS', 311 | 'LOW_PRIORITY', 312 | 'MARIA', 313 | 'MASTER_CONNECT_RETRY', 314 | 'MASTER_HOST', 315 | 'MASTER_LOG_FILE', 316 | 'MASTER', 317 | 'MATCH', 318 | 'MAX_CONNECTIONS_PER_HOUR', 319 | 'MAX_QUERIES_PER_HOUR', 320 | 'MAX_ROWS', 321 | 'MAX_UPDATES_PER_HOUR', 322 | 'MAX_USER_CONNECTIONS', 323 | 'MEDIUM', 324 | 'MERGE', 325 | 'MIN_ROWS', 326 | 'MINUTE_SECOND', 327 | 'MODE', 328 | 'MODIFY', 329 | 'MRG_MYISAM', 330 | 'MYISAM', 331 | 'NAMES', 332 | 'NATURAL', 333 | 'NOT NULL', 334 | 'NOT', 335 | 'NOW()', 336 | 'NULL', 337 | 'OFFSET', 338 | 'ON DELETE', 339 | 'ON UPDATE', 340 | 'ON', 341 | 'ONLY', 342 | 'OPEN', 343 | 'OPTIMIZE', 344 | 'OPTION', 345 | 'OPTIONALLY', 346 | 'OR', 347 | 'ORDER BY', 348 | 'OUTER JOIN', 349 | 'OUTFILE', 350 | 'PACK_KEYS', 351 | 'PAGE', 352 | 'PARTIAL', 353 | 'PARTITION', 354 | 'PARTITIONS', 355 | 'PASSWORD', 356 | 'PRIMARY KEY', 357 | 'PRIMARY', 358 | 'PRIVILEGES', 359 | 'PROCEDURE', 360 | 'PROCESS', 361 | 'PROCESSLIST', 362 | 'PURGE', 363 | 'QUICK', 364 | 'RAID_CHUNKS', 365 | 'RAID_CHUNKSIZE', 366 | 'RAID_TYPE', 367 | 'RAID0', 368 | 'RANGE', 369 | 'READ_ONLY', 370 | 'READ_WRITE', 371 | 'READ', 372 | 'REFERENCES', 373 | 'RELOAD', 374 | 'RENAME', 375 | 'REPAIR', 376 | 'REPEATABLE', 377 | 'REPLICATION', 378 | 'RESET', 379 | 'RESTORE', 380 | 'RESTRICT', 381 | 'RETURN', 382 | 'RETURNS', 383 | 'REVOKE', 384 | 'RIGHT JOIN', 385 | 'ROLLBACK', 386 | 'ROW_FORMAT', 387 | 'ROW', 388 | 'ROWNUM', 389 | 'ROWS', 390 | 'SECURITY', 391 | 'SELECT DISTINCT', 392 | 'SELECT INTO', 393 | 'SELECT TOP', 394 | 'SELECT', 395 | 'SEPARATOR', 396 | 'SERIALIZABLE', 397 | 'SESSION', 398 | 'SET', 399 | 'SHARE', 400 | 'SHOW', 401 | 'SHUTDOWN', 402 | 'SLAVE', 403 | 'SONAME', 404 | 'SOUNDS', 405 | 'SQL_AUTO_IS_NULL', 406 | 'SQL_BIG_RESULT', 407 | 'SQL_BIG_SELECTS', 408 | 'SQL_BIG_TABLES', 409 | 'SQL_BUFFER_RESULT', 410 | 'SQL_CACHE', 411 | 'SQL_CALC_FOUND_ROWS', 412 | 'SQL_LOG_BIN', 413 | 'SQL_LOG_OFF', 414 | 'SQL_LOG_UPDATE', 415 | 'SQL_LOW_PRIORITY_UPDATES', 416 | 'SQL_MAX_JOIN_SIZE', 417 | 'SQL_NO_CACHE', 418 | 'SQL_QUOTE_SHOW_CREATE', 419 | 'SQL_SAFE_UPDATES', 420 | 'SQL_SELECT_LIMIT', 421 | 'SQL_SLAVE_SKIP_COUNTER', 422 | 'SQL_SMALL_RESULT', 423 | 'SQL_WARNINGS', 424 | 'SQL', 425 | 'START', 426 | 'STARTING', 427 | 'STATUS', 428 | 'STOP', 429 | 'STORAGE', 430 | 'STRAIGHT_JOIN', 431 | 'STRING', 432 | 'STRIPED', 433 | 'SUPER', 434 | 'TABLE', 435 | 'TABLES', 436 | 'TEMPORARY', 437 | 'TERMINATED', 438 | 'THEN', 439 | 'TO', 440 | 'TOP', 441 | 'TRAILING', 442 | 'TRANSACTIONAL', 443 | 'TRUE', 444 | 'TRUNCATE TABLE', 445 | 'TYPE', 446 | 'TYPES', 447 | 'UNCOMMITTED', 448 | 'UNION ALL', 449 | 'UNION', 450 | 'UNIQUE', 451 | 'UNLOCK', 452 | 'UNSIGNED', 453 | 'UPDATE', 454 | 'USAGE', 455 | 'USE', 456 | 'USING', 457 | 'VALUES', 458 | 'VARIABLES', 459 | 'VIEW', 460 | 'WHEN', 461 | 'WHERE', 462 | 'WITH', 463 | 'WORK', 464 | 'WRITE', 465 | 'YEAR_MONTH', 466 | ]; 467 | 468 | export default { 469 | functions, 470 | keywords, 471 | operators, 472 | }; 473 | -------------------------------------------------------------------------------- /src/types/index.d.ts: -------------------------------------------------------------------------------- 1 | export type Options = { 2 | format?: boolean; 3 | noColors?: boolean; 4 | settings?: Settings; 5 | }; 6 | 7 | export type Settings = { 8 | functions?: Object; 9 | keywords?: Object; 10 | strings?: Object; 11 | numbers?: Object; 12 | operators?: Object; 13 | }; 14 | 15 | export type OutputSettings = { 16 | color: Object | string; 17 | modifiers: string[]; 18 | }; 19 | -------------------------------------------------------------------------------- /test/index.test.ts: -------------------------------------------------------------------------------- 1 | import { prettify } from '../src'; 2 | 3 | const sampleQuery = `SELECT * FROM custom_table WHERE id = 1 AND name = 'Test'`; 4 | const resultQuery = `SELECT 5 | * 6 | FROM 7 | custom_table 8 | WHERE 9 | id = 1 10 | AND name = 'Test'`; 11 | 12 | describe('sql prettify', () => { 13 | it('should not format SQL', () => { 14 | const notFormatedQuery = prettify(sampleQuery, { 15 | format: false, 16 | noColors: true, 17 | }); 18 | expect(notFormatedQuery).toEqual(sampleQuery); 19 | }); 20 | 21 | it('should format SQL', () => { 22 | const formatedQuery = prettify(sampleQuery, { 23 | format: true, 24 | noColors: true, 25 | }); 26 | expect(formatedQuery).toEqual(resultQuery); 27 | }); 28 | 29 | it('should not color SQL', () => { 30 | const settings = { 31 | keywords: { 32 | color: '#FF0000', 33 | }, 34 | }; 35 | const coloredQuery = prettify(sampleQuery, { noColors: true, settings }); 36 | expect(JSON.stringify(coloredQuery)).not.toContain('\\u001b[38;2;255;0;0m'); 37 | }); 38 | 39 | it('should color SQL', () => { 40 | const settings = { 41 | keywords: { 42 | color: '#FF0000', 43 | }, 44 | numbers: { 45 | color: '#33cc33', // \u001b[38;2;51;204;51m 46 | }, 47 | }; 48 | const coloredQuery = prettify(sampleQuery, { settings }); 49 | expect(JSON.stringify(coloredQuery)).toContain('\\u001b[38;2;255;0;0m'); 50 | expect(JSON.stringify(coloredQuery)).toContain('\\u001b[38;2;51;204;51m'); 51 | }); 52 | 53 | it('should color SQL and add bold modifier', () => { 54 | const settings = { 55 | keywords: { 56 | color: '#FF0000', // \u001b[38;2;255;0;0m 57 | modifiers: ['bold'], // \u001b[1m 58 | }, 59 | }; 60 | const coloredQuery = prettify(sampleQuery, { settings }); 61 | expect(JSON.stringify(coloredQuery)).toContain( 62 | '\\u001b[38;2;255;0;0m\\u001b[1m' 63 | ); 64 | }); 65 | }); 66 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src", "src/types", "test"], 3 | "compilerOptions": { 4 | "target": "es5", 5 | "module": "esnext", 6 | "lib": ["esnext"], 7 | "importHelpers": true, 8 | "declaration": true, 9 | "sourceMap": true, 10 | "rootDir": "./", 11 | "strict": true, 12 | "noImplicitAny": true, 13 | "strictNullChecks": true, 14 | "suppressImplicitAnyIndexErrors": true, 15 | "strictFunctionTypes": true, 16 | "strictPropertyInitialization": true, 17 | "noImplicitThis": true, 18 | "alwaysStrict": true, 19 | "noUnusedLocals": true, 20 | "noUnusedParameters": true, 21 | "noImplicitReturns": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "moduleResolution": "node", 24 | "baseUrl": "./", 25 | "paths": { 26 | "*": ["src/*", "node_modules/*"] 27 | }, 28 | "esModuleInterop": true 29 | } 30 | } 31 | --------------------------------------------------------------------------------