node-querybuilder
Advanced tools
Comparing version 1.2.2 to 2.0.0-beta
{ | ||
"mysql": { | ||
"connection_types": { "single": true, "pool": true, "cluster": true }, | ||
"connection_types": { "single": true, "pool": true, "cluster": false }, | ||
"versions": { | ||
@@ -15,9 +15,9 @@ "2.5.4": { | ||
"mssql": { | ||
"connection_types": { "single": true, "pool": false, "cluster": false }, | ||
"connection_types": { "single": true, "pool": true, "cluster": false }, | ||
"versions": { | ||
"1.3.0": { | ||
"4.1.0": { | ||
"path": "./drivers/mssql/", | ||
"active": false | ||
"active": true | ||
}, | ||
"default": "1.3.0" | ||
"default": "4.1.0" | ||
} | ||
@@ -24,0 +24,0 @@ }, |
@@ -0,18 +1,20 @@ | ||
const QueryBuilder = require('./query_builder.js'); | ||
// **************************************************************************** | ||
// QueryBuilder "Query Execution" methods. | ||
// ----- | ||
// @param Object qb The QueryBuilder object | ||
// @param Object adapter The connection adapter object | ||
// **************************************************************************** | ||
const QueryExec = function (qb, conn) { | ||
class QueryExec extends QueryBuilder { | ||
constructor() { | ||
super(); | ||
} | ||
const exec = (sql, callback) => { | ||
if (Object.prototype.toString.call(conn) == Object.prototype.toString.call({})) { | ||
conn.query(sql, (err, results) => { | ||
_exec(sql, cb) { | ||
if (Object.prototype.toString.call(this._connection) === Object.prototype.toString.call({})) { | ||
this._connection.query(sql, (err, results) => { | ||
// Standardize some important properties | ||
if (!err && results.length > 0) { | ||
if (!err && results && !Array.isArray(results)) { | ||
// Insert ID | ||
if (results.hasOwnProperty('insertId')) { | ||
results.insert_id = results.insertId; | ||
results.insert_id = results.insertId || null; | ||
} | ||
@@ -31,179 +33,185 @@ | ||
callback(err, results); | ||
cb(err, results); | ||
}); | ||
} else { | ||
throw new Error("No connection object supplied to the Query Exec Library!"); | ||
throw new Error("No connection object available to the Query Exec Library!"); | ||
} | ||
}; | ||
} | ||
return { | ||
query: function(sql, callback) { | ||
exec(sql, callback); | ||
}, | ||
query(sql, cb) { | ||
this._exec(sql, cb); | ||
} | ||
count: function(table, callback) { | ||
if (typeof table === 'function' && typeof callback !== 'function') { | ||
table = null; | ||
callback = table; | ||
} | ||
count(table, cb) { | ||
if (typeof table === 'function' && typeof cb !== 'function') { | ||
table = null; | ||
cb = table; | ||
} | ||
const sql = qb.count(table); | ||
qb.reset_query(sql); | ||
exec(sql, (err, row) => { | ||
if (!err) { | ||
//console.dir(row[0].numrows); | ||
callback(err, row[0].numrows); | ||
} | ||
else { | ||
callback(err, row); | ||
} | ||
}); | ||
}, | ||
get: function(table,callback,conn) { | ||
// The table parameter is optional, it could be the callback... | ||
if (typeof table === 'function' && typeof callback !== 'function') { | ||
callback = table; | ||
const sql = this._count(table); | ||
this.reset_query(sql); | ||
this._exec(sql, (err, row) => { | ||
if (!err) { | ||
//console.dir(row[0].numrows); | ||
cb(err, row[0].numrows); | ||
} | ||
else if (typeof table === 'undefined' && typeof callback !== 'function') { | ||
throw new Error("No callback function has been provided in your 'get' call!"); | ||
else { | ||
cb(err, row); | ||
} | ||
}); | ||
} | ||
const sql = qb.get(table); | ||
qb.reset_query(sql); | ||
exec(sql,callback); | ||
}, | ||
get(table,cb,conn) { | ||
// The table parameter is optional, it could be the cb... | ||
if (typeof table === 'function' && typeof cb !== 'function') { | ||
cb = table; | ||
} | ||
else if (typeof table === 'undefined' && typeof cb !== 'function') { | ||
throw new Error("No cb function has been provided in your 'get' call!"); | ||
} | ||
get_where: function(table,where,callback) { | ||
if (typeof table !== 'string' && !Array.isArray(table)) { | ||
throw new Error("First parameter of get_where() must be a string or an array of strings."); | ||
} | ||
if (Object.prototype.toString.call(where) !== Object.prototype.toString.call({})) { | ||
throw new Error("Second parameter of get_where() must be an object with key:value pairs."); | ||
} | ||
const sql = qb.get_where(table,where); | ||
qb.reset_query(sql); | ||
exec(sql,callback); | ||
}, | ||
const sql = this._get(table); | ||
this.reset_query(sql); | ||
this._exec(sql,cb); | ||
} | ||
insert: function(table,set,callback,ignore,suffix) { | ||
const sql = qb.insert(table,set,ignore,suffix); | ||
qb.reset_query(sql); | ||
exec(sql,callback); | ||
}, | ||
get_where(table,where,cb) { | ||
if (typeof table !== 'string' && !Array.isArray(table)) { | ||
throw new Error("First parameter of get_where() must be a string or an array of strings."); | ||
} | ||
if (Object.prototype.toString.call(where) !== Object.prototype.toString.call({})) { | ||
throw new Error("Second parameter of get_where() must be an object with key:value pairs."); | ||
} | ||
const sql = this._get_where(table,where); | ||
this.reset_query(sql); | ||
this._exec(sql,cb); | ||
} | ||
insert_ignore: function(table,set,on_dupe,callback) { | ||
if (typeof on_dupe === 'function') { | ||
callback = on_dupe; | ||
on_dupe = null; | ||
} | ||
const sql = qb.insert_ignore(table,set,on_dupe); | ||
qb.reset_query(sql); | ||
exec(sql,callback); | ||
}, | ||
insert(table,set,cb,ignore,suffix) { | ||
const sql = this._insert(table, set, ignore, suffix); | ||
this.reset_query(sql); | ||
this._exec(sql, cb); | ||
} | ||
insert_batch: function(table,set,callback) { | ||
const sql = qb.insert_batch(table,set); | ||
qb.reset_query(sql); | ||
exec(sql,callback); | ||
}, | ||
insert_ignore(table, set, on_dupe, cb) { | ||
if (typeof on_dupe === 'function') { | ||
cb = on_dupe; | ||
on_dupe = null; | ||
} | ||
const sql = this._insert_ignore(table, set, on_dupe); | ||
this.reset_query(sql); | ||
this._exec(sql,cb); | ||
} | ||
update: function(table,set,where,callback) { | ||
// The where parameter is optional, it could be the callback... | ||
if (typeof where === 'function' && typeof callback !== 'function') { | ||
callback = where; | ||
where = null; | ||
} | ||
else if (typeof where === 'undefined' && typeof callback !== 'function') { | ||
throw new Error("No callback function has been provided in your update call!"); | ||
} | ||
else if (typeof where === 'undefined' || where === false || (where !== null && typeof where === 'object' && where.length == 0)) { | ||
where = null; | ||
} | ||
insert_batch(table, set, ignore, on_dupe, cb) { | ||
if (typeof ignore === 'function') { | ||
cb = ignore; | ||
ignore = null; | ||
} | ||
else if (typeof on_dupe === 'function') { | ||
cb = on_dupe; | ||
on_dupe = null; | ||
} | ||
const sql = this._insert_batch(table, set, ignore, on_dupe); | ||
this.reset_query(sql); | ||
this._exec(sql, cb); | ||
} | ||
const sql = qb.update(table,set,where); | ||
qb.reset_query(sql); | ||
exec(sql,callback); | ||
}, | ||
update(table,set,where,cb) { | ||
// The where parameter is optional, it could be the cb... | ||
if (typeof where === 'function' && typeof cb !== 'function') { | ||
cb = where; | ||
where = null; | ||
} | ||
else if (typeof where === 'undefined' && typeof cb !== 'function') { | ||
throw new Error("No cb function has been provided in your update call!"); | ||
} | ||
else if (typeof where === 'undefined' || where === false || (where !== null && typeof where === 'object' && where.length == 0)) { | ||
where = null; | ||
} | ||
// TODO: Write this complicated-ass function | ||
update_batch: function(table,set,index,where,callback) { | ||
// The where parameter is optional, it could be the callback... | ||
if (typeof where === 'function' && typeof callback !== 'function') { | ||
callback = where; | ||
where = null; | ||
} | ||
else if (typeof where === 'undefined' && typeof callback !== 'function') { | ||
throw new Error("No callback function has been provided in your update_batch call!"); | ||
} | ||
else if (typeof where === 'undefined' || where === false || (where !== null && typeof where === 'object' && where.length == 0)) { | ||
where = null; | ||
} | ||
const sql = this._update(table, set, where); | ||
this.reset_query(sql); | ||
this._exec(sql, cb); | ||
} | ||
const sqls = qb.update_batch(table,set,index,where); | ||
const results = null; | ||
const errors = []; | ||
// TODO: Write this complicated-ass function | ||
update_batch(table,set,index,where,cb) { | ||
// The where parameter is optional, it could be the cb... | ||
if (typeof where === 'function' && typeof cb !== 'function') { | ||
cb = where; | ||
where = null; | ||
} | ||
else if (typeof where === 'undefined' && typeof cb !== 'function') { | ||
throw new Error("No cb function has been provided in your update_batch call!"); | ||
} | ||
else if (typeof where === 'undefined' || where === false || (where !== null && typeof where === 'object' && where.length == 0)) { | ||
where = null; | ||
} | ||
// Execute each batch of (at least) 100 | ||
(function next_batch() { | ||
const sql = sqls.shift(); | ||
qb.reset_query(sql); | ||
const sqls = this._update_batch(table, set, index, where); | ||
const results = null; | ||
const errors = []; | ||
exec(sql, (err, res) => { | ||
if (!err) { | ||
if (null === results) { | ||
results = res; | ||
} else { | ||
results.affected_rows += res.affected_rows; | ||
results.changed_rows += res.changed_rows; | ||
} | ||
} else { | ||
errors.push(err); | ||
} | ||
// Execute each batch of (at least) 100 | ||
(function next_batch() { | ||
const sql = sqls.shift(); | ||
this.reset_query(sql); | ||
if (sqls.length > 0) { | ||
setTimeout(next_batch,0); | ||
this._exec(sql, (err, res) => { | ||
if (!err) { | ||
if (null === results) { | ||
results = res; | ||
} else { | ||
return callback(errors, results); | ||
results.affected_rows += res.affected_rows; | ||
results.changed_rows += res.changed_rows; | ||
} | ||
}); | ||
})(); | ||
}, | ||
} else { | ||
errors.push(err); | ||
} | ||
delete: function(table, where, callback) { | ||
if (typeof where === 'function' && typeof callback !== 'function') { | ||
callback = where; | ||
where = undefined; | ||
} | ||
if (sqls.length > 0) { | ||
setTimeout(next_batch,0); | ||
} else { | ||
return cb(errors, results); | ||
} | ||
}); | ||
})(); | ||
} | ||
if (typeof table === 'function' && typeof callback !== 'function') { | ||
callback = table; | ||
table = undefined; | ||
where = undefined; | ||
} | ||
delete(table, where, cb) { | ||
if (typeof where === 'function' && typeof cb !== 'function') { | ||
cb = where; | ||
where = undefined; | ||
} | ||
if (typeof callback !== 'function') { | ||
throw new Error("delete(): No callback function has been provided!"); | ||
} | ||
if (typeof table === 'function' && typeof cb !== 'function') { | ||
cb = table; | ||
table = undefined; | ||
where = undefined; | ||
} | ||
const sql = qb.delete(table, where); | ||
if (typeof cb !== 'function') { | ||
throw new Error("delete(): No callback function has been provided!"); | ||
} | ||
qb.reset_query(sql); | ||
exec(sql,callback); | ||
}, | ||
const sql = this._delete(table, where); | ||
empty_table: function(table, callback) { | ||
const sql = qb.empty_table(table,callback); | ||
qb.reset_query(sql); | ||
exec(sql,callback); | ||
}, | ||
this.reset_query(sql); | ||
this._exec(sql,cb); | ||
} | ||
truncate: function(table, callback) { | ||
const sql = qb.truncate(table,callback); | ||
qb.reset_query(sql); | ||
exec(sql,callback); | ||
}, | ||
empty_table(table, cb) { | ||
const sql = this._empty_table(table,cb); | ||
this.reset_query(sql); | ||
this._exec(sql,cb); | ||
} | ||
truncate(table, cb) { | ||
const sql = this._truncate(table,cb); | ||
this.reset_query(sql); | ||
this._exec(sql,cb); | ||
} | ||
} | ||
exports.QueryExec = QueryExec; | ||
module.exports = QueryExec; |
@@ -7,2 +7,26 @@ # Changes | ||
## v2.0.0 (2018-06-15) | ||
### Breaking Changes | ||
* Changed the Query Builder instantiation syntax | ||
* Passing an empty array to `where_in` and `where_not_in` no longer throws an error ([#34](https://github.com/kylefarris/node-querybuilder/issues/34)) | ||
# General Enhancements/Changes/Features | ||
* Added mssql (t-sql) support using `tedious` as the underlying driver | ||
* Updated class files to use new ES6 class syntax for easier-maintainability | ||
* Added new options: | ||
** `pool_min` (minimum number of pooled connections (`mssql` driver only)) | ||
** `acquireTimeout` (milliseconds before a timeout occurs during the connection acquisition) | ||
* Added new query building method: `returning()` to allow for insert IDs to be returned. See docs for more info. | ||
* Added new tests | ||
### Bug Fixes | ||
* Fixed [#18](https://github.com/kylefarris/node-querybuilder/issues/18) | ||
* Fixed [#23](https://github.com/kylefarris/node-querybuilder/issues/23) | ||
* Fixed [#26](https://github.com/kylefarris/node-querybuilder/issues/26) | ||
* Fixed [#28](https://github.com/kylefarris/node-querybuilder/issues/28) | ||
* Fixed [#30](https://github.com/kylefarris/node-querybuilder/issues/30) | ||
* Fixed [#33](https://github.com/kylefarris/node-querybuilder/issues/33) | ||
## v1.2.0 (2018-05-18) | ||
@@ -9,0 +33,0 @@ |
176
index.js
/** | ||
* QueryBuilder for Node.js | ||
* (C) Kyle Farris 2014-2015 | ||
* (C) Kyle Farris 2014-2018 | ||
* kyle@chomponllc.com | ||
@@ -41,92 +41,106 @@ * | ||
**/ | ||
const lo_assign = require('lodash.assign'); | ||
const QueryBuilder = (settings,driver,type) => { | ||
class QueryBuilder { | ||
constructor(settings, driver, type) { | ||
this.settings = (settings ? Object.assign({}, settings) : {}); | ||
this.driver = driver || 'mysql'; | ||
this.connection_type = type || 'single'; | ||
this.drivers = require('./drivers/drivers.json'); | ||
this.driver_version = 'default'; | ||
this.driver_info = null; | ||
this.pool = []; | ||
this.settings = (settings ? lo_assign({}, settings) : {}); | ||
this.driver = driver || 'mysql'; | ||
this.connection_type = type || 'single'; | ||
this.drivers = require('./drivers/drivers.json'); | ||
this.driver_version = 'default'; | ||
this.driver_info = null; | ||
this.pool = []; | ||
this.get_driver_info(); | ||
this.get_connection_type(); | ||
return this.get_adapter(); | ||
} | ||
// **************************************************************************** | ||
// Get information about the driver the user wants to use and modify QB object | ||
// ----- | ||
// @param Object qb The QueryBuilder object | ||
// @return Object Modified QueryBuilder object | ||
// **************************************************************************** | ||
const get_driver_info = qb => { | ||
// A driver must be specified | ||
if (typeof this.driver !== 'string') { | ||
throw new Error("No database driver specified!"); | ||
} | ||
// **************************************************************************** | ||
// Get information about the driver the user wants to use and modify QB object | ||
// ----- | ||
// @return Object Modified QueryBuilder object | ||
// **************************************************************************** | ||
get_driver_info() { | ||
// A driver must be specified | ||
if (typeof this.driver !== 'string') { | ||
throw new Error("No database driver specified!"); | ||
} | ||
qb.driver = qb.driver.toLowerCase(); | ||
this.driver = this.driver.toLowerCase(); | ||
// Verify that the driver is one we fundamentally support | ||
if (Object.keys(qb.drivers).indexOf(qb.driver) === -1) { | ||
throw new Error("Invalid driver specified!"); | ||
} | ||
// Verify that the driver is one we fundamentally support | ||
if (Object.keys(this.drivers).indexOf(this.driver) === -1) { | ||
throw new Error("Invalid driver specified!"); | ||
} | ||
// Determine version of driver to use | ||
if (qb.settings.hasOwnProperty('version') && /^(string|number)$/i.test(typeof qb.settings.version)) { | ||
qb.driver_version = qb.settings.version; | ||
delete qb.settings.version; | ||
} | ||
// Determine version of driver to use | ||
if (this.settings.hasOwnProperty('version') && /^(string|number)$/i.test(typeof this.settings.version)) { | ||
this.driver_version = this.settings.version; | ||
delete this.settings.version; | ||
} | ||
// Retrieve info about driver if available, error if not | ||
if (qb.drivers[qb.driver].versions.hasOwnProperty(qb.driver_version)) { | ||
if (qb.drivers[qb.driver].versions[qb.driver_version].hasOwnProperty('version')) { | ||
qb.driver_info = qb.drivers[qb.driver].versions[qb.drivers[qb.driver].versions[qb.driver_version].version]; | ||
} else { | ||
qb.driver_info = qb.drivers[qb.driver].versions[qb.driver_version]; | ||
} | ||
} else { | ||
throw new Error(qb.driver_version + " is not a version of the " + qb.driver + " driver that this library specifically supports. Try being more generic."); | ||
} | ||
// Retrieve info about driver if available, error if not | ||
if (this.drivers[this.driver].versions.hasOwnProperty(this.driver_version)) { | ||
if (this.drivers[this.driver].versions[this.driver_version].hasOwnProperty('version')) { | ||
this.driver_info = this.drivers[this.driver].versions[this.drivers[this.driver].versions[this.driver_version].version]; | ||
} else { | ||
this.driver_info = this.drivers[this.driver].versions[this.driver_version]; | ||
} | ||
} else { | ||
throw new Error(`${this.driver_version} is not a version of the ${this.driver} driver that this library specifically supports. Try being more generic.`); | ||
} | ||
// Fail if specified driver is inactive | ||
if (qb.driver_info.active === false) { | ||
const err = (qb.driver_version == 'default' ? 'The default version' : "Version " + qb.driver_version) | ||
+ " of the " + qb.driver + " driver you are attempting to load is not currently available!"; | ||
throw new Error(err); | ||
} | ||
}; | ||
get_driver_info(this); | ||
// Fail if specified driver is inactive | ||
if (this.driver_info.active === false) { | ||
const err = (this.driver_version == 'default' ? 'The default version' : "Version " + this.driver_version) | ||
+ ` of the ${this.driver} driver you are attempting to load is not currently available!`; | ||
throw new Error(err); | ||
} | ||
} | ||
// **************************************************************************** | ||
// Determine the type of connection (single, pool, cluster, etc...) | ||
// ----- | ||
// @param Object qb The QueryBuilder object | ||
// @return Object Modified QueryBuilder object | ||
// **************************************************************************** | ||
const get_connection_type = qb => { | ||
if (!Object.keys(qb.drivers[qb.driver].connection_types).includes(qb.connection_type)) { | ||
throw new Error("You have specified a invalid database connection method: " + qb.connection_type); | ||
} | ||
if (qb.drivers[qb.driver].connection_types[qb.connection_type] !== true) { | ||
throw new Error("You cannot connect to a " + qb.driver + " database using the " + qb.connection_type + " connection type using this library."); | ||
} | ||
return qb; | ||
} | ||
get_connection_type(this); | ||
// **************************************************************************** | ||
// Determine the type of connection (single, pool, cluster, etc...) | ||
// ----- | ||
// @return Object Modified QueryBuilder object | ||
// **************************************************************************** | ||
get_connection_type() { | ||
if (!Object.keys(this.drivers[this.driver].connection_types).includes(this.connection_type)) { | ||
throw new Error(`You have specified a invalid database connection method: ${this.connection_type}`); | ||
} | ||
if (this.drivers[this.driver].connection_types[this.connection_type] !== true) { | ||
throw new Error(`You cannot connect to a ${this.driver} database using the ${this.connection_type} connection type using this library.`); | ||
} | ||
return this; | ||
} | ||
// **************************************************************************** | ||
// Returns the single, pool, or cluster adapter | ||
// ----- | ||
// @return VOID This method responds asychronously via a callback | ||
// **************************************************************************** | ||
const get_adapter = qb => { | ||
try { | ||
const adapter = require(qb.driver_info.path + 'adapters.js').Adapters(qb); | ||
return adapter; | ||
} catch(e) { | ||
throw new Error("Couldn't load the Connection library for " + qb.driver + "(" + JSON.stringify(qb.settings) + "): " + e); | ||
} | ||
}; | ||
// **************************************************************************** | ||
// Returns the single, pool, or cluster adapter | ||
// ----- | ||
// @return VOID This method responds asychronously via a callback | ||
// **************************************************************************** | ||
get_adapter() { | ||
const settings = Object.assign({}, this.settings); | ||
return get_adapter(this); | ||
}; | ||
let Single; | ||
exports.QueryBuilder = QueryBuilder; | ||
try { | ||
switch (this.connection_type) { | ||
case 'cluster': | ||
const Cluster = require(`${this.driver_info.path}/adapters/cluster.js`); | ||
return new Cluster(settings); | ||
case 'pool': | ||
const Pool = require(`${this.driver_info.path}/adapters/pool.js`) | ||
return new Pool(settings); | ||
case 'single': | ||
Single = require(`${this.driver_info.path}/adapters/single.js`) | ||
return new Single(settings, {}); | ||
default: | ||
Single = require(`${this.driver_info.path}/adapters/single.js`) | ||
return new Single(settings, {}); | ||
} | ||
} catch(e) { | ||
throw new Error(`Couldn't load the "${this.connection_type}" Adapter library for ${this.driver} (${JSON.stringify(this.settings)}): ${e}`); | ||
} | ||
} | ||
} | ||
module.exports = QueryBuilder; |
{ | ||
"name": "node-querybuilder", | ||
"version": "1.2.2", | ||
"version": "2.0.0-beta", | ||
"author": "Kyle Farris <kyle@chomponllc.com>", | ||
"description": "Modeled after Codeigniter's QueryBuilder. Build and execute queries in a safe and database-agnostic way.", | ||
"keywords": "nodejs, node, mysql, active record, activerecord, querybuilder, query builder, codeigniter, postgres, mssql, mongo, sqlite, translator", | ||
"bugs": "https://github.com/kylefarris/node-querybuilder/issues", | ||
"scripts": { | ||
@@ -21,13 +22,15 @@ "test": "make test" | ||
"dependencies": { | ||
"lodash.assign": "^4.0.7", | ||
"mysql": "^2.10.1" | ||
"mysql": "^2.10.1", | ||
"tedious": "^2.6.3", | ||
"tedious-connection-pool": "^1.0.5", | ||
"tsqlstring": "^1.0.0" | ||
}, | ||
"devDependencies": { | ||
"chai": "~1.4.2", | ||
"chai": "^4.1.2", | ||
"mocha": "*" | ||
}, | ||
"main": "./", | ||
"main": "index.js", | ||
"engines": { | ||
"node": "*" | ||
"node": ">=8.0" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
1650623
90
8472
2203
4
1
4
1
+ Addedtedious@^2.6.3
+ Addedtsqlstring@^1.0.0
+ Addedbabel-runtime@6.26.0(transitive)
+ Addedbig-number@0.3.1(transitive)
+ Addedbl@1.2.3(transitive)
+ Addedcore-js@2.6.12(transitive)
+ Addeddepd@1.1.2(transitive)
+ Addeddns-lookup-all@1.0.2(transitive)
+ Addediconv-lite@0.4.24(transitive)
+ Addednative-duplexpair@1.0.0(transitive)
+ Addedpunycode@2.3.1(transitive)
+ Addedregenerator-runtime@0.11.1(transitive)
+ Addedsafer-buffer@2.1.2(transitive)
+ Addedsemver@5.7.2(transitive)
+ Addedsprintf@0.1.5(transitive)
+ Addedsprintf-js@1.1.3(transitive)
+ Addedtedious@1.15.02.7.1(transitive)
+ Addedtedious-connection-pool@1.0.5(transitive)
+ Addedtsqlstring@1.0.1(transitive)
- Removedlodash.assign@^4.0.7
- Removedlodash.assign@4.2.0(transitive)