├── .gitignore ├── .jsbeautifyrc ├── .jshintrc ├── .prettierrc ├── .travis.yml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── index.js ├── lib ├── common.js └── pool.js ├── package.json ├── test ├── data │ └── database_test.sql ├── docker.local.setup ├── mocha │ ├── instance.js │ └── mysql.js ├── setup.sh └── start-tests.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Hide docker setup file 9 | test/docker.local.setup 10 | 11 | # Example scripts 12 | eg 13 | 14 | # Runtime data 15 | pids 16 | *.pid 17 | *.seed 18 | *.pid.lock 19 | 20 | # Directory for instrumented libs generated by jscoverage/JSCover 21 | lib-cov 22 | 23 | # Coverage directory used by tools like istanbul 24 | coverage 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (http://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Typescript v1 declaration files 46 | typings/ 47 | 48 | # Optional npm cache directory 49 | .npm 50 | 51 | # Optional eslint cache 52 | .eslintcache 53 | 54 | # Optional REPL history 55 | .node_repl_history 56 | 57 | # Output of 'npm pack' 58 | *.tgz 59 | 60 | # Yarn Integrity file 61 | .yarn-integrity 62 | 63 | # dotenv environment variables file 64 | .env 65 | -------------------------------------------------------------------------------- /.jsbeautifyrc: -------------------------------------------------------------------------------- 1 | { 2 | "html": { 3 | "allowed_file_extensions": ["htm", "html", "xhtml", "shtml", "xml", "svg"] 4 | , "brace_style": "collapse" 5 | , "preserve_ternary_lines": true 6 | , "end_with_newline": false 7 | , "indent_char": " " 8 | , "indent_handlebars": false 9 | , "indent_inner_html": false 10 | , "indent_scripts": "keep" 11 | , "indent_size": 2 12 | , "max_preserve_newlines": 0 13 | , "preserve_newlines": true 14 | , "unformatted": ["a", "span", "img", "code", "pre", "sub", "sup", "em" 15 | , "strong", "b", "i", "u", "strike", "big" 16 | , "small", "pre", "h1", "h2", "h3", "h4", "h5", "h6" 17 | ] 18 | , "wrap_line_length": 80 19 | } 20 | , "css": { 21 | "allowed_file_extensions": ["css", "scss", "sass", "less"] 22 | , "end_with_newline": false 23 | , "preserve_ternary_lines": true 24 | , "indent_char": " " 25 | , "indent_size": 2 26 | , "newline_between_rules": true 27 | , "selector_separator_newline": true 28 | } 29 | , "js": { 30 | "allowed_file_extensions": ["js", "jsx", "json", "eslintrc", "jsbeautifyrc"] 31 | , "brace_style": "collapse-preserve-inline" 32 | , "preserve_ternary_lines": true 33 | , "break_chained_methods": false 34 | , "comma_first": false 35 | , "e4x": false 36 | , "end_with_newline": false 37 | , "indent_char": " " 38 | , "indent_level": 0 39 | , "indent_size": 2 40 | , "jslint_happy": false 41 | , "keep_array_indentation": false 42 | , "keep_function_indentation": false 43 | , "max_preserve_newlines": 0 44 | , "preserve_newlines": true 45 | , "space_after_anon_function": false 46 | , "space_before_conditional": false 47 | , "space_in_empty_paren": false 48 | , "space_in_paren": false 49 | , "unescape_strings": false 50 | , "wrap_line_length": 80 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | // JSHint Default Configuration File (as on JSHint website) 3 | // See http://jshint.com/docs/ for more details 4 | 5 | "maxerr" : 50, // {int} Maximum error before stopping 6 | 7 | // Enforcing 8 | "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.) 9 | "camelcase" : false, // true: Identifiers must be in camelCase 10 | "curly" : true, // true: Require {} for every new block or scope 11 | "eqeqeq" : true, // true: Require triple equals (===) for comparison 12 | "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty() 13 | "freeze" : true, // true: prohibits overwriting prototypes of native objects such as Array, Date etc. 14 | "immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());` 15 | "latedef" : false, // true: Require variables/functions to be defined before being used 16 | "newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()` 17 | "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee` 18 | "noempty" : true, // true: Prohibit use of empty blocks 19 | "nonbsp" : true, // true: Prohibit "non-breaking whitespace" characters. 20 | "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment) 21 | "plusplus" : false, // true: Prohibit use of `++` and `--` 22 | "quotmark" : false, // Quotation mark consistency: 23 | // false : do nothing (default) 24 | // true : ensure whatever is used is consistent 25 | // "single" : require single quotes 26 | // "double" : require double quotes 27 | "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) 28 | "unused" : true, // Unused variables: 29 | // true : all variables, last function parameter 30 | // "vars" : all variables only 31 | // "strict" : all variables, all function parameters 32 | "strict" : true, // true: Requires all functions run in ES5 Strict Mode 33 | "maxparams" : false, // {int} Max number of formal params allowed per function 34 | "maxdepth" : false, // {int} Max depth of nested blocks (within functions) 35 | "maxstatements" : false, // {int} Max number statements per function 36 | "maxcomplexity" : false, // {int} Max cyclomatic complexity per function 37 | "maxlen" : false, // {int} Max number of characters per line 38 | "varstmt" : false, // true: Disallow any var statements. Only `let` and `const` are allowed. 39 | 40 | // Relaxing 41 | "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons) 42 | "boss" : false, // true: Tolerate assignments where comparisons would be expected 43 | "debug" : false, // true: Allow debugger statements e.g. browser breakpoints. 44 | "eqnull" : false, // true: Tolerate use of `== null` 45 | "esversion" : 6, // {int} Specify the ECMAScript version to which the code must adhere. 46 | "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features) 47 | // (ex: `for each`, multiple try/catch, function expression…) 48 | "evil" : false, // true: Tolerate use of `eval` and `new Function()` 49 | "expr" : false, // true: Tolerate `ExpressionStatement` as Programs 50 | "funcscope" : false, // true: Tolerate defining variables inside control statements 51 | "globalstrict" : true, // true: Allow global "use strict" (also enables 'strict') 52 | "iterator" : false, // true: Tolerate using the `__iterator__` property 53 | "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block 54 | "laxbreak" : false, // true: Tolerate possibly unsafe line breakings 55 | "laxcomma" : true, // true: Tolerate comma-first style coding 56 | "loopfunc" : false, // true: Tolerate functions being defined in loops 57 | "multistr" : false, // true: Tolerate multi-line strings 58 | "noyield" : false, // true: Tolerate generator functions with no yield statement in them. 59 | "notypeof" : false, // true: Tolerate invalid typeof operator values 60 | "proto" : false, // true: Tolerate using the `__proto__` property 61 | "scripturl" : false, // true: Tolerate script-targeted URLs 62 | "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;` 63 | "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation 64 | "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;` 65 | "validthis" : true, // true: Tolerate using this in a non-constructor function 66 | 67 | // Environments 68 | "browser" : true, // Web Browser (window, document, etc) 69 | "browserify" : true, // Browserify (node.js code in the browser) 70 | "couch" : false, // CouchDB 71 | "devel" : true, // Development/debugging (alert, confirm, etc) 72 | "dojo" : false, // Dojo Toolkit 73 | "jasmine" : false, // Jasmine 74 | "jquery" : false, // jQuery 75 | "mocha" : true, // Mocha 76 | "mootools" : false, // MooTools 77 | "node" : true, // Node.js 78 | "nonstandard" : false, // Widely adopted globals (escape, unescape, etc) 79 | "phantom" : false, // PhantomJS 80 | "prototypejs" : false, // Prototype and Scriptaculous 81 | "qunit" : false, // QUnit 82 | "rhino" : false, // Rhino 83 | "shelljs" : true, // ShellJS 84 | "typed" : false, // Globals for typed array constructions 85 | "worker" : false, // Web Workers 86 | "wsh" : false, // Windows Scripting Host 87 | "yui" : false, // Yahoo User Interface 88 | 89 | // Custom Globals 90 | "globals" : {} // additional predefined global variables 91 | } 92 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": true, 6 | "singleQuote": true, 7 | "trailingComma": "es5", 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | services: 3 | - mysql 4 | sudo: true 5 | node_js: 6 | - '8' 7 | - '10' 8 | - '11' 9 | - '12' 10 | - 'lts/*' 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to 'MySQL Connection Pool Manager' 2 | 3 | The following is a set of guidelines for contributing to 'MySQL Connection Pool Manager'. Please spend several minutes in reading these guidelines before you create an issue or pull request. 4 | 5 | Anyway, these are just guidelines, not rules, use your best judgment and feel free to propose changes to this document in a pull request. 6 | 7 | 8 | ## Do your homework before asking a question 9 | 10 | It's a great idea to read Eric Steven Raymond's [How To Ask Questions The Smart Way](http://www.catb.org/esr/faqs/smart-questions.html) twice before asking a question. But if you are busy now, I recommend to read [Don't post homework questions](http://www.catb.org/esr/faqs/smart-questions.html#homework) first. 11 | 12 | The following guidelines are about *How to avoid Homework Questions*. 13 | 14 | ## Read the documentation. 15 | 16 | Please read the documentation closely. Most answers will be here but if its not clear let me know! 17 | 18 | ## Close your issue if it's solved 19 | 20 | It is a good habit which will save maintainers' time. Thank you! 21 | 22 | ## Providing a demo while reporting a bug 23 | 24 | It would be helpful to provide a demo which can re-produce the bug 100%. Please fork this project and re-produce the bug you met in the repo or provide detailed instructions to reproduce the issue. Then, create an issue. The most important thing is: double check before claiming that you have found a bug. 25 | 26 | ## Tips about Feature Request 27 | 28 | If you believe that 'MySQL Connection Pool Manager' should provide some features, but it does not. You could create an issue to discuss. 29 | 30 | ## Tips about Pull Request 31 | 32 | **Working on your first Pull Request?** You can learn how from this *free* series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 33 | 34 | It's welcomed to pull request. And there are some tips about that: 35 | 36 | 1. It is a good habit to create a feature request issue to discuss whether the feature is necessary before you implement it. However, it's unnecessary to create an issue to claim that you found a typo or improved the readability of documentation, just create a pull request. 37 | 1. Rebase before creating a PR to keep commit history clear. 38 | 1. Add some descriptions and refer relative issues for you PR. 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Makz 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MySQL Connection Pool Manager 2 | 3 | [![Greenkeeper badge](https://badges.greenkeeper.io/daviemakz/mysql-connection-pool-manager.svg)](https://greenkeeper.io/) 4 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fdaviemakz%2Fmysql-connection-pool-manager.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fdaviemakz%2Fmysql-connection-pool-manager?ref=badge_shield) 5 | 6 | [![NPM](https://nodei.co/npm/mysql-connection-pool-manager.png?compact=true)](https://www.npmjs.com/package/mysql-connection-pool-manager) 7 | 8 | [![Build Status](https://travis-ci.org/daviemakz/mysql-connection-pool-manager.svg?branch=master)](https://travis-ci.org/daviemakz/mysql-connection-pool-manager) 9 | [![Downloads](https://img.shields.io/npm/dm/mysql-connection-pool-manager.svg)](https://www.npmjs.com/package/mysql-connection-pool-manager) 10 | [![Dependencies Status](https://david-dm.org/daviemakz/mysql-connection-pool-manager/status.svg)](https://david-dm.org/daviemakz/mysql-connection-pool-manager) 11 | [![Development Dependencies Status](https://david-dm.org/daviemakz/mysql-connection-pool-manager/dev-status.svg)](https://david-dm.org/daviemakz/mysql-connection-pool-manager?type=dev) 12 | 13 | This is a production level Node.JS mySQL connection pool wrapper powered by [mysqljs/mysql](https://github.com/mysqljs/mysql). 14 | 15 | _Supports Node 8.x +_ 16 | 17 | # Summary 18 | 19 | This module allows for intelligent management & load balancing of mySQL connection pools. It is written in JavaScript, does not require compiling, and is MIT licensed. Its designed to be used by persistent and self-terminating processes. 20 | 21 | # Installation 22 | 23 | To use this module ensure you have installed the [mysqljs/mysql](https://github.com/mysqljs/mysql) module (if you haven’t already): 24 | 25 | npm install mysql@2.x --save 26 | 27 | Aftewards install this module normally: 28 | 29 | npm install mysql-connection-pool-manager --save 30 | 31 | Please note, currently this module supports: **[mysqljs/mysql](https://github.com/mysqljs/mysql) @ >= 2.14.0 < 3.0.0** 32 | 33 | # Features 34 | 35 | This module is designed to be highly flexible with exported internal functions which you can utilise to create your own custom scripts or change the behaviour of the module. The module supports instancing so you can create as many as you want. You could even setup a JavaScript powered mySQL cluster where your application natively load balances between two instances, the possibilities are endless. 36 | 37 | - Fully powered by [mysqljs/mysql](https://github.com/mysqljs/mysql) under the hood. 38 | - Will automatically close all connections after an elapsed time, allowing scripts to exit properly. 39 | - Intelligent and configurable connection management, load balancing & termination. 40 | - Highly customisable instance which allows changes in instance configuration after initialisation. 41 | - Ability to change mySQL settings during execution, module will connect on next query database. 42 | - Lightning fast query response time due to keeping connections primed for the next request. 43 | - Completely asynchronous so no thread blocking & can handle high throughput situations. 44 | - Extensively mocha tested and already in use in a production environment. 45 | 46 | # Detailed Description 47 | 48 | Using the standard `mysql.createPool()`, connections are lazily created by the pool. If you configure the pool to allow up to 100 connections, but only ever use 5 simultaneously, only 5 connections will be made. However if you configure it for 500 connections and use all 500 they will **remain open** for the durations of the process, even if they are idle! 49 | 50 | This means if your MySQL Server `max_connections` is 510 your system will only have **10** mySQL connections available until your MySQL Server closes them (depends on what you have set your `wait_timeout` to) or your application closes! The only way to free them up is to manually close the connections via the pool instance or close the pool. 51 | 52 | This module was created to fix this issue and **automatically** scale the number of connections dependant on the load. Inactive connections are closed and idle connection pools are eventually closed if there has not been any activity. 53 | 54 | When a new query comes in, the pool is automatically initialised if its been closed and remains so as long as its in use. All this happens under the hood so they is no need to do anything but perform queries as you would normally. There is also no need to invest too heavily into flow control as this is taken care of by the module. 55 | 56 | # MySQL Configuration Options 57 | 58 | When establishing a connection, you can set the following options: 59 | 60 | - `host`: The hostname of the database you are connecting to. (Default: 61 | `localhost`) 62 | - `port`: The port number to connect to. (Default: `3306`) 63 | - `localAddress`: The source IP address to use for TCP connection. (Optional) 64 | - `socketPath`: The path to a unix domain socket to connect to. When used `host` 65 | and `port` are ignored. 66 | - `user`: The MySQL user to authenticate as. 67 | - `password`: The password of that MySQL user. 68 | - `database`: Name of the database to use for this connection (Optional). 69 | - `charset`: The charset for the connection. This is called "collation" in the SQL-level 70 | of MySQL (like `utf8_general_ci`). If a SQL-level charset is specified (like `utf8mb4`) 71 | then the default collation for that charset is used. (Default: `'UTF8_GENERAL_CI'`) 72 | - `timezone`: The timezone configured on the MySQL server. This is used to type cast server date/time values to JavaScript `Date` object and vice versa. This can be `'local'`, `'Z'`, or an offset in the form `+HH:MM` or `-HH:MM`. (Default: `'local'`) 73 | - `connectTimeout`: The milliseconds before a timeout occurs during the initial connection 74 | to the MySQL server. (Default: `10000`) 75 | - `stringifyObjects`: Stringify objects instead of converting to values. (Default: `false`) 76 | - `insecureAuth`: Allow connecting to MySQL instances that ask for the old 77 | (insecure) authentication method. (Default: `false`) 78 | - `typeCast`: Determines if column values should be converted to native 79 | JavaScript types. (Default: `true`) 80 | - `queryFormat`: A custom query format function. 81 | - `supportBigNumbers`: When dealing with big numbers (BIGINT and DECIMAL columns) in the database, 82 | you should enable this option (Default: `false`). 83 | - `bigNumberStrings`: Enabling both `supportBigNumbers` and `bigNumberStrings` forces big numbers 84 | (BIGINT and DECIMAL columns) to be always returned as JavaScript String objects (Default: `false`). 85 | Enabling `supportBigNumbers` but leaving `bigNumberStrings` disabled will return big numbers as String 86 | objects only when they cannot be accurately represented with [JavaScript Number objects](http://ecma262-5.com/ELS5_HTML.htm#Section_8.5) 87 | (which happens when they exceed the [-2^53, +2^53] range), otherwise they will be returned as 88 | Number objects. This option is ignored if `supportBigNumbers` is disabled. 89 | - `dateStrings`: Force date types (TIMESTAMP, DATETIME, DATE) to be returned as strings rather then 90 | inflated into JavaScript Date objects. Can be `true`/`false` or an array of type names to keep as 91 | strings. (Default: `false`) 92 | - `debug`: Prints protocol details to stdout. Can be `true`/`false` or an array of packet type names 93 | that should be printed. (Default: `false`) 94 | - `trace`: Generates stack traces on `Error` to include call site of library 95 | entrance ("long stack traces"). Slight performance penalty for most calls. 96 | (Default: `true`) 97 | - `multipleStatements`: Allow multiple mysql statements per query. Be careful 98 | with this, it could increase the scope of SQL injection attacks. (Default: `false`) 99 | - `flags`: List of connection flags to use other than the default ones. It is 100 | also possible to blacklist default ones. 101 | - `ssl`: object with ssl parameters or a string containing name of ssl profile. 102 | - `acquireTimeout`: The milliseconds before a timeout occurs during the connection 103 | acquisition. This is slightly different from `connectTimeout`, because acquiring 104 | a pool connection does not always involve making a connection. (Default: `10000`) 105 | - `waitForConnections`: Determines the pool's action when no connections are 106 | available and the limit has been reached. If `true`, the pool will queue the 107 | connection request and call it when one becomes available. If `false`, the 108 | pool will immediately call back with an error. (Default: `true`) 109 | - `connectionLimit`: The maximum number of connections to create at once. 110 | (Default: `10`) 111 | - `queueLimit`: The maximum number of connection requests the pool will queue 112 | before returning an error from `getConnection`. If set to `0`, there is no 113 | limit to the number of queued connection requests. (Default: `0`) 114 | 115 | _For a full list please visit this [link](https://github.com/mysqljs/mysql#connection-options)._ 116 | 117 | # Instance Configuration Options 118 | 119 | Below are the options available to tweak the behaviour of the pool manager (in ms): 120 | 121 | - `idleCheckInterval`: How often to check if connections are idle before closing them. _(required)_ 122 | - `maxConnextionTimeout`: The length of time to wait before connections are removed from the pool. _(required)_ 123 | - `idlePoolTimeout`: The length of time to wait before closing the connection pool if all connections are idle. _(required)_ 124 | - `errorLimit`: The number of times to attempt getting a connection / starting a connection pool. 125 | - `preInitDelay`: How long to wait between attempts to initialise a connection pool. _(required)_ 126 | - `sessionTimeout`: Sets a mySQL `wait_timeout` on the connection session to close connections if your process blocks. _(required)_ 127 | - `onConnectionAcquire`: When a connection is _acquired_ from the pool. _(optional)_ 128 | - `onConnectionConnect`: When a new connection is _made_ within the pool. _(optional)_ 129 | - `onConnectionEnqueue`: When a query has been _queued_ to wait for an available connection. _(optional)_ 130 | - `onConnectionRelease`: When a connection is _released_ back to the pool. _(optional)_ 131 | 132 | # Available Methods 133 | 134 | Here is a list of available methods: 135 | 136 | - `checkPool(pool)`: Checks the status of the connection pool. Returns `boolean`. 137 | - `closePool(pool)`: Closes the connection pool. Returns `undefined`. 138 | - `closePoolNow(callback)`: Close the currently active connection pool. Returns `undefined`. 139 | - `createPool(mySQLSettings)`: Creates a connection pool. Returns `instance`. 140 | - `escapeValue(data)`: In order to avoid SQL injection attacks, you should always escape any user provided data. Returns `string`. 141 | - `query(sql)`: This method allows you to perform a query. Returns `(result = [], error = {})`. 142 | - `config(options)`: Allows you to change the instance / mySQL settings of an instance. Returns `undefined`. 143 | 144 | You can also access the [mysqljs/mysql](https://github.com/mysqljs/mysql) directly like so... 145 | 146 | ``` 147 | "use strict" 148 | 149 | // Load modules 150 | const PoolManager = require('mysql-connection-pool-manager'); 151 | 152 | // Options 153 | const options = { 154 | ...example settings 155 | } 156 | 157 | // Initialising the instance 158 | const mySQL = PoolManager(options); 159 | 160 | // Accessing mySQL directly 161 | var connection = mySQL.raw.createConnection({ 162 | host : 'localhost', 163 | user : 'me', 164 | password : 'secret', 165 | database : 'my_db' 166 | }); 167 | 168 | // Initialising connection 169 | connection.connect(); 170 | 171 | // Performing query 172 | connection.query('SELECT 1 + 1 AS solution', function (error, results, fields) { 173 | if (error) throw error; 174 | console.log('The solution is: ', results[0].solution); 175 | }); 176 | 177 | // Ending connection 178 | connection.end(); 179 | ``` 180 | 181 | ...and you can still use the module normally! 182 | 183 | # Basic Usage 184 | 185 | ## Simple Insertion Script 186 | 187 | A simple script to bulk insert data into a table. Make sure you have an idea of how many connection you expect to queue at once and adjust your `queueLimit` accordingly. If this limit is reached the query callback will be called with an error. 188 | 189 | ``` 190 | "use strict" 191 | 192 | // Load modules 193 | const PoolManager = require('mysql-connection-pool-manager'); 194 | 195 | const options = { 196 | idleCheckInterval: 1000, 197 | maxConnextionTimeout: 30000, 198 | idlePoolTimeout: 3000, 199 | errorLimit: 5, 200 | preInitDelay: 50, 201 | sessionTimeout: 60000, 202 | onConnectionAcquire: () => { console.log("Acquire"); }, 203 | onConnectionConnect: () => { console.log("Connect"); }, 204 | onConnectionEnqueue: () => { console.log("Enqueue"); }, 205 | onConnectionRelease: () => { console.log("Release"); }, 206 | mySQLSettings: { 207 | host: 'localhost', 208 | user: 'me', 209 | password: 'secret', 210 | database: 'example_database', 211 | port: '3306', 212 | socketPath: '/var/run/mysqld/mysqld.sock', 213 | charset: 'utf8', 214 | multipleStatements: true, 215 | connectTimeout: 15000, 216 | acquireTimeout: 10000, 217 | waitForConnections: true, 218 | connectionLimit: 1000, 219 | queueLimit: 5000, 220 | debug: false 221 | } 222 | } 223 | 224 | // Initialising the instance 225 | const mySQL = PoolManager(options); 226 | 227 | // Execute 30000 queries at once... 228 | for (var i = 0; i < 30000; i++) { 229 | var count = i; 230 | mySQL.query(`INSERT INTO table_name VALUES (${count}, ${count}, ${count}, ${count});`,(res, msg) => { 231 | console.log(res,msg); 232 | }); 233 | } 234 | ``` 235 | 236 | # Contributing 237 | 238 | All contributions are very welcome, please read my [CONTRIBUTING.md](https://github.com/daviemakz/mysql-connection-pool-manager/blob/master/CONTRIBUTING.md) first. You can submit any ideas as [pull requests](https://github.com/daviemakz/mysql-connection-pool-manager/pulls) or as [GitHub issues](https://github.com/daviemakz/mysql-connection-pool-manager/issues). If you'd like to improve code, please feel free! 239 | 240 | ## License 241 | 242 | [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fdaviemakz%2Fmysql-connection-pool-manager.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fdaviemakz%2Fmysql-connection-pool-manager?ref=badge_large) 243 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Load NPM modules 4 | const autoBind = require('auto-bind'); 5 | 6 | // Load library modules 7 | const PoolCore = require('./lib/pool'); 8 | 9 | // Build instance 10 | class MySQLPoolManagerInstance extends PoolCore { 11 | // Initial constructor 12 | constructor(options) { 13 | // Allow access to 'this' 14 | super() && autoBind(this); 15 | // Check configuration 16 | return this.config(options); 17 | } 18 | 19 | // Function: Assign settings 20 | config(options) { 21 | // Define required properties 22 | const props = [ 23 | 'idlePoolTimeout', 24 | 'errorLimit', 25 | 'preInitDelay', 26 | 'sessionTimeout', 27 | 'maxConnextionTimeout', 28 | 'idleCheckInterval', 29 | ]; 30 | // Validation configuration 31 | props.forEach(prop => { 32 | if (!options.hasOwnProperty(prop)) { 33 | throw new Error(`The required property ${prop} is not defined!`); 34 | } 35 | if (typeof options[prop] !== 'number' && props.includes(prop)) { 36 | throw new Error(`The property ${prop} is not a number!`); 37 | } 38 | }); 39 | // Check mysql settings are defined 40 | if (typeof options.mySQLSettings !== 'object') { 41 | throw new Error(`MySQL settings are not defined or not an object!`); 42 | } 43 | // Spread options to this 44 | return (this.options = Object.assign({}, options)) && this; 45 | } 46 | } 47 | 48 | // Exports 49 | module.exports = options => new MySQLPoolManagerInstance(options); 50 | -------------------------------------------------------------------------------- /lib/common.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Load NPM modules 4 | const mySQL = require('mysql'); 5 | 6 | // Declare class 7 | class PoolManagerFunctionsCommon { 8 | // Initial constructor 9 | constructor() { 10 | // Assign module directly to instance 11 | this.raw = mySQL; 12 | // Bind methods 13 | return [ 14 | 'checkConnectionDetails', 15 | 'checkPool', 16 | 'checkTimestamp', 17 | 'closeIdleConnections', 18 | 'closeConnection', 19 | 'closePool', 20 | 'createPool', 21 | 'escapeValue', 22 | 'getTimestamp', 23 | ].forEach(func => (this[func] = this[func].bind(this))); 24 | } 25 | 26 | // FUNCTION: Escape value 27 | escapeValue(value) { 28 | return mySQL.escape(value); 29 | } 30 | 31 | // FUNCTION: Create connection pool 32 | createPool(settings) { 33 | return mySQL.createPool(settings); 34 | } 35 | 36 | // FUNCTION: Check connection pool 37 | checkPool(pool) { 38 | return pool ? true : false; 39 | } 40 | 41 | // FUNCTION: Close Connection Pool 42 | closePool(pool, callback) { 43 | // Close all remaining connections.. 44 | return ( 45 | pool && 46 | pool.end(err => { 47 | // Check for errors.. 48 | err && 49 | console.warn( 50 | `Failed to close pool / already closed. MORE INFO: ${err}` 51 | ); 52 | // Set to undefined 53 | pool = undefined; 54 | // Return callback 55 | return typeof callback === 'function' ? callback() : void 0; 56 | }) 57 | ); 58 | } 59 | 60 | // FUNCTION: Check if connection details are equal 61 | checkConnectionDetails(x, y) { 62 | // Initial quick check 63 | if (x === null || x === undefined || y === null || y === undefined) { 64 | return x === y; 65 | } 66 | // After this just checking type of one would be enough 67 | if (x.constructor !== y.constructor) { 68 | return false; 69 | } 70 | // If they are functions, they should exactly refer to same one (because of closures) 71 | if (x instanceof Function) { 72 | return x === y; 73 | } 74 | // If they are regexps, they should exactly refer to same one (it is hard to better equality check on current ES) 75 | if (x instanceof RegExp) { 76 | return x === y; 77 | } 78 | if (x === y || x.valueOf() === y.valueOf()) { 79 | return true; 80 | } 81 | if (Array.isArray(x) && x.length !== y.length) { 82 | return false; 83 | } 84 | // If they are dates, they must had equal valueOf 85 | if (x instanceof Date) { 86 | return false; 87 | } 88 | // If they are strictly equal, they both need to be object at least 89 | if (!(x instanceof Object)) { 90 | return false; 91 | } 92 | if (!(y instanceof Object)) { 93 | return false; 94 | } 95 | // Recursive object equality check 96 | var p = Object.keys(x); 97 | // Return 98 | return ( 99 | Object.keys(y).every(i => { 100 | return p.indexOf(i) !== -1; 101 | }) && 102 | p.every(i => { 103 | return this.checkConnectionDetails(x[i], y[i]); 104 | }) 105 | ); 106 | } 107 | 108 | // FUNCTION: Get current timestamp 109 | getTimestamp() { 110 | return Math.floor(Date.now()); 111 | } 112 | 113 | // FUNCTION: Check the timestamp has elapsed 114 | checkTimestamp(time, limit) { 115 | return Math.floor(Date.now()) - time >= limit ? true : false; 116 | } 117 | 118 | // FUNCTION: Close connection 119 | closeConnection(connection, list, reference) { 120 | // Remove connection from list 121 | delete reference[list][connection.threadId]; 122 | // Close the connection 123 | return typeof connection.destroy === 'function' && connection.destroy(); 124 | } 125 | 126 | // FUNCTION: Close idle connection pool 127 | closeIdleConnections(pool, list, reference) { 128 | // Check for idle connections and close them after time limit 129 | return setTimeout(() => { 130 | if (!pool._closed) { 131 | // Check if any connections are free 132 | if (pool._freeConnections.length === 0) { 133 | // Reschedule check 134 | return this.closeIdleConnections(pool, list, reference); 135 | } else { 136 | // Check and close idle connections 137 | pool._freeConnections.forEach(freeConnection => { 138 | // Check connection timestamp 139 | if ( 140 | this.checkTimestamp( 141 | reference[list][freeConnection.threadId], 142 | this.options.maxConnextionTimeout 143 | ) 144 | ) { 145 | // Remove connection from list 146 | delete reference[list][freeConnection.threadId]; 147 | // Close the connection 148 | return freeConnection.destroy(); 149 | } 150 | }); 151 | // Reschedule check 152 | return this.closeIdleConnections(pool, list, reference); 153 | } 154 | } else { 155 | // Remove all connections from tracking object of closed pool 156 | for (var connectRef in reference[list]) { 157 | if (reference[list].hasOwnProperty(connectRef)) { 158 | delete reference[list][connectRef]; 159 | } 160 | } 161 | // Return 162 | return; 163 | } 164 | }, this.options.idleCheckInterval); 165 | } 166 | 167 | // FUNCTION: Check & close idle connection pools 168 | closeIdlePools(pool, activity, tracking, timeout) { 169 | // Capture current activity 170 | let currentActivity = tracking[activity]; 171 | // Wait and then check if no activity has been registered 172 | return setTimeout( 173 | () => 174 | currentActivity === tracking[activity] 175 | ? this.closePool(pool) 176 | : this.closeIdlePools(pool, activity, tracking, timeout), 177 | timeout 178 | ); 179 | } 180 | } 181 | 182 | // EXPORTS 183 | module.exports = PoolManagerFunctionsCommon; 184 | -------------------------------------------------------------------------------- /lib/pool.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Load NPM modules 4 | const aysnc = require('async'); 5 | const md5Hash = require('md5'); 6 | 7 | // Load custom modules 8 | const PoolManagerFunctions = require('./common.js'); 9 | 10 | // Declare class 11 | class PoolManagerCore extends PoolManagerFunctions { 12 | // Initial constructor 13 | constructor() { 14 | // Allow access to 'this' 15 | super(); 16 | // Instance pool storage 17 | this.poolStorage = void 0; 18 | // Instance settings 19 | ['poolActivity', 'poolConnectionList', 'poolSettings'].forEach( 20 | prop => (this[prop] = {}) 21 | ); 22 | // Bind methods 23 | return [ 24 | 'assignEventListeners', 25 | 'checkPoolStatus', 26 | 'closePoolNow', 27 | 'currentSessionId', 28 | 'execute', 29 | 'getConnection', 30 | 'query', 31 | 'startPool', 32 | ].forEach(func => (this[func] = this[func].bind(this))); 33 | } 34 | 35 | // FUNCTION: Build settings hash 36 | currentSessionId() { 37 | return md5Hash(JSON.stringify(this.options.mySQLSettings)); 38 | } 39 | 40 | // FUNCTION: Close connection pool now 41 | closePoolNow(cb) { 42 | return this.poolStorage.end(cb); 43 | } 44 | 45 | // FUNCTION: Assign event listeners 46 | assignEventListeners() { 47 | // Add to connection tracking 48 | this.poolStorage.on('connection', connection => { 49 | // Set hard wait timeout session limit 50 | connection.query( 51 | `SET SESSION wait_timeout = ${this.options.sessionTimeout}` 52 | ); 53 | // Check if connection tracking list exists... 54 | !this.poolConnectionList[this.currentSessionId()] && 55 | (this.poolConnectionList[this.currentSessionId()] = {}); 56 | // Assign timestamp.. 57 | this.poolConnectionList[this.currentSessionId()][ 58 | connection.threadId 59 | ] = this.getTimestamp(); 60 | // Assign `onConnectionConnect` if defined 61 | return typeof this.options.onConnectionConnect === 'function' 62 | ? this.options.onConnectionConnect(connection) 63 | : void 0; 64 | }); 65 | // Assign connection event listeners if defined 66 | return ['acquire', 'enqueue', 'release'].forEach( 67 | event => 68 | typeof this.options[ 69 | `onConnection${event.charAt(0).toUpperCase() + event.substr(1)}` 70 | ] === 'function' && 71 | this.poolStorage.on(event, connection => 72 | this.options[ 73 | `onConnection${event.charAt(0).toUpperCase() + event.substr(1)}` 74 | ](connection) 75 | ) 76 | ); 77 | } 78 | 79 | // FUNCTION: Start connection pool 80 | startPool(callback) { 81 | // Invoke connection pool 82 | this.poolStorage = this.createPool(this.options.mySQLSettings); 83 | // Start connection pool monitor 84 | this.closeIdlePools( 85 | this.poolStorage, 86 | this.currentSessionId(), 87 | this.poolActivity, 88 | this.options.idlePoolTimeout 89 | ); 90 | // Start idle connection monitor 91 | this.closeIdleConnections( 92 | this.poolStorage, 93 | this.currentSessionId(), 94 | this.poolConnectionList 95 | ); 96 | // Assign event listeners to pool 97 | this.assignEventListeners(); 98 | // Register connection pool settings 99 | this.poolSettings[this.currentSessionId()] = this.options.mySQLSettings; 100 | // Set connection activity to 0 101 | this.poolActivity[this.currentSessionId()] = 0; 102 | // Callback if nessesary 103 | return typeof callback === 'function' ? callback() : void 0; 104 | } 105 | 106 | // FUNCTION: Check pool is active & settings are correct 107 | checkPoolStatus(cb, scope) { 108 | // Check connection pool settings are the same for the active pool 109 | if ( 110 | this.checkConnectionDetails( 111 | this.options.mySQLSettings, 112 | this.poolSettings[this.currentSessionId()] 113 | ) || 114 | !this.poolSettings[this.currentSessionId()] 115 | ) { 116 | // Check the pool is active 117 | if (this.checkPool(this.poolStorage)) { 118 | // Callback 119 | return cb(); 120 | } else { 121 | // Start connection pool, wait slightly then move on... 122 | return this.startPool(() => { 123 | setTimeout(() => { 124 | return cb(); 125 | }, this.options.preInitDelay); 126 | }); 127 | } 128 | } else { 129 | // Close the connection pool 130 | return this.closePool(this.poolStorage, () => 131 | this.startPool(() => { 132 | setTimeout(() => { 133 | this.checkPoolStatus(cb, scope); 134 | }, this.options.preInitDelay); 135 | }) 136 | ); 137 | } 138 | } 139 | 140 | // FUNCTION: Get connection from pool 141 | getConnection(cb, scope) { 142 | // Register query 143 | this.poolActivity[this.currentSessionId()]++; 144 | // Attempt to get connection 145 | return this.poolStorage.getConnection((err, con) => { 146 | // Check for errors getting the connection 147 | if (err) { 148 | if (this.options.errorLimit > scope.errorTracking) { 149 | // Track the failiure 150 | scope.errorTracking++; 151 | // Try getting another connection? 152 | if (err.code === 'POOL_CLOSED') { 153 | return this.startPool(() => { 154 | setTimeout(() => { 155 | this.getConnection(cb, scope); 156 | }, this.options.errorLimit); 157 | }); 158 | } else if (err.code === 'POOL_ENQUEUELIMIT') { 159 | // Assign error message 160 | scope.errorMessage = { 161 | internalMsg: `Query limit reached, try increasing this value! MORE INFO: ${JSON.stringify( 162 | err, 163 | null, 164 | 2 165 | )}`, 166 | err: err, 167 | }; 168 | // Callback a null object 169 | return cb(); 170 | } else { 171 | return setTimeout(() => { 172 | this.getConnection(cb, scope); 173 | }, this.options.errorLimit); 174 | } 175 | } else { 176 | // Assign error message 177 | scope.errorMessage = { 178 | internalMsg: `Initializing connection failed. MORE INFO: ${JSON.stringify( 179 | err, 180 | null, 181 | 2 182 | )}`, 183 | err: err, 184 | }; 185 | // Callback a null object 186 | return cb(); 187 | } 188 | } else { 189 | // Update connection timestamp 190 | this.poolConnectionList[this.currentSessionId()][ 191 | con.threadId 192 | ] = this.getTimestamp(); 193 | // Assign connection 194 | scope.connection = con; 195 | // Callback to execution stage 196 | return cb(); 197 | } 198 | }); 199 | } 200 | 201 | // FUNCTION: Execute query 202 | execute(cb, scope) { 203 | // Check connection is initialized... 204 | if (!scope.connection) { 205 | return typeof scope.returnCallback === 'function' 206 | ? scope.returnCallback([], scope.errorMessage) 207 | : void 0; 208 | } 209 | // Start query execution.. 210 | return scope.connection.query(scope.sqlCommand, (err, rows) => { 211 | // Register query 212 | this.poolActivity[this.currentSessionId()]++; 213 | // Check for any errors 214 | if (err) { 215 | // Assign sql commands 216 | err.sql = scope.sqlCommand; 217 | // Release connection 218 | scope.connection.release(); 219 | // Destroy this connection as it has a failed query 220 | this.closeConnection( 221 | scope.connection, 222 | this.currentSessionId(), 223 | this.poolConnectionList 224 | ); 225 | // Callback [ERROR] 226 | return typeof scope.returnCallback === 'function' 227 | ? scope.returnCallback([], err) 228 | : void 0; 229 | } else { 230 | // Release connection 231 | scope.connection.release(); 232 | // Callback [SUCCESS] 233 | return typeof scope.returnCallback === 'function' 234 | ? scope.returnCallback(rows, err) 235 | : void 0; 236 | } 237 | }); 238 | } 239 | 240 | // FUNCTION: Execute query in services database 241 | query(command, callback) { 242 | // Scope... 243 | const scope = { 244 | connection: '', 245 | errorMessage: '', 246 | sqlCommand: command, 247 | returnCallback: callback, 248 | errorTracking: 0, 249 | }; 250 | // Execute series 251 | setTimeout( 252 | scope => { 253 | aysnc.series( 254 | [ 255 | callback => this.checkPoolStatus(callback, scope), 256 | callback => this.getConnection(callback, scope), 257 | callback => this.execute(callback, scope), 258 | ], 259 | error => { 260 | if (error) { 261 | console.warn( 262 | `Unknown error in async series stack. MORE INFO: ${JSON.stringify( 263 | error, 264 | null, 265 | 2 266 | )}` 267 | ); 268 | } 269 | } 270 | ); 271 | }, 272 | 0, 273 | scope 274 | ); 275 | } 276 | } 277 | 278 | // EXPORTS 279 | module.exports = PoolManagerCore; 280 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mysql-connection-pool-manager", 3 | "version": "1.5.8", 4 | "description": "This is a mySQL Connection Pool Manager wrapper powered by mysqljs/mysql and allows for intelligent management & load balancing mysql connection pools.", 5 | "main": "index.js", 6 | "scripts": { 7 | "pretest": "cd ./test/ && bash setup.sh && cd ./../", 8 | "test": "cd ./test/ && node start-tests.js", 9 | "format": "prettier --config ./.prettierrc --write './**/*.js'", 10 | "format-windows": "prettier --config ./.prettierrc --write ./**/*.js", 11 | "deploy-patch": "git commit -a -m 'module update: patch' && git push && npm version patch && npm publish", 12 | "deploy-minor": "git commit -a -m 'module update: minor' && git push && npm version minor && npm publish", 13 | "deploy-major": "git commit -a -m 'module update: major' && git push && npm version major && npm publish" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git+https://github.com/daviemakz/mysql-connection-pool-manager.git" 18 | }, 19 | "keywords": [ 20 | "mysql", 21 | "connection", 22 | "pool", 23 | "manager" 24 | ], 25 | "author": "David Makuni", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/daviemakz/mysql-connection-pool-manager/issues" 29 | }, 30 | "homepage": "https://github.com/daviemakz/mysql-connection-pool-manager#readme", 31 | "dependencies": { 32 | "async": "^3.0.1", 33 | "auto-bind": "^4.0.0", 34 | "lodash": "^4.17.11", 35 | "md5": "^2.2.1" 36 | }, 37 | "peerDependencies": { 38 | "mysql": ">= 2.14.0 < 3.0.0" 39 | }, 40 | "devDependencies": { 41 | "assert": "^2.0.0", 42 | "bluebird": "^3.5.0", 43 | "chai": "^4.1.1", 44 | "graceful-fs": "^4.1.11", 45 | "mocha": "7.0.1", 46 | "mysql": "^2.15.0", 47 | "path": "^0.12.7", 48 | "prettier": "^2.0.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /test/data/database_test.sql: -------------------------------------------------------------------------------- 1 | DROP TABLE IF EXISTS `test_table`; 2 | CREATE TABLE `test_table` ( `column_one` int(11) NOT NULL, `column_two` int(11) NOT NULL DEFAULT '0', PRIMARY KEY (`column_one`) ) ENGINE=MyISAM AUTO_INCREMENT=6437 DEFAULT CHARSET=utf8; 3 | -------------------------------------------------------------------------------- /test/docker.local.setup: -------------------------------------------------------------------------------- 1 | sudo docker rm $(sudo docker ps -a -q) && sudo docker run -it --volume=/home/david/dev/testing/user-auto:/user_auto --workdir="/user_auto" --memory=4g --entrypoint=/bin/bash node:7.10.0 2 | -------------------------------------------------------------------------------- /test/mocha/instance.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Load assertions & framework 4 | const Assert = require('assert'); 5 | const Promise = require('bluebird'); 6 | const Chai = require('chai'); 7 | 8 | // Load module 9 | const PoolManager = require('./../../'); 10 | 11 | // An example options configuration 12 | const options = { 13 | idleCheckInterval: 1000, 14 | maxConnextionTimeout: 30000, 15 | idlePoolTimeout: 3000, 16 | errorLimit: 5, 17 | preInitDelay: 50, 18 | sessionTimeout: 60000, 19 | onConnectionAcquire: () => {}, 20 | onConnectionConnect: () => {}, 21 | onConnectionEnqueue: () => {}, 22 | onConnectionRelease: () => {}, 23 | mySQLSettings: { 24 | host: 'localhost', 25 | user: 'root', 26 | password: '', 27 | database: 'database_test', 28 | port: '3306', 29 | socketPath: '/var/run/mysqld/mysqld.sock', 30 | charset: 'utf8', 31 | multipleStatements: true, 32 | connectTimeout: 15000, 33 | acquireTimeout: 10000, 34 | waitForConnections: true, 35 | connectionLimit: 1000, 36 | queueLimit: 5000, 37 | debug: false, 38 | }, 39 | }; 40 | 41 | // Initialising the instance 42 | const mySQL = PoolManager(options); 43 | 44 | describe('instance', function() { 45 | // Check properties 46 | [ 47 | 'raw', 48 | 'checkConnectionDetails', 49 | 'checkPool', 50 | 'checkTimestamp', 51 | 'closeIdleConnections', 52 | 'closeConnection', 53 | 'closePool', 54 | 'createPool', 55 | 'escapeValue', 56 | 'getTimestamp', 57 | 'poolActivity', 58 | 'poolConnectionList', 59 | 'poolSettings', 60 | 'poolStorage', 61 | 'assignEventListeners', 62 | 'checkPoolStatus', 63 | 'closePoolNow', 64 | 'currentSessionId', 65 | 'execute', 66 | 'getConnection', 67 | 'query', 68 | 'startPool', 69 | 'config', 70 | 'options', 71 | ].forEach(prop => { 72 | it(`checking instance property: ${prop}`, function() { 73 | return new Promise(function(resolve, reject) { 74 | mySQL.hasOwnProperty(prop) 75 | ? resolve() 76 | : reject(`property not found: ${prop}`); 77 | }); 78 | }); 79 | }); 80 | }); 81 | -------------------------------------------------------------------------------- /test/mocha/mysql.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // Load assertions & framework 4 | const Promise = require('bluebird'); 5 | 6 | // Load module 7 | const PoolManager = require('./../../'); 8 | 9 | // An example options configuration 10 | const options = { 11 | idleCheckInterval: 1000, 12 | maxConnextionTimeout: 30000, 13 | idlePoolTimeout: 3000, 14 | errorLimit: 5, 15 | preInitDelay: 50, 16 | sessionTimeout: 60000, 17 | onConnectionAcquire: () => {}, 18 | onConnectionConnect: () => {}, 19 | onConnectionEnqueue: () => {}, 20 | onConnectionRelease: () => {}, 21 | mySQLSettings: { 22 | host: 'localhost', 23 | user: 'root', 24 | password: '', 25 | database: 'database_test', 26 | port: '3306', 27 | socketPath: '/var/run/mysqld/mysqld.sock', 28 | charset: 'utf8', 29 | multipleStatements: true, 30 | connectTimeout: 15000, 31 | acquireTimeout: 10000, 32 | waitForConnections: true, 33 | connectionLimit: 1000, 34 | queueLimit: 15000, 35 | debug: false, 36 | }, 37 | }; 38 | 39 | // Const Test Limit 40 | const testLimit = 10000; 41 | 42 | // Initialising the instance 43 | const mySQL = PoolManager(options); 44 | 45 | describe('mysql', function() { 46 | // Set variables 47 | var inc = 0; 48 | // Run before tests 49 | before(function(done) { 50 | // Count number of successes 51 | var completedQueries = 0; 52 | // Set timeout 53 | this.timeout(30000); 54 | // Put some stuff into the database 55 | for (var i = 0; i < testLimit; i++) { 56 | // Get count 57 | var count = i; 58 | // Perform query 59 | mySQL.query( 60 | `INSERT IGNORE INTO test_table VALUES (${count}, ${count});`, 61 | () => { 62 | // Increment completed queries 63 | completedQueries++; 64 | // Check if all is finished then contine test 65 | testLimit === completedQueries && done(); 66 | } 67 | ); 68 | } 69 | }); 70 | // Build test cases 71 | for (var i = 0; i < testLimit; i++) { 72 | // Set timeout 73 | this.timeout(30000); 74 | // Start tests 75 | it(`connection query number: #${i}`, function() { 76 | return new Promise(function(resolve, reject) { 77 | // Increment count 78 | var curInc = inc++; 79 | // Return new promise 80 | mySQL.query( 81 | `SELECT * FROM test_table WHERE column_one=${curInc};`, 82 | (res, msg) => { 83 | res.length > 0 ? resolve() : reject(msg); 84 | } 85 | ); 86 | }); 87 | }); 88 | } 89 | }); 90 | -------------------------------------------------------------------------------- /test/setup.sh: -------------------------------------------------------------------------------- 1 | # Default mySQL Settings 2 | mysqlUser='root' 3 | mysqlPass='' 4 | 5 | # Setup MySQL Test Database [] 6 | mysql --user="$mysqlUser" --database=mysql --execute="DROP DATABASE IF EXISTS database_test; CREATE DATABASE IF NOT EXISTS database_test;" 7 | mysql --user="$mysqlUser" database_test < ./data/database_test.sql 8 | 9 | # Setup MySQL Timezone 10 | mysql --user="$mysqlUser" --database=mysql --execute="SET GLOBAL time_zone = 'Europe/London';" 11 | 12 | # Setup MySQL Max Connections 13 | mysql --user="$mysqlUser" --database=mysql --execute="SET GLOBAL max_connections = 5000;" 14 | -------------------------------------------------------------------------------- /test/start-tests.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* This is the core file for running tests in the daemon programmically... */ 4 | 5 | // Modules 6 | const MC = require('mocha'); 7 | const FS = require('graceful-fs'); 8 | const PT = require('path'); 9 | 10 | // Base Test Configuration File 11 | const MochaInstanceAll = new MC(); 12 | const DirectoryAll = ['./mocha/']; 13 | 14 | // Get all mocha test files 15 | DirectoryAll.forEach(function(element) { 16 | FS.readdirSync(element) 17 | .filter(function(file) { 18 | return file.substr(-3) === '.js'; 19 | }) 20 | .forEach(function(file) { 21 | MochaInstanceAll.addFile(PT.join(element, file)); 22 | }); 23 | }); 24 | 25 | // FUNCTION: Run all tests 26 | function RUN_ALL() { 27 | MochaInstanceAll.run(function(failures) { 28 | process.on('exit', function() { 29 | process.exit(failures); 30 | }); 31 | }); 32 | } 33 | 34 | // Run tests... 35 | RUN_ALL(); 36 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-colors@3.2.3: 6 | version "3.2.3" 7 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" 8 | integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== 9 | 10 | ansi-regex@^3.0.0: 11 | version "3.0.1" 12 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" 13 | integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== 14 | 15 | ansi-regex@^4.1.0: 16 | version "4.1.1" 17 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" 18 | integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== 19 | 20 | ansi-styles@^3.2.0, ansi-styles@^3.2.1: 21 | version "3.2.1" 22 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 23 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 24 | dependencies: 25 | color-convert "^1.9.0" 26 | 27 | anymatch@~3.1.1: 28 | version "3.1.1" 29 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" 30 | integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== 31 | dependencies: 32 | normalize-path "^3.0.0" 33 | picomatch "^2.0.4" 34 | 35 | argparse@^1.0.7: 36 | version "1.0.10" 37 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 38 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 39 | dependencies: 40 | sprintf-js "~1.0.2" 41 | 42 | assert@^2.0.0: 43 | version "2.0.0" 44 | resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32" 45 | integrity sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A== 46 | dependencies: 47 | es6-object-assign "^1.1.0" 48 | is-nan "^1.2.1" 49 | object-is "^1.0.1" 50 | util "^0.12.0" 51 | 52 | assertion-error@^1.1.0: 53 | version "1.1.0" 54 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" 55 | integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== 56 | 57 | async@^3.0.1: 58 | version "3.2.2" 59 | resolved "https://registry.yarnpkg.com/async/-/async-3.2.2.tgz#2eb7671034bb2194d45d30e31e24ec7e7f9670cd" 60 | integrity sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g== 61 | 62 | auto-bind@^4.0.0: 63 | version "4.0.0" 64 | resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-4.0.0.tgz#e3589fc6c2da8f7ca43ba9f84fa52a744fc997fb" 65 | integrity sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ== 66 | 67 | balanced-match@^1.0.0: 68 | version "1.0.0" 69 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 70 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 71 | 72 | bignumber.js@7.2.1: 73 | version "7.2.1" 74 | resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" 75 | integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ== 76 | 77 | binary-extensions@^2.0.0: 78 | version "2.0.0" 79 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" 80 | integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== 81 | 82 | bluebird@^3.5.0: 83 | version "3.7.2" 84 | resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" 85 | integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== 86 | 87 | brace-expansion@^1.1.7: 88 | version "1.1.11" 89 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 90 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 91 | dependencies: 92 | balanced-match "^1.0.0" 93 | concat-map "0.0.1" 94 | 95 | braces@~3.0.2: 96 | version "3.0.2" 97 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 98 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 99 | dependencies: 100 | fill-range "^7.0.1" 101 | 102 | browser-stdout@1.3.1: 103 | version "1.3.1" 104 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 105 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 106 | 107 | camelcase@^5.0.0: 108 | version "5.3.1" 109 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 110 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 111 | 112 | chai@^4.1.1: 113 | version "4.2.0" 114 | resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" 115 | integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== 116 | dependencies: 117 | assertion-error "^1.1.0" 118 | check-error "^1.0.2" 119 | deep-eql "^3.0.1" 120 | get-func-name "^2.0.0" 121 | pathval "^1.1.0" 122 | type-detect "^4.0.5" 123 | 124 | chalk@^2.0.1: 125 | version "2.4.2" 126 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 127 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 128 | dependencies: 129 | ansi-styles "^3.2.1" 130 | escape-string-regexp "^1.0.5" 131 | supports-color "^5.3.0" 132 | 133 | charenc@~0.0.1: 134 | version "0.0.2" 135 | resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" 136 | integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc= 137 | 138 | check-error@^1.0.2: 139 | version "1.0.2" 140 | resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" 141 | integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= 142 | 143 | chokidar@3.3.0: 144 | version "3.3.0" 145 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" 146 | integrity sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A== 147 | dependencies: 148 | anymatch "~3.1.1" 149 | braces "~3.0.2" 150 | glob-parent "~5.1.0" 151 | is-binary-path "~2.1.0" 152 | is-glob "~4.0.1" 153 | normalize-path "~3.0.0" 154 | readdirp "~3.2.0" 155 | optionalDependencies: 156 | fsevents "~2.1.1" 157 | 158 | cliui@^5.0.0: 159 | version "5.0.0" 160 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" 161 | integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== 162 | dependencies: 163 | string-width "^3.1.0" 164 | strip-ansi "^5.2.0" 165 | wrap-ansi "^5.1.0" 166 | 167 | color-convert@^1.9.0: 168 | version "1.9.3" 169 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 170 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 171 | dependencies: 172 | color-name "1.1.3" 173 | 174 | color-name@1.1.3: 175 | version "1.1.3" 176 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 177 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 178 | 179 | concat-map@0.0.1: 180 | version "0.0.1" 181 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 182 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 183 | 184 | core-util-is@~1.0.0: 185 | version "1.0.2" 186 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 187 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 188 | 189 | crypt@~0.0.1: 190 | version "0.0.2" 191 | resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" 192 | integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs= 193 | 194 | debug@3.2.6: 195 | version "3.2.6" 196 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" 197 | integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== 198 | dependencies: 199 | ms "^2.1.1" 200 | 201 | decamelize@^1.2.0: 202 | version "1.2.0" 203 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 204 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 205 | 206 | deep-eql@^3.0.1: 207 | version "3.0.1" 208 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" 209 | integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== 210 | dependencies: 211 | type-detect "^4.0.0" 212 | 213 | define-properties@^1.1.1, define-properties@^1.1.2, define-properties@^1.1.3: 214 | version "1.1.3" 215 | resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" 216 | integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== 217 | dependencies: 218 | object-keys "^1.0.12" 219 | 220 | diff@3.5.0: 221 | version "3.5.0" 222 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" 223 | integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== 224 | 225 | emoji-regex@^7.0.1: 226 | version "7.0.3" 227 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" 228 | integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== 229 | 230 | es-abstract@^1.12.0, es-abstract@^1.5.1: 231 | version "1.16.3" 232 | resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.16.3.tgz#52490d978f96ff9f89ec15b5cf244304a5bca161" 233 | integrity sha512-WtY7Fx5LiOnSYgF5eg/1T+GONaGmpvpPdCpSnYij+U2gDTL0UPfWrhDw7b2IYb+9NQJsYpCA0wOQvZfsd6YwRw== 234 | dependencies: 235 | es-to-primitive "^1.2.1" 236 | function-bind "^1.1.1" 237 | has "^1.0.3" 238 | has-symbols "^1.0.1" 239 | is-callable "^1.1.4" 240 | is-regex "^1.0.4" 241 | object-inspect "^1.7.0" 242 | object-keys "^1.1.1" 243 | string.prototype.trimleft "^2.1.0" 244 | string.prototype.trimright "^2.1.0" 245 | 246 | es-to-primitive@^1.2.1: 247 | version "1.2.1" 248 | resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" 249 | integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== 250 | dependencies: 251 | is-callable "^1.1.4" 252 | is-date-object "^1.0.1" 253 | is-symbol "^1.0.2" 254 | 255 | es6-object-assign@^1.1.0: 256 | version "1.1.0" 257 | resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" 258 | integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw= 259 | 260 | escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: 261 | version "1.0.5" 262 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 263 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 264 | 265 | esprima@^4.0.0: 266 | version "4.0.1" 267 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 268 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 269 | 270 | fill-range@^7.0.1: 271 | version "7.0.1" 272 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 273 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 274 | dependencies: 275 | to-regex-range "^5.0.1" 276 | 277 | find-up@3.0.0, find-up@^3.0.0: 278 | version "3.0.0" 279 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" 280 | integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== 281 | dependencies: 282 | locate-path "^3.0.0" 283 | 284 | flat@^4.1.0: 285 | version "4.1.0" 286 | resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" 287 | integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw== 288 | dependencies: 289 | is-buffer "~2.0.3" 290 | 291 | fs.realpath@^1.0.0: 292 | version "1.0.0" 293 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 294 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 295 | 296 | fsevents@~2.1.1: 297 | version "2.1.2" 298 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" 299 | integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== 300 | 301 | function-bind@^1.1.1: 302 | version "1.1.1" 303 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 304 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 305 | 306 | get-caller-file@^2.0.1: 307 | version "2.0.5" 308 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 309 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 310 | 311 | get-func-name@^2.0.0: 312 | version "2.0.0" 313 | resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" 314 | integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= 315 | 316 | glob-parent@~5.1.0: 317 | version "5.1.2" 318 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 319 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 320 | dependencies: 321 | is-glob "^4.0.1" 322 | 323 | glob@7.1.3: 324 | version "7.1.3" 325 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" 326 | integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== 327 | dependencies: 328 | fs.realpath "^1.0.0" 329 | inflight "^1.0.4" 330 | inherits "2" 331 | minimatch "^3.0.4" 332 | once "^1.3.0" 333 | path-is-absolute "^1.0.0" 334 | 335 | graceful-fs@^4.1.11: 336 | version "4.2.3" 337 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" 338 | integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== 339 | 340 | growl@1.10.5: 341 | version "1.10.5" 342 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" 343 | integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== 344 | 345 | has-flag@^3.0.0: 346 | version "3.0.0" 347 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 348 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 349 | 350 | has-symbols@^1.0.0, has-symbols@^1.0.1: 351 | version "1.0.1" 352 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" 353 | integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== 354 | 355 | has@^1.0.1, has@^1.0.3: 356 | version "1.0.3" 357 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 358 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 359 | dependencies: 360 | function-bind "^1.1.1" 361 | 362 | he@1.2.0: 363 | version "1.2.0" 364 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" 365 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 366 | 367 | inflight@^1.0.4: 368 | version "1.0.6" 369 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 370 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 371 | dependencies: 372 | once "^1.3.0" 373 | wrappy "1" 374 | 375 | inherits@2, inherits@^2.0.3, inherits@~2.0.3: 376 | version "2.0.4" 377 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 378 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 379 | 380 | inherits@2.0.3: 381 | version "2.0.3" 382 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 383 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 384 | 385 | is-arguments@^1.0.4: 386 | version "1.0.4" 387 | resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" 388 | integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== 389 | 390 | is-binary-path@~2.1.0: 391 | version "2.1.0" 392 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 393 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 394 | dependencies: 395 | binary-extensions "^2.0.0" 396 | 397 | is-buffer@~1.1.1: 398 | version "1.1.6" 399 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" 400 | integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== 401 | 402 | is-buffer@~2.0.3: 403 | version "2.0.4" 404 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" 405 | integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== 406 | 407 | is-callable@^1.1.4: 408 | version "1.1.4" 409 | resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" 410 | integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== 411 | 412 | is-date-object@^1.0.1: 413 | version "1.0.1" 414 | resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" 415 | integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= 416 | 417 | is-extglob@^2.1.1: 418 | version "2.1.1" 419 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 420 | integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= 421 | 422 | is-fullwidth-code-point@^2.0.0: 423 | version "2.0.0" 424 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 425 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 426 | 427 | is-generator-function@^1.0.7: 428 | version "1.0.7" 429 | resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" 430 | integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw== 431 | 432 | is-glob@^4.0.1, is-glob@~4.0.1: 433 | version "4.0.1" 434 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" 435 | integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== 436 | dependencies: 437 | is-extglob "^2.1.1" 438 | 439 | is-nan@^1.2.1: 440 | version "1.2.1" 441 | resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.2.1.tgz#9faf65b6fb6db24b7f5c0628475ea71f988401e2" 442 | integrity sha1-n69ltvttskt/XAYoR16nH5iEAeI= 443 | dependencies: 444 | define-properties "^1.1.1" 445 | 446 | is-number@^7.0.0: 447 | version "7.0.0" 448 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 449 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 450 | 451 | is-regex@^1.0.4: 452 | version "1.0.4" 453 | resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" 454 | integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= 455 | dependencies: 456 | has "^1.0.1" 457 | 458 | is-symbol@^1.0.2: 459 | version "1.0.3" 460 | resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937" 461 | integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ== 462 | dependencies: 463 | has-symbols "^1.0.1" 464 | 465 | isarray@~1.0.0: 466 | version "1.0.0" 467 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 468 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 469 | 470 | isexe@^2.0.0: 471 | version "2.0.0" 472 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 473 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 474 | 475 | js-yaml@3.13.1: 476 | version "3.13.1" 477 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" 478 | integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== 479 | dependencies: 480 | argparse "^1.0.7" 481 | esprima "^4.0.0" 482 | 483 | locate-path@^3.0.0: 484 | version "3.0.0" 485 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" 486 | integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== 487 | dependencies: 488 | p-locate "^3.0.0" 489 | path-exists "^3.0.0" 490 | 491 | lodash@^4.17.11, lodash@^4.17.15: 492 | version "4.17.21" 493 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 494 | integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== 495 | 496 | log-symbols@2.2.0: 497 | version "2.2.0" 498 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" 499 | integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== 500 | dependencies: 501 | chalk "^2.0.1" 502 | 503 | md5@^2.2.1: 504 | version "2.2.1" 505 | resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9" 506 | integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk= 507 | dependencies: 508 | charenc "~0.0.1" 509 | crypt "~0.0.1" 510 | is-buffer "~1.1.1" 511 | 512 | minimatch@3.0.4, minimatch@^3.0.4: 513 | version "3.0.4" 514 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 515 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 516 | dependencies: 517 | brace-expansion "^1.1.7" 518 | 519 | minimist@0.0.8: 520 | version "0.0.8" 521 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 522 | integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= 523 | 524 | mkdirp@0.5.1: 525 | version "0.5.1" 526 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 527 | integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= 528 | dependencies: 529 | minimist "0.0.8" 530 | 531 | mocha@7.0.1: 532 | version "7.0.1" 533 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.0.1.tgz#276186d35a4852f6249808c6dd4a1376cbf6c6ce" 534 | integrity sha512-9eWmWTdHLXh72rGrdZjNbG3aa1/3NRPpul1z0D979QpEnFdCG0Q5tv834N+94QEN2cysfV72YocQ3fn87s70fg== 535 | dependencies: 536 | ansi-colors "3.2.3" 537 | browser-stdout "1.3.1" 538 | chokidar "3.3.0" 539 | debug "3.2.6" 540 | diff "3.5.0" 541 | escape-string-regexp "1.0.5" 542 | find-up "3.0.0" 543 | glob "7.1.3" 544 | growl "1.10.5" 545 | he "1.2.0" 546 | js-yaml "3.13.1" 547 | log-symbols "2.2.0" 548 | minimatch "3.0.4" 549 | mkdirp "0.5.1" 550 | ms "2.1.1" 551 | node-environment-flags "1.0.6" 552 | object.assign "4.1.0" 553 | strip-json-comments "2.0.1" 554 | supports-color "6.0.0" 555 | which "1.3.1" 556 | wide-align "1.1.3" 557 | yargs "13.3.0" 558 | yargs-parser "13.1.1" 559 | yargs-unparser "1.6.0" 560 | 561 | ms@2.1.1: 562 | version "2.1.1" 563 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 564 | integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== 565 | 566 | ms@^2.1.1: 567 | version "2.1.2" 568 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 569 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 570 | 571 | mysql@^2.15.0: 572 | version "2.17.1" 573 | resolved "https://registry.yarnpkg.com/mysql/-/mysql-2.17.1.tgz#62bba4a039a9b2f73638cd1652ce50fc6f682899" 574 | integrity sha512-7vMqHQ673SAk5C8fOzTG2LpPcf3bNt0oL3sFpxPEEFp1mdlDcrLK0On7z8ZYKaaHrHwNcQ/MTUz7/oobZ2OyyA== 575 | dependencies: 576 | bignumber.js "7.2.1" 577 | readable-stream "2.3.6" 578 | safe-buffer "5.1.2" 579 | sqlstring "2.3.1" 580 | 581 | node-environment-flags@1.0.6: 582 | version "1.0.6" 583 | resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" 584 | integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== 585 | dependencies: 586 | object.getownpropertydescriptors "^2.0.3" 587 | semver "^5.7.0" 588 | 589 | normalize-path@^3.0.0, normalize-path@~3.0.0: 590 | version "3.0.0" 591 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 592 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 593 | 594 | object-inspect@^1.7.0: 595 | version "1.7.0" 596 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" 597 | integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== 598 | 599 | object-is@^1.0.1: 600 | version "1.0.1" 601 | resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.1.tgz#0aa60ec9989a0b3ed795cf4d06f62cf1ad6539b6" 602 | integrity sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY= 603 | 604 | object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: 605 | version "1.1.1" 606 | resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" 607 | integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== 608 | 609 | object.assign@4.1.0: 610 | version "4.1.0" 611 | resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" 612 | integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== 613 | dependencies: 614 | define-properties "^1.1.2" 615 | function-bind "^1.1.1" 616 | has-symbols "^1.0.0" 617 | object-keys "^1.0.11" 618 | 619 | object.entries@^1.1.0: 620 | version "1.1.0" 621 | resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.0.tgz#2024fc6d6ba246aee38bdb0ffd5cfbcf371b7519" 622 | integrity sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA== 623 | dependencies: 624 | define-properties "^1.1.3" 625 | es-abstract "^1.12.0" 626 | function-bind "^1.1.1" 627 | has "^1.0.3" 628 | 629 | object.getownpropertydescriptors@^2.0.3: 630 | version "2.0.3" 631 | resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" 632 | integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= 633 | dependencies: 634 | define-properties "^1.1.2" 635 | es-abstract "^1.5.1" 636 | 637 | once@^1.3.0: 638 | version "1.4.0" 639 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 640 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 641 | dependencies: 642 | wrappy "1" 643 | 644 | p-limit@^2.0.0: 645 | version "2.2.1" 646 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" 647 | integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== 648 | dependencies: 649 | p-try "^2.0.0" 650 | 651 | p-locate@^3.0.0: 652 | version "3.0.0" 653 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" 654 | integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== 655 | dependencies: 656 | p-limit "^2.0.0" 657 | 658 | p-try@^2.0.0: 659 | version "2.2.0" 660 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" 661 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== 662 | 663 | path-exists@^3.0.0: 664 | version "3.0.0" 665 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" 666 | integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= 667 | 668 | path-is-absolute@^1.0.0: 669 | version "1.0.1" 670 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 671 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 672 | 673 | path@^0.12.7: 674 | version "0.12.7" 675 | resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" 676 | integrity sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8= 677 | dependencies: 678 | process "^0.11.1" 679 | util "^0.10.3" 680 | 681 | pathval@^1.1.0: 682 | version "1.1.1" 683 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" 684 | integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== 685 | 686 | picomatch@^2.0.4: 687 | version "2.2.1" 688 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" 689 | integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA== 690 | 691 | prettier@^2.0.0: 692 | version "2.0.0" 693 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.0.tgz#9c8fdba0aeae3faf0d9d9391623ac4f9321a4455" 694 | integrity sha512-vI55PC+GFLOVtpwr2di1mYhJF36v+kztJov8sx3AmqbfdA+2Dhozxb+3e1hTgoV9lyhnVJFF3Z8GCVeMBOS1bA== 695 | 696 | process-nextick-args@~2.0.0: 697 | version "2.0.1" 698 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 699 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== 700 | 701 | process@^0.11.1: 702 | version "0.11.10" 703 | resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" 704 | integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= 705 | 706 | readable-stream@2.3.6: 707 | version "2.3.6" 708 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" 709 | integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== 710 | dependencies: 711 | core-util-is "~1.0.0" 712 | inherits "~2.0.3" 713 | isarray "~1.0.0" 714 | process-nextick-args "~2.0.0" 715 | safe-buffer "~5.1.1" 716 | string_decoder "~1.1.1" 717 | util-deprecate "~1.0.1" 718 | 719 | readdirp@~3.2.0: 720 | version "3.2.0" 721 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" 722 | integrity sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ== 723 | dependencies: 724 | picomatch "^2.0.4" 725 | 726 | require-directory@^2.1.1: 727 | version "2.1.1" 728 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 729 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 730 | 731 | require-main-filename@^2.0.0: 732 | version "2.0.0" 733 | resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" 734 | integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== 735 | 736 | safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: 737 | version "5.1.2" 738 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 739 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 740 | 741 | safe-buffer@^5.1.2: 742 | version "5.2.0" 743 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" 744 | integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== 745 | 746 | semver@^5.7.0: 747 | version "5.7.1" 748 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" 749 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== 750 | 751 | set-blocking@^2.0.0: 752 | version "2.0.0" 753 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 754 | integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= 755 | 756 | sprintf-js@~1.0.2: 757 | version "1.0.3" 758 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 759 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 760 | 761 | sqlstring@2.3.1: 762 | version "2.3.1" 763 | resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.1.tgz#475393ff9e91479aea62dcaf0ca3d14983a7fb40" 764 | integrity sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A= 765 | 766 | "string-width@^1.0.2 || 2": 767 | version "2.1.1" 768 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 769 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== 770 | dependencies: 771 | is-fullwidth-code-point "^2.0.0" 772 | strip-ansi "^4.0.0" 773 | 774 | string-width@^3.0.0, string-width@^3.1.0: 775 | version "3.1.0" 776 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" 777 | integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== 778 | dependencies: 779 | emoji-regex "^7.0.1" 780 | is-fullwidth-code-point "^2.0.0" 781 | strip-ansi "^5.1.0" 782 | 783 | string.prototype.trimleft@^2.1.0: 784 | version "2.1.0" 785 | resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" 786 | integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== 787 | dependencies: 788 | define-properties "^1.1.3" 789 | function-bind "^1.1.1" 790 | 791 | string.prototype.trimright@^2.1.0: 792 | version "2.1.0" 793 | resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" 794 | integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== 795 | dependencies: 796 | define-properties "^1.1.3" 797 | function-bind "^1.1.1" 798 | 799 | string_decoder@~1.1.1: 800 | version "1.1.1" 801 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 802 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 803 | dependencies: 804 | safe-buffer "~5.1.0" 805 | 806 | strip-ansi@^4.0.0: 807 | version "4.0.0" 808 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 809 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= 810 | dependencies: 811 | ansi-regex "^3.0.0" 812 | 813 | strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: 814 | version "5.2.0" 815 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" 816 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== 817 | dependencies: 818 | ansi-regex "^4.1.0" 819 | 820 | strip-json-comments@2.0.1: 821 | version "2.0.1" 822 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 823 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= 824 | 825 | supports-color@6.0.0: 826 | version "6.0.0" 827 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" 828 | integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== 829 | dependencies: 830 | has-flag "^3.0.0" 831 | 832 | supports-color@^5.3.0: 833 | version "5.5.0" 834 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 835 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 836 | dependencies: 837 | has-flag "^3.0.0" 838 | 839 | to-regex-range@^5.0.1: 840 | version "5.0.1" 841 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 842 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 843 | dependencies: 844 | is-number "^7.0.0" 845 | 846 | type-detect@^4.0.0, type-detect@^4.0.5: 847 | version "4.0.8" 848 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" 849 | integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== 850 | 851 | util-deprecate@~1.0.1: 852 | version "1.0.2" 853 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 854 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 855 | 856 | util@^0.10.3: 857 | version "0.10.4" 858 | resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" 859 | integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== 860 | dependencies: 861 | inherits "2.0.3" 862 | 863 | util@^0.12.0: 864 | version "0.12.1" 865 | resolved "https://registry.yarnpkg.com/util/-/util-0.12.1.tgz#f908e7b633e7396c764e694dd14e716256ce8ade" 866 | integrity sha512-MREAtYOp+GTt9/+kwf00IYoHZyjM8VU4aVrkzUlejyqaIjd2GztVl5V9hGXKlvBKE3gENn/FMfHE5v6hElXGcQ== 867 | dependencies: 868 | inherits "^2.0.3" 869 | is-arguments "^1.0.4" 870 | is-generator-function "^1.0.7" 871 | object.entries "^1.1.0" 872 | safe-buffer "^5.1.2" 873 | 874 | which-module@^2.0.0: 875 | version "2.0.0" 876 | resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" 877 | integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= 878 | 879 | which@1.3.1: 880 | version "1.3.1" 881 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" 882 | integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== 883 | dependencies: 884 | isexe "^2.0.0" 885 | 886 | wide-align@1.1.3: 887 | version "1.1.3" 888 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" 889 | integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== 890 | dependencies: 891 | string-width "^1.0.2 || 2" 892 | 893 | wrap-ansi@^5.1.0: 894 | version "5.1.0" 895 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" 896 | integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== 897 | dependencies: 898 | ansi-styles "^3.2.0" 899 | string-width "^3.0.0" 900 | strip-ansi "^5.0.0" 901 | 902 | wrappy@1: 903 | version "1.0.2" 904 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 905 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 906 | 907 | y18n@^4.0.0: 908 | version "4.0.1" 909 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" 910 | integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== 911 | 912 | yargs-parser@13.1.1, yargs-parser@^13.1.1: 913 | version "13.1.1" 914 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" 915 | integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== 916 | dependencies: 917 | camelcase "^5.0.0" 918 | decamelize "^1.2.0" 919 | 920 | yargs-unparser@1.6.0: 921 | version "1.6.0" 922 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" 923 | integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== 924 | dependencies: 925 | flat "^4.1.0" 926 | lodash "^4.17.15" 927 | yargs "^13.3.0" 928 | 929 | yargs@13.3.0, yargs@^13.3.0: 930 | version "13.3.0" 931 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" 932 | integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== 933 | dependencies: 934 | cliui "^5.0.0" 935 | find-up "^3.0.0" 936 | get-caller-file "^2.0.1" 937 | require-directory "^2.1.1" 938 | require-main-filename "^2.0.0" 939 | set-blocking "^2.0.0" 940 | string-width "^3.0.0" 941 | which-module "^2.0.0" 942 | y18n "^4.0.0" 943 | yargs-parser "^13.1.1" 944 | --------------------------------------------------------------------------------